Expose the DRM LUMINANCE connector property for eDP, LVDS, and DSI panels
when CONFIG_DRM_LUMINANCE is enabled. Keep registering the existing
backlight class device otherwise, preserving its userspace ABI.

Use the existing Intel brightness scaling and programming path from
connector helper callbacks. Apply atomic luminance after modeset enables
so updates made while a panel is inactive take effect when it is enabled
again. The shared display code provides the same behavior to i915 and Xe.

Signed-off-by: Mario Limonciello <[email protected]>
---
 drivers/gpu/drm/i915/Kconfig                  |  2 +-
 drivers/gpu/drm/i915/display/icl_dsi.c        |  1 +
 .../gpu/drm/i915/display/intel_backlight.c    | 20 +++++++++++++++++++
 .../gpu/drm/i915/display/intel_backlight.h    |  1 +
 drivers/gpu/drm/i915/display/intel_display.c  |  2 ++
 drivers/gpu/drm/i915/display/intel_dp.c       |  1 +
 drivers/gpu/drm/i915/display/intel_lvds.c     |  1 +
 drivers/gpu/drm/i915/display/intel_panel.c    |  8 +++++---
 drivers/gpu/drm/i915/display/vlv_dsi.c        |  1 +
 drivers/gpu/drm/xe/Kconfig                    |  2 +-
 10 files changed, 34 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
index 5e939004b6463..f2113642a7aa3 100644
--- a/drivers/gpu/drm/i915/Kconfig
+++ b/drivers/gpu/drm/i915/Kconfig
@@ -26,7 +26,7 @@ config DRM_I915
        select IRQ_WORK
        # i915 depends on ACPI_VIDEO when ACPI is enabled
        # but for select to work, need to select ACPI_VIDEO's dependencies, ick
-       select BACKLIGHT_CLASS_DEVICE if ACPI
+       select BACKLIGHT_CLASS_DEVICE if ACPI && !DRM_LUMINANCE
        select INPUT if ACPI
        select X86_PLATFORM_DEVICES if ACPI
        select ACPI_WMI if ACPI
diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c 
b/drivers/gpu/drm/i915/display/icl_dsi.c
index ea0cdb7822f39..37ff84c03ce05 100644
--- a/drivers/gpu/drm/i915/display/icl_dsi.c
+++ b/drivers/gpu/drm/i915/display/icl_dsi.c
@@ -1801,6 +1801,7 @@ static const struct drm_connector_helper_funcs 
gen11_dsi_connector_helper_funcs
        .get_modes = intel_dsi_get_modes,
        .mode_valid = gen11_dsi_mode_valid,
        .atomic_check = intel_digital_connector_atomic_check,
+       .set_luminance = intel_backlight_set_luminance,
 };
 
 static int gen11_dsi_host_attach(struct mipi_dsi_host *host,
diff --git a/drivers/gpu/drm/i915/display/intel_backlight.c 
b/drivers/gpu/drm/i915/display/intel_backlight.c
index b128896cb1c2d..6d658c7b5d99f 100644
--- a/drivers/gpu/drm/i915/display/intel_backlight.c
+++ b/drivers/gpu/drm/i915/display/intel_backlight.c
@@ -9,6 +9,7 @@
 #include <linux/string_helpers.h>
 #include <acpi/video.h>
 
+#include <drm/drm_connector.h>
 #include <drm/drm_file.h>
 #include <drm/drm_print.h>
 #include <drm/intel/pci_config.h>
@@ -1670,6 +1671,9 @@ int intel_backlight_setup(struct intel_connector 
*connector, enum pipe pipe)
 {
        struct intel_display *display = to_intel_display(connector);
        struct intel_panel *panel = &connector->panel;
+       struct drm_connector *base = &connector->base;
+       u32 brightness;
+       u32 max;
        int ret;
 
        if (!connector->panel.vbt.backlight.present) {
@@ -1703,6 +1707,13 @@ int intel_backlight_setup(struct intel_connector 
*connector, enum pipe pipe)
 
        panel->backlight.present = true;
 
+       max = panel->backlight.max;
+       brightness = scale_hw_to_user(connector, panel->backlight.level, max);
+       if (IS_ENABLED(CONFIG_DRM_LUMINANCE)) {
+               ret = drm_connector_attach_luminance_property(base, 0, max, 
brightness);
+               drm_WARN_ON(display->drm, ret);
+       }
+
        drm_dbg_kms(display->drm,
                    "[CONNECTOR:%d:%s] backlight initialized, %s, brightness 
%u/%u\n",
                    connector->base.base.id, connector->base.name,
@@ -1712,6 +1723,15 @@ int intel_backlight_setup(struct intel_connector 
*connector, enum pipe pipe)
        return 0;
 }
 
+void intel_backlight_set_luminance(const struct drm_connector_state 
*conn_state)
+{
+       struct intel_connector *connector =
+               to_intel_connector(conn_state->connector);
+
+       intel_panel_set_backlight(conn_state, conn_state->luminance,
+                                 connector->panel.backlight.max);
+}
+
 void intel_backlight_destroy(struct intel_panel *panel)
 {
        /* dispose of the pwm */
diff --git a/drivers/gpu/drm/i915/display/intel_backlight.h 
b/drivers/gpu/drm/i915/display/intel_backlight.h
index 339643f638978..1634ce414695a 100644
--- a/drivers/gpu/drm/i915/display/intel_backlight.h
+++ b/drivers/gpu/drm/i915/display/intel_backlight.h
@@ -32,6 +32,7 @@ void intel_backlight_set_acpi(const struct 
drm_connector_state *conn_state,
                              u32 level, u32 max);
 void intel_backlight_set_pwm_level(const struct drm_connector_state 
*conn_state,
                                   u32 level);
+void intel_backlight_set_luminance(const struct drm_connector_state 
*conn_state);
 u32 intel_backlight_invert_pwm_level(struct intel_connector *connector, u32 
level);
 u32 intel_backlight_level_to_pwm(struct intel_connector *connector, u32 level);
 u32 intel_backlight_level_from_pwm(struct intel_connector *connector, u32 val);
diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index fc30a455bed36..497d387bb6c0d 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -7656,6 +7656,8 @@ static void intel_atomic_commit_tail(struct 
intel_atomic_state *state)
        /* Now enable the clocks, plane, pipe, and connectors that we set up. */
        display->modeset.funcs->commit_modeset_enables(state);
 
+       drm_atomic_helper_commit_luminance_enables(&state->base);
+
        intel_display_power_dc3co_compute(state);
 
        /* FIXME probably need to sequence this properly */
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 0cd5e6b5034cf..c800cffc6444d 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -6802,6 +6802,7 @@ static const struct drm_connector_helper_funcs 
intel_dp_connector_helper_funcs =
        .get_modes = intel_dp_get_modes,
        .mode_valid = intel_dp_mode_valid,
        .atomic_check = intel_dp_connector_atomic_check,
+       .set_luminance = intel_backlight_set_luminance,
 };
 
 enum irqreturn
diff --git a/drivers/gpu/drm/i915/display/intel_lvds.c 
b/drivers/gpu/drm/i915/display/intel_lvds.c
index 872753478cf21..fa668b1debb21 100644
--- a/drivers/gpu/drm/i915/display/intel_lvds.c
+++ b/drivers/gpu/drm/i915/display/intel_lvds.c
@@ -502,6 +502,7 @@ static const struct drm_connector_helper_funcs 
intel_lvds_connector_helper_funcs
        .get_modes = intel_lvds_get_modes,
        .mode_valid = intel_lvds_mode_valid,
        .atomic_check = intel_digital_connector_atomic_check,
+       .set_luminance = intel_backlight_set_luminance,
 };
 
 static const struct drm_connector_funcs intel_lvds_connector_funcs = {
diff --git a/drivers/gpu/drm/i915/display/intel_panel.c 
b/drivers/gpu/drm/i915/display/intel_panel.c
index 81e638d0c7b33..501573a75b89c 100644
--- a/drivers/gpu/drm/i915/display/intel_panel.c
+++ b/drivers/gpu/drm/i915/display/intel_panel.c
@@ -610,9 +610,11 @@ int intel_panel_register(struct intel_connector *connector)
        struct intel_panel *panel = &connector->panel;
        int ret;
 
-       ret = intel_backlight_device_register(connector);
-       if (ret)
-               return ret;
+       if (!IS_ENABLED(CONFIG_DRM_LUMINANCE)) {
+               ret = intel_backlight_device_register(connector);
+               if (ret)
+                       return ret;
+       }
 
        if (connector->base.connector_type == DRM_MODE_CONNECTOR_DSI ||
            connector->base.connector_type == DRM_MODE_CONNECTOR_eDP) {
diff --git a/drivers/gpu/drm/i915/display/vlv_dsi.c 
b/drivers/gpu/drm/i915/display/vlv_dsi.c
index 8829f365592ef..7e60407e0af4a 100644
--- a/drivers/gpu/drm/i915/display/vlv_dsi.c
+++ b/drivers/gpu/drm/i915/display/vlv_dsi.c
@@ -1555,6 +1555,7 @@ static const struct drm_connector_helper_funcs 
intel_dsi_connector_helper_funcs
        .get_modes = intel_dsi_get_modes,
        .mode_valid = vlv_dsi_mode_valid,
        .atomic_check = intel_digital_connector_atomic_check,
+       .set_luminance = intel_backlight_set_luminance,
 };
 
 static const struct drm_connector_funcs intel_dsi_connector_funcs = {
diff --git a/drivers/gpu/drm/xe/Kconfig b/drivers/gpu/drm/xe/Kconfig
index 4d7dcaff2b915..becb9a06d66bd 100644
--- a/drivers/gpu/drm/xe/Kconfig
+++ b/drivers/gpu/drm/xe/Kconfig
@@ -27,7 +27,7 @@ config DRM_XE
        select IRQ_WORK
        # xe depends on ACPI_VIDEO when ACPI is enabled
        # but for select to work, need to select ACPI_VIDEO's dependencies, ick
-       select BACKLIGHT_CLASS_DEVICE if ACPI
+       select BACKLIGHT_CLASS_DEVICE if ACPI && !DRM_LUMINANCE
        select INPUT if ACPI
        select ACPI_VIDEO if X86 && ACPI
        select ACPI_WMI if X86 && ACPI
-- 
2.43.0

Reply via email to