NativeGraphicsAdapter.h 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. /*
  2. * Copyright (c) 2021, Liav A. <liavalb@hotmail.co.il>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/String.h>
  8. #include <AK/Types.h>
  9. #include <Kernel/Bus/PCI/Device.h>
  10. #include <Kernel/Graphics/Definitions.h>
  11. #include <Kernel/Graphics/FramebufferDevice.h>
  12. #include <Kernel/Graphics/VGACompatibleAdapter.h>
  13. #include <Kernel/PhysicalAddress.h>
  14. namespace Kernel {
  15. namespace IntelGraphics {
  16. enum RegisterIndex {
  17. PipeAConf = 0x70008,
  18. PipeBConf = 0x71008,
  19. GMBusData = 0x510C,
  20. GMBusStatus = 0x5108,
  21. GMBusCommand = 0x5104,
  22. GMBusClock = 0x5100,
  23. DisplayPlaneAControl = 0x70180,
  24. DisplayPlaneALinearOffset = 0x70184,
  25. DisplayPlaneAStride = 0x70188,
  26. DisplayPlaneASurface = 0x7019C,
  27. DPLLDivisorA0 = 0x6040,
  28. DPLLDivisorA1 = 0x6044,
  29. DPLLControlA = 0x6014,
  30. DPLLControlB = 0x6018,
  31. DPLLMultiplierA = 0x601C,
  32. HTotalA = 0x60000,
  33. HBlankA = 0x60004,
  34. HSyncA = 0x60008,
  35. VTotalA = 0x6000C,
  36. VBlankA = 0x60010,
  37. VSyncA = 0x60014,
  38. PipeASource = 0x6001C,
  39. AnalogDisplayPort = 0x61100,
  40. VGADisplayPlaneControl = 0x71400,
  41. };
  42. }
  43. class IntelNativeGraphicsAdapter final
  44. : public VGACompatibleAdapter {
  45. AK_MAKE_ETERNAL
  46. public:
  47. struct PLLSettings {
  48. bool is_valid() const { return (n != 0 && m1 != 0 && m2 != 0 && p1 != 0 && p2 != 0); }
  49. u64 compute_dot_clock(u64 refclock) const
  50. {
  51. return (refclock * (5 * (m1) + (m2)) / (n)) / (p1 * p2);
  52. }
  53. u64 compute_vco(u64 refclock) const
  54. {
  55. return refclock * (5 * (m1) + (m2)) / n;
  56. }
  57. u64 compute_m() const
  58. {
  59. return 5 * (m1) + (m2);
  60. }
  61. u64 compute_p() const
  62. {
  63. return p1 * p2;
  64. }
  65. u64 n { 0 };
  66. u64 m1 { 0 };
  67. u64 m2 { 0 };
  68. u64 p1 { 0 };
  69. u64 p2 { 0 };
  70. };
  71. struct PLLParameterLimit {
  72. size_t min, max;
  73. };
  74. struct PLLMaxSettings {
  75. PLLParameterLimit dot_clock, vco, n, m, m1, m2, p, p1, p2;
  76. };
  77. private:
  78. enum GMBusPinPair : u8 {
  79. None = 0,
  80. DedicatedControl = 1,
  81. DedicatedAnalog = 0b10,
  82. IntegratedDigital = 0b11,
  83. sDVO = 0b101,
  84. Dconnector = 0b111,
  85. };
  86. enum class GMBusStatus {
  87. TransactionCompletion,
  88. HardwareReady
  89. };
  90. enum GMBusCycle {
  91. Wait = 1,
  92. Stop = 4,
  93. };
  94. public:
  95. static RefPtr<IntelNativeGraphicsAdapter> initialize(PCI::Address);
  96. private:
  97. explicit IntelNativeGraphicsAdapter(PCI::Address);
  98. void write_to_register(IntelGraphics::RegisterIndex, u32 value) const;
  99. u32 read_from_register(IntelGraphics::RegisterIndex) const;
  100. // ^GraphicsDevice
  101. virtual void initialize_framebuffer_devices() override;
  102. virtual Type type() const override { return Type::VGACompatible; }
  103. bool pipe_a_enabled() const;
  104. bool pipe_b_enabled() const;
  105. bool is_resolution_valid(size_t width, size_t height);
  106. bool set_crt_resolution(size_t width, size_t height);
  107. void disable_output();
  108. void enable_output(PhysicalAddress fb_address, size_t width);
  109. void disable_vga_emulation();
  110. void enable_vga_plane();
  111. void disable_dac_output();
  112. void enable_dac_output();
  113. void disable_all_planes();
  114. void disable_pipe_a();
  115. void disable_pipe_b();
  116. void disable_dpll();
  117. void set_dpll_registers(const PLLSettings&);
  118. void enable_dpll_without_vga(const PLLSettings&, size_t dac_multiplier);
  119. void set_display_timings(const Graphics::Modesetting&);
  120. void enable_pipe_a();
  121. void set_framebuffer_parameters(size_t, size_t);
  122. void enable_primary_plane(PhysicalAddress fb_address, size_t stride);
  123. bool wait_for_enabled_pipe_a(size_t milliseconds_timeout) const;
  124. bool wait_for_disabled_pipe_a(size_t milliseconds_timeout) const;
  125. bool wait_for_disabled_pipe_b(size_t milliseconds_timeout) const;
  126. void set_gmbus_default_rate();
  127. void set_gmbus_pin_pair(GMBusPinPair pin_pair);
  128. // FIXME: It would be better if we generalize the I2C access later on
  129. void gmbus_read_edid();
  130. void gmbus_write(unsigned address, u32 byte);
  131. void gmbus_read(unsigned address, u8* buf, size_t length);
  132. bool gmbus_wait_for(GMBusStatus desired_status, Optional<size_t> milliseconds_timeout);
  133. Optional<PLLSettings> create_pll_settings(u64 target_frequency, u64 reference_clock, const PLLMaxSettings&);
  134. Spinlock<u8> m_control_lock;
  135. Spinlock<u8> m_modeset_lock;
  136. mutable Spinlock<u8> m_registers_lock;
  137. Graphics::VideoInfoBlock m_crt_edid;
  138. const PhysicalAddress m_registers;
  139. const PhysicalAddress m_framebuffer_addr;
  140. OwnPtr<Memory::Region> m_registers_region;
  141. };
  142. }