/* * 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/Graphics/DisplayConnector.h> #include <Kernel/Graphics/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; }; }