/* * Copyright (c) 2022, Liav A. * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include #include #include namespace Kernel { class IntelDisplayConnectorGroup; class IntelDisplayPlane { public: enum class PipeSelect { PipeA, PipeB, PipeC, PipeD, }; // 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 control; u32 linear_offset; u32 stride; u32 surface_base; }; public: static ErrorOr> create_with_physical_address(PhysicalAddress plane_registers_start_address); ErrorOr set_horizontal_active_pixels_count(Badge, size_t horizontal_active_pixels_count); ErrorOr set_vertical_active_pixels_count(Badge, size_t vertical_active_pixels_count); ErrorOr set_horizontal_stride(Badge, size_t horizontal_stride); ErrorOr set_aperture_base(Badge, PhysicalAddress aperture_start); ErrorOr set_pipe(Badge, PipeSelect); virtual ErrorOr enable(Badge) = 0; bool is_enabled(Badge); ErrorOr disable(Badge); ShadowRegisters shadow_registers() const; virtual ~IntelDisplayPlane() = default; protected: struct [[gnu::packed]] PlaneRegisters { u32 control; u32 linear_offset; u32 stride; u8 padding[24]; // Note: This might contain other registers, don't touch them. u32 surface_base; }; explicit IntelDisplayPlane(Memory::TypedMapping registers_mapping); mutable Spinlock m_access_lock; ShadowRegisters m_shadow_registers {}; Memory::TypedMapping m_plane_registers; // Note: The PipeSelect value is used only in planes until Skylake graphics. PipeSelect m_pipe_select { PipeSelect::PipeA }; PhysicalAddress m_aperture_start; size_t m_horizontal_stride { 0 }; size_t m_horizontal_active_pixels_count { 0 }; size_t m_vertical_active_pixels_count { 0 }; }; }