1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 07:28:11 +00:00

Kernel: Move all Graphics-related code into Devices/GPU directory

Like the HID, Audio and Storage subsystem, the Graphics subsystem (which
handles GPUs technically) exposes unix device files (typically in /dev).
To ensure consistency across the repository, move all related files to a
new directory under Kernel/Devices called "GPU".

Also remove the redundant "GPU" word from the VirtIO driver directory,
and the word "Graphics" from GraphicsManagement.{h,cpp} filenames.
This commit is contained in:
Liav A 2023-06-03 14:47:47 +03:00 committed by Jelle Raaijmakers
parent 31a7dabf02
commit 9ee098b119
69 changed files with 167 additions and 167 deletions

View file

@ -0,0 +1,89 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <Kernel/Arch/Delay.h>
#include <Kernel/Devices/GPU/Intel/Transcoder/AnalogDisplayTranscoder.h>
#include <Kernel/Memory/PhysicalAddress.h>
namespace Kernel {
ErrorOr<NonnullOwnPtr<IntelAnalogDisplayTranscoder>> IntelAnalogDisplayTranscoder::create_with_physical_addresses(PhysicalAddress transcoder_registers_start_address,
PhysicalAddress pipe_registers_start_address, PhysicalAddress dpll_registers_start_address, PhysicalAddress dpll_multiplier_register_start_address)
{
auto transcoder_registers_mapping = TRY(Memory::map_typed<TranscoderRegisters volatile>(transcoder_registers_start_address, sizeof(IntelDisplayTranscoder::TranscoderRegisters), Memory::Region::Access::ReadWrite));
auto pipe_registers_mapping = TRY(Memory::map_typed<PipeRegisters volatile>(pipe_registers_start_address, sizeof(IntelDisplayTranscoder::PipeRegisters), Memory::Region::Access::ReadWrite));
auto dpll_registers_mapping = TRY(Memory::map_typed<DPLLRegisters volatile>(dpll_registers_start_address, sizeof(DPLLRegisters), Memory::Region::Access::ReadWrite));
auto dpll_control_mapping = TRY(Memory::map_typed<DPLLControlRegisters volatile>(dpll_multiplier_register_start_address, sizeof(DPLLControlRegisters), Memory::Region::Access::ReadWrite));
return adopt_nonnull_own_or_enomem(new (nothrow) IntelAnalogDisplayTranscoder(move(transcoder_registers_mapping), move(pipe_registers_mapping), move(dpll_registers_mapping), move(dpll_control_mapping)));
}
IntelAnalogDisplayTranscoder::IntelAnalogDisplayTranscoder(Memory::TypedMapping<TranscoderRegisters volatile> transcoder_registers_mapping,
Memory::TypedMapping<PipeRegisters volatile> pipe_registers_mapping, Memory::TypedMapping<DPLLRegisters volatile> dpll_registers_mapping, Memory::TypedMapping<DPLLControlRegisters volatile> dpll_control_registers)
: IntelDisplayTranscoder(move(transcoder_registers_mapping), move(pipe_registers_mapping))
, m_dpll_registers(move(dpll_registers_mapping))
, m_dpll_control_registers(move(dpll_control_registers))
{
}
ErrorOr<void> IntelAnalogDisplayTranscoder::set_dpll_settings(Badge<IntelDisplayConnectorGroup>, IntelGraphics::PLLSettings const& settings, size_t dac_multiplier)
{
SpinlockLocker locker(m_access_lock);
u32 value = (settings.m2 - 2) | ((settings.m1 - 2) << 8) | ((settings.n - 2) << 16);
m_dpll_registers->divisor_a0 = value;
m_dpll_registers->divisor_a1 = value;
m_shadow_registers.dpll_divisor_a0 = value;
m_shadow_registers.dpll_divisor_a1 = value;
// Note: We don't set the DAC multiplier now but reserve it for later usage (e.g. when enabling the DPLL)
m_shadow_registers.dpll_reserved_dac_multiplier = dac_multiplier;
// Note: We don't set the DPLL P1 now but reserve it for later usage (e.g. when enabling the DPLL)
m_shadow_registers.dpll_p1 = settings.p1;
return {};
}
ErrorOr<void> IntelAnalogDisplayTranscoder::enable_dpll_without_vga(Badge<IntelDisplayConnectorGroup>)
{
SpinlockLocker locker(m_access_lock);
// Explanation for Gen4 DPLL control bits:
// 1. 0b0110 in bits 9 to 12 - use clock phase 6 (Default)
// 2. bits 24,25 - set to 0b00 to ensure FPA0/FPA1 (DPLL A Divisor 0, 1) divide by 10 (used for DAC modes under 270 MHz)
// 3. bit 26 - set to 0b1 to ensure mode select to DAC mode
// 4. bit 28 - set to 0b1 to disable VGA mode
// 5. bit 31 - enable DPLL VCO (DPLL enabled and operational)
u32 control_value = (6 << 9) | (m_shadow_registers.dpll_p1) << 16 | (1 << 26) | (1 << 28) | (1 << 31);
m_dpll_control_registers->control = control_value;
m_shadow_registers.dpll_control = control_value;
// Explanation for Gen4 DPLL multiplier bits:
// 1. 0b0110 in bits 9 to 12 - use clock phase 6 (Default)
// 2. bits 24,25 - set to 0b00 to ensure FPA0/FPA1 (DPLL A Divisor 0, 1) divide by 10 (used for DAC modes under 270 MHz)
// 3. bit 26 - set to 0b1 to ensure mode select to DAC mode
// 4. bit 28 - set to 0b1 to disable VGA mode
// 5. bit 31 - enable DPLL VCO (DPLL enabled and operational)
u32 dac_multiplier_value = (m_shadow_registers.dpll_reserved_dac_multiplier - 1) | ((m_shadow_registers.dpll_reserved_dac_multiplier - 1) << 8);
m_dpll_control_registers->multiplier = dac_multiplier_value;
m_shadow_registers.dpll_raw_dac_multiplier = dac_multiplier_value;
// The specification says we should wait (at least) about 150 microseconds
// after enabling the DPLL to allow the clock to stabilize
microseconds_delay(200);
for (size_t milliseconds_elapsed = 0; milliseconds_elapsed < 5; milliseconds_elapsed++) {
u32 control_value = m_dpll_control_registers->control;
if (control_value & (1 << 31))
return {};
}
return Error::from_errno(EBUSY);
}
ErrorOr<void> IntelAnalogDisplayTranscoder::disable_dpll(Badge<IntelDisplayConnectorGroup>)
{
SpinlockLocker locker(m_access_lock);
m_dpll_control_registers->control = 0;
m_shadow_registers.dpll_control = 0;
return {};
}
}

