Skip to content

feat(nvidia): lit the chosen head once its link is ready - #523

Merged
FlareCoding merged 4 commits into
masterfrom
pr/nvidia-light
Nov 2, 2026
Merged

FlareCoding merged 4 commits into
masterfrom
pr/nvidia-light

Conversation

@FlareCoding

Copy link
Copy Markdown
Owner

Summary

Bring-up stopped the head the boot firmware lit and trained the chosen monitor's link, then lit no head (the display engine's unit timing one monitor) in its place, so every monitor stayed dark.

Changes

  • A head is lit with the methods NVIDIA's mode set writes: build_head_light_methods (core_methods.h) gives, in NVIDIA's order, the core channel's methods (the register writes of the display channel that sets up heads and links) lighting a head with RGB at 8 bits a color: its raster and pixel clock, its control written whole, the serial link (NVIDIA's SOR) carrying it alone in DisplayPort on the display id's sublink, the display id and an unscaled viewport the size of the mode. Each method is re-declared in rm.h from NVIDIA's core channel class.
  • The head's output pipeline is lit with it: the same methods point the head's output table (which converts the display engine's colors back for the link) at the identity table in the look-up table surface (the video memory holding the window's and the head's tables), turn on OCSC0 (the head's first output color space conversion) with NVIDIA's matrix for RGB and give the head usage bounds (the most of each feature it may use) allowing the table. The display engine refuses a window's first image on a head with neither an output table nor OCSC0, and an unlit head's usage bounds forbid the table.
  • The engine keeps what the light names: display_engine keeps the context DMAs (the handles a channel names a surface by) of the base buffer and the look-up table surface, binds the table to the core channel too, whose heads read their output table from it, and keeps the window channel's queue of methods. set_up_output_link (display_link.h) hands back the output resource and link it readied.
  • Bring-up lights the chosen head once its link is ready: set_up writes the head's methods, the window's usage bounds (build_window_usage_methods) and, into the window's channel, its first image (the base buffer through the look-up table, from build_window_image_methods), then one core update naming the completion notifier and interlocked with the window channel's update. It waits for the notifier and logs the lit head's display id and link control as the core channel's armed state reads them.
  • The lit monitor shows black: the lit head scans out the base buffer (the video memory its window shows), cleared to black, at the chosen mode, while the desktop keeps drawing into the boot framebuffer, which the light does not scan out.
  • A first update changing a window's owner goes in two: when the light's update is the first since the core channel's allocation and changes the head a present window serves, or a present window serves no head, it interlocks no window, and the window's usage bounds and first image follow in an update of their own naming no notifier, as NVIDIA's modesetting module orders them.
  • A failed light takes the engine down: when a write, the wait or the notifier's stop fails, bring-up logs it and stops the heads found active and the lit head in one shutdown update, detaching the lit head's link too.
  • Modes past a head's raster are refused: choose_first_light (display_light.h) refuses a mode whose totals pass 32,767 pixels or lines, the largest raster a head takes, without asking the bandwidth check (the firmware's check that the display engine can fetch a mode), as NVIDIA's mode validation refuses it, and logs it.
  • Departure, totals compared whole: the refusal compares the 32-bit totals edid::timing holds, where NVIDIA's mode timings hold 16-bit totals, so a total past 65,535 is refused rather than cut.
  • Departure, color controls and dither: the head's color controls are written once, where NVIDIA's mode set writes them again for its digital vibrance, and the head's dither is left as it is, where NVIDIA's mode set writes it.
  • Readbacks left out: set_up reads back the light's completion notifier and the lit head's display id and link control alone, not the head's output table and OCSC0 controls, the window's CSC0 and CSC1 controls (its color space conversions), the link status over AUX (DisplayPort's side channel) after the update or the base buffer through BAR1 (the card's window onto video memory).
  • Card: these exact commits have not run on the RTX 3080 yet, and the maintainer tests them live on the card tonight, at the monitor. The boots below ran earlier versions of the same four pieces, with no one watching the monitor.
  • Card, Oct 29: the four pieces as drafted (ab4faca5, before the raster refusal was folded in and before their move onto master past feat(nvidia): built the window channel's methods showing an image #520, which landed build_window_image_methods drafted ahead of them, and fix(nvidia): logged the display set-up's counts of 1 in the singular #521) lit head 0 over DisplayPort on both boot paths, the card's own display (run land-light5-card-4) and QEMU's VGA (land-light5-vga-4). Each read the light's completion notifier finished and head 0's display id 0x100 in the armed state, with no Xid (NVIDIA's error report) or error-log event from the GSP (the card's firmware processor) after window 0's first image and 0 IOMMU or PCIe faults.
  • Card, after the move onto feat(nvidia): built the window channel's methods showing an image #520 and fix(nvidia): logged the display set-up's counts of 1 in the singular #521: runs land-light-rest-card-1 and land-light-rest-vga-1 of b31e9a96, this PR's code on master f2a9ad8 before folds of comments, docs and one log line's wording, read the same, lighting head 0 at 2560 by 1440 on the card's IOC 25G2S monitor.
  • Tests of the head's methods: nvidia_core_methods checks head 0's methods at 2560 by 1440 against NVIDIA's, method for method and value for value, that they follow the head, link and windows given, bound no window for a head serving none and take each negative sync, that a window's usage methods bound its formats, scale factor and fetch, and that the raster keeps 15 bits of each position, the pixel clock 31 bits of its hertz and a window's fetch bound 15 bits of its pixels.
  • Tests of the light: nvidia_display_engine checks the light in one update interlocked with its window, in two when the first update changes a window's owner or a present window serves no head, in one first update doing neither, the lit head taken down with its link after a failed light and alone after a failed first light, no light after a refused stream, the surfaces' bindings, a look-up table surface it cannot unbind from the core channel included, and the window channel's queue, which the release drops. nvidia_display_light checks the output table's identity entries and the raster refusal, with a total whose low 16 bits would pass, and that refusing every mode leaves the choice unchanged.

The light names both surfaces by their context DMAs, writes through the
window channel's queue and the link set_up_output_link readies, and
interlocks the core update with its window.
A head with neither an output table nor OCSC0 refuses a window's first
image, and an unlit head's usage bounds forbid the table, so the light's
methods write all three and set_up binds the table to the core channel.
Bring-up lights the head in one update interlocked with its window, or
two when the first changes an owner or a window serves no head, a failed
light taking the engine down. Modes past a head's raster are refused.
@FlareCoding
FlareCoding added this pull request to stack #525 November 2, 2026 22:07
@FlareCoding
FlareCoding merged commit 770e2d6 into master Nov 2, 2026
10 checks passed
@FlareCoding
FlareCoding deleted the pr/nvidia-light branch November 2, 2026 22:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant