From: sashiko-bot@kernel.org
To: "Mario Limonciello (AMD)" <superm1@kernel.org>
Cc: dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org,
intel-xe@lists.freedesktop.org
Subject: Re: [PATCH v10 03/15] drm/amd: add luminance property support
Date: Mon, 02 Nov 2026 17:32:18 +0000 [thread overview]
Message-ID: <sashiko-outbox-193840@kernel.org> (raw)
In-Reply-To: <20261102-superm1-backlight-property-v10-3-b2a6f24131f5@kernel.org>
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] drm/amdgpu: broken atomic LUMINANCE support on non-atomic legacy display
- [High] drm/amd/display: skipped backlight restore and setup when DRM_LUMINANCE=y
- [Medium] drm/amd/display: unconditional backlight programming blocks PSR/Replay
- [Low] drm/amd: Kconfig and link breakage when DRM_LUMINANCE=y without backlight
--
commit de26f6665aed29ccc412fe4be3f0737b06b98759
Author: Mario Limonciello <mario.limonciello@amd.com>
drm/amd: add luminance property support
This commit adds support for the DRM LUMINANCE connector property on internal
panels when CONFIG_DRM_LUMINANCE is enabled, bypassing sysfs backlight device
registration and wiring connector luminance callbacks for Display Core and
legacy display paths.
> diff --git a/drivers/gpu/drm/amd/amdgpu/Kconfig b/drivers/gpu/drm/amd/amdgpu/Kconfig
> index 50305630f5335..7a6a049aa6e90 100644
> --- a/drivers/gpu/drm/amd/amdgpu/Kconfig
> +++ b/drivers/gpu/drm/amd/amdgpu/Kconfig
> @@ -20,7 +20,7 @@ config DRM_AMDGPU
> select I2C
> select I2C_ALGOBIT
> select CRC16
> - select BACKLIGHT_CLASS_DEVICE
> + select BACKLIGHT_CLASS_DEVICE if !DRM_LUMINANCE
> select INTERVAL_TREE
> select DRM_BUDDY
> select DRM_SUBALLOC_HELPER
[Severity: Low]
Does dropping select BACKLIGHT_CLASS_DEVICE when CONFIG_DRM_LUMINANCE is
enabled cause Kconfig dependency warnings and link errors when
CONFIG_BACKLIGHT_CLASS_DEVICE is disabled (or built as a module with
CONFIG_DRM_AMDGPU=y)?
In drivers/gpu/drm/amd/amdgpu/Kconfig, config DRM_AMDGPU still unconditionally
selects ACPI_VIDEO when ACPI is enabled:
# decidable, for the moment, to just select all of ACPI_VIDEO's
# dependencies, which is fewer than you might think.
select ACPI_VIDEO if ACPI
Because config ACPI_VIDEO in drivers/acpi/Kconfig depends on
BACKLIGHT_CLASS_DEVICE, enabling CONFIG_DRM_LUMINANCE=y with CONFIG_ACPI=y and
CONFIG_BACKLIGHT_CLASS_DEVICE=n triggers an unmet direct dependency warning
for ACPI_VIDEO.
In addition, include/linux/backlight.h declares backlight_device_register(),
backlight_device_unregister(), and backlight_device_set_brightness() without
inline stubs when CONFIG_BACKLIGHT_CLASS_DEVICE is disabled, while amdgpu
still compiles direct references to those symbols:
- amdgpu_dm_register_backlight_device() in
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_backlight.c is a non-static
function compiled unconditionally that calls backlight_device_register().
- amdgpu_dm_connector_destroy() in
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c and
amdgpu_atombios_encoder_fini_backlight() in
drivers/gpu/drm/amd/amdgpu/atombios_encoders.c call
backlight_device_unregister() behind runtime pointer checks.
- amdgpu_atif_handler() in drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c calls
backlight_device_set_brightness(atif->bd, req.backlight_level) behind a
runtime check on atif->bd.
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
> index 92c98e999efe9..209a7a6c246db 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
> @@ -798,11 +798,31 @@ static int amdgpu_connector_set_lcd_property(struct drm_connector *connector,
> return 0;
> }
>
> +static void amdgpu_connector_set_luminance(const struct drm_connector_state *conn_state)
> +{
> + struct drm_encoder *encoder =
> + amdgpu_connector_best_single_encoder(conn_state->connector);
> +
> + if (encoder)
> + amdgpu_atombios_encoder_set_backlight_level(to_amdgpu_encoder(encoder),
> + conn_state->luminance);
> +}
> +
> +static void amdgpu_connector_disable_luminance(const struct drm_connector_state *conn_state)
> +{
> + struct drm_encoder *encoder =
> + amdgpu_connector_best_single_encoder(conn_state->connector);
> +
> + if (encoder)
> + amdgpu_atombios_encoder_set_backlight_level(to_amdgpu_encoder(encoder), 0);
> +}
>
> static const struct drm_connector_helper_funcs amdgpu_connector_lvds_helper_funcs = {
> .get_modes = amdgpu_connector_lvds_get_modes,
> .mode_valid = amdgpu_connector_lvds_mode_valid,
> .best_encoder = amdgpu_connector_best_single_encoder,
> + .set_luminance = amdgpu_connector_set_luminance,
> + .disable_luminance = amdgpu_connector_disable_luminance,
> };
>
> static const struct drm_connector_funcs amdgpu_connector_lvds_funcs = {
> diff --git a/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c b/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c
> index a1d05df0ac99b..dbff532ac1bcd 100644
> --- a/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c
> +++ b/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c
> @@ -191,6 +191,21 @@ void amdgpu_atombios_encoder_init_backlight(struct amdgpu_encoder *amdgpu_encode
> goto register_acpi_backlight;
> }
>
> + dig = amdgpu_encoder->enc_priv;
> + if (IS_ENABLED(CONFIG_DRM_LUMINANCE)) {
> + unsigned int brightness;
> +
> + brightness = amdgpu_atombios_encoder_get_backlight_level(amdgpu_encoder);
> + if (drm_connector_attach_luminance_property(drm_connector, 0,
> + AMDGPU_MAX_BL_LEVEL,
> + brightness))
> + return;
> +
> + dig->backlight_level = brightness;
> + dig->bl_dev = NULL;
> + return;
> + }
[Severity: High]
Can atomic LUMINANCE work on the legacy non-DC display path in
drivers/gpu/drm/amd/amdgpu/atombios_encoders.c and amdgpu_connectors.c?
Those files are used only when Display Core is not active, where
amdgpu_pci_probe() in drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c clears
DRIVER_ATOMIC:
if (!supports_atomic)
ddev->driver_features &= ~DRIVER_ATOMIC;
On this legacy path, connectors do not implement atomic state callbacks
(.reset, .atomic_duplicate_state, .atomic_destroy_state), so
drm_connector->state is NULL, and modesets use legacy CRTC helpers
(drm_crtc_helper_set_config() and drm_helper_connector_dpms()).
Because drm_connector_attach_luminance_property() creates LUMINANCE with
DRM_MODE_PROP_ATOMIC, non-atomic drivers hide LUMINANCE from userspace, legacy
property updates go through amdgpu_connector_set_lcd_property() (which ignores
everything except scaling_mode_property), and the legacy helpers never invoke
drm_atomic_helper_commit_luminance_enables() or
drm_atomic_helper_commit_luminance_disables(). Skipping backlight_device_register()
in amdgpu_atombios_encoder_init_backlight() therefore leaves legacy panels
with no working brightness control when CONFIG_DRM_LUMINANCE=y.
Even if atomic callbacks were reachable here, there are two additional issues
in drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c:
1. .set_luminance and .disable_luminance are only added to
amdgpu_connector_lvds_helper_funcs and are missing from
amdgpu_connector_dp_helper_funcs, which is used by DRM_MODE_CONNECTOR_eDP
and DP-bridge LVDS connectors that also call
amdgpu_atombios_encoder_init_backlight().
2. amdgpu_connector_disable_luminance() calls
amdgpu_atombios_encoder_set_backlight_level(to_amdgpu_encoder(encoder), 0),
which overwrites dig->backlight_level = 0 and mmBIOS_SCRATCH_2 = 0,
clobbering the saved brightness level used by
amdgpu_atombios_encoder_setup_dig() on enable and by dce_v*_suspend().
[ ... ]
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> index 0ea45ab12119c..53ff9a55c3a8e 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
[ ... ]
> @@ -5397,11 +5398,16 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_commit *state)
> /* Update audio instances for each connector. */
> amdgpu_dm_commit_audio(dev, state);
>
> - /* restore the backlight level */
> - for (i = 0; i < dm->num_of_edps; i++) {
> - if (dm->backlight_dev[i] &&
> - (dm->actual_brightness[i] != dm->brightness[i]))
> - amdgpu_dm_backlight_set_level(dm, i, dm->brightness[i]);
> + if (IS_ENABLED(CONFIG_DRM_LUMINANCE)) {
> + /* Apply brightness after the display pipeline is enabled. */
> + drm_atomic_helper_commit_luminance_enables(state);
> + } else {
> + /* Restore the legacy backlight level. */
> + for (i = 0; i < dm->num_of_edps; i++) {
> + if (dm->backlight_dev[i] &&
> + dm->actual_brightness[i] != dm->brightness[i])
> + amdgpu_dm_backlight_set_level(dm, i, dm->brightness[i]);
> + }
> }
[Severity: Medium]
Unlike the !CONFIG_DRM_LUMINANCE branch, which checks
dm->actual_brightness[i] != dm->brightness[i], doesn't calling
drm_atomic_helper_commit_luminance_enables(state) -> amdgpu_dm_set_luminance() ->
amdgpu_dm_backlight_set_level() here reprogram the backlight on every atomic
commit that includes an active eDP connector in state even when
state->luminance has not changed?
In amdgpu_dm_atomic_commit_tail(), drm_atomic_helper_commit_luminance_enables()
runs after amdgpu_dm_commit_planes(). Inside amdgpu_dm_backlight_set_level()
in drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_backlight.c, the driver
exits IPS, reprograms the backlight via mod_power_set_backlight_nits() or
mod_power_set_backlight_percent(), and disables PSR and Panel Replay until the
next plane flip:
amdgpu_dm_psr_set_event(dm, stream, true,
psr_event_hw_programming, true);
amdgpu_dm_replay_set_event(dm, stream, true,
replay_event_hw_programming, true);
Because amdgpu_dm_commit_planes() -> amdgpu_dm_enable_self_refresh() has
already run earlier in amdgpu_dm_atomic_commit_tail(), any commit that pulls
the active eDP connector into state without changing state->luminance (such as
CRTC color management or VRR updates via drm_atomic_add_affected_connectors(),
ABM/HDR/scaling connector property updates, or compositor commits that include
connector properties) will immediately re-assert psr_event_hw_programming and
replay_event_hw_programming and block PSR/Replay entry.
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_backlight.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_backlight.c
> index 0f664c658a127..0857354e7327e 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_backlight.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_backlight.c
[ ... ]
> @@ -657,6 +662,10 @@ void amdgpu_dm_setup_backlight_device(struct amdgpu_display_manager *dm,
> {
> struct dc_link *link = aconnector->dc_link;
> int bl_idx = dm->num_of_edps;
> + struct backlight_properties props = { 0 };
> + struct amdgpu_dm_backlight_caps *caps;
> + struct drm_connector *connector = &aconnector->base;
> + int ret;
>
> if (!(link->connector_signal & (SIGNAL_TYPE_EDP | SIGNAL_TYPE_LVDS)) ||
> link->type == dc_connection_none)
> @@ -675,6 +684,19 @@ void amdgpu_dm_setup_backlight_device(struct amdgpu_display_manager *dm,
>
> amdgpu_dm_update_connector_ext_caps(aconnector);
>
> + caps = &dm->backlight_caps[bl_idx];
> + amdgpu_dm_backlight_fill_props(caps, power_supply_is_system_supplied() > 0,
> + !(amdgpu_dc_debug_mask &
> + DC_DISABLE_CUSTOM_BRIGHTNESS_CURVE),
> + &props);
> + if (IS_ENABLED(CONFIG_DRM_LUMINANCE)) {
> + unsigned int max = props.max_brightness;
> + unsigned int value = props.brightness;
> +
> + ret = drm_connector_attach_luminance_property(connector, 0, max, value);
> + drm_WARN_ON(adev_to_drm(dm->adev), ret);
> + }
> +
> /* Offer ABM property when user didn't turn off by module parameter.
> * OLED panels are included to support CACP (Content Adaptive
> * Contrast and Power) feature via set_abm_level.
[ ... ]
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c
> index b498fc5fbb140..f2c2a2e730d3e 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c
[ ... ]
> @@ -2038,7 +2039,8 @@ amdgpu_dm_connector_late_register(struct drm_connector *connector)
> return r;
> }
>
> - amdgpu_dm_register_backlight_device(amdgpu_dm_connector);
> + if (!IS_ENABLED(CONFIG_DRM_LUMINANCE))
> + amdgpu_dm_register_backlight_device(amdgpu_dm_connector);
[Severity: High]
When CONFIG_DRM_LUMINANCE is enabled, skipping
amdgpu_dm_register_backlight_device() leaves dm->backlight_dev[i] as NULL and
leaves dm->brightness[bl_idx] uninitialized (0) in
amdgpu_dm_setup_backlight_device(). Doesn't this break several backlight
restoration and initialization paths in Display Core?
Specifically:
1. In dm_resume() in drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c, the
GPU reset recovery branch (if (amdgpu_in_reset(adev))) does not go through
drm_atomic_helper_resume() or amdgpu_dm_atomic_commit_tail(), and instead
restores panel brightness via:
/* set the backlight after a reset */
for (i = 0; i < dm->num_of_edps; i++) {
if (dm->backlight_dev[i])
amdgpu_dm_backlight_set_level(dm, i, dm->brightness[i]);
}
Because dm->backlight_dev[i] is NULL (and dm->brightness[i] is 0 until a
luminance commit occurs), panel brightness will not be restored after a GPU
reset.
2. In amdgpu_dm_commit_streams() in
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c, after dc_commit_streams()
is called, backlight restoration is likewise gated on dm->backlight_dev[i]:
if (set_backlight_level) {
for (i = 0; i < dm->num_of_edps; i++) {
if (dm->backlight_dev[i])
amdgpu_dm_backlight_set_level(dm, i, dm->brightness[i]);
}
}
If a modeset happens on an external display on another CRTC while the eDP
connector is not part of the atomic commit state, neither
amdgpu_dm_commit_streams() nor drm_atomic_helper_commit_luminance_enables(state)
will restore the eDP brightness.
3. Unlike amdgpu_dm_register_backlight_device(), amdgpu_dm_setup_backlight_device()
does not check acpi_video_backlight_use_native() before attaching the
LUMINANCE property, and skipping amdgpu_dm_register_backlight_device() also
skips the acpi_video_register_backlight() fallback when native backlight
control should not be used.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261102-superm1-backlight-property-v10-0-b2a6f24131f5@kernel.org?part=3
next prev parent reply other threads:[~2026-11-02 17:32 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-02 16:49 [PATCH v10 00/15] Add support for a DRM backlight capability Mario Limonciello (AMD)
2026-11-02 16:49 ` [PATCH v10 01/15] drm: add connector LUMINANCE property Mario Limonciello (AMD)
2026-11-02 17:07 ` sashiko-bot
2026-11-02 16:49 ` [PATCH v10 02/15] drm/amd/display: Pass up errors reading actual brightness Mario Limonciello (AMD)
2026-11-02 16:49 ` [PATCH v10 03/15] drm/amd: add luminance property support Mario Limonciello (AMD)
2026-11-02 17:32 ` sashiko-bot [this message]
2026-11-03 15:58 ` Leo Li
2026-11-03 15:58 ` Leo Li
2026-11-02 16:49 ` [PATCH v10 04/15] drm/amdgpu: Check bios_scratch_reg_offset in backlight level helper Mario Limonciello (AMD)
2026-11-02 16:49 ` [PATCH v10 05/15] drm/amd/display: update KUnit luminance fixtures Mario Limonciello (AMD)
2026-11-02 18:00 ` sashiko-bot
2026-11-02 16:49 ` [PATCH v10 06/15] drm/i915/display: add luminance property support Mario Limonciello (AMD)
2026-11-02 18:17 ` sashiko-bot
2026-11-02 16:49 ` [PATCH v10 07/15] drm/bridge: add connector luminance operations Mario Limonciello (AMD)
2026-11-02 18:24 ` sashiko-bot
2026-11-02 16:49 ` [PATCH v10 08/15] drm/panel: add connector luminance forwarding Mario Limonciello (AMD)
2026-11-02 18:34 ` sashiko-bot
2026-11-02 16:49 ` [PATCH v10 09/15] drm/bridge_connector: add luminance support Mario Limonciello (AMD)
2026-11-02 16:49 ` [PATCH v10 10/15] drm/nouveau: add connector " Mario Limonciello (AMD)
2026-11-02 18:49 ` sashiko-bot
2026-11-02 16:49 ` [PATCH v10 11/15] drm/gud: " Mario Limonciello (AMD)
2026-11-02 19:02 ` sashiko-bot
2026-11-02 16:49 ` [PATCH v10 12/15] drm/radeon: " Mario Limonciello (AMD)
2026-11-02 19:13 ` sashiko-bot
2026-11-02 16:49 ` [PATCH v10 13/15] drm/gma500: " Mario Limonciello (AMD)
2026-11-02 19:22 ` sashiko-bot
2026-11-02 16:49 ` [PATCH v10 14/15] drm/bridge: add PS8622 " Mario Limonciello (AMD)
2026-11-02 19:31 ` sashiko-bot
2026-11-02 16:49 ` [PATCH v10 15/15] drm/solomon: add SSD130x " Mario Limonciello (AMD)
2026-11-02 19:49 ` sashiko-bot
2026-11-02 18:52 ` ✗ Fi.CI.BUILD: failure for Add support for a DRM backlight capability (rev5) Patchwork
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=sashiko-outbox-193840@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=intel-gfx@lists.freedesktop.org \
--cc=intel-xe@lists.freedesktop.org \
--cc=sashiko-reviews@lists.linux.dev \
--cc=superm1@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.