View file

@ -0,0 +1,42 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/RefPtr.h>
#include <AK/Try.h>
#include <AK/Types.h>
#include <Kernel/Devices/GPU/Intel/Transcoder/DisplayTranscoder.h>
namespace Kernel {
class IntelDisplayConnectorGroup;
class IntelAnalogDisplayTranscoder final : public IntelDisplayTranscoder {
public:
static ErrorOr<NonnullOwnPtr<IntelAnalogDisplayTranscoder>> create_with_physical_addresses(PhysicalAddress transcoder_registers_start_address,
PhysicalAddress pipe_registers_start_address, PhysicalAddress dpll_registers_start_address, PhysicalAddress dpll_control_registers_start_address);
virtual ErrorOr<void> set_dpll_settings(Badge<IntelDisplayConnectorGroup>, IntelGraphics::PLLSettings const& settings, size_t dac_multiplier) override;
virtual ErrorOr<void> enable_dpll_without_vga(Badge<IntelDisplayConnectorGroup>) override;
virtual ErrorOr<void> disable_dpll(Badge<IntelDisplayConnectorGroup>) override;
private:
struct [[gnu::packed]] DPLLRegisters {
u32 divisor_a0;
u32 divisor_a1;
};
struct [[gnu::packed]] DPLLControlRegisters {
u32 control;
u32 padding; // On Gen4, this is the control register of DPLL B, don't touch this
u32 multiplier;
};
IntelAnalogDisplayTranscoder(Memory::TypedMapping<TranscoderRegisters volatile>, Memory::TypedMapping<PipeRegisters volatile>, Memory::TypedMapping<DPLLRegisters volatile>, Memory::TypedMapping<DPLLControlRegisters volatile>);
Memory::TypedMapping<DPLLRegisters volatile> m_dpll_registers;
Memory::TypedMapping<DPLLControlRegisters volatile> m_dpll_control_registers;
};
}

