Skip to content

drm: apple: answer eDP for the J313 backlight and cap it at 394 nits - #225

Open
ludagoo wants to merge 2 commits into
omacom:integration/aurorafrom
ludagoo:fix/j313-panel-backlight
Open

ludagoo wants to merge 2 commits into
omacom:integration/aurorafrom
ludagoo:fix/j313-panel-backlight

Conversation

@ludagoo

@ludagoo ludagoo commented Oct 25, 2026 •

Copy link
Copy Markdown

J313 BrightnessLCD::nitsToDBV rejects 395 nits and above (iDAC 1956 is accepted, 1957 is not). apple,max-brightness is 420, so 100% asked for a level the firmware drops. apple,panel-j313, and a panel id of J313, is capped at 394 nits. Other panels keep the device-tree maximum, and 100% on this panel lands on 394.

dcpep_cb_create_backlight_service still answers true for an eDP connector as well as for dcp_has_panel(). On this J313 the panel node is read before firmware start, so width_mm is already set and dcp_has_panel() is already true when firmware asks during start_ios_gated. Answering eDP does not change that return value. DCP 13.5 still logs that it could not find the backlight service, and brightness writes still apply only after a modeset. This change does not fix that. External displays are not eDP and still answer false.

Measured on a MacBook Air (M1, 2020, J313, DCP firmware 13.5) running linux-aurora 7.2.11: with the cap, setting 394 read back as 420 and setting 393 read back as 419 (393×420/394). The firmware was still reporting on the old 420 scale.

Session build, Monday 26 Oct 2026 05:02 PM -03: linux-aurora 7.2.11-6-2-ARCH (package 7.2.11.aurora6-2), branch local/j313-test at 7638df0. makepkg exited 0. rustc 1.85.0, LLVM/clang 18.1.8. This machine is running that kernel. This pull request's earlier head was a7b3793, which is not the commit that was built.

The v14 backlight KUnit tests were not run.

A separate perceptual-scale draft may touch the same backlight file and should be rebased rather than merged on top. That draft remaps the range; this one uses levels the firmware already accepts.

Follow-up, not hardware-tested

c230f92268ab clamps actual_brightness, the pr_publish nits store, and the powerlog nits store to the panel maximum. A read of 420 with max_brightness 394 comes back as 394. The 420-scale proportion is not remapped, so the 419 that followed a write of 393 also clamps to 394. The eDP answer is unchanged. This clamp is not hardware-tested.

Firmware older than 26 answers create_backlight_service with
dcp_has_panel() only. That stays false until the panel dimensions have
been parsed, which is after 13.5 firmware asks during start_ios_gated.
The firmware then reports that it could not find the Backlight service,
and later backlight writes are ignored until a modeset power cycle.
connector_type is already eDP when the panel node has been read. Answer
an eDP connector on that path the same way firmware 26 and newer does.
External displays are not eDP and still answer false.

J313 BrightnessLCD rejects 395 nits and above: iDAC 1956 is accepted
and 1957 is not. apple,max-brightness is 420, so 100% asks for a level
the firmware drops. Cap apple,panel-j313, and a panel id of J313, at
394 nits. Other panels keep the device-tree maximum, and 100% on this
panel lands on 394.

Measured on a MacBook Air (M1, 2020, J313, DCP firmware 13.5) running
linux-aurora 7.2.11. This commit has not been booted as a new kernel.

Signed-off-by: Lucas Goossen <lucas.goossen@hey.com>
@malik-na

Copy link
Copy Markdown
Member

Tested on a J313 (M1 Air), automated and by eye: the 394-nit cap works. The create_backlight_service change doesn't make brightness writes apply after boot on DCP 13.5, and actual_brightness exceeds max_brightness.

baseline this PR
max_brightness 420 394 (capping panel backlight at 394 nits)
nitsToDBV: iDAC out of range at the top (sysfs and brightness keys) yes 0
IOMFB: Could not find Backlight service 2 (both DCPs) 2, unchanged: the internal panel's 231c00000.dcp still logs it 14 ms after the cap message
brightness changes on screen after boot, before any modeset no no
… after one lid sleep/wake yes yes, every step up to 394, no glitch
set 394 → actual_brightness – 420 (> max_brightness)
set 393 → actual_brightness – 419
  • Backlight service: by eye, sysfs steps 30 → 45 → 100 → 200 → 300 → 394 right after boot changed nothing on the panel. actual_brightness followed each write, so it's not a reliable signal here. One lid sleep/wake later, every step and every brightness key press applied. That's the same as the installed kernel and the baseline. So answering create_backlight_service true for eDP doesn't change the outcome on 13.5. Either the firmware asks before connector_type is eDP, or 13.5 needs something else.
  • Cap: after the modeset, the keys go up to 394 cleanly, with 0 iDAC rejections.
  • actual_brightness above max_brightness: 393 → 419 matches 393 × 420 / 394, so the firmware-reported nits come back on the old 420 scale and aren't clamped. drm/apple: map panel nits into the DAC range #224's clamp in iomfb_cb_pr_publish() and powerlog_report() would mask that. Without it, userspace sees actual_brightness > max_brightness.
  • All lab tests passed, with no omarchy-m-test regressions.
How this was tested
  • MacBook Air (M1, 2020), J313, DCP 13.5, BCM4378, booted through U-Boot → Limine.
  • This PR's head and its parent 19f4965180f4 (the baseline), built with the Air's own /proc/config.gz and booted as one-shot test entries. The Mac returns to its installed 7.2.11-6-1-ARCH after every run.
  • Automated boots: device-phase suspend (pm_test=devices), omarchy-m-test, and a check script (dmesg counters, keyboard and panel backlight writes, ALS channels, two nmcli con up re-associations, one pm_test=platform s2idle cycle).
  • Hands-on boots: a person at the Mac doing a real lid-close sleep and keypress wake, using the brightness keys, and covering or lighting the ALS, while the kernel's state was logged every 2 s.
  • Tested commit: 529d348d0187 on 19f4965180f4. The PR has since been rebased to a7b3793e9d0c on 937b727ef9a3 with an identical diff; the new base wasn't re-tested.

@ludagoo
ludagoo marked this pull request as ready for review October 27, 2026 00:24
DCP 13.5 reports brightness on the old 420-nit scale after the panel
is capped at 394, so actual_brightness read back as 420 and a write of
393 came back as 419. Clamp the stored nits, and the sysfs readback,
to the panel maximum.

On this machine the panel node is read before firmware starts, so
dcp_has_panel() is already true when the backlight service is created
and answering eDP as well does not change that return. The missing
service log and the need for a modeset before writes apply are
unchanged.

Not hardware-tested.

Signed-off-by: Lucas Goossen <lucas.goossen@hey.com>
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.

2 participants