Skip to content

Display and brightness ​

Start after platform and memory. Collect the firmware GOP base, size, dimensions, stride, pixel format and reserved-memory range. Identify the panel, display controller, backlight controller and their power owners.

Use driver build integration to connect initialization, archive recipes and the OS ABI, then run this page's hardware checks.

Sources and interfaces ​

These links identify reviewed source revisions. Match interfaces to the selected SoC, component and OS versions. Files in UniXNU-sheng provide board integration examples.

ImplementationSourceWhat to read and implement
OS display interfaceNativeLegacyDisplay.cpp, OriginalMobileFramebufferABI.hProvider methods, request layouts and selected MobileFramebuffer ABI
Frame ownershipNativeGOPWire.h, NativeGOPPresenter.cppNGPPresent, NGPSwap, NGPComplete: buffer bounds and swap retirement
Brightness implementationAppleARMBacklight.cpp, GeniI2c.hOS properties and geni_i2c_start_write/read, event and timeout handling
Timing referenceDisplayTimingProbe.cppTarget controller counters and refresh measurement

1. Establish firmware scanout ​

Build the integrated UEFI firmware. Confirm that its menu displays correctly. Compare GOP geometry and framebuffer bounds with the firmware memory map and board DTS. Preserve the active scanout allocation through kernel handoff.

Expected result: a stable firmware image with correct colors and dimensions. Resolve this before enabling the XNU presentation backend.

2. Adapt the XNU display backend ​

Read GopFramebuffer and its NativeLegacyDisplay.cpp, NativeGOPPresenter.cpp and NativeGOPWire.h. It consumes PE_current_console and integrates with the selected MobileFramebuffer and IOSurface ABI.

In the sheng package, inspect LegacyDisplayProbe.cpp and DisplayTimingProbe.cpp. The device's scripts/build-gop-legacy-display.py qualifies ABI methods against a prelinked candidate before producing the late display archive. Supply the matching candidate and audit inputs listed in build inputs.

  1. Select GopFramebuffer and the display archive recipe, preserving its dependencies.
  2. Enable the recipe's kernel configuration and initialization caller. sheng uses CONFIG_XNU_NATIVE_LEGACY_DISPLAY=y and its offline-legacy-* arguments.
  3. Check pixel layout, row stride, allocation size and cache handling in CPU presentation. Confirm that a known frame reaches the display.
  4. Check swap completion and IOSurface lifetime before enabling GPU presentation.
  5. Adapt timing reads to the target display controller. sheng's sheng-dpu=1 samples the SM8550 DPU and dual-DSI counters through DisplayTimingProbe.cpp. Set refresh policy from the observed panel mode. sheng-vsync=120 is sheng's requested timing value.

For the NativeGOPWire.h path, query mode/geometry first and validate each present buffer's size and stride. In GPU handoff, track the pending frame by NGPSwap.sequence and return NGPComplete with that sequence after copying. Retain the source frame and IOSurface until the swap completes, and complete the corresponding error path on timeout or failure.

Expected result: XNU publishes the display, presents frames and completes swaps. Record requested refresh and measured frame timing separately.

Read the display pipes ​

Before changing what the display fetches, read how firmware left it. DisplayTimingProbe.cpp does this on sheng:

ArgumentReads
sheng-dpu=2VIG 0 and 1 source, size, format and fetch settings; CTL 0 state; the tear check of both interfaces; the display streams in the apps SMMU
sheng-dpu=3Also rewrites each pipe's current address and times the CTL flush latch

On sheng both VIG pipes fetch one 32-bit physical address, the right pipe from its own source x, and a flush latches within 5.4 ms without a start because the panel refreshes by itself. The display context bank starts with translation off.

Direct scanout (sheng-dpu-scanout=2) is experimental and off by default: it gives the display bank a stage 1 window (ShengUfs) and points the pipes at the compositor's surfaces. Any failure falls back to the GPU copy.

3. Identify the brightness transport ​

Select the target's I2C, DSI-command or PWM transport and its brightness encoding. AppleARMBacklight.cpp provides an OS-service example for KTZ8866 controllers; GeniI2c.h defines the GENI transfer state machine used by that example.

Before reuse, record the target's controller count, register encoding, brightness range, I2C engine, slave address, pins, clocks, interrupts and power sequence. For a DSI-command or PWM backlight, implement that transport and its level encoding behind the OS-facing brightness service.

4. Adapt and enable brightness ​

  1. Update the board's engine mappings, clock votes and interrupt routing. sheng's GENI path adopts firmware-loaded engine code and timing; verify that handoff or implement the target's initialization sequence.
  2. Implement the target controller's level encoding, write and readback. Match the number of controllers and update order to the panel's wiring.
  3. For the GENI example, call geni_i2c_prepare, start a read/write, feed interrupt status to geni_i2c_event and call geni_i2c_timeout when its deadline expires. Complete or cancel the transfer before starting the next one. Keep service requests on the work loop and inspect failures before enabling fades.
  4. Match IODisplayParameters brightness limits and backlight-control to the selected OS ABI. The service accepts brightness and FadePeriod properties.
  5. Build the service and its registration wrapper. sheng's display recipe does both; sheng-backlight=1 enables its probe.

From the resolved target tree, locate these integration points:

sh
rg -n 'kSeA|kSeB|kSpi|kMaxLevel|backlight-control|FadePeriod' kits/sheng/AppleARMBacklight.cpp
rg -n 'backlight|GeniI2c' scripts/build-gop-legacy-display.py

Use the equivalent kit path for the new board. Rebuild the kernel, payload and boot image through Building.

Expected result: minimum, middle and maximum settings produce corresponding readback and visible levels; fades complete; timeout counters remain stable. On sheng, native_backlight_stats records publication, requests, readback, interrupts and failures. Verify UI brightness changes as a separate step from raw controller writes.

Next step ​

Record display and brightness results separately, then continue with touch and buttons.

Released under the BSD-2-Clause-Patent License.