View file

@ -0,0 +1,110 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <Kernel/Arch/Delay.h>
#include <Kernel/Devices/GPU/Intel/Transcoder/DisplayTranscoder.h>
#include <Kernel/Memory/PhysicalAddress.h>
namespace Kernel {
IntelDisplayTranscoder::IntelDisplayTranscoder(Memory::TypedMapping<TranscoderRegisters volatile> registers_mapping, Memory::TypedMapping<PipeRegisters volatile> pipe_registers_mapping)
: m_transcoder_registers(move(registers_mapping))
, m_pipe_registers(move(pipe_registers_mapping))
{
}
IntelDisplayTranscoder::ShadowRegisters IntelDisplayTranscoder::current_registers_state() const
{
SpinlockLocker locker(m_access_lock);
return m_shadow_registers;
}
ErrorOr<void> IntelDisplayTranscoder::set_mode_setting_timings(Badge<IntelDisplayConnectorGroup>, DisplayConnector::ModeSetting const& mode_setting)
{
SpinlockLocker locker(m_access_lock);
dbgln_if(INTEL_GRAPHICS_DEBUG, "htotal - {}, {}", (mode_setting.horizontal_active - 1), (mode_setting.horizontal_total() - 1));
m_shadow_registers.horizontal_total = ((mode_setting.horizontal_active - 1) | (mode_setting.horizontal_total() - 1) << 16);
m_transcoder_registers->horizontal_total = ((mode_setting.horizontal_active - 1) | (mode_setting.horizontal_total() - 1) << 16);
dbgln_if(INTEL_GRAPHICS_DEBUG, "hblank - {}, {}", (mode_setting.horizontal_blanking_start() - 1), (mode_setting.horizontal_blanking_start() + mode_setting.horizontal_blank_pixels - 1));
m_shadow_registers.horizontal_blank = ((mode_setting.horizontal_blanking_start() - 1) | (mode_setting.horizontal_blanking_start() + mode_setting.horizontal_blank_pixels - 1) << 16);
m_transcoder_registers->horizontal_blank = ((mode_setting.horizontal_blanking_start() - 1) | (mode_setting.horizontal_blanking_start() + mode_setting.horizontal_blank_pixels - 1) << 16);
dbgln_if(INTEL_GRAPHICS_DEBUG, "hsync - {}, {}", (mode_setting.horizontal_sync_start() - 1), (mode_setting.horizontal_sync_end() - 1));
m_shadow_registers.horizontal_sync = ((mode_setting.horizontal_sync_start() - 1) | (mode_setting.horizontal_sync_end() - 1) << 16);
m_transcoder_registers->horizontal_sync = ((mode_setting.horizontal_sync_start() - 1) | (mode_setting.horizontal_sync_end() - 1) << 16);
dbgln_if(INTEL_GRAPHICS_DEBUG, "vtotal - {}, {}", (mode_setting.vertical_active - 1), (mode_setting.vertical_blanking_start() + mode_setting.vertical_blank_lines - 1));
m_shadow_registers.vertical_total = ((mode_setting.vertical_active - 1) | (mode_setting.vertical_blanking_start() + mode_setting.vertical_blank_lines - 1) << 16);
m_transcoder_registers->vertical_total = ((mode_setting.vertical_active - 1) | (mode_setting.vertical_blanking_start() + mode_setting.vertical_blank_lines - 1) << 16);
dbgln_if(INTEL_GRAPHICS_DEBUG, "vblank - {}, {}", (mode_setting.vertical_blanking_start() - 1), (mode_setting.vertical_blanking_start() + mode_setting.vertical_blank_lines - 1));
m_shadow_registers.vertical_blank = ((mode_setting.vertical_blanking_start() - 1) | (mode_setting.vertical_blanking_start() + mode_setting.vertical_blank_lines - 1) << 16);
m_transcoder_registers->vertical_blank = ((mode_setting.vertical_blanking_start() - 1) | (mode_setting.vertical_blanking_start() + mode_setting.vertical_blank_lines - 1) << 16);
dbgln_if(INTEL_GRAPHICS_DEBUG, "vsync - {}, {}", (mode_setting.vertical_sync_start() - 1), (mode_setting.vertical_sync_end() - 1));
m_shadow_registers.vertical_sync = ((mode_setting.vertical_sync_start() - 1) | (mode_setting.vertical_sync_end() - 1) << 16);
m_transcoder_registers->vertical_sync = ((mode_setting.vertical_sync_start() - 1) | (mode_setting.vertical_sync_end() - 1) << 16);
dbgln_if(INTEL_GRAPHICS_DEBUG, "sourceSize - {}, {}", (mode_setting.vertical_active - 1), (mode_setting.horizontal_active - 1));
m_shadow_registers.pipe_source = ((mode_setting.vertical_active - 1) | (mode_setting.horizontal_active - 1) << 16);
m_transcoder_registers->pipe_source = ((mode_setting.vertical_active - 1) | (mode_setting.horizontal_active - 1) << 16);
return {};
}
ErrorOr<void> IntelDisplayTranscoder::disable_pipe(Badge<IntelDisplayConnectorGroup>)
{
SpinlockLocker locker(m_access_lock);
m_pipe_registers->pipe_configuration = 0;
m_shadow_registers.pipe_conf = 0;
dbgln_if(INTEL_GRAPHICS_DEBUG, "Disabling Pipe");
size_t milliseconds_elapsed = 0;
while (milliseconds_elapsed < 100) {
u32 value = m_pipe_registers->pipe_configuration;
if (!(value & (1 << 30)))
return {};
microseconds_delay(1000);
milliseconds_elapsed++;
}
return Error::from_errno(EBUSY);
}
ErrorOr<void> IntelDisplayTranscoder::enable_pipe(Badge<IntelDisplayConnectorGroup>)
{
SpinlockLocker locker(m_access_lock);
u32 value = m_pipe_registers->pipe_configuration;
// Note: Just verify these are not already enabled...
if ((value & (1 << 30)) && (value & (1 << 31)))
return {};
// Note: Set the pipe configuration register with these bits:
// 1. Bit 31 - to enable the Pipe
// 2. Bit 24 - to enable Gamma Unit Mode to 10 bit Gamma mode.
// 3. Bits 21-23 are set to zero to indicate Progressive mode (non Interlaced mode)
// 4. Bits 18 and 19 are set to zero to indicate Normal operations of assigned
// Cursor and Display planes.
m_pipe_registers->pipe_configuration = (1 << 31) | (1 << 24);
m_shadow_registers.pipe_conf = (1 << 31) | (1 << 24);
dbgln_if(INTEL_GRAPHICS_DEBUG, "Enabling Pipe");
size_t milliseconds_elapsed = 0;
while (milliseconds_elapsed < 100) {
u32 value = m_pipe_registers->pipe_configuration;
if ((value & (1 << 30)))
return {};
microseconds_delay(1000);
milliseconds_elapsed++;
}
// FIXME: Seems like my video card is buggy and doesn't set the enabled bit (bit 30)!!
return {};
}
bool IntelDisplayTranscoder::pipe_enabled(Badge<IntelDisplayConnectorGroup>) const
{
SpinlockLocker locker(m_access_lock);
u32 value = m_pipe_registers->pipe_configuration;
return (value & (1 << 30));
}
}

View file

@ -0,0 +1,118 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/RefPtr.h>
#include <AK/Try.h>
#include <AK/Types.h>
#include <Kernel/Devices/GPU/DisplayConnector.h>
#include <Kernel/Devices/GPU/Intel/Definitions.h>
#include <Kernel/Locking/Spinlock.h>
#include <Kernel/Memory/TypedMapping.h>
namespace Kernel {
class IntelDisplayConnectorGroup;
class IntelDisplayTranscoder {
public:
// Note: This is used to "cache" all the registers we wrote to, because
// we might not be able to read them directly from hardware later.
struct ShadowRegisters {
u32 horizontal_total;
u32 horizontal_blank;
u32 horizontal_sync;
u32 vertical_total;
u32 vertical_blank;
u32 vertical_sync;
u32 exit_line;
u32 pipe_source;
u32 pipe_border_color_pattern;
u32 reserved;
u32 vsync_shift;
u32 pipe_mult;
u32 dpll_reserved_dac_multiplier;
u32 dpll_raw_dac_multiplier;
u32 dpll_divisor_a0;
u32 dpll_divisor_a1;
u32 dpll_p1;
u32 dpll_control;
u32 m1_value;
u32 n1_value;
u32 m2_value;
u32 n2_value;
u32 m1_link;
u32 n1_link;
u32 m2_link;
u32 n2_link;
u32 pipe_conf;
};
ErrorOr<void> set_mode_setting_timings(Badge<IntelDisplayConnectorGroup>, DisplayConnector::ModeSetting const&);
virtual ErrorOr<void> set_dpll_settings(Badge<IntelDisplayConnectorGroup>, IntelGraphics::PLLSettings const& settings, size_t dac_multiplier) = 0;
virtual ErrorOr<void> enable_dpll_without_vga(Badge<IntelDisplayConnectorGroup>) = 0;
virtual ErrorOr<void> disable_dpll(Badge<IntelDisplayConnectorGroup>) = 0;
ErrorOr<void> disable_pipe(Badge<IntelDisplayConnectorGroup>);
ErrorOr<void> enable_pipe(Badge<IntelDisplayConnectorGroup>);
bool pipe_enabled(Badge<IntelDisplayConnectorGroup>) const;
ShadowRegisters current_registers_state() const;
virtual ~IntelDisplayTranscoder() = default;
protected:
struct [[gnu::packed]] TranscoderRegisters {
u32 horizontal_total;
u32 horizontal_blank;
u32 horizontal_sync;
u32 vertical_total;
u32 vertical_blank;
u32 vertical_sync;
u32 exit_line;
u32 pipe_source;
u32 pipe_border_color_pattern;
u32 reserved;
u32 vsync_shift;
u32 pipe_mult;
u32 m1_value;
u32 n1_value;
u32 m2_value;
u32 n2_value;
u32 m1_link;
u32 n1_link;
u32 m2_link;
u32 n2_link;
};
struct [[gnu::packed]] PipeRegisters {
u32 pipe_display_scan_line;
u32 pipe_display_scan_line_count_range_compare;
u32 pipe_configuration;
u32 reserved;
u32 pipe_gamma_correction_max_red;
u32 pipe_gamma_correction_max_green;
u32 pipe_gamma_correction_max_blue;
u32 reserved2[2];
u32 pipe_display_status;
u32 reserved3[2];
u32 display_arbitration_control;
u32 display_fifo_watermark_control1;
u32 display_fifo_watermark_control2;
u32 display_fifo_watermark_control3;
u32 pipe_frame_count_high;
// Note: The specification calls this "Pipe Frame Count Low and Pixel Count"
u32 pipe_frame_count_low;
};
IntelDisplayTranscoder(Memory::TypedMapping<TranscoderRegisters volatile>, Memory::TypedMapping<PipeRegisters volatile>);
mutable Spinlock<LockRank::None> m_access_lock;
ShadowRegisters m_shadow_registers {};
Memory::TypedMapping<TranscoderRegisters volatile> m_transcoder_registers;
Memory::TypedMapping<PipeRegisters volatile> m_pipe_registers;
};
}

