Serenity Operating System
1/*
2 * Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#pragma once
8
9#include <AK/RefPtr.h>
10#include <AK/Try.h>
11#include <AK/Types.h>
12#include <Kernel/Graphics/DisplayConnector.h>
13#include <Kernel/Graphics/Intel/Definitions.h>
14#include <Kernel/Locking/Spinlock.h>
15#include <Kernel/Memory/TypedMapping.h>
16
17namespace Kernel {
18
19class IntelDisplayConnectorGroup;
20class IntelDisplayPlane {
21public:
22 enum class PipeSelect {
23 PipeA,
24 PipeB,
25 PipeC,
26 PipeD,
27 };
28
29 // Note: This is used to "cache" all the registers we wrote to, because
30 // we might not be able to read them directly from hardware later.
31 struct ShadowRegisters {
32 u32 control;
33 u32 linear_offset;
34 u32 stride;
35 u32 surface_base;
36 };
37
38public:
39 static ErrorOr<NonnullOwnPtr<IntelDisplayPlane>> create_with_physical_address(PhysicalAddress plane_registers_start_address);
40
41 ErrorOr<void> set_horizontal_active_pixels_count(Badge<IntelDisplayConnectorGroup>, size_t horizontal_active_pixels_count);
42 ErrorOr<void> set_vertical_active_pixels_count(Badge<IntelDisplayConnectorGroup>, size_t vertical_active_pixels_count);
43 ErrorOr<void> set_horizontal_stride(Badge<IntelDisplayConnectorGroup>, size_t horizontal_stride);
44 ErrorOr<void> set_aperture_base(Badge<IntelDisplayConnectorGroup>, PhysicalAddress aperture_start);
45 ErrorOr<void> set_pipe(Badge<IntelDisplayConnectorGroup>, PipeSelect);
46
47 virtual ErrorOr<void> enable(Badge<IntelDisplayConnectorGroup>) = 0;
48 bool is_enabled(Badge<IntelDisplayConnectorGroup>);
49 ErrorOr<void> disable(Badge<IntelDisplayConnectorGroup>);
50
51 ShadowRegisters shadow_registers() const;
52
53 virtual ~IntelDisplayPlane() = default;
54
55protected:
56 struct [[gnu::packed]] PlaneRegisters {
57 u32 control;
58 u32 linear_offset;
59 u32 stride;
60 u8 padding[24]; // Note: This might contain other registers, don't touch them.
61 u32 surface_base;
62 };
63
64 explicit IntelDisplayPlane(Memory::TypedMapping<PlaneRegisters volatile> registers_mapping);
65 mutable Spinlock<LockRank::None> m_access_lock;
66 ShadowRegisters m_shadow_registers {};
67 Memory::TypedMapping<PlaneRegisters volatile> m_plane_registers;
68
69 // Note: The PipeSelect value is used only in planes until Skylake graphics.
70 PipeSelect m_pipe_select { PipeSelect::PipeA };
71
72 PhysicalAddress m_aperture_start;
73 size_t m_horizontal_stride { 0 };
74 size_t m_horizontal_active_pixels_count { 0 };
75 size_t m_vertical_active_pixels_count { 0 };
76};
77}