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 <Kernel/Graphics/Console/GenericFramebufferConsole.h>
12#include <Kernel/Graphics/Intel/Auxiliary/GMBusConnector.h>
13#include <Kernel/Graphics/Intel/Definitions.h>
14#include <Kernel/Graphics/Intel/NativeDisplayConnector.h>
15#include <Kernel/Graphics/Intel/Plane/DisplayPlane.h>
16#include <Kernel/Graphics/Intel/Transcoder/DisplayTranscoder.h>
17#include <Kernel/Library/LockRefPtr.h>
18#include <Kernel/Memory/TypedMapping.h>
19#include <LibEDID/EDID.h>
20
21namespace Kernel {
22
23class IntelNativeGraphicsAdapter;
24class IntelDisplayConnectorGroup : public RefCounted<IntelDisplayConnectorGroup> {
25 friend class IntelNativeGraphicsAdapter;
26
27public:
28 struct MMIORegion {
29 enum class BARAssigned {
30 BAR0,
31 BAR2,
32 };
33 BARAssigned pci_bar_assigned;
34 PhysicalAddress pci_bar_paddr;
35 size_t pci_bar_space_length;
36 };
37
38private:
39 AK_TYPEDEF_DISTINCT_ORDERED_ID(size_t, RegisterOffset);
40
41 enum class AnalogOutputRegisterOffset {
42 AnalogDisplayPort = 0x61100,
43 VGADisplayPlaneControl = 0x71400,
44 };
45
46public:
47 static ErrorOr<NonnullLockRefPtr<IntelDisplayConnectorGroup>> try_create(Badge<IntelNativeGraphicsAdapter>, IntelGraphics::Generation, MMIORegion const&, MMIORegion const&);
48
49 ErrorOr<void> set_safe_mode_setting(Badge<IntelNativeDisplayConnector>, IntelNativeDisplayConnector&);
50 ErrorOr<void> set_mode_setting(Badge<IntelNativeDisplayConnector>, IntelNativeDisplayConnector&, DisplayConnector::ModeSetting const&);
51
52private:
53 IntelDisplayConnectorGroup(IntelGraphics::Generation generation, NonnullOwnPtr<GMBusConnector>, NonnullOwnPtr<Memory::Region> registers_region, MMIORegion const&, MMIORegion const&);
54
55 ErrorOr<void> set_mode_setting(IntelNativeDisplayConnector&, DisplayConnector::ModeSetting const&);
56
57 StringView convert_analog_output_register_to_string(AnalogOutputRegisterOffset index) const;
58 void write_to_analog_output_register(AnalogOutputRegisterOffset, u32 value);
59 u32 read_from_analog_output_register(AnalogOutputRegisterOffset) const;
60 void write_to_general_register(RegisterOffset offset, u32 value);
61 u32 read_from_general_register(RegisterOffset offset) const;
62
63 // DisplayConnector initialization related methods
64 ErrorOr<void> initialize_connectors();
65 ErrorOr<void> initialize_gen4_connectors();
66
67 // General Modesetting methods
68 ErrorOr<void> set_gen4_mode_setting(IntelNativeDisplayConnector&, DisplayConnector::ModeSetting const&);
69
70 bool set_crt_resolution(DisplayConnector::ModeSetting const&);
71
72 void disable_vga_emulation();
73 void enable_vga_plane();
74
75 void disable_dac_output();
76 void enable_dac_output();
77
78 Spinlock<LockRank::None> m_control_lock;
79 Spinlock<LockRank::None> m_modeset_lock;
80 mutable Spinlock<LockRank::None> m_registers_lock;
81
82 // Note: The linux driver specifies an enum of possible ports and there is only
83 // 9 ports (PORT_{A-I}). PORT_TC{1-6} are mapped to PORT_{D-I}.
84 Array<LockRefPtr<IntelNativeDisplayConnector>, 9> m_connectors;
85
86 Array<OwnPtr<IntelDisplayTranscoder>, 5> m_transcoders;
87 Array<OwnPtr<IntelDisplayPlane>, 3> m_planes;
88
89 const MMIORegion m_mmio_first_region;
90 const MMIORegion m_mmio_second_region;
91 MMIORegion const& m_assigned_mmio_registers_region;
92
93 const IntelGraphics::Generation m_generation;
94 NonnullOwnPtr<Memory::Region> m_registers_region;
95 NonnullOwnPtr<GMBusConnector> m_gmbus_connector;
96};
97}