View file

@ -0,0 +1,125 @@
/*
* Copyright (c) 2023, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/Format.h>
#include <Kernel/Debug.h>
#include <Kernel/Devices/GPU/Intel/Transcoder/PLL.h>
namespace Kernel::IntelGraphics {
static constexpr PLLMaxSettings g35limits {
{ 20'000'000, 400'000'000 }, // values in Hz, dot_clock
{ 1'400'000'000, 2'800'000'000 }, // values in Hz, VCO
{ 3, 8 }, // n
{ 70, 120 }, // m
{ 10, 20 }, // m1
{ 5, 9 }, // m2
{ 5, 80 }, // p
{ 1, 8 }, // p1
{ 5, 10 } // p2
};
PLLMaxSettings const& pll_max_settings_for_generation(Generation generation)
{
switch (generation) {
case Generation::Gen4:
return g35limits;
default:
VERIFY_NOT_REACHED();
}
}
static size_t find_absolute_difference(u64 target_frequency, u64 checked_frequency)
{
if (target_frequency >= checked_frequency)
return target_frequency - checked_frequency;
return checked_frequency - target_frequency;
}
Optional<PLLSettings> create_pll_settings(Generation generation, u64 target_frequency, u64 reference_clock)
{
PLLSettings settings {};
PLLSettings best_settings {};
auto& limits = pll_max_settings_for_generation(generation);
// FIXME: Is this correct for all Intel Native graphics cards?
settings.p2 = 10;
dbgln_if(INTEL_GRAPHICS_DEBUG, "Check PLL settings for ref clock of {} Hz, for target of {} Hz", reference_clock, target_frequency);
u64 best_difference = 0xffffffff;
for (settings.n = limits.n.min; settings.n <= limits.n.max; ++settings.n) {
for (settings.m1 = limits.m1.max; settings.m1 >= limits.m1.min; --settings.m1) {
for (settings.m2 = limits.m2.max; settings.m2 >= limits.m2.min; --settings.m2) {
for (settings.p1 = limits.p1.max; settings.p1 >= limits.p1.min; --settings.p1) {
dbgln_if(INTEL_GRAPHICS_DEBUG, "Check PLL settings for {} {} {} {} {}", settings.n, settings.m1, settings.m2, settings.p1, settings.p2);
if (!check_pll_settings(settings, reference_clock, limits))
continue;
auto current_dot_clock = settings.compute_dot_clock(reference_clock);
if (current_dot_clock == target_frequency)
return settings;
auto difference = find_absolute_difference(target_frequency, current_dot_clock);
if (difference < best_difference && (current_dot_clock > target_frequency)) {
best_settings = settings;
best_difference = difference;
}
}
}
}
}
if (best_settings.is_valid())
return best_settings;
return {};
}
bool check_pll_settings(PLLSettings const& settings, size_t reference_clock, PLLMaxSettings const& limits)
{
if (settings.n < limits.n.min || settings.n > limits.n.max) {
dbgln_if(INTEL_GRAPHICS_DEBUG, "N is invalid {}", settings.n);
return false;
}
if (settings.m1 < limits.m1.min || settings.m1 > limits.m1.max) {
dbgln_if(INTEL_GRAPHICS_DEBUG, "m1 is invalid {}", settings.m1);
return false;
}
if (settings.m2 < limits.m2.min || settings.m2 > limits.m2.max) {
dbgln_if(INTEL_GRAPHICS_DEBUG, "m2 is invalid {}", settings.m2);
return false;
}
if (settings.p1 < limits.p1.min || settings.p1 > limits.p1.max) {
dbgln_if(INTEL_GRAPHICS_DEBUG, "p1 is invalid {}", settings.p1);
return false;
}
if (settings.m1 <= settings.m2) {
dbgln_if(INTEL_GRAPHICS_DEBUG, "m2 is invalid {} as it is bigger than m1 {}", settings.m2, settings.m1);
return false;
}
auto m = settings.compute_m();
auto p = settings.compute_p();
if (m < limits.m.min || m > limits.m.max) {
dbgln_if(INTEL_GRAPHICS_DEBUG, "m invalid {}", m);
return false;
}
if (p < limits.p.min || p > limits.p.max) {
dbgln_if(INTEL_GRAPHICS_DEBUG, "p invalid {}", p);
return false;
}
auto dot = settings.compute_dot_clock(reference_clock);
auto vco = settings.compute_vco(reference_clock);
if (dot < limits.dot_clock.min || dot > limits.dot_clock.max) {
dbgln_if(INTEL_GRAPHICS_DEBUG, "Dot clock invalid {}", dot);
return false;
}
if (vco < limits.vco.min || vco > limits.vco.max) {
dbgln_if(INTEL_GRAPHICS_DEBUG, "VCO clock invalid {}", vco);
return false;
}
return true;
}
}

View file

@ -0,0 +1,18 @@
/*
* Copyright (c) 2023, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Optional.h>
#include <Kernel/Devices/GPU/Intel/Definitions.h>
namespace Kernel::IntelGraphics {
PLLMaxSettings const& pll_max_settings_for_generation(Generation);
Optional<PLLSettings> create_pll_settings(Generation, u64 target_frequency, u64 reference_clock);
bool check_pll_settings(PLLSettings const& settings, size_t reference_clock, PLLMaxSettings const& limits);
}