Anonymous user
Native Intel graphics: Difference between revisions
no edit summary
[unchecked revision] | [unchecked revision] |
No edit summary |
|||
(15 intermediate revisions by 3 users not shown) | |||
Line 10:
===Prerequisites===
Before trying to implement a native driver for your OS, make sure
* Read the [[VGA Hardware]] page. Especially the part about display timings it is still relevant for modern graphics cards. You should know what horizontal/vertical active, total, sync start/end and blanking start/end values mean
* You need to be able to access [[PCI]] configuration space and find MMIO regions that are determined by BARs.
==Getting EDID via DDC==
In order to determine the graphics modes that are supported on a connected monitor it is necessary to parse the monitor's [[EDID]] information. EDID is obtained via [[DDC]] which is a simple protocol over [[I²C]]. Intel graphics chips provide a relative straightforward way to interact with the I²C bus.
Before using the I²C bus a connector has to be selected in the <code>GMBUS0</code> register. This register also sets the bus rate. 100 kHz is a conservative default choice.
In order to send a packet to the bus the following steps suffice:
* Write the first 4 bytes of data to the <code>GMBUS3</code> register.
* Write the destination address, the byte count and the software-ready bit to the <code>GMBUS1</code> register. The simplest way to use the bus is to program the bus cycle selects bits so that no index or STOP is generated and the bus just enters a wait state after the packet is transferred.
* Wait until the hardware-ready bit in <code>GMBUS2</code> is set. Optionally an IRQ can be enabled to avoid busy waiting.
* Write the next 4 bytes to <code>GMBUS3</code> and wait for hardware-ready in <code>GMBUS2</code>. Repeat this last step until all data is transferred.
Receiving a packet works as follows:
* Write the destination address, the byte count, the software-ready bit and the direction bit to the <code>GMBUS1</code> register.
* Wait for hardware-ready in <code>GMBUS2</code>. Read 4 bytes of data from <code>GMBUS3</code>. Repeat this last step until all data is transferred.
After a packet was sent or received the driver should wait until the bus enters a wait state by checking for the wait-phase bit in <code>GMBUS2</code>. If the transaction (possibly consisting of multiple packets) is complete a STOP condition should be generated via the bus cycle select bit in <code>GMBUS1</code>.
==Generation 4 GMA desktop chips (aka Intel G45)==
Line 25 ⟶ 39:
===Architecture overview===
G45 chips appear as devices on the PCI bus. They are identified a vendor ID of 0x8086 and a model-specific device ID. The PCI configuration space is used to access two BARs:
The chip supports two independent graphics pipelines. Each pipeline is made of the following:
Line 32 ⟶ 46:
* A primary plane and secondary planes. The primary plane supplies the primary framebuffer to the display pipe. Secondary planes are mostly used to implement hardware mouse cursors.
Both pipelines share a set of connectors that are used to attach monitors to the card. G45 supports DAC (digital-to-analog converter, i.e. CRTs via the usual VGA plug) connectors, SDVO (serial digital video out) connectors
===Documentation===
Line 39 ⟶ 53:
* Intel's documentation is available [https://01.org/linuxgraphics/documentation/hardware-specification-prms here]. We are primarily interested in the [https://01.org/sites/default/files/documentation/g45_vol_3_register_0_0.pdf G45: Volume Three: Display Register] that describes the display registers. [https://01.org/sites/default/files/documentation/g45_vol_1a_core_updated.pdf G45: Volume 1a Graphics Core] documents the graphics memory interface and the PCI configuration space. The [https://01.org/sites/default/files/documentation/965_g35_vol_3_display_registers_updated.pdf G35: Volume Three: Display Registers] contains a few registers that are undocumented in the G45 manual but still must be programmed by the driver.
* The [http://lxr.free-electrons.com/source/drivers/gpu/drm/i915 i915 driver] of the Linux kernel. Almost all of the mode setting logic is in [
===Mode setting===
Line 50 ⟶ 64:
* Disable the display pipe.
* Disable the DPLL.
* Disable the legacy VGA emulation.
Enabling the display reverses this sequence:
Line 145 ⟶ 160:
Note that connectors must only be enabled or disabled while their respective pipes are enabled.
====Disabling the legacy VGA emulation====
The VGA emulation is controlled via the <code>VGACNTRL</code> register. For non-VGA modes the <code>VGA Display Disable</code> bit should be set. Likewise the <code>VGA Centering Enable</code> bits should be set to 0.
==Intel HD Graphics==
See [[Intel HD Graphics]].
==Debugging tips==
* While debugging a display driver logging messages to the screen is often not possible. Use [[Serial Ports]] instead.
* Because there are no emulators that emulate Intel graphics cards you have to test your driver on a physical machine. Make sure that you can recompile your driver and reboot your test machine with little effort. Things like [[PXE]] might help with that.
* Read the initial values of each register and ensure you understand them before you try to change the registers.
==Implementations in hobby OSs==
* [https://github.com/avdgrinten/managarm managarm] (as of commit 0e9d37c) has a G45 mode setting driver in [https://github.com/avdgrinten/managarm/blob/master/drivers/gfx/intel/src/main.cpp drivers/gfx/intel]. Note that the code makes heavy use of C++ features, particularly operator overloading of the register classes.
[[Category:Video]]
|