Intel HD Graphics
This page covers implementing driver support for Intel's integrated graphics technology. At the moment this only covers first generation 'Intel HD graphics’, codename Ironlake. Please note that graphics drivers are complex and while Intel's is on the simpler side, it is still a difficult topic not intended for newcomers, some experience writing drivers for other modern hardware is suggested before attempting this. Additionally, the reader is responsible for any damage due to inaccuracies in this documentation.
Experimenting with the device
There are various tools available to study the behavior of the graphics device for simpler tasks in order to gain an understanding of how something is done. One way to do so is to use Intel's graphics debugging utilities (The intel-gpu-tools package), which allow reading and writing to the device registers from the terminal. This can be very useful, for instance, this method proved invaluable when studying the GMBUS. The same can be done using GRUB2’s built in terminal by obtaining the MMIO base address using lspci and then using the read/write commands to perform the associated operation on the desired register.
Register Locations and Definitions
Many registers may move between generations or may be replaced completely with a different set of registers, an appropriate note will be made where possible, but it is recommended that this document be read alongside the programming reference manuals for the intended generation. Additionally, the register location definitions for the driver for Cardinal can be found Cardinal GitHub.
Some additional reading is highly recommended before tackling graphics/display drivers which will help clarify a lot of the designs and terminology used in the official PRMs. Understanding the following is recommended:
- Intel Integrated graphics Programming Reference Manuals (PRMs)
- OpenGL 4.0+/Vulkan/DirectX 9+: This is only really necessary if you intend to implement 3d acceleration. Understanding how the graphics pipeline functions and is structured at a higher level will help with understanding the hardware level structure exposed the graphics chipset.
Graphics Northbridge and Southbridge
The display controller pipeline structure is split among two components depending on their speed requirements and overall use. The Northbridge is connected directly to the processor, and is used for the built-in display as well as the display pipes and various planes. The Southbridge contains the external ports and the GMBUS (Graphics Management Bus). The GMBUS is an I2C compatible protocol used to communicate with devices to obtain information from them (such as the display's EDID). The two bridges communicate through a transmitter and receiver mechanism; this is done by assigning FDIs to displays on the Southbridge and configuring the display pipes on the Northbridge to receive from the assigned FDI. This system is discussed in detail in the #Display Pipeline Structure section.
PCI interface and graphics memory
The PCI BARs 0 (offset 0x10) and 2 (offset 0x18) contains the 64bit addresses for the MMIO region and snooped graphics memory respectively.
Built-in display backlight
The display backlight is controlled by a PWM (pulse width modulation) unit. For the built in LVDS display, the PWM initialization registers are present on the south bridge, while the actual control value is specified on a register on the North bridge.
Display detection can be done by either polling or using interrupts. The interrupt method will be discussed here.
GMBUS registers and the EDID
The GMBUS or Graphics Management Bus is an i2c compatible protocol used to communicate with the attached displays to obtain their information such as the EDID. At the moment it is unclear if this method can be used to read the EDID of a DisplayPort device as they utilize I2C over the DisplayPort AUX channel for this kind of communication.
To obtain the EDID for a device, we want to read 0x80 bytes from the I2C device index 0 of the desired device from an offset of 0x50.
The following execution sequence demonstrates how the first 8 bytes can be retrieved:
Display pipeline structure
Three types of display planes are available for each pipe, namely:
- Display plane
- Cursor plane
- Video/sprite plane
A VGA plane is also available, allowing for the use of the VGA emulation hardware present in every Intel graphics device, however it is very limiting and its use is discouraged by the author.
None of the planes besides the cursor plane (in pop-up cursor mode) can be enabled alongside the VGA plane.
The display plane provides the high resolution framebuffer and needs to be enabled for any of the other planes to function (besides the VGA plane).
As the name implies, the cursor plane provides hardware accelerated cursor drawing. Similarly, the video/sprite plane provides a second source which can be drawn on top of the display plane, its purpose is to allow for efficient use of the video decoding hardware by allowing the decoded data to be directly drawn to the window.
Simple mode set sequence
A simple mode set sequence can be used with the default/built-in display, assuming that the boot firmware has configured the display timings correctly. If not, it is necessary to perform a full mode set operation involving a display power cycle.
The steps are as follows:
Full mode set sequence
The full mode set sequence is much longer than the simple sequence, but it is guaranteed to work with all connected displays, assuming that the EDID is valid. This sequence involves completely disabling the display, configuring the timings for the FDIs and pipes again and then powering on the display again.
The steps are as follows: