From ea840a8c53f8ce00a63ae72f6eee6d49fba748a3 Mon Sep 17 00:00:00 2001 From: Alyssa Ross Date: Wed, 19 Jan 2022 00:28:28 +0000 Subject: kernelPatches.eve-backlight: backport upstream patches --- overlays/patches/linux/eve-backlight.patch | 3963 +++++++++++++++++++++++++++- 1 file changed, 3840 insertions(+), 123 deletions(-) (limited to 'overlays/patches') diff --git a/overlays/patches/linux/eve-backlight.patch b/overlays/patches/linux/eve-backlight.patch index 6df8577008c5..b54a84356a40 100644 --- a/overlays/patches/linux/eve-backlight.patch +++ b/overlays/patches/linux/eve-backlight.patch @@ -1,19 +1,3459 @@ -From 4b5c309e05e3033ebc2dc00c17a1884449cf4e2b Mon Sep 17 00:00:00 2001 -From: Alyssa Ross -Date: Thu, 24 Jun 2021 00:46:26 +0000 -Subject: [PATCH 1/2] Revert "drm/i915/dp: Don't use DPCD backlights that need - PWM enable/disable" +From 81887483c3d8f651d49876ee96c57bded46705b0 Mon Sep 17 00:00:00 2001 +From: Jani Nikula +Date: Wed, 25 Aug 2021 14:06:50 +0300 +Subject: [PATCH 1/5] drm/i915/backlight: extract backlight code to a separate + file -This reverts commit fe7d52bccab674a22776a2f31236bf4232e85410. +In a long overdue refactoring, split out backlight code to new +intel_backlight.[ch]. Simple code movement, leave renames for follow-up +work. No functional changes. + +Cc: Lyude Paul +Reviewed-by: Lyude Paul +Signed-off-by: Jani Nikula +Link: https://patchwork.freedesktop.org/patch/msgid/97d310848f03061473b9b2328e2c5c4dcf263cfa.1629888677.git.jani.nikula@intel.com +(cherry-picked from commit 6cc42fbeb150ff33b17cbf108713ca4be23994d8) +--- + drivers/gpu/drm/i915/Makefile | 1 + + drivers/gpu/drm/i915/display/g4x_dp.c | 2 +- + drivers/gpu/drm/i915/display/icl_dsi.c | 1 + + .../{intel_panel.c => intel_backlight.c} | 498 +---- + .../{intel_panel.h => intel_backlight.h} | 35 +- + .../gpu/drm/i915/display/intel_connector.c | 4 +- + drivers/gpu/drm/i915/display/intel_ddi.c | 2 +- + drivers/gpu/drm/i915/display/intel_dp.c | 1 + + .../drm/i915/display/intel_dp_aux_backlight.c | 2 +- + drivers/gpu/drm/i915/display/intel_lvds.c | 1 + + drivers/gpu/drm/i915/display/intel_opregion.c | 3 +- + drivers/gpu/drm/i915/display/intel_panel.c | 1767 +---------------- + drivers/gpu/drm/i915/display/intel_panel.h | 34 +- + drivers/gpu/drm/i915/display/vlv_dsi.c | 1 + + 14 files changed, 32 insertions(+), 2320 deletions(-) + copy drivers/gpu/drm/i915/display/{intel_panel.c => intel_backlight.c} (78%) + copy drivers/gpu/drm/i915/display/{intel_panel.h => intel_backlight.h} (58%) + +diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile +index 335ba9f43d8f..1ffdc2afc456 100644 +--- a/drivers/gpu/drm/i915/Makefile ++++ b/drivers/gpu/drm/i915/Makefile +@@ -247,6 +247,7 @@ i915-y += \ + display/g4x_dp.o \ + display/g4x_hdmi.o \ + display/icl_dsi.o \ ++ display/intel_backlight.o \ + display/intel_crt.o \ + display/intel_ddi.o \ + display/intel_ddi_buf_trans.o \ +diff --git a/drivers/gpu/drm/i915/display/g4x_dp.c b/drivers/gpu/drm/i915/display/g4x_dp.c +index de0f358184aa..29c0eca647e3 100644 +--- a/drivers/gpu/drm/i915/display/g4x_dp.c ++++ b/drivers/gpu/drm/i915/display/g4x_dp.c +@@ -7,6 +7,7 @@ + + #include "g4x_dp.h" + #include "intel_audio.h" ++#include "intel_backlight.h" + #include "intel_connector.h" + #include "intel_de.h" + #include "intel_display_types.h" +@@ -16,7 +17,6 @@ + #include "intel_fifo_underrun.h" + #include "intel_hdmi.h" + #include "intel_hotplug.h" +-#include "intel_panel.h" + #include "intel_pps.h" + #include "intel_sideband.h" + +diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c +index 638a00b2dc2d..2601873e1546 100644 +--- a/drivers/gpu/drm/i915/display/icl_dsi.c ++++ b/drivers/gpu/drm/i915/display/icl_dsi.c +@@ -29,6 +29,7 @@ + #include + + #include "intel_atomic.h" ++#include "intel_backlight.h" + #include "intel_combo_phy.h" + #include "intel_connector.h" + #include "intel_crtc.h" +diff --git a/drivers/gpu/drm/i915/display/intel_panel.c b/drivers/gpu/drm/i915/display/intel_backlight.c +similarity index 78% +copy from drivers/gpu/drm/i915/display/intel_panel.c +copy to drivers/gpu/drm/i915/display/intel_backlight.c +index 7d7a60b4d2de..4b0086ee4851 100644 +--- a/drivers/gpu/drm/i915/display/intel_panel.c ++++ b/drivers/gpu/drm/i915/display/intel_backlight.c +@@ -1,39 +1,12 @@ ++// SPDX-License-Identifier: MIT + /* +- * Copyright © 2006-2010 Intel Corporation +- * Copyright (c) 2006 Dave Airlie +- * +- * Permission is hereby granted, free of charge, to any person obtaining a +- * copy of this software and associated documentation files (the "Software"), +- * to deal in the Software without restriction, including without limitation +- * the rights to use, copy, modify, merge, publish, distribute, sublicense, +- * and/or sell copies of the Software, and to permit persons to whom the +- * Software is furnished to do so, subject to the following conditions: +- * +- * The above copyright notice and this permission notice (including the next +- * paragraph) shall be included in all copies or substantial portions of the +- * Software. +- * +- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +- * DEALINGS IN THE SOFTWARE. +- * +- * Authors: +- * Eric Anholt +- * Dave Airlie +- * Jesse Barnes +- * Chris Wilson ++ * Copyright © 2021 Intel Corporation + */ + +-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +- + #include +-#include + #include + ++#include "intel_backlight.h" + #include "intel_connector.h" + #include "intel_de.h" + #include "intel_display_types.h" +@@ -41,421 +14,6 @@ + #include "intel_dsi_dcs_backlight.h" + #include "intel_panel.h" + +-void +-intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode, +- struct drm_display_mode *adjusted_mode) +-{ +- drm_mode_copy(adjusted_mode, fixed_mode); +- +- drm_mode_set_crtcinfo(adjusted_mode, 0); +-} +- +-static bool is_downclock_mode(const struct drm_display_mode *downclock_mode, +- const struct drm_display_mode *fixed_mode) +-{ +- return drm_mode_match(downclock_mode, fixed_mode, +- DRM_MODE_MATCH_TIMINGS | +- DRM_MODE_MATCH_FLAGS | +- DRM_MODE_MATCH_3D_FLAGS) && +- downclock_mode->clock < fixed_mode->clock; +-} +- +-struct drm_display_mode * +-intel_panel_edid_downclock_mode(struct intel_connector *connector, +- const struct drm_display_mode *fixed_mode) +-{ +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +- const struct drm_display_mode *scan, *best_mode = NULL; +- struct drm_display_mode *downclock_mode; +- int best_clock = fixed_mode->clock; +- +- list_for_each_entry(scan, &connector->base.probed_modes, head) { +- /* +- * If one mode has the same resolution with the fixed_panel +- * mode while they have the different refresh rate, it means +- * that the reduced downclock is found. In such +- * case we can set the different FPx0/1 to dynamically select +- * between low and high frequency. +- */ +- if (is_downclock_mode(scan, fixed_mode) && +- scan->clock < best_clock) { +- /* +- * The downclock is already found. But we +- * expect to find the lower downclock. +- */ +- best_clock = scan->clock; +- best_mode = scan; +- } +- } +- +- if (!best_mode) +- return NULL; +- +- downclock_mode = drm_mode_duplicate(&dev_priv->drm, best_mode); +- if (!downclock_mode) +- return NULL; +- +- drm_dbg_kms(&dev_priv->drm, +- "[CONNECTOR:%d:%s] using downclock mode from EDID: ", +- connector->base.base.id, connector->base.name); +- drm_mode_debug_printmodeline(downclock_mode); +- +- return downclock_mode; +-} +- +-struct drm_display_mode * +-intel_panel_edid_fixed_mode(struct intel_connector *connector) +-{ +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +- const struct drm_display_mode *scan; +- struct drm_display_mode *fixed_mode; +- +- if (list_empty(&connector->base.probed_modes)) +- return NULL; +- +- /* prefer fixed mode from EDID if available */ +- list_for_each_entry(scan, &connector->base.probed_modes, head) { +- if ((scan->type & DRM_MODE_TYPE_PREFERRED) == 0) +- continue; +- +- fixed_mode = drm_mode_duplicate(&dev_priv->drm, scan); +- if (!fixed_mode) +- return NULL; +- +- drm_dbg_kms(&dev_priv->drm, +- "[CONNECTOR:%d:%s] using preferred mode from EDID: ", +- connector->base.base.id, connector->base.name); +- drm_mode_debug_printmodeline(fixed_mode); +- +- return fixed_mode; +- } +- +- scan = list_first_entry(&connector->base.probed_modes, +- typeof(*scan), head); +- +- fixed_mode = drm_mode_duplicate(&dev_priv->drm, scan); +- if (!fixed_mode) +- return NULL; +- +- fixed_mode->type |= DRM_MODE_TYPE_PREFERRED; +- +- drm_dbg_kms(&dev_priv->drm, +- "[CONNECTOR:%d:%s] using first mode from EDID: ", +- connector->base.base.id, connector->base.name); +- drm_mode_debug_printmodeline(fixed_mode); +- +- return fixed_mode; +-} +- +-struct drm_display_mode * +-intel_panel_vbt_fixed_mode(struct intel_connector *connector) +-{ +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +- struct drm_display_info *info = &connector->base.display_info; +- struct drm_display_mode *fixed_mode; +- +- if (!dev_priv->vbt.lfp_lvds_vbt_mode) +- return NULL; +- +- fixed_mode = drm_mode_duplicate(&dev_priv->drm, +- dev_priv->vbt.lfp_lvds_vbt_mode); +- if (!fixed_mode) +- return NULL; +- +- fixed_mode->type |= DRM_MODE_TYPE_PREFERRED; +- +- drm_dbg_kms(&dev_priv->drm, "[CONNECTOR:%d:%s] using mode from VBT: ", +- connector->base.base.id, connector->base.name); +- drm_mode_debug_printmodeline(fixed_mode); +- +- info->width_mm = fixed_mode->width_mm; +- info->height_mm = fixed_mode->height_mm; +- +- return fixed_mode; +-} +- +-/* adjusted_mode has been preset to be the panel's fixed mode */ +-int intel_pch_panel_fitting(struct intel_crtc_state *crtc_state, +- const struct drm_connector_state *conn_state) +-{ +- const struct drm_display_mode *adjusted_mode = +- &crtc_state->hw.adjusted_mode; +- int x, y, width, height; +- +- /* Native modes don't need fitting */ +- if (adjusted_mode->crtc_hdisplay == crtc_state->pipe_src_w && +- adjusted_mode->crtc_vdisplay == crtc_state->pipe_src_h && +- crtc_state->output_format != INTEL_OUTPUT_FORMAT_YCBCR420) +- return 0; +- +- switch (conn_state->scaling_mode) { +- case DRM_MODE_SCALE_CENTER: +- width = crtc_state->pipe_src_w; +- height = crtc_state->pipe_src_h; +- x = (adjusted_mode->crtc_hdisplay - width + 1)/2; +- y = (adjusted_mode->crtc_vdisplay - height + 1)/2; +- break; +- +- case DRM_MODE_SCALE_ASPECT: +- /* Scale but preserve the aspect ratio */ +- { +- u32 scaled_width = adjusted_mode->crtc_hdisplay +- * crtc_state->pipe_src_h; +- u32 scaled_height = crtc_state->pipe_src_w +- * adjusted_mode->crtc_vdisplay; +- if (scaled_width > scaled_height) { /* pillar */ +- width = scaled_height / crtc_state->pipe_src_h; +- if (width & 1) +- width++; +- x = (adjusted_mode->crtc_hdisplay - width + 1) / 2; +- y = 0; +- height = adjusted_mode->crtc_vdisplay; +- } else if (scaled_width < scaled_height) { /* letter */ +- height = scaled_width / crtc_state->pipe_src_w; +- if (height & 1) +- height++; +- y = (adjusted_mode->crtc_vdisplay - height + 1) / 2; +- x = 0; +- width = adjusted_mode->crtc_hdisplay; +- } else { +- x = y = 0; +- width = adjusted_mode->crtc_hdisplay; +- height = adjusted_mode->crtc_vdisplay; +- } +- } +- break; +- +- case DRM_MODE_SCALE_NONE: +- WARN_ON(adjusted_mode->crtc_hdisplay != crtc_state->pipe_src_w); +- WARN_ON(adjusted_mode->crtc_vdisplay != crtc_state->pipe_src_h); +- fallthrough; +- case DRM_MODE_SCALE_FULLSCREEN: +- x = y = 0; +- width = adjusted_mode->crtc_hdisplay; +- height = adjusted_mode->crtc_vdisplay; +- break; +- +- default: +- MISSING_CASE(conn_state->scaling_mode); +- return -EINVAL; +- } +- +- drm_rect_init(&crtc_state->pch_pfit.dst, +- x, y, width, height); +- crtc_state->pch_pfit.enabled = true; +- +- return 0; +-} +- +-static void +-centre_horizontally(struct drm_display_mode *adjusted_mode, +- int width) +-{ +- u32 border, sync_pos, blank_width, sync_width; +- +- /* keep the hsync and hblank widths constant */ +- sync_width = adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start; +- blank_width = adjusted_mode->crtc_hblank_end - adjusted_mode->crtc_hblank_start; +- sync_pos = (blank_width - sync_width + 1) / 2; +- +- border = (adjusted_mode->crtc_hdisplay - width + 1) / 2; +- border += border & 1; /* make the border even */ +- +- adjusted_mode->crtc_hdisplay = width; +- adjusted_mode->crtc_hblank_start = width + border; +- adjusted_mode->crtc_hblank_end = adjusted_mode->crtc_hblank_start + blank_width; +- +- adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hblank_start + sync_pos; +- adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + sync_width; +-} +- +-static void +-centre_vertically(struct drm_display_mode *adjusted_mode, +- int height) +-{ +- u32 border, sync_pos, blank_width, sync_width; +- +- /* keep the vsync and vblank widths constant */ +- sync_width = adjusted_mode->crtc_vsync_end - adjusted_mode->crtc_vsync_start; +- blank_width = adjusted_mode->crtc_vblank_end - adjusted_mode->crtc_vblank_start; +- sync_pos = (blank_width - sync_width + 1) / 2; +- +- border = (adjusted_mode->crtc_vdisplay - height + 1) / 2; +- +- adjusted_mode->crtc_vdisplay = height; +- adjusted_mode->crtc_vblank_start = height + border; +- adjusted_mode->crtc_vblank_end = adjusted_mode->crtc_vblank_start + blank_width; +- +- adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vblank_start + sync_pos; +- adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_start + sync_width; +-} +- +-static u32 panel_fitter_scaling(u32 source, u32 target) +-{ +- /* +- * Floating point operation is not supported. So the FACTOR +- * is defined, which can avoid the floating point computation +- * when calculating the panel ratio. +- */ +-#define ACCURACY 12 +-#define FACTOR (1 << ACCURACY) +- u32 ratio = source * FACTOR / target; +- return (FACTOR * ratio + FACTOR/2) / FACTOR; +-} +- +-static void i965_scale_aspect(struct intel_crtc_state *crtc_state, +- u32 *pfit_control) +-{ +- const struct drm_display_mode *adjusted_mode = +- &crtc_state->hw.adjusted_mode; +- u32 scaled_width = adjusted_mode->crtc_hdisplay * +- crtc_state->pipe_src_h; +- u32 scaled_height = crtc_state->pipe_src_w * +- adjusted_mode->crtc_vdisplay; +- +- /* 965+ is easy, it does everything in hw */ +- if (scaled_width > scaled_height) +- *pfit_control |= PFIT_ENABLE | +- PFIT_SCALING_PILLAR; +- else if (scaled_width < scaled_height) +- *pfit_control |= PFIT_ENABLE | +- PFIT_SCALING_LETTER; +- else if (adjusted_mode->crtc_hdisplay != crtc_state->pipe_src_w) +- *pfit_control |= PFIT_ENABLE | PFIT_SCALING_AUTO; +-} +- +-static void i9xx_scale_aspect(struct intel_crtc_state *crtc_state, +- u32 *pfit_control, u32 *pfit_pgm_ratios, +- u32 *border) +-{ +- struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; +- u32 scaled_width = adjusted_mode->crtc_hdisplay * +- crtc_state->pipe_src_h; +- u32 scaled_height = crtc_state->pipe_src_w * +- adjusted_mode->crtc_vdisplay; +- u32 bits; +- +- /* +- * For earlier chips we have to calculate the scaling +- * ratio by hand and program it into the +- * PFIT_PGM_RATIO register +- */ +- if (scaled_width > scaled_height) { /* pillar */ +- centre_horizontally(adjusted_mode, +- scaled_height / +- crtc_state->pipe_src_h); +- +- *border = LVDS_BORDER_ENABLE; +- if (crtc_state->pipe_src_h != adjusted_mode->crtc_vdisplay) { +- bits = panel_fitter_scaling(crtc_state->pipe_src_h, +- adjusted_mode->crtc_vdisplay); +- +- *pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT | +- bits << PFIT_VERT_SCALE_SHIFT); +- *pfit_control |= (PFIT_ENABLE | +- VERT_INTERP_BILINEAR | +- HORIZ_INTERP_BILINEAR); +- } +- } else if (scaled_width < scaled_height) { /* letter */ +- centre_vertically(adjusted_mode, +- scaled_width / +- crtc_state->pipe_src_w); +- +- *border = LVDS_BORDER_ENABLE; +- if (crtc_state->pipe_src_w != adjusted_mode->crtc_hdisplay) { +- bits = panel_fitter_scaling(crtc_state->pipe_src_w, +- adjusted_mode->crtc_hdisplay); +- +- *pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT | +- bits << PFIT_VERT_SCALE_SHIFT); +- *pfit_control |= (PFIT_ENABLE | +- VERT_INTERP_BILINEAR | +- HORIZ_INTERP_BILINEAR); +- } +- } else { +- /* Aspects match, Let hw scale both directions */ +- *pfit_control |= (PFIT_ENABLE | +- VERT_AUTO_SCALE | HORIZ_AUTO_SCALE | +- VERT_INTERP_BILINEAR | +- HORIZ_INTERP_BILINEAR); +- } +-} +- +-int intel_gmch_panel_fitting(struct intel_crtc_state *crtc_state, +- const struct drm_connector_state *conn_state) +-{ +- struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); +- struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); +- u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0; +- struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; +- +- /* Native modes don't need fitting */ +- if (adjusted_mode->crtc_hdisplay == crtc_state->pipe_src_w && +- adjusted_mode->crtc_vdisplay == crtc_state->pipe_src_h) +- goto out; +- +- switch (conn_state->scaling_mode) { +- case DRM_MODE_SCALE_CENTER: +- /* +- * For centered modes, we have to calculate border widths & +- * heights and modify the values programmed into the CRTC. +- */ +- centre_horizontally(adjusted_mode, crtc_state->pipe_src_w); +- centre_vertically(adjusted_mode, crtc_state->pipe_src_h); +- border = LVDS_BORDER_ENABLE; +- break; +- case DRM_MODE_SCALE_ASPECT: +- /* Scale but preserve the aspect ratio */ +- if (DISPLAY_VER(dev_priv) >= 4) +- i965_scale_aspect(crtc_state, &pfit_control); +- else +- i9xx_scale_aspect(crtc_state, &pfit_control, +- &pfit_pgm_ratios, &border); +- break; +- case DRM_MODE_SCALE_FULLSCREEN: +- /* +- * Full scaling, even if it changes the aspect ratio. +- * Fortunately this is all done for us in hw. +- */ +- if (crtc_state->pipe_src_h != adjusted_mode->crtc_vdisplay || +- crtc_state->pipe_src_w != adjusted_mode->crtc_hdisplay) { +- pfit_control |= PFIT_ENABLE; +- if (DISPLAY_VER(dev_priv) >= 4) +- pfit_control |= PFIT_SCALING_AUTO; +- else +- pfit_control |= (VERT_AUTO_SCALE | +- VERT_INTERP_BILINEAR | +- HORIZ_AUTO_SCALE | +- HORIZ_INTERP_BILINEAR); +- } +- break; +- default: +- MISSING_CASE(conn_state->scaling_mode); +- return -EINVAL; +- } +- +- /* 965+ wants fuzzy fitting */ +- /* FIXME: handle multiple panels by failing gracefully */ +- if (DISPLAY_VER(dev_priv) >= 4) +- pfit_control |= PFIT_PIPE(crtc->pipe) | PFIT_FILTER_FUZZY; +- +-out: +- if ((pfit_control & PFIT_ENABLE) == 0) { +- pfit_control = 0; +- pfit_pgm_ratios = 0; +- } +- +- /* Make sure pre-965 set dither correctly for 18bpp panels. */ +- if (DISPLAY_VER(dev_priv) < 4 && crtc_state->pipe_bpp == 18) +- pfit_control |= PANEL_8TO6_DITHER_ENABLE; +- +- crtc_state->gmch_pfit.control = pfit_control; +- crtc_state->gmch_pfit.pgm_ratios = pfit_pgm_ratios; +- crtc_state->gmch_pfit.lvds_border_bits = border; +- +- return 0; +-} +- + /** + * scale - scale values from one range to another + * @source_val: value in range [@source_min..@source_max] +@@ -488,8 +46,10 @@ static u32 scale(u32 source_val, + return target_val; + } + +-/* Scale user_level in range [0..user_max] to [0..hw_max], clamping the result +- * to [hw_min..hw_max]. */ ++/* ++ * Scale user_level in range [0..user_max] to [0..hw_max], clamping the result ++ * to [hw_min..hw_max]. ++ */ + static u32 clamp_user_to_hw(struct intel_connector *connector, + u32 user_level, u32 user_max) + { +@@ -1322,7 +882,7 @@ static int intel_backlight_device_update_status(struct backlight_device *bd) + + /* + * Allow flipping bl_power as a sub-state of enabled. Sadly the +- * backlight class device does not make it easy to to differentiate ++ * backlight class device does not make it easy to differentiate + * between callbacks for brightness and bl_power, so our backlight_power + * callback needs to take this into account. + */ +@@ -2077,7 +1637,7 @@ int intel_panel_setup_backlight(struct drm_connector *connector, enum pipe pipe) + return 0; + } + +-static void intel_panel_destroy_backlight(struct intel_panel *panel) ++void intel_panel_destroy_backlight(struct intel_panel *panel) + { + /* dispose of the pwm */ + if (panel->backlight.pwm) +@@ -2175,7 +1735,7 @@ static const struct intel_panel_bl_funcs pwm_bl_funcs = { + }; + + /* Set up chip specific backlight functions */ +-static void ++void + intel_panel_init_backlight_funcs(struct intel_panel *panel) + { + struct intel_connector *connector = +@@ -2216,41 +1776,3 @@ intel_panel_init_backlight_funcs(struct intel_panel *panel) + /* We're using a standard PWM backlight interface */ + panel->backlight.funcs = &pwm_bl_funcs; + } +- +-enum drm_connector_status +-intel_panel_detect(struct drm_connector *connector, bool force) +-{ +- struct drm_i915_private *i915 = to_i915(connector->dev); +- +- if (!INTEL_DISPLAY_ENABLED(i915)) +- return connector_status_disconnected; +- +- return connector_status_connected; +-} +- +-int intel_panel_init(struct intel_panel *panel, +- struct drm_display_mode *fixed_mode, +- struct drm_display_mode *downclock_mode) +-{ +- intel_panel_init_backlight_funcs(panel); +- +- panel->fixed_mode = fixed_mode; +- panel->downclock_mode = downclock_mode; +- +- return 0; +-} +- +-void intel_panel_fini(struct intel_panel *panel) +-{ +- struct intel_connector *intel_connector = +- container_of(panel, struct intel_connector, panel); +- +- intel_panel_destroy_backlight(panel); +- +- if (panel->fixed_mode) +- drm_mode_destroy(intel_connector->base.dev, panel->fixed_mode); +- +- if (panel->downclock_mode) +- drm_mode_destroy(intel_connector->base.dev, +- panel->downclock_mode); +-} +diff --git a/drivers/gpu/drm/i915/display/intel_panel.h b/drivers/gpu/drm/i915/display/intel_backlight.h +similarity index 58% +copy from drivers/gpu/drm/i915/display/intel_panel.h +copy to drivers/gpu/drm/i915/display/intel_backlight.h +index 1d340f77bffc..282020cb47d5 100644 +--- a/drivers/gpu/drm/i915/display/intel_panel.h ++++ b/drivers/gpu/drm/i915/display/intel_backlight.h +@@ -1,36 +1,24 @@ + /* SPDX-License-Identifier: MIT */ + /* +- * Copyright © 2019 Intel Corporation ++ * Copyright © 2021 Intel Corporation + */ + +-#ifndef __INTEL_PANEL_H__ +-#define __INTEL_PANEL_H__ ++#ifndef __INTEL_BACKLIGHT_H__ ++#define __INTEL_BACKLIGHT_H__ + + #include + +-#include "intel_display.h" +- + struct drm_connector; + struct drm_connector_state; +-struct drm_display_mode; ++struct intel_atomic_state; + struct intel_connector; +-struct intel_crtc; + struct intel_crtc_state; + struct intel_encoder; + struct intel_panel; ++enum pipe; + +-int intel_panel_init(struct intel_panel *panel, +- struct drm_display_mode *fixed_mode, +- struct drm_display_mode *downclock_mode); +-void intel_panel_fini(struct intel_panel *panel); +-enum drm_connector_status +-intel_panel_detect(struct drm_connector *connector, bool force); +-void intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode, +- struct drm_display_mode *adjusted_mode); +-int intel_pch_panel_fitting(struct intel_crtc_state *crtc_state, +- const struct drm_connector_state *conn_state); +-int intel_gmch_panel_fitting(struct intel_crtc_state *crtc_state, +- const struct drm_connector_state *conn_state); ++void intel_panel_init_backlight_funcs(struct intel_panel *panel); ++void intel_panel_destroy_backlight(struct intel_panel *panel); + void intel_panel_set_backlight_acpi(const struct drm_connector_state *conn_state, + u32 level, u32 max); + int intel_panel_setup_backlight(struct drm_connector *connector, +@@ -42,13 +30,6 @@ void intel_panel_update_backlight(struct intel_atomic_state *state, + const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state); + void intel_panel_disable_backlight(const struct drm_connector_state *old_conn_state); +-struct drm_display_mode * +-intel_panel_edid_downclock_mode(struct intel_connector *connector, +- const struct drm_display_mode *fixed_mode); +-struct drm_display_mode * +-intel_panel_edid_fixed_mode(struct intel_connector *connector); +-struct drm_display_mode * +-intel_panel_vbt_fixed_mode(struct intel_connector *connector); + void intel_panel_set_pwm_level(const struct drm_connector_state *conn_state, u32 level); + u32 intel_panel_invert_pwm_level(struct intel_connector *connector, u32 level); + u32 intel_panel_backlight_level_to_pwm(struct intel_connector *connector, u32 level); +@@ -67,4 +48,4 @@ static inline void intel_backlight_device_unregister(struct intel_connector *con + } + #endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */ + +-#endif /* __INTEL_PANEL_H__ */ ++#endif /* __INTEL_BACKLIGHT_H__ */ +diff --git a/drivers/gpu/drm/i915/display/intel_connector.c b/drivers/gpu/drm/i915/display/intel_connector.c +index 9bed1ccecea0..4f49d782eca2 100644 +--- a/drivers/gpu/drm/i915/display/intel_connector.c ++++ b/drivers/gpu/drm/i915/display/intel_connector.c +@@ -29,13 +29,13 @@ + #include + #include + +-#include "display/intel_panel.h" +- + #include "i915_drv.h" ++#include "intel_backlight.h" + #include "intel_connector.h" + #include "intel_display_debugfs.h" + #include "intel_display_types.h" + #include "intel_hdcp.h" ++#include "intel_panel.h" + + int intel_connector_init(struct intel_connector *connector) + { +diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c +index 82e5064b4ce7..8e981861699e 100644 +--- a/drivers/gpu/drm/i915/display/intel_ddi.c ++++ b/drivers/gpu/drm/i915/display/intel_ddi.c +@@ -29,6 +29,7 @@ + + #include "i915_drv.h" + #include "intel_audio.h" ++#include "intel_backlight.h" + #include "intel_combo_phy.h" + #include "intel_connector.h" + #include "intel_crtc.h" +@@ -48,7 +49,6 @@ + #include "intel_hdmi.h" + #include "intel_hotplug.h" + #include "intel_lspcon.h" +-#include "intel_panel.h" + #include "intel_pps.h" + #include "intel_psr.h" + #include "intel_snps_phy.h" +diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c +index d55363f1fa10..269ba112acd1 100644 +--- a/drivers/gpu/drm/i915/display/intel_dp.c ++++ b/drivers/gpu/drm/i915/display/intel_dp.c +@@ -45,6 +45,7 @@ + #include "i915_drv.h" + #include "intel_atomic.h" + #include "intel_audio.h" ++#include "intel_backlight.h" + #include "intel_connector.h" + #include "intel_ddi.h" + #include "intel_de.h" +diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c +index c82f8febe730..07c36c98ae1b 100644 +--- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c ++++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c +@@ -34,10 +34,10 @@ + * for some reason. + */ + ++#include "intel_backlight.h" + #include "intel_display_types.h" + #include "intel_dp.h" + #include "intel_dp_aux_backlight.h" +-#include "intel_panel.h" + + /* TODO: + * Implement HDR, right now we just implement the bare minimum to bring us back into SDR mode so we +diff --git a/drivers/gpu/drm/i915/display/intel_lvds.c b/drivers/gpu/drm/i915/display/intel_lvds.c +index e0381b0fce91..8f5741ebd58d 100644 +--- a/drivers/gpu/drm/i915/display/intel_lvds.c ++++ b/drivers/gpu/drm/i915/display/intel_lvds.c +@@ -40,6 +40,7 @@ + + #include "i915_drv.h" + #include "intel_atomic.h" ++#include "intel_backlight.h" + #include "intel_connector.h" + #include "intel_de.h" + #include "intel_display_types.h" +diff --git a/drivers/gpu/drm/i915/display/intel_opregion.c b/drivers/gpu/drm/i915/display/intel_opregion.c +index 3855fba70980..3a7a8598d1ec 100644 +--- a/drivers/gpu/drm/i915/display/intel_opregion.c ++++ b/drivers/gpu/drm/i915/display/intel_opregion.c +@@ -30,10 +30,9 @@ + #include + #include + +-#include "display/intel_panel.h" +- + #include "i915_drv.h" + #include "intel_acpi.h" ++#include "intel_backlight.h" + #include "intel_display_types.h" + #include "intel_opregion.h" + +diff --git a/drivers/gpu/drm/i915/display/intel_panel.c b/drivers/gpu/drm/i915/display/intel_panel.c +index 7d7a60b4d2de..ad54767440c1 100644 +--- a/drivers/gpu/drm/i915/display/intel_panel.c ++++ b/drivers/gpu/drm/i915/display/intel_panel.c +@@ -28,17 +28,13 @@ + * Chris Wilson + */ + +-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +- + #include +-#include + #include + ++#include "intel_backlight.h" + #include "intel_connector.h" + #include "intel_de.h" + #include "intel_display_types.h" +-#include "intel_dp_aux_backlight.h" +-#include "intel_dsi_dcs_backlight.h" + #include "intel_panel.h" + + void +@@ -456,1767 +452,6 @@ int intel_gmch_panel_fitting(struct intel_crtc_state *crtc_state, + return 0; + } + +-/** +- * scale - scale values from one range to another +- * @source_val: value in range [@source_min..@source_max] +- * @source_min: minimum legal value for @source_val +- * @source_max: maximum legal value for @source_val +- * @target_min: corresponding target value for @source_min +- * @target_max: corresponding target value for @source_max +- * +- * Return @source_val in range [@source_min..@source_max] scaled to range +- * [@target_min..@target_max]. +- */ +-static u32 scale(u32 source_val, +- u32 source_min, u32 source_max, +- u32 target_min, u32 target_max) +-{ +- u64 target_val; +- +- WARN_ON(source_min > source_max); +- WARN_ON(target_min > target_max); +- +- /* defensive */ +- source_val = clamp(source_val, source_min, source_max); +- +- /* avoid overflows */ +- target_val = mul_u32_u32(source_val - source_min, +- target_max - target_min); +- target_val = DIV_ROUND_CLOSEST_ULL(target_val, source_max - source_min); +- target_val += target_min; +- +- return target_val; +-} +- +-/* Scale user_level in range [0..user_max] to [0..hw_max], clamping the result +- * to [hw_min..hw_max]. */ +-static u32 clamp_user_to_hw(struct intel_connector *connector, +- u32 user_level, u32 user_max) +-{ +- struct intel_panel *panel = &connector->panel; +- u32 hw_level; +- +- hw_level = scale(user_level, 0, user_max, 0, panel->backlight.max); +- hw_level = clamp(hw_level, panel->backlight.min, panel->backlight.max); +- +- return hw_level; +-} +- +-/* Scale hw_level in range [hw_min..hw_max] to [0..user_max]. */ +-static u32 scale_hw_to_user(struct intel_connector *connector, +- u32 hw_level, u32 user_max) +-{ +- struct intel_panel *panel = &connector->panel; +- +- return scale(hw_level, panel->backlight.min, panel->backlight.max, +- 0, user_max); +-} +- +-u32 intel_panel_invert_pwm_level(struct intel_connector *connector, u32 val) +-{ +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +- struct intel_panel *panel = &connector->panel; +- +- drm_WARN_ON(&dev_priv->drm, panel->backlight.pwm_level_max == 0); +- +- if (dev_priv->params.invert_brightness < 0) +- return val; +- +- if (dev_priv->params.invert_brightness > 0 || +- dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS) { +- return panel->backlight.pwm_level_max - val + panel->backlight.pwm_level_min; +- } +- +- return val; +-} +- +-void intel_panel_set_pwm_level(const struct drm_connector_state *conn_state, u32 val) +-{ +- struct intel_connector *connector = to_intel_connector(conn_state->connector); +- struct drm_i915_private *i915 = to_i915(connector->base.dev); +- struct intel_panel *panel = &connector->panel; +- +- drm_dbg_kms(&i915->drm, "set backlight PWM = %d\n", val); +- panel->backlight.pwm_funcs->set(conn_state, val); +-} +- +-u32 intel_panel_backlight_level_to_pwm(struct intel_connector *connector, u32 val) +-{ +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +- struct intel_panel *panel = &connector->panel; +- +- drm_WARN_ON_ONCE(&dev_priv->drm, +- panel->backlight.max == 0 || panel->backlight.pwm_level_max == 0); +- +- val = scale(val, panel->backlight.min, panel->backlight.max, +- panel->backlight.pwm_level_min, panel->backlight.pwm_level_max); +- +- return intel_panel_invert_pwm_level(connector, val); +-} +- +-u32 intel_panel_backlight_level_from_pwm(struct intel_connector *connector, u32 val) +-{ +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +- struct intel_panel *panel = &connector->panel; +- +- drm_WARN_ON_ONCE(&dev_priv->drm, +- panel->backlight.max == 0 || panel->backlight.pwm_level_max == 0); +- +- if (dev_priv->params.invert_brightness > 0 || +- (dev_priv->params.invert_brightness == 0 && dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS)) +- val = panel->backlight.pwm_level_max - (val - panel->backlight.pwm_level_min); +- +- return scale(val, panel->backlight.pwm_level_min, panel->backlight.pwm_level_max, +- panel->backlight.min, panel->backlight.max); +-} +- +-static u32 lpt_get_backlight(struct intel_connector *connector, enum pipe unused) +-{ +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +- +- return intel_de_read(dev_priv, BLC_PWM_PCH_CTL2) & BACKLIGHT_DUTY_CYCLE_MASK; +-} +- +-static u32 pch_get_backlight(struct intel_connector *connector, enum pipe unused) +-{ +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +- +- return intel_de_read(dev_priv, BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK; +-} +- +-static u32 i9xx_get_backlight(struct intel_connector *connector, enum pipe unused) +-{ +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +- struct intel_panel *panel = &connector->panel; +- u32 val; +- +- val = intel_de_read(dev_priv, BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK; +- if (DISPLAY_VER(dev_priv) < 4) +- val >>= 1; +- +- if (panel->backlight.combination_mode) { +- u8 lbpc; +- +- pci_read_config_byte(to_pci_dev(dev_priv->drm.dev), LBPC, &lbpc); +- val *= lbpc; +- } +- +- return val; +-} +- +-static u32 vlv_get_backlight(struct intel_connector *connector, enum pipe pipe) +-{ +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +- +- if (drm_WARN_ON(&dev_priv->drm, pipe != PIPE_A && pipe != PIPE_B)) +- return 0; +- +- return intel_de_read(dev_priv, VLV_BLC_PWM_CTL(pipe)) & BACKLIGHT_DUTY_CYCLE_MASK; +-} +- +-static u32 bxt_get_backlight(struct intel_connector *connector, enum pipe unused) +-{ +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +- struct intel_panel *panel = &connector->panel; +- +- return intel_de_read(dev_priv, +- BXT_BLC_PWM_DUTY(panel->backlight.controller)); +-} +- +-static u32 ext_pwm_get_backlight(struct intel_connector *connector, enum pipe unused) +-{ +- struct intel_panel *panel = &connector->panel; +- struct pwm_state state; +- +- pwm_get_state(panel->backlight.pwm, &state); +- return pwm_get_relative_duty_cycle(&state, 100); +-} +- +-static void lpt_set_backlight(const struct drm_connector_state *conn_state, u32 level) +-{ +- struct intel_connector *connector = to_intel_connector(conn_state->connector); +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +- +- u32 val = intel_de_read(dev_priv, BLC_PWM_PCH_CTL2) & ~BACKLIGHT_DUTY_CYCLE_MASK; +- intel_de_write(dev_priv, BLC_PWM_PCH_CTL2, val | level); +-} +- +-static void pch_set_backlight(const struct drm_connector_state *conn_state, u32 level) +-{ +- struct intel_connector *connector = to_intel_connector(conn_state->connector); +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +- u32 tmp; +- +- tmp = intel_de_read(dev_priv, BLC_PWM_CPU_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK; +- intel_de_write(dev_priv, BLC_PWM_CPU_CTL, tmp | level); +-} +- +-static void i9xx_set_backlight(const struct drm_connector_state *conn_state, u32 level) +-{ +- struct intel_connector *connector = to_intel_connector(conn_state->connector); +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +- struct intel_panel *panel = &connector->panel; +- u32 tmp, mask; +- +- drm_WARN_ON(&dev_priv->drm, panel->backlight.pwm_level_max == 0); +- +- if (panel->backlight.combination_mode) { +- u8 lbpc; +- +- lbpc = level * 0xfe / panel->backlight.pwm_level_max + 1; +- level /= lbpc; +- pci_write_config_byte(to_pci_dev(dev_priv->drm.dev), LBPC, lbpc); +- } +- +- if (DISPLAY_VER(dev_priv) == 4) { +- mask = BACKLIGHT_DUTY_CYCLE_MASK; +- } else { +- level <<= 1; +- mask = BACKLIGHT_DUTY_CYCLE_MASK_PNV; +- } +- +- tmp = intel_de_read(dev_priv, BLC_PWM_CTL) & ~mask; +- intel_de_write(dev_priv, BLC_PWM_CTL, tmp | level); +-} +- +-static void vlv_set_backlight(const struct drm_connector_state *conn_state, u32 level) +-{ +- struct intel_connector *connector = to_intel_connector(conn_state->connector); +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +- enum pipe pipe = to_intel_crtc(conn_state->crtc)->pipe; +- u32 tmp; +- +- tmp = intel_de_read(dev_priv, VLV_BLC_PWM_CTL(pipe)) & ~BACKLIGHT_DUTY_CYCLE_MASK; +- intel_de_write(dev_priv, VLV_BLC_PWM_CTL(pipe), tmp | level); +-} +- +-static void bxt_set_backlight(const struct drm_connector_state *conn_state, u32 level) +-{ +- struct intel_connector *connector = to_intel_connector(conn_state->connector); +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +- struct intel_panel *panel = &connector->panel; +- +- intel_de_write(dev_priv, +- BXT_BLC_PWM_DUTY(panel->backlight.controller), level); +-} +- +-static void ext_pwm_set_backlight(const struct drm_connector_state *conn_state, u32 level) +-{ +- struct intel_panel *panel = &to_intel_connector(conn_state->connector)->panel; +- +- pwm_set_relative_duty_cycle(&panel->backlight.pwm_state, level, 100); +- pwm_apply_state(panel->backlight.pwm, &panel->backlight.pwm_state); +-} +- +-static void +-intel_panel_actually_set_backlight(const struct drm_connector_state *conn_state, u32 level) +-{ +- struct intel_connector *connector = to_intel_connector(conn_state->connector); +- struct drm_i915_private *i915 = to_i915(connector->base.dev); +- struct intel_panel *panel = &connector->panel; +- +- drm_dbg_kms(&i915->drm, "set backlight level = %d\n", level); +- +- panel->backlight.funcs->set(conn_state, level); +-} +- +-/* set backlight brightness to level in range [0..max], assuming hw min is +- * respected. +- */ +-void intel_panel_set_backlight_acpi(const struct drm_connector_state *conn_state, +- u32 user_level, u32 user_max) +-{ +- struct intel_connector *connector = to_intel_connector(conn_state->connector); +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +- struct intel_panel *panel = &connector->panel; +- u32 hw_level; +- +- /* +- * Lack of crtc may occur during driver init because +- * connection_mutex isn't held across the entire backlight +- * setup + modeset readout, and the BIOS can issue the +- * requests at any time. +- */ +- if (!panel->backlight.present || !conn_state->crtc) +- return; +- +- mutex_lock(&dev_priv->backlight_lock); +- +- drm_WARN_ON(&dev_priv->drm, panel->backlight.max == 0); +- +- hw_level = clamp_user_to_hw(connector, user_level, user_max); +- panel->backlight.level = hw_level; +- +- if (panel->backlight.device) +- panel->backlight.device->props.brightness = +- scale_hw_to_user(connector, +- panel->backlight.level, +- panel->backlight.device->props.max_brightness); +- +- if (panel->backlight.enabled) +- intel_panel_actually_set_backlight(conn_state, hw_level); +- +- mutex_unlock(&dev_priv->backlight_lock); +-} +- +-static void lpt_disable_backlight(const struct drm_connector_state *old_conn_state, u32 level) +-{ +- struct intel_connector *connector = to_intel_connector(old_conn_state->connector); +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +- u32 tmp; +- +- intel_panel_set_pwm_level(old_conn_state, level); +- +- /* +- * Although we don't support or enable CPU PWM with LPT/SPT based +- * systems, it may have been enabled prior to loading the +- * driver. Disable to avoid warnings on LCPLL disable. +- * +- * This needs rework if we need to add support for CPU PWM on PCH split +- * platforms. +- */ +- tmp = intel_de_read(dev_priv, BLC_PWM_CPU_CTL2); +- if (tmp & BLM_PWM_ENABLE) { +- drm_dbg_kms(&dev_priv->drm, +- "cpu backlight was enabled, disabling\n"); +- intel_de_write(dev_priv, BLC_PWM_CPU_CTL2, +- tmp & ~BLM_PWM_ENABLE); +- } +- +- tmp = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1); +- intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, tmp & ~BLM_PCH_PWM_ENABLE); +-} +- +-static void pch_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val) +-{ +- struct intel_connector *connector = to_intel_connector(old_conn_state->connector); +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +- u32 tmp; +- +- intel_panel_set_pwm_level(old_conn_state, val); +- +- tmp = intel_de_read(dev_priv, BLC_PWM_CPU_CTL2); +- intel_de_write(dev_priv, BLC_PWM_CPU_CTL2, tmp & ~BLM_PWM_ENABLE); +- +- tmp = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1); +- intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, tmp & ~BLM_PCH_PWM_ENABLE); +-} +- +-static void i9xx_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val) +-{ +- intel_panel_set_pwm_level(old_conn_state, val); +-} +- +-static void i965_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val) +-{ +- struct drm_i915_private *dev_priv = to_i915(old_conn_state->connector->dev); +- u32 tmp; +- +- intel_panel_set_pwm_level(old_conn_state, val); +- +- tmp = intel_de_read(dev_priv, BLC_PWM_CTL2); +- intel_de_write(dev_priv, BLC_PWM_CTL2, tmp & ~BLM_PWM_ENABLE); +-} +- +-static void vlv_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val) +-{ +- struct intel_connector *connector = to_intel_connector(old_conn_state->connector); +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +- enum pipe pipe = to_intel_crtc(old_conn_state->crtc)->pipe; +- u32 tmp; +- +- intel_panel_set_pwm_level(old_conn_state, val); +- +- tmp = intel_de_read(dev_priv, VLV_BLC_PWM_CTL2(pipe)); +- intel_de_write(dev_priv, VLV_BLC_PWM_CTL2(pipe), +- tmp & ~BLM_PWM_ENABLE); +-} +- +-static void bxt_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val) +-{ +- struct intel_connector *connector = to_intel_connector(old_conn_state->connector); +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +- struct intel_panel *panel = &connector->panel; +- u32 tmp; +- +- intel_panel_set_pwm_level(old_conn_state, val); +- +- tmp = intel_de_read(dev_priv, +- BXT_BLC_PWM_CTL(panel->backlight.controller)); +- intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller), +- tmp & ~BXT_BLC_PWM_ENABLE); +- +- if (panel->backlight.controller == 1) { +- val = intel_de_read(dev_priv, UTIL_PIN_CTL); +- val &= ~UTIL_PIN_ENABLE; +- intel_de_write(dev_priv, UTIL_PIN_CTL, val); +- } +-} +- +-static void cnp_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val) +-{ +- struct intel_connector *connector = to_intel_connector(old_conn_state->connector); +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +- struct intel_panel *panel = &connector->panel; +- u32 tmp; +- +- intel_panel_set_pwm_level(old_conn_state, val); +- +- tmp = intel_de_read(dev_priv, +- BXT_BLC_PWM_CTL(panel->backlight.controller)); +- intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller), +- tmp & ~BXT_BLC_PWM_ENABLE); +-} +- +-static void ext_pwm_disable_backlight(const struct drm_connector_state *old_conn_state, u32 level) +-{ +- struct intel_connector *connector = to_intel_connector(old_conn_state->connector); +- struct intel_panel *panel = &connector->panel; +- +- panel->backlight.pwm_state.enabled = false; +- pwm_apply_state(panel->backlight.pwm, &panel->backlight.pwm_state); +-} +- +-void intel_panel_disable_backlight(const struct drm_connector_state *old_conn_state) +-{ +- struct intel_connector *connector = to_intel_connector(old_conn_state->connector); +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +- struct intel_panel *panel = &connector->panel; +- +- if (!panel->backlight.present) +- return; +- +- /* +- * Do not disable backlight on the vga_switcheroo path. When switching +- * away from i915, the other client may depend on i915 to handle the +- * backlight. This will leave the backlight on unnecessarily when +- * another client is not activated. +- */ +- if (dev_priv->drm.switch_power_state == DRM_SWITCH_POWER_CHANGING) { +- drm_dbg_kms(&dev_priv->drm, +- "Skipping backlight disable on vga switch\n"); +- return; +- } +- +- mutex_lock(&dev_priv->backlight_lock); +- +- if (panel->backlight.device) +- panel->backlight.device->props.power = FB_BLANK_POWERDOWN; +- panel->backlight.enabled = false; +- panel->backlight.funcs->disable(old_conn_state, 0); +- +- mutex_unlock(&dev_priv->backlight_lock); +-} +- +-static void lpt_enable_backlight(const struct intel_crtc_state *crtc_state, +- const struct drm_connector_state *conn_state, u32 level) +-{ +- struct intel_connector *connector = to_intel_connector(conn_state->connector); +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +- struct intel_panel *panel = &connector->panel; +- u32 pch_ctl1, pch_ctl2, schicken; +- +- pch_ctl1 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1); +- if (pch_ctl1 & BLM_PCH_PWM_ENABLE) { +- drm_dbg_kms(&dev_priv->drm, "pch backlight already enabled\n"); +- pch_ctl1 &= ~BLM_PCH_PWM_ENABLE; +- intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, pch_ctl1); +- } +- +- if (HAS_PCH_LPT(dev_priv)) { +- schicken = intel_de_read(dev_priv, SOUTH_CHICKEN2); +- if (panel->backlight.alternate_pwm_increment) +- schicken |= LPT_PWM_GRANULARITY; +- else +- schicken &= ~LPT_PWM_GRANULARITY; +- intel_de_write(dev_priv, SOUTH_CHICKEN2, schicken); +- } else { +- schicken = intel_de_read(dev_priv, SOUTH_CHICKEN1); +- if (panel->backlight.alternate_pwm_increment) +- schicken |= SPT_PWM_GRANULARITY; +- else +- schicken &= ~SPT_PWM_GRANULARITY; +- intel_de_write(dev_priv, SOUTH_CHICKEN1, schicken); +- } +- +- pch_ctl2 = panel->backlight.pwm_level_max << 16; +- intel_de_write(dev_priv, BLC_PWM_PCH_CTL2, pch_ctl2); +- +- pch_ctl1 = 0; +- if (panel->backlight.active_low_pwm) +- pch_ctl1 |= BLM_PCH_POLARITY; +- +- /* After LPT, override is the default. */ +- if (HAS_PCH_LPT(dev_priv)) +- pch_ctl1 |= BLM_PCH_OVERRIDE_ENABLE; +- +- intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, pch_ctl1); +- intel_de_posting_read(dev_priv, BLC_PWM_PCH_CTL1); +- intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, +- pch_ctl1 | BLM_PCH_PWM_ENABLE); +- +- /* This won't stick until the above enable. */ +- intel_panel_set_pwm_level(conn_state, level); +-} +- +-static void pch_enable_backlight(const struct intel_crtc_state *crtc_state, +- const struct drm_connector_state *conn_state, u32 level) +-{ +- struct intel_connector *connector = to_intel_connector(conn_state->connector); +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +- struct intel_panel *panel = &connector->panel; +- enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; +- u32 cpu_ctl2, pch_ctl1, pch_ctl2; +- +- cpu_ctl2 = intel_de_read(dev_priv, BLC_PWM_CPU_CTL2); +- if (cpu_ctl2 & BLM_PWM_ENABLE) { +- drm_dbg_kms(&dev_priv->drm, "cpu backlight already enabled\n"); +- cpu_ctl2 &= ~BLM_PWM_ENABLE; +- intel_de_write(dev_priv, BLC_PWM_CPU_CTL2, cpu_ctl2); +- } +- +- pch_ctl1 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1); +- if (pch_ctl1 & BLM_PCH_PWM_ENABLE) { +- drm_dbg_kms(&dev_priv->drm, "pch backlight already enabled\n"); +- pch_ctl1 &= ~BLM_PCH_PWM_ENABLE; +- intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, pch_ctl1); +- } +- +- if (cpu_transcoder == TRANSCODER_EDP) +- cpu_ctl2 = BLM_TRANSCODER_EDP; +- else +- cpu_ctl2 = BLM_PIPE(cpu_transcoder); +- intel_de_write(dev_priv, BLC_PWM_CPU_CTL2, cpu_ctl2); +- intel_de_posting_read(dev_priv, BLC_PWM_CPU_CTL2); +- intel_de_write(dev_priv, BLC_PWM_CPU_CTL2, cpu_ctl2 | BLM_PWM_ENABLE); +- +- /* This won't stick until the above enable. */ +- intel_panel_set_pwm_level(conn_state, level); +- +- pch_ctl2 = panel->backlight.pwm_level_max << 16; +- intel_de_write(dev_priv, BLC_PWM_PCH_CTL2, pch_ctl2); +- +- pch_ctl1 = 0; +- if (panel->backlight.active_low_pwm) +- pch_ctl1 |= BLM_PCH_POLARITY; +- +- intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, pch_ctl1); +- intel_de_posting_read(dev_priv, BLC_PWM_PCH_CTL1); +- intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, +- pch_ctl1 | BLM_PCH_PWM_ENABLE); +-} +- +-static void i9xx_enable_backlight(const struct intel_crtc_state *crtc_state, +- const struct drm_connector_state *conn_state, u32 level) +-{ +- struct intel_connector *connector = to_intel_connector(conn_state->connector); +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +- struct intel_panel *panel = &connector->panel; +- u32 ctl, freq; +- +- ctl = intel_de_read(dev_priv, BLC_PWM_CTL); +- if (ctl & BACKLIGHT_DUTY_CYCLE_MASK_PNV) { +- drm_dbg_kms(&dev_priv->drm, "backlight already enabled\n"); +- intel_de_write(dev_priv, BLC_PWM_CTL, 0); +- } +- +- freq = panel->backlight.pwm_level_max; +- if (panel->backlight.combination_mode) +- freq /= 0xff; +- +- ctl = freq << 17; +- if (panel->backlight.combination_mode) +- ctl |= BLM_LEGACY_MODE; +- if (IS_PINEVIEW(dev_priv) && panel->backlight.active_low_pwm) +- ctl |= BLM_POLARITY_PNV; +- +- intel_de_write(dev_priv, BLC_PWM_CTL, ctl); +- intel_de_posting_read(dev_priv, BLC_PWM_CTL); +- +- /* XXX: combine this into above write? */ +- intel_panel_set_pwm_level(conn_state, level); +- +- /* +- * Needed to enable backlight on some 855gm models. BLC_HIST_CTL is +- * 855gm only, but checking for gen2 is safe, as 855gm is the only gen2 +- * that has backlight. +- */ +- if (DISPLAY_VER(dev_priv) == 2) +- intel_de_write(dev_priv, BLC_HIST_CTL, BLM_HISTOGRAM_ENABLE); +-} +- +-static void i965_enable_backlight(const struct intel_crtc_state *crtc_state, +- const struct drm_connector_state *conn_state, u32 level) +-{ +- struct intel_connector *connector = to_intel_connector(conn_state->connector); +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +- struct intel_panel *panel = &connector->panel; +- enum pipe pipe = to_intel_crtc(conn_state->crtc)->pipe; +- u32 ctl, ctl2, freq; +- +- ctl2 = intel_de_read(dev_priv, BLC_PWM_CTL2); +- if (ctl2 & BLM_PWM_ENABLE) { +- drm_dbg_kms(&dev_priv->drm, "backlight already enabled\n"); +- ctl2 &= ~BLM_PWM_ENABLE; +- intel_de_write(dev_priv, BLC_PWM_CTL2, ctl2); +- } +- +- freq = panel->backlight.pwm_level_max; +- if (panel->backlight.combination_mode) +- freq /= 0xff; +- +- ctl = freq << 16; +- intel_de_write(dev_priv, BLC_PWM_CTL, ctl); +- +- ctl2 = BLM_PIPE(pipe); +- if (panel->backlight.combination_mode) +- ctl2 |= BLM_COMBINATION_MODE; +- if (panel->backlight.active_low_pwm) +- ctl2 |= BLM_POLARITY_I965; +- intel_de_write(dev_priv, BLC_PWM_CTL2, ctl2); +- intel_de_posting_read(dev_priv, BLC_PWM_CTL2); +- intel_de_write(dev_priv, BLC_PWM_CTL2, ctl2 | BLM_PWM_ENABLE); +- +- intel_panel_set_pwm_level(conn_state, level); +-} +- +-static void vlv_enable_backlight(const struct intel_crtc_state *crtc_state, +- const struct drm_connector_state *conn_state, u32 level) +-{ +- struct intel_connector *connector = to_intel_connector(conn_state->connector); +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +- struct intel_panel *panel = &connector->panel; +- enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe; +- u32 ctl, ctl2; +- +- ctl2 = intel_de_read(dev_priv, VLV_BLC_PWM_CTL2(pipe)); +- if (ctl2 & BLM_PWM_ENABLE) { +- drm_dbg_kms(&dev_priv->drm, "backlight already enabled\n"); +- ctl2 &= ~BLM_PWM_ENABLE; +- intel_de_write(dev_priv, VLV_BLC_PWM_CTL2(pipe), ctl2); +- } +- +- ctl = panel->backlight.pwm_level_max << 16; +- intel_de_write(dev_priv, VLV_BLC_PWM_CTL(pipe), ctl); +- +- /* XXX: combine this into above write? */ +- intel_panel_set_pwm_level(conn_state, level); +- +- ctl2 = 0; +- if (panel->backlight.active_low_pwm) +- ctl2 |= BLM_POLARITY_I965; +- intel_de_write(dev_priv, VLV_BLC_PWM_CTL2(pipe), ctl2); +- intel_de_posting_read(dev_priv, VLV_BLC_PWM_CTL2(pipe)); +- intel_de_write(dev_priv, VLV_BLC_PWM_CTL2(pipe), +- ctl2 | BLM_PWM_ENABLE); +-} +- +-static void bxt_enable_backlight(const struct intel_crtc_state *crtc_state, +- const struct drm_connector_state *conn_state, u32 level) +-{ +- struct intel_connector *connector = to_intel_connector(conn_state->connector); +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +- struct intel_panel *panel = &connector->panel; +- enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe; +- u32 pwm_ctl, val; +- +- /* Controller 1 uses the utility pin. */ +- if (panel->backlight.controller == 1) { +- val = intel_de_read(dev_priv, UTIL_PIN_CTL); +- if (val & UTIL_PIN_ENABLE) { +- drm_dbg_kms(&dev_priv->drm, +- "util pin already enabled\n"); +- val &= ~UTIL_PIN_ENABLE; +- intel_de_write(dev_priv, UTIL_PIN_CTL, val); +- } +- +- val = 0; +- if (panel->backlight.util_pin_active_low) +- val |= UTIL_PIN_POLARITY; +- intel_de_write(dev_priv, UTIL_PIN_CTL, +- val | UTIL_PIN_PIPE(pipe) | UTIL_PIN_MODE_PWM | UTIL_PIN_ENABLE); +- } +- +- pwm_ctl = intel_de_read(dev_priv, +- BXT_BLC_PWM_CTL(panel->backlight.controller)); +- if (pwm_ctl & BXT_BLC_PWM_ENABLE) { +- drm_dbg_kms(&dev_priv->drm, "backlight already enabled\n"); +- pwm_ctl &= ~BXT_BLC_PWM_ENABLE; +- intel_de_write(dev_priv, +- BXT_BLC_PWM_CTL(panel->backlight.controller), +- pwm_ctl); +- } +- +- intel_de_write(dev_priv, +- BXT_BLC_PWM_FREQ(panel->backlight.controller), +- panel->backlight.pwm_level_max); +- +- intel_panel_set_pwm_level(conn_state, level); +- +- pwm_ctl = 0; +- if (panel->backlight.active_low_pwm) +- pwm_ctl |= BXT_BLC_PWM_POLARITY; +- +- intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller), +- pwm_ctl); +- intel_de_posting_read(dev_priv, +- BXT_BLC_PWM_CTL(panel->backlight.controller)); +- intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller), +- pwm_ctl | BXT_BLC_PWM_ENABLE); +-} +- +-static void cnp_enable_backlight(const struct intel_crtc_state *crtc_state, +- const struct drm_connector_state *conn_state, u32 level) +-{ +- struct intel_connector *connector = to_intel_connector(conn_state->connector); +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +- struct intel_panel *panel = &connector->panel; +- u32 pwm_ctl; +- +- pwm_ctl = intel_de_read(dev_priv, +- BXT_BLC_PWM_CTL(panel->backlight.controller)); +- if (pwm_ctl & BXT_BLC_PWM_ENABLE) { +- drm_dbg_kms(&dev_priv->drm, "backlight already enabled\n"); +- pwm_ctl &= ~BXT_BLC_PWM_ENABLE; +- intel_de_write(dev_priv, +- BXT_BLC_PWM_CTL(panel->backlight.controller), +- pwm_ctl); +- } +- +- intel_de_write(dev_priv, +- BXT_BLC_PWM_FREQ(panel->backlight.controller), +- panel->backlight.pwm_level_max); +- +- intel_panel_set_pwm_level(conn_state, level); +- +- pwm_ctl = 0; +- if (panel->backlight.active_low_pwm) +- pwm_ctl |= BXT_BLC_PWM_POLARITY; +- +- intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller), +- pwm_ctl); +- intel_de_posting_read(dev_priv, +- BXT_BLC_PWM_CTL(panel->backlight.controller)); +- intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller), +- pwm_ctl | BXT_BLC_PWM_ENABLE); +-} +- +-static void ext_pwm_enable_backlight(const struct intel_crtc_state *crtc_state, +- const struct drm_connector_state *conn_state, u32 level) +-{ +- struct intel_connector *connector = to_intel_connector(conn_state->connector); +- struct intel_panel *panel = &connector->panel; +- +- pwm_set_relative_duty_cycle(&panel->backlight.pwm_state, level, 100); +- panel->backlight.pwm_state.enabled = true; +- pwm_apply_state(panel->backlight.pwm, &panel->backlight.pwm_state); +-} +- +-static void __intel_panel_enable_backlight(const struct intel_crtc_state *crtc_state, +- const struct drm_connector_state *conn_state) +-{ +- struct intel_connector *connector = to_intel_connector(conn_state->connector); +- struct intel_panel *panel = &connector->panel; +- +- WARN_ON(panel->backlight.max == 0); +- +- if (panel->backlight.level <= panel->backlight.min) { +- panel->backlight.level = panel->backlight.max; +- if (panel->backlight.device) +- panel->backlight.device->props.brightness = +- scale_hw_to_user(connector, +- panel->backlight.level, +- panel->backlight.device->props.max_brightness); +- } +- +- panel->backlight.funcs->enable(crtc_state, conn_state, panel->backlight.level); +- panel->backlight.enabled = true; +- if (panel->backlight.device) +- panel->backlight.device->props.power = FB_BLANK_UNBLANK; +-} +- +-void intel_panel_enable_backlight(const struct intel_crtc_state *crtc_state, +- const struct drm_connector_state *conn_state) +-{ +- struct intel_connector *connector = to_intel_connector(conn_state->connector); +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +- struct intel_panel *panel = &connector->panel; +- enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe; +- +- if (!panel->backlight.present) +- return; +- +- drm_dbg_kms(&dev_priv->drm, "pipe %c\n", pipe_name(pipe)); +- +- mutex_lock(&dev_priv->backlight_lock); +- +- __intel_panel_enable_backlight(crtc_state, conn_state); +- +- mutex_unlock(&dev_priv->backlight_lock); +-} +- +-#if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE) +-static u32 intel_panel_get_backlight(struct intel_connector *connector) +-{ +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +- struct intel_panel *panel = &connector->panel; +- u32 val = 0; +- +- mutex_lock(&dev_priv->backlight_lock); +- +- if (panel->backlight.enabled) +- val = panel->backlight.funcs->get(connector, intel_connector_get_pipe(connector)); +- +- mutex_unlock(&dev_priv->backlight_lock); +- +- drm_dbg_kms(&dev_priv->drm, "get backlight PWM = %d\n", val); +- return val; +-} +- +-/* Scale user_level in range [0..user_max] to [hw_min..hw_max]. */ +-static u32 scale_user_to_hw(struct intel_connector *connector, +- u32 user_level, u32 user_max) +-{ +- struct intel_panel *panel = &connector->panel; +- +- return scale(user_level, 0, user_max, +- panel->backlight.min, panel->backlight.max); +-} +- +-/* set backlight brightness to level in range [0..max], scaling wrt hw min */ +-static void intel_panel_set_backlight(const struct drm_connector_state *conn_state, +- u32 user_level, u32 user_max) +-{ +- struct intel_connector *connector = to_intel_connector(conn_state->connector); +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +- struct intel_panel *panel = &connector->panel; +- u32 hw_level; +- +- if (!panel->backlight.present) +- return; +- +- mutex_lock(&dev_priv->backlight_lock); +- +- drm_WARN_ON(&dev_priv->drm, panel->backlight.max == 0); +- +- hw_level = scale_user_to_hw(connector, user_level, user_max); +- panel->backlight.level = hw_level; +- +- if (panel->backlight.enabled) +- intel_panel_actually_set_backlight(conn_state, hw_level); +- +- mutex_unlock(&dev_priv->backlight_lock); +-} +- +-static int intel_backlight_device_update_status(struct backlight_device *bd) +-{ +- struct intel_connector *connector = bl_get_data(bd); +- struct intel_panel *panel = &connector->panel; +- struct drm_device *dev = connector->base.dev; +- +- drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); +- DRM_DEBUG_KMS("updating intel_backlight, brightness=%d/%d\n", +- bd->props.brightness, bd->props.max_brightness); +- intel_panel_set_backlight(connector->base.state, bd->props.brightness, +- bd->props.max_brightness); +- +- /* +- * Allow flipping bl_power as a sub-state of enabled. Sadly the +- * backlight class device does not make it easy to to differentiate +- * between callbacks for brightness and bl_power, so our backlight_power +- * callback needs to take this into account. +- */ +- if (panel->backlight.enabled) { +- if (panel->backlight.power) { +- bool enable = bd->props.power == FB_BLANK_UNBLANK && +- bd->props.brightness != 0; +- panel->backlight.power(connector, enable); +- } +- } else { +- bd->props.power = FB_BLANK_POWERDOWN; +- } +- +- drm_modeset_unlock(&dev->mode_config.connection_mutex); +- return 0; +-} +- +-static int intel_backlight_device_get_brightness(struct backlight_device *bd) +-{ +- struct intel_connector *connector = bl_get_data(bd); +- struct drm_device *dev = connector->base.dev; +- struct drm_i915_private *dev_priv = to_i915(dev); +- intel_wakeref_t wakeref; +- int ret = 0; +- +- with_intel_runtime_pm(&dev_priv->runtime_pm, wakeref) { +- u32 hw_level; +- +- drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); +- +- hw_level = intel_panel_get_backlight(connector); +- ret = scale_hw_to_user(connector, +- hw_level, bd->props.max_brightness); +- +- drm_modeset_unlock(&dev->mode_config.connection_mutex); +- } +- +- return ret; +-} +- +-static const struct backlight_ops intel_backlight_device_ops = { +- .update_status = intel_backlight_device_update_status, +- .get_brightness = intel_backlight_device_get_brightness, +-}; +- +-int intel_backlight_device_register(struct intel_connector *connector) +-{ +- struct drm_i915_private *i915 = to_i915(connector->base.dev); +- struct intel_panel *panel = &connector->panel; +- struct backlight_properties props; +- struct backlight_device *bd; +- const char *name; +- int ret = 0; +- +- if (WARN_ON(panel->backlight.device)) +- return -ENODEV; +- +- if (!panel->backlight.present) +- return 0; +- +- WARN_ON(panel->backlight.max == 0); +- +- memset(&props, 0, sizeof(props)); +- props.type = BACKLIGHT_RAW; +- +- /* +- * Note: Everything should work even if the backlight device max +- * presented to the userspace is arbitrarily chosen. +- */ +- props.max_brightness = panel->backlight.max; +- props.brightness = scale_hw_to_user(connector, +- panel->backlight.level, +- props.max_brightness); +- +- if (panel->backlight.enabled) +- props.power = FB_BLANK_UNBLANK; +- else +- props.power = FB_BLANK_POWERDOWN; +- +- name = kstrdup("intel_backlight", GFP_KERNEL); +- if (!name) +- return -ENOMEM; +- +- bd = backlight_device_register(name, connector->base.kdev, connector, +- &intel_backlight_device_ops, &props); +- +- /* +- * Using the same name independent of the drm device or connector +- * prevents registration of multiple backlight devices in the +- * driver. However, we need to use the default name for backward +- * compatibility. Use unique names for subsequent backlight devices as a +- * fallback when the default name already exists. +- */ +- if (IS_ERR(bd) && PTR_ERR(bd) == -EEXIST) { +- kfree(name); +- name = kasprintf(GFP_KERNEL, "card%d-%s-backlight", +- i915->drm.primary->index, connector->base.name); +- if (!name) +- return -ENOMEM; +- +- bd = backlight_device_register(name, connector->base.kdev, connector, +- &intel_backlight_device_ops, &props); +- } +- +- if (IS_ERR(bd)) { +- drm_err(&i915->drm, +- "[CONNECTOR:%d:%s] backlight device %s register failed: %ld\n", +- connector->base.base.id, connector->base.name, name, PTR_ERR(bd)); +- ret = PTR_ERR(bd); +- goto out; +- } +- +- panel->backlight.device = bd; +- +- drm_dbg_kms(&i915->drm, +- "[CONNECTOR:%d:%s] backlight device %s registered\n", +- connector->base.base.id, connector->base.name, name); +- +-out: +- kfree(name); +- +- return ret; +-} +- +-void intel_backlight_device_unregister(struct intel_connector *connector) +-{ +- struct intel_panel *panel = &connector->panel; +- +- if (panel->backlight.device) { +- backlight_device_unregister(panel->backlight.device); +- panel->backlight.device = NULL; +- } +-} +-#endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */ +- +-/* +- * CNP: PWM clock frequency is 19.2 MHz or 24 MHz. +- * PWM increment = 1 +- */ +-static u32 cnp_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) +-{ +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +- +- return DIV_ROUND_CLOSEST(KHz(RUNTIME_INFO(dev_priv)->rawclk_freq), +- pwm_freq_hz); +-} +- +-/* +- * BXT: PWM clock frequency = 19.2 MHz. +- */ +-static u32 bxt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) +-{ +- return DIV_ROUND_CLOSEST(KHz(19200), pwm_freq_hz); +-} +- +-/* +- * SPT: This value represents the period of the PWM stream in clock periods +- * multiplied by 16 (default increment) or 128 (alternate increment selected in +- * SCHICKEN_1 bit 0). PWM clock is 24 MHz. +- */ +-static u32 spt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) +-{ +- struct intel_panel *panel = &connector->panel; +- u32 mul; +- +- if (panel->backlight.alternate_pwm_increment) +- mul = 128; +- else +- mul = 16; +- +- return DIV_ROUND_CLOSEST(MHz(24), pwm_freq_hz * mul); +-} +- +-/* +- * LPT: This value represents the period of the PWM stream in clock periods +- * multiplied by 128 (default increment) or 16 (alternate increment, selected in +- * LPT SOUTH_CHICKEN2 register bit 5). +- */ +-static u32 lpt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) +-{ +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +- struct intel_panel *panel = &connector->panel; +- u32 mul, clock; +- +- if (panel->backlight.alternate_pwm_increment) +- mul = 16; +- else +- mul = 128; +- +- if (HAS_PCH_LPT_H(dev_priv)) +- clock = MHz(135); /* LPT:H */ +- else +- clock = MHz(24); /* LPT:LP */ +- +- return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * mul); +-} +- +-/* +- * ILK/SNB/IVB: This value represents the period of the PWM stream in PCH +- * display raw clocks multiplied by 128. +- */ +-static u32 pch_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) +-{ +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +- +- return DIV_ROUND_CLOSEST(KHz(RUNTIME_INFO(dev_priv)->rawclk_freq), +- pwm_freq_hz * 128); +-} +- +-/* +- * Gen2: This field determines the number of time base events (display core +- * clock frequency/32) in total for a complete cycle of modulated backlight +- * control. +- * +- * Gen3: A time base event equals the display core clock ([DevPNV] HRAW clock) +- * divided by 32. +- */ +-static u32 i9xx_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) +-{ +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +- int clock; +- +- if (IS_PINEVIEW(dev_priv)) +- clock = KHz(RUNTIME_INFO(dev_priv)->rawclk_freq); +- else +- clock = KHz(dev_priv->cdclk.hw.cdclk); +- +- return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * 32); +-} +- +-/* +- * Gen4: This value represents the period of the PWM stream in display core +- * clocks ([DevCTG] HRAW clocks) multiplied by 128. +- * +- */ +-static u32 i965_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) +-{ +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +- int clock; +- +- if (IS_G4X(dev_priv)) +- clock = KHz(RUNTIME_INFO(dev_priv)->rawclk_freq); +- else +- clock = KHz(dev_priv->cdclk.hw.cdclk); +- +- return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * 128); +-} +- +-/* +- * VLV: This value represents the period of the PWM stream in display core +- * clocks ([DevCTG] 200MHz HRAW clocks) multiplied by 128 or 25MHz S0IX clocks +- * multiplied by 16. CHV uses a 19.2MHz S0IX clock. +- */ +-static u32 vlv_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) +-{ +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +- int mul, clock; +- +- if ((intel_de_read(dev_priv, CBR1_VLV) & CBR_PWM_CLOCK_MUX_SELECT) == 0) { +- if (IS_CHERRYVIEW(dev_priv)) +- clock = KHz(19200); +- else +- clock = MHz(25); +- mul = 16; +- } else { +- clock = KHz(RUNTIME_INFO(dev_priv)->rawclk_freq); +- mul = 128; +- } +- +- return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * mul); +-} +- +-static u16 get_vbt_pwm_freq(struct drm_i915_private *dev_priv) +-{ +- u16 pwm_freq_hz = dev_priv->vbt.backlight.pwm_freq_hz; +- +- if (pwm_freq_hz) { +- drm_dbg_kms(&dev_priv->drm, +- "VBT defined backlight frequency %u Hz\n", +- pwm_freq_hz); +- } else { +- pwm_freq_hz = 200; +- drm_dbg_kms(&dev_priv->drm, +- "default backlight frequency %u Hz\n", +- pwm_freq_hz); +- } +- +- return pwm_freq_hz; +-} +- +-static u32 get_backlight_max_vbt(struct intel_connector *connector) +-{ +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +- struct intel_panel *panel = &connector->panel; +- u16 pwm_freq_hz = get_vbt_pwm_freq(dev_priv); +- u32 pwm; +- +- if (!panel->backlight.pwm_funcs->hz_to_pwm) { +- drm_dbg_kms(&dev_priv->drm, +- "backlight frequency conversion not supported\n"); +- return 0; +- } +- +- pwm = panel->backlight.pwm_funcs->hz_to_pwm(connector, pwm_freq_hz); +- if (!pwm) { +- drm_dbg_kms(&dev_priv->drm, +- "backlight frequency conversion failed\n"); +- return 0; +- } +- +- return pwm; +-} +- +-/* +- * Note: The setup hooks can't assume pipe is set! +- */ +-static u32 get_backlight_min_vbt(struct intel_connector *connector) +-{ +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +- struct intel_panel *panel = &connector->panel; +- int min; +- +- drm_WARN_ON(&dev_priv->drm, panel->backlight.pwm_level_max == 0); +- +- /* +- * XXX: If the vbt value is 255, it makes min equal to max, which leads +- * to problems. There are such machines out there. Either our +- * interpretation is wrong or the vbt has bogus data. Or both. Safeguard +- * against this by letting the minimum be at most (arbitrarily chosen) +- * 25% of the max. +- */ +- min = clamp_t(int, dev_priv->vbt.backlight.min_brightness, 0, 64); +- if (min != dev_priv->vbt.backlight.min_brightness) { +- drm_dbg_kms(&dev_priv->drm, +- "clamping VBT min backlight %d/255 to %d/255\n", +- dev_priv->vbt.backlight.min_brightness, min); +- } +- +- /* vbt value is a coefficient in range [0..255] */ +- return scale(min, 0, 255, 0, panel->backlight.pwm_level_max); +-} +- +-static int lpt_setup_backlight(struct intel_connector *connector, enum pipe unused) +-{ +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +- struct intel_panel *panel = &connector->panel; +- u32 cpu_ctl2, pch_ctl1, pch_ctl2, val; +- bool alt, cpu_mode; +- +- if (HAS_PCH_LPT(dev_priv)) +- alt = intel_de_read(dev_priv, SOUTH_CHICKEN2) & LPT_PWM_GRANULARITY; +- else +- alt = intel_de_read(dev_priv, SOUTH_CHICKEN1) & SPT_PWM_GRANULARITY; +- panel->backlight.alternate_pwm_increment = alt; +- +- pch_ctl1 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1); +- panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY; +- +- pch_ctl2 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL2); +- panel->backlight.pwm_level_max = pch_ctl2 >> 16; +- +- cpu_ctl2 = intel_de_read(dev_priv, BLC_PWM_CPU_CTL2); +- +- if (!panel->backlight.pwm_level_max) +- panel->backlight.pwm_level_max = get_backlight_max_vbt(connector); +- +- if (!panel->backlight.pwm_level_max) +- return -ENODEV; +- +- panel->backlight.pwm_level_min = get_backlight_min_vbt(connector); +- +- panel->backlight.pwm_enabled = pch_ctl1 & BLM_PCH_PWM_ENABLE; +- +- cpu_mode = panel->backlight.pwm_enabled && HAS_PCH_LPT(dev_priv) && +- !(pch_ctl1 & BLM_PCH_OVERRIDE_ENABLE) && +- (cpu_ctl2 & BLM_PWM_ENABLE); +- +- if (cpu_mode) { +- val = pch_get_backlight(connector, unused); +- +- drm_dbg_kms(&dev_priv->drm, +- "CPU backlight register was enabled, switching to PCH override\n"); +- +- /* Write converted CPU PWM value to PCH override register */ +- lpt_set_backlight(connector->base.state, val); +- intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, +- pch_ctl1 | BLM_PCH_OVERRIDE_ENABLE); +- +- intel_de_write(dev_priv, BLC_PWM_CPU_CTL2, +- cpu_ctl2 & ~BLM_PWM_ENABLE); +- } +- +- return 0; +-} +- +-static int pch_setup_backlight(struct intel_connector *connector, enum pipe unused) +-{ +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +- struct intel_panel *panel = &connector->panel; +- u32 cpu_ctl2, pch_ctl1, pch_ctl2; +- +- pch_ctl1 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1); +- panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY; +- +- pch_ctl2 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL2); +- panel->backlight.pwm_level_max = pch_ctl2 >> 16; +- +- if (!panel->backlight.pwm_level_max) +- panel->backlight.pwm_level_max = get_backlight_max_vbt(connector); +- +- if (!panel->backlight.pwm_level_max) +- return -ENODEV; +- +- panel->backlight.pwm_level_min = get_backlight_min_vbt(connector); +- +- cpu_ctl2 = intel_de_read(dev_priv, BLC_PWM_CPU_CTL2); +- panel->backlight.pwm_enabled = (cpu_ctl2 & BLM_PWM_ENABLE) && +- (pch_ctl1 & BLM_PCH_PWM_ENABLE); +- +- return 0; +-} +- +-static int i9xx_setup_backlight(struct intel_connector *connector, enum pipe unused) +-{ +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +- struct intel_panel *panel = &connector->panel; +- u32 ctl, val; +- +- ctl = intel_de_read(dev_priv, BLC_PWM_CTL); +- +- if (DISPLAY_VER(dev_priv) == 2 || IS_I915GM(dev_priv) || IS_I945GM(dev_priv)) +- panel->backlight.combination_mode = ctl & BLM_LEGACY_MODE; +- +- if (IS_PINEVIEW(dev_priv)) +- panel->backlight.active_low_pwm = ctl & BLM_POLARITY_PNV; +- +- panel->backlight.pwm_level_max = ctl >> 17; +- +- if (!panel->backlight.pwm_level_max) { +- panel->backlight.pwm_level_max = get_backlight_max_vbt(connector); +- panel->backlight.pwm_level_max >>= 1; +- } +- +- if (!panel->backlight.pwm_level_max) +- return -ENODEV; +- +- if (panel->backlight.combination_mode) +- panel->backlight.pwm_level_max *= 0xff; +- +- panel->backlight.pwm_level_min = get_backlight_min_vbt(connector); +- +- val = i9xx_get_backlight(connector, unused); +- val = intel_panel_invert_pwm_level(connector, val); +- val = clamp(val, panel->backlight.pwm_level_min, panel->backlight.pwm_level_max); +- +- panel->backlight.pwm_enabled = val != 0; +- +- return 0; +-} +- +-static int i965_setup_backlight(struct intel_connector *connector, enum pipe unused) +-{ +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +- struct intel_panel *panel = &connector->panel; +- u32 ctl, ctl2; +- +- ctl2 = intel_de_read(dev_priv, BLC_PWM_CTL2); +- panel->backlight.combination_mode = ctl2 & BLM_COMBINATION_MODE; +- panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965; +- +- ctl = intel_de_read(dev_priv, BLC_PWM_CTL); +- panel->backlight.pwm_level_max = ctl >> 16; +- +- if (!panel->backlight.pwm_level_max) +- panel->backlight.pwm_level_max = get_backlight_max_vbt(connector); +- +- if (!panel->backlight.pwm_level_max) +- return -ENODEV; +- +- if (panel->backlight.combination_mode) +- panel->backlight.pwm_level_max *= 0xff; +- +- panel->backlight.pwm_level_min = get_backlight_min_vbt(connector); +- +- panel->backlight.pwm_enabled = ctl2 & BLM_PWM_ENABLE; +- +- return 0; +-} +- +-static int vlv_setup_backlight(struct intel_connector *connector, enum pipe pipe) +-{ +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +- struct intel_panel *panel = &connector->panel; +- u32 ctl, ctl2; +- +- if (drm_WARN_ON(&dev_priv->drm, pipe != PIPE_A && pipe != PIPE_B)) +- return -ENODEV; +- +- ctl2 = intel_de_read(dev_priv, VLV_BLC_PWM_CTL2(pipe)); +- panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965; +- +- ctl = intel_de_read(dev_priv, VLV_BLC_PWM_CTL(pipe)); +- panel->backlight.pwm_level_max = ctl >> 16; +- +- if (!panel->backlight.pwm_level_max) +- panel->backlight.pwm_level_max = get_backlight_max_vbt(connector); +- +- if (!panel->backlight.pwm_level_max) +- return -ENODEV; +- +- panel->backlight.pwm_level_min = get_backlight_min_vbt(connector); +- +- panel->backlight.pwm_enabled = ctl2 & BLM_PWM_ENABLE; +- +- return 0; +-} +- +-static int +-bxt_setup_backlight(struct intel_connector *connector, enum pipe unused) +-{ +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +- struct intel_panel *panel = &connector->panel; +- u32 pwm_ctl, val; +- +- panel->backlight.controller = dev_priv->vbt.backlight.controller; +- +- pwm_ctl = intel_de_read(dev_priv, +- BXT_BLC_PWM_CTL(panel->backlight.controller)); +- +- /* Controller 1 uses the utility pin. */ +- if (panel->backlight.controller == 1) { +- val = intel_de_read(dev_priv, UTIL_PIN_CTL); +- panel->backlight.util_pin_active_low = +- val & UTIL_PIN_POLARITY; +- } +- +- panel->backlight.active_low_pwm = pwm_ctl & BXT_BLC_PWM_POLARITY; +- panel->backlight.pwm_level_max = +- intel_de_read(dev_priv, BXT_BLC_PWM_FREQ(panel->backlight.controller)); +- +- if (!panel->backlight.pwm_level_max) +- panel->backlight.pwm_level_max = get_backlight_max_vbt(connector); +- +- if (!panel->backlight.pwm_level_max) +- return -ENODEV; +- +- panel->backlight.pwm_level_min = get_backlight_min_vbt(connector); +- +- panel->backlight.pwm_enabled = pwm_ctl & BXT_BLC_PWM_ENABLE; +- +- return 0; +-} +- +-static int +-cnp_setup_backlight(struct intel_connector *connector, enum pipe unused) +-{ +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +- struct intel_panel *panel = &connector->panel; +- u32 pwm_ctl; +- +- /* +- * CNP has the BXT implementation of backlight, but with only one +- * controller. TODO: ICP has multiple controllers but we only use +- * controller 0 for now. +- */ +- panel->backlight.controller = 0; +- +- pwm_ctl = intel_de_read(dev_priv, +- BXT_BLC_PWM_CTL(panel->backlight.controller)); +- +- panel->backlight.active_low_pwm = pwm_ctl & BXT_BLC_PWM_POLARITY; +- panel->backlight.pwm_level_max = +- intel_de_read(dev_priv, BXT_BLC_PWM_FREQ(panel->backlight.controller)); +- +- if (!panel->backlight.pwm_level_max) +- panel->backlight.pwm_level_max = get_backlight_max_vbt(connector); +- +- if (!panel->backlight.pwm_level_max) +- return -ENODEV; +- +- panel->backlight.pwm_level_min = get_backlight_min_vbt(connector); +- +- panel->backlight.pwm_enabled = pwm_ctl & BXT_BLC_PWM_ENABLE; +- +- return 0; +-} +- +-static int ext_pwm_setup_backlight(struct intel_connector *connector, +- enum pipe pipe) +-{ +- struct drm_device *dev = connector->base.dev; +- struct drm_i915_private *dev_priv = to_i915(dev); +- struct intel_panel *panel = &connector->panel; +- const char *desc; +- u32 level; +- +- /* Get the right PWM chip for DSI backlight according to VBT */ +- if (dev_priv->vbt.dsi.config->pwm_blc == PPS_BLC_PMIC) { +- panel->backlight.pwm = pwm_get(dev->dev, "pwm_pmic_backlight"); +- desc = "PMIC"; +- } else { +- panel->backlight.pwm = pwm_get(dev->dev, "pwm_soc_backlight"); +- desc = "SoC"; +- } +- +- if (IS_ERR(panel->backlight.pwm)) { +- drm_err(&dev_priv->drm, "Failed to get the %s PWM chip\n", +- desc); +- panel->backlight.pwm = NULL; +- return -ENODEV; +- } +- +- panel->backlight.pwm_level_max = 100; /* 100% */ +- panel->backlight.pwm_level_min = get_backlight_min_vbt(connector); +- +- if (pwm_is_enabled(panel->backlight.pwm)) { +- /* PWM is already enabled, use existing settings */ +- pwm_get_state(panel->backlight.pwm, &panel->backlight.pwm_state); +- +- level = pwm_get_relative_duty_cycle(&panel->backlight.pwm_state, +- 100); +- level = intel_panel_invert_pwm_level(connector, level); +- panel->backlight.pwm_enabled = true; +- +- drm_dbg_kms(&dev_priv->drm, "PWM already enabled at freq %ld, VBT freq %d, level %d\n", +- NSEC_PER_SEC / (unsigned long)panel->backlight.pwm_state.period, +- get_vbt_pwm_freq(dev_priv), level); +- } else { +- /* Set period from VBT frequency, leave other settings at 0. */ +- panel->backlight.pwm_state.period = +- NSEC_PER_SEC / get_vbt_pwm_freq(dev_priv); +- } +- +- drm_info(&dev_priv->drm, "Using %s PWM for LCD backlight control\n", +- desc); +- return 0; +-} +- +-static void intel_pwm_set_backlight(const struct drm_connector_state *conn_state, u32 level) +-{ +- struct intel_connector *connector = to_intel_connector(conn_state->connector); +- struct intel_panel *panel = &connector->panel; +- +- panel->backlight.pwm_funcs->set(conn_state, +- intel_panel_invert_pwm_level(connector, level)); +-} +- +-static u32 intel_pwm_get_backlight(struct intel_connector *connector, enum pipe pipe) +-{ +- struct intel_panel *panel = &connector->panel; +- +- return intel_panel_invert_pwm_level(connector, +- panel->backlight.pwm_funcs->get(connector, pipe)); +-} +- +-static void intel_pwm_enable_backlight(const struct intel_crtc_state *crtc_state, +- const struct drm_connector_state *conn_state, u32 level) +-{ +- struct intel_connector *connector = to_intel_connector(conn_state->connector); +- struct intel_panel *panel = &connector->panel; +- +- panel->backlight.pwm_funcs->enable(crtc_state, conn_state, +- intel_panel_invert_pwm_level(connector, level)); +-} +- +-static void intel_pwm_disable_backlight(const struct drm_connector_state *conn_state, u32 level) +-{ +- struct intel_connector *connector = to_intel_connector(conn_state->connector); +- struct intel_panel *panel = &connector->panel; +- +- panel->backlight.pwm_funcs->disable(conn_state, +- intel_panel_invert_pwm_level(connector, level)); +-} +- +-static int intel_pwm_setup_backlight(struct intel_connector *connector, enum pipe pipe) +-{ +- struct intel_panel *panel = &connector->panel; +- int ret = panel->backlight.pwm_funcs->setup(connector, pipe); +- +- if (ret < 0) +- return ret; +- +- panel->backlight.min = panel->backlight.pwm_level_min; +- panel->backlight.max = panel->backlight.pwm_level_max; +- panel->backlight.level = intel_pwm_get_backlight(connector, pipe); +- panel->backlight.enabled = panel->backlight.pwm_enabled; +- +- return 0; +-} +- +-void intel_panel_update_backlight(struct intel_atomic_state *state, +- struct intel_encoder *encoder, +- const struct intel_crtc_state *crtc_state, +- const struct drm_connector_state *conn_state) +-{ +- struct intel_connector *connector = to_intel_connector(conn_state->connector); +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +- struct intel_panel *panel = &connector->panel; +- +- if (!panel->backlight.present) +- return; +- +- mutex_lock(&dev_priv->backlight_lock); +- if (!panel->backlight.enabled) +- __intel_panel_enable_backlight(crtc_state, conn_state); +- +- mutex_unlock(&dev_priv->backlight_lock); +-} +- +-int intel_panel_setup_backlight(struct drm_connector *connector, enum pipe pipe) +-{ +- struct drm_i915_private *dev_priv = to_i915(connector->dev); +- struct intel_connector *intel_connector = to_intel_connector(connector); +- struct intel_panel *panel = &intel_connector->panel; +- int ret; +- +- if (!dev_priv->vbt.backlight.present) { +- if (dev_priv->quirks & QUIRK_BACKLIGHT_PRESENT) { +- drm_dbg_kms(&dev_priv->drm, +- "no backlight present per VBT, but present per quirk\n"); +- } else { +- drm_dbg_kms(&dev_priv->drm, +- "no backlight present per VBT\n"); +- return 0; +- } +- } +- +- /* ensure intel_panel has been initialized first */ +- if (drm_WARN_ON(&dev_priv->drm, !panel->backlight.funcs)) +- return -ENODEV; +- +- /* set level and max in panel struct */ +- mutex_lock(&dev_priv->backlight_lock); +- ret = panel->backlight.funcs->setup(intel_connector, pipe); +- mutex_unlock(&dev_priv->backlight_lock); +- +- if (ret) { +- drm_dbg_kms(&dev_priv->drm, +- "failed to setup backlight for connector %s\n", +- connector->name); +- return ret; +- } +- +- panel->backlight.present = true; +- +- drm_dbg_kms(&dev_priv->drm, +- "Connector %s backlight initialized, %s, brightness %u/%u\n", +- connector->name, +- enableddisabled(panel->backlight.enabled), +- panel->backlight.level, panel->backlight.max); +- +- return 0; +-} +- +-static void intel_panel_destroy_backlight(struct intel_panel *panel) +-{ +- /* dispose of the pwm */ +- if (panel->backlight.pwm) +- pwm_put(panel->backlight.pwm); +- +- panel->backlight.present = false; +-} +- +-static const struct intel_panel_bl_funcs bxt_pwm_funcs = { +- .setup = bxt_setup_backlight, +- .enable = bxt_enable_backlight, +- .disable = bxt_disable_backlight, +- .set = bxt_set_backlight, +- .get = bxt_get_backlight, +- .hz_to_pwm = bxt_hz_to_pwm, +-}; +- +-static const struct intel_panel_bl_funcs cnp_pwm_funcs = { +- .setup = cnp_setup_backlight, +- .enable = cnp_enable_backlight, +- .disable = cnp_disable_backlight, +- .set = bxt_set_backlight, +- .get = bxt_get_backlight, +- .hz_to_pwm = cnp_hz_to_pwm, +-}; +- +-static const struct intel_panel_bl_funcs lpt_pwm_funcs = { +- .setup = lpt_setup_backlight, +- .enable = lpt_enable_backlight, +- .disable = lpt_disable_backlight, +- .set = lpt_set_backlight, +- .get = lpt_get_backlight, +- .hz_to_pwm = lpt_hz_to_pwm, +-}; +- +-static const struct intel_panel_bl_funcs spt_pwm_funcs = { +- .setup = lpt_setup_backlight, +- .enable = lpt_enable_backlight, +- .disable = lpt_disable_backlight, +- .set = lpt_set_backlight, +- .get = lpt_get_backlight, +- .hz_to_pwm = spt_hz_to_pwm, +-}; +- +-static const struct intel_panel_bl_funcs pch_pwm_funcs = { +- .setup = pch_setup_backlight, +- .enable = pch_enable_backlight, +- .disable = pch_disable_backlight, +- .set = pch_set_backlight, +- .get = pch_get_backlight, +- .hz_to_pwm = pch_hz_to_pwm, +-}; +- +-static const struct intel_panel_bl_funcs ext_pwm_funcs = { +- .setup = ext_pwm_setup_backlight, +- .enable = ext_pwm_enable_backlight, +- .disable = ext_pwm_disable_backlight, +- .set = ext_pwm_set_backlight, +- .get = ext_pwm_get_backlight, +-}; +- +-static const struct intel_panel_bl_funcs vlv_pwm_funcs = { +- .setup = vlv_setup_backlight, +- .enable = vlv_enable_backlight, +- .disable = vlv_disable_backlight, +- .set = vlv_set_backlight, +- .get = vlv_get_backlight, +- .hz_to_pwm = vlv_hz_to_pwm, +-}; +- +-static const struct intel_panel_bl_funcs i965_pwm_funcs = { +- .setup = i965_setup_backlight, +- .enable = i965_enable_backlight, +- .disable = i965_disable_backlight, +- .set = i9xx_set_backlight, +- .get = i9xx_get_backlight, +- .hz_to_pwm = i965_hz_to_pwm, +-}; +- +-static const struct intel_panel_bl_funcs i9xx_pwm_funcs = { +- .setup = i9xx_setup_backlight, +- .enable = i9xx_enable_backlight, +- .disable = i9xx_disable_backlight, +- .set = i9xx_set_backlight, +- .get = i9xx_get_backlight, +- .hz_to_pwm = i9xx_hz_to_pwm, +-}; +- +-static const struct intel_panel_bl_funcs pwm_bl_funcs = { +- .setup = intel_pwm_setup_backlight, +- .enable = intel_pwm_enable_backlight, +- .disable = intel_pwm_disable_backlight, +- .set = intel_pwm_set_backlight, +- .get = intel_pwm_get_backlight, +-}; +- +-/* Set up chip specific backlight functions */ +-static void +-intel_panel_init_backlight_funcs(struct intel_panel *panel) +-{ +- struct intel_connector *connector = +- container_of(panel, struct intel_connector, panel); +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +- +- if (connector->base.connector_type == DRM_MODE_CONNECTOR_DSI && +- intel_dsi_dcs_init_backlight_funcs(connector) == 0) +- return; +- +- if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) { +- panel->backlight.pwm_funcs = &bxt_pwm_funcs; +- } else if (INTEL_PCH_TYPE(dev_priv) >= PCH_CNP) { +- panel->backlight.pwm_funcs = &cnp_pwm_funcs; +- } else if (INTEL_PCH_TYPE(dev_priv) >= PCH_LPT) { +- if (HAS_PCH_LPT(dev_priv)) +- panel->backlight.pwm_funcs = &lpt_pwm_funcs; +- else +- panel->backlight.pwm_funcs = &spt_pwm_funcs; +- } else if (HAS_PCH_SPLIT(dev_priv)) { +- panel->backlight.pwm_funcs = &pch_pwm_funcs; +- } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { +- if (connector->base.connector_type == DRM_MODE_CONNECTOR_DSI) { +- panel->backlight.pwm_funcs = &ext_pwm_funcs; +- } else { +- panel->backlight.pwm_funcs = &vlv_pwm_funcs; +- } +- } else if (DISPLAY_VER(dev_priv) == 4) { +- panel->backlight.pwm_funcs = &i965_pwm_funcs; +- } else { +- panel->backlight.pwm_funcs = &i9xx_pwm_funcs; +- } +- +- if (connector->base.connector_type == DRM_MODE_CONNECTOR_eDP && +- intel_dp_aux_init_backlight_funcs(connector) == 0) +- return; +- +- /* We're using a standard PWM backlight interface */ +- panel->backlight.funcs = &pwm_bl_funcs; +-} +- + enum drm_connector_status + intel_panel_detect(struct drm_connector *connector, bool force) + { +diff --git a/drivers/gpu/drm/i915/display/intel_panel.h b/drivers/gpu/drm/i915/display/intel_panel.h +index 1d340f77bffc..67dbb15026bf 100644 +--- a/drivers/gpu/drm/i915/display/intel_panel.h ++++ b/drivers/gpu/drm/i915/display/intel_panel.h +@@ -8,15 +8,13 @@ + + #include + +-#include "intel_display.h" +- ++enum drm_connector_status; + struct drm_connector; + struct drm_connector_state; + struct drm_display_mode; ++struct drm_i915_private; + struct intel_connector; +-struct intel_crtc; + struct intel_crtc_state; +-struct intel_encoder; + struct intel_panel; + + int intel_panel_init(struct intel_panel *panel, +@@ -31,17 +29,6 @@ int intel_pch_panel_fitting(struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state); + int intel_gmch_panel_fitting(struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state); +-void intel_panel_set_backlight_acpi(const struct drm_connector_state *conn_state, +- u32 level, u32 max); +-int intel_panel_setup_backlight(struct drm_connector *connector, +- enum pipe pipe); +-void intel_panel_enable_backlight(const struct intel_crtc_state *crtc_state, +- const struct drm_connector_state *conn_state); +-void intel_panel_update_backlight(struct intel_atomic_state *state, +- struct intel_encoder *encoder, +- const struct intel_crtc_state *crtc_state, +- const struct drm_connector_state *conn_state); +-void intel_panel_disable_backlight(const struct drm_connector_state *old_conn_state); + struct drm_display_mode * + intel_panel_edid_downclock_mode(struct intel_connector *connector, + const struct drm_display_mode *fixed_mode); +@@ -49,22 +36,5 @@ struct drm_display_mode * + intel_panel_edid_fixed_mode(struct intel_connector *connector); + struct drm_display_mode * + intel_panel_vbt_fixed_mode(struct intel_connector *connector); +-void intel_panel_set_pwm_level(const struct drm_connector_state *conn_state, u32 level); +-u32 intel_panel_invert_pwm_level(struct intel_connector *connector, u32 level); +-u32 intel_panel_backlight_level_to_pwm(struct intel_connector *connector, u32 level); +-u32 intel_panel_backlight_level_from_pwm(struct intel_connector *connector, u32 val); +- +-#if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE) +-int intel_backlight_device_register(struct intel_connector *connector); +-void intel_backlight_device_unregister(struct intel_connector *connector); +-#else /* CONFIG_BACKLIGHT_CLASS_DEVICE */ +-static inline int intel_backlight_device_register(struct intel_connector *connector) +-{ +- return 0; +-} +-static inline void intel_backlight_device_unregister(struct intel_connector *connector) +-{ +-} +-#endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */ + + #endif /* __INTEL_PANEL_H__ */ +diff --git a/drivers/gpu/drm/i915/display/vlv_dsi.c b/drivers/gpu/drm/i915/display/vlv_dsi.c +index 0ee4ff341e25..b27738df447d 100644 +--- a/drivers/gpu/drm/i915/display/vlv_dsi.c ++++ b/drivers/gpu/drm/i915/display/vlv_dsi.c +@@ -32,6 +32,7 @@ + + #include "i915_drv.h" + #include "intel_atomic.h" ++#include "intel_backlight.h" + #include "intel_connector.h" + #include "intel_crtc.h" + #include "intel_de.h" + +base-commit: 25960cafa06e6fcd830e6c792e6a7de68c1e25ed +-- +2.33.0 + + +From 51f48c569a821c50eb1f23a60758b954c7de0c57 Mon Sep 17 00:00:00 2001 +From: Jani Nikula +Date: Wed, 25 Aug 2021 14:06:51 +0300 +Subject: [PATCH 2/5] drm/i915/backlight: mass rename functions to have + intel_backlight_ prefix + +Follow the usual naming conventions. As a drive-by cleanup, also pass +intel_connector instead of drm_connector to intel_backlight_setup(). No +functional changes. + +Cc: Lyude Paul +Reviewed-by: Lyude Paul +Signed-off-by: Jani Nikula +Link: https://patchwork.freedesktop.org/patch/msgid/ea1c22370210abdd4f5547af73c71b902061ea50.1629888677.git.jani.nikula@intel.com +(cherry-picked from commit c0a52f8bd755732284d5c08aefe0d3dd3291f64a) +--- + drivers/gpu/drm/i915/display/g4x_dp.c | 2 +- + drivers/gpu/drm/i915/display/icl_dsi.c | 8 +- + .../gpu/drm/i915/display/intel_backlight.c | 94 +++++++++---------- + .../gpu/drm/i915/display/intel_backlight.h | 37 ++++---- + drivers/gpu/drm/i915/display/intel_ddi.c | 2 +- + drivers/gpu/drm/i915/display/intel_dp.c | 6 +- + .../drm/i915/display/intel_dp_aux_backlight.c | 10 +- + drivers/gpu/drm/i915/display/intel_lvds.c | 10 +- + drivers/gpu/drm/i915/display/intel_opregion.c | 2 +- + drivers/gpu/drm/i915/display/intel_panel.c | 4 +- + drivers/gpu/drm/i915/display/vlv_dsi.c | 8 +- + 11 files changed, 91 insertions(+), 92 deletions(-) + +diff --git a/drivers/gpu/drm/i915/display/g4x_dp.c b/drivers/gpu/drm/i915/display/g4x_dp.c +index 29c0eca647e3..9577f6843f79 100644 +--- a/drivers/gpu/drm/i915/display/g4x_dp.c ++++ b/drivers/gpu/drm/i915/display/g4x_dp.c +@@ -1334,7 +1334,7 @@ bool g4x_dp_init(struct drm_i915_private *dev_priv, + intel_encoder->get_config = intel_dp_get_config; + intel_encoder->sync_state = intel_dp_sync_state; + intel_encoder->initial_fastset_check = intel_dp_initial_fastset_check; +- intel_encoder->update_pipe = intel_panel_update_backlight; ++ intel_encoder->update_pipe = intel_backlight_update; + intel_encoder->suspend = intel_dp_encoder_suspend; + intel_encoder->shutdown = intel_dp_encoder_shutdown; + if (IS_CHERRYVIEW(dev_priv)) { +diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c +index 2601873e1546..5f138b0695e3 100644 +--- a/drivers/gpu/drm/i915/display/icl_dsi.c ++++ b/drivers/gpu/drm/i915/display/icl_dsi.c +@@ -1282,7 +1282,7 @@ static void gen11_dsi_enable(struct intel_atomic_state *state, + gen11_dsi_enable_transcoder(encoder); + + /* step7: enable backlight */ +- intel_panel_enable_backlight(crtc_state, conn_state); ++ intel_backlight_enable(crtc_state, conn_state); + intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_BACKLIGHT_ON); + + intel_crtc_vblank_on(crtc_state); +@@ -1435,7 +1435,7 @@ static void gen11_dsi_disable(struct intel_atomic_state *state, + + /* step1: turn off backlight */ + intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_BACKLIGHT_OFF); +- intel_panel_disable_backlight(old_conn_state); ++ intel_backlight_disable(old_conn_state); + + /* step2d,e: disable transcoder and wait */ + gen11_dsi_disable_transcoder(encoder); +@@ -2009,7 +2009,7 @@ void icl_dsi_init(struct drm_i915_private *dev_priv) + encoder->port = port; + encoder->get_config = gen11_dsi_get_config; + encoder->sync_state = gen11_dsi_sync_state; +- encoder->update_pipe = intel_panel_update_backlight; ++ encoder->update_pipe = intel_backlight_update; + encoder->compute_config = gen11_dsi_compute_config; + encoder->get_hw_state = gen11_dsi_get_hw_state; + encoder->initial_fastset_check = gen11_dsi_initial_fastset_check; +@@ -2043,7 +2043,7 @@ void icl_dsi_init(struct drm_i915_private *dev_priv) + } + + intel_panel_init(&intel_connector->panel, fixed_mode, NULL); +- intel_panel_setup_backlight(connector, INVALID_PIPE); ++ intel_backlight_setup(intel_connector, INVALID_PIPE); + + if (dev_priv->vbt.dsi.config->dual_link) + intel_dsi->ports = BIT(PORT_A) | BIT(PORT_B); +diff --git a/drivers/gpu/drm/i915/display/intel_backlight.c b/drivers/gpu/drm/i915/display/intel_backlight.c +index 4b0086ee4851..9523411cddd8 100644 +--- a/drivers/gpu/drm/i915/display/intel_backlight.c ++++ b/drivers/gpu/drm/i915/display/intel_backlight.c +@@ -72,7 +72,7 @@ static u32 scale_hw_to_user(struct intel_connector *connector, + 0, user_max); + } + +-u32 intel_panel_invert_pwm_level(struct intel_connector *connector, u32 val) ++u32 intel_backlight_invert_pwm_level(struct intel_connector *connector, u32 val) + { + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_panel *panel = &connector->panel; +@@ -90,7 +90,7 @@ u32 intel_panel_invert_pwm_level(struct intel_connector *connector, u32 val) + return val; + } + +-void intel_panel_set_pwm_level(const struct drm_connector_state *conn_state, u32 val) ++void intel_backlight_set_pwm_level(const struct drm_connector_state *conn_state, u32 val) + { + struct intel_connector *connector = to_intel_connector(conn_state->connector); + struct drm_i915_private *i915 = to_i915(connector->base.dev); +@@ -100,7 +100,7 @@ void intel_panel_set_pwm_level(const struct drm_connector_state *conn_state, u32 + panel->backlight.pwm_funcs->set(conn_state, val); + } + +-u32 intel_panel_backlight_level_to_pwm(struct intel_connector *connector, u32 val) ++u32 intel_backlight_level_to_pwm(struct intel_connector *connector, u32 val) + { + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_panel *panel = &connector->panel; +@@ -111,10 +111,10 @@ u32 intel_panel_backlight_level_to_pwm(struct intel_connector *connector, u32 va + val = scale(val, panel->backlight.min, panel->backlight.max, + panel->backlight.pwm_level_min, panel->backlight.pwm_level_max); + +- return intel_panel_invert_pwm_level(connector, val); ++ return intel_backlight_invert_pwm_level(connector, val); + } + +-u32 intel_panel_backlight_level_from_pwm(struct intel_connector *connector, u32 val) ++u32 intel_backlight_level_from_pwm(struct intel_connector *connector, u32 val) + { + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_panel *panel = &connector->panel; +@@ -283,8 +283,8 @@ intel_panel_actually_set_backlight(const struct drm_connector_state *conn_state, + /* set backlight brightness to level in range [0..max], assuming hw min is + * respected. + */ +-void intel_panel_set_backlight_acpi(const struct drm_connector_state *conn_state, +- u32 user_level, u32 user_max) ++void intel_backlight_set_acpi(const struct drm_connector_state *conn_state, ++ u32 user_level, u32 user_max) + { + struct intel_connector *connector = to_intel_connector(conn_state->connector); + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +@@ -325,7 +325,7 @@ static void lpt_disable_backlight(const struct drm_connector_state *old_conn_sta + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + u32 tmp; + +- intel_panel_set_pwm_level(old_conn_state, level); ++ intel_backlight_set_pwm_level(old_conn_state, level); + + /* + * Although we don't support or enable CPU PWM with LPT/SPT based +@@ -353,7 +353,7 @@ static void pch_disable_backlight(const struct drm_connector_state *old_conn_sta + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + u32 tmp; + +- intel_panel_set_pwm_level(old_conn_state, val); ++ intel_backlight_set_pwm_level(old_conn_state, val); + + tmp = intel_de_read(dev_priv, BLC_PWM_CPU_CTL2); + intel_de_write(dev_priv, BLC_PWM_CPU_CTL2, tmp & ~BLM_PWM_ENABLE); +@@ -364,7 +364,7 @@ static void pch_disable_backlight(const struct drm_connector_state *old_conn_sta + + static void i9xx_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val) + { +- intel_panel_set_pwm_level(old_conn_state, val); ++ intel_backlight_set_pwm_level(old_conn_state, val); + } + + static void i965_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val) +@@ -372,7 +372,7 @@ static void i965_disable_backlight(const struct drm_connector_state *old_conn_st + struct drm_i915_private *dev_priv = to_i915(old_conn_state->connector->dev); + u32 tmp; + +- intel_panel_set_pwm_level(old_conn_state, val); ++ intel_backlight_set_pwm_level(old_conn_state, val); + + tmp = intel_de_read(dev_priv, BLC_PWM_CTL2); + intel_de_write(dev_priv, BLC_PWM_CTL2, tmp & ~BLM_PWM_ENABLE); +@@ -385,7 +385,7 @@ static void vlv_disable_backlight(const struct drm_connector_state *old_conn_sta + enum pipe pipe = to_intel_crtc(old_conn_state->crtc)->pipe; + u32 tmp; + +- intel_panel_set_pwm_level(old_conn_state, val); ++ intel_backlight_set_pwm_level(old_conn_state, val); + + tmp = intel_de_read(dev_priv, VLV_BLC_PWM_CTL2(pipe)); + intel_de_write(dev_priv, VLV_BLC_PWM_CTL2(pipe), +@@ -399,7 +399,7 @@ static void bxt_disable_backlight(const struct drm_connector_state *old_conn_sta + struct intel_panel *panel = &connector->panel; + u32 tmp; + +- intel_panel_set_pwm_level(old_conn_state, val); ++ intel_backlight_set_pwm_level(old_conn_state, val); + + tmp = intel_de_read(dev_priv, + BXT_BLC_PWM_CTL(panel->backlight.controller)); +@@ -420,7 +420,7 @@ static void cnp_disable_backlight(const struct drm_connector_state *old_conn_sta + struct intel_panel *panel = &connector->panel; + u32 tmp; + +- intel_panel_set_pwm_level(old_conn_state, val); ++ intel_backlight_set_pwm_level(old_conn_state, val); + + tmp = intel_de_read(dev_priv, + BXT_BLC_PWM_CTL(panel->backlight.controller)); +@@ -437,7 +437,7 @@ static void ext_pwm_disable_backlight(const struct drm_connector_state *old_conn + pwm_apply_state(panel->backlight.pwm, &panel->backlight.pwm_state); + } + +-void intel_panel_disable_backlight(const struct drm_connector_state *old_conn_state) ++void intel_backlight_disable(const struct drm_connector_state *old_conn_state) + { + struct intel_connector *connector = to_intel_connector(old_conn_state->connector); + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +@@ -516,7 +516,7 @@ static void lpt_enable_backlight(const struct intel_crtc_state *crtc_state, + pch_ctl1 | BLM_PCH_PWM_ENABLE); + + /* This won't stick until the above enable. */ +- intel_panel_set_pwm_level(conn_state, level); ++ intel_backlight_set_pwm_level(conn_state, level); + } + + static void pch_enable_backlight(const struct intel_crtc_state *crtc_state, +@@ -551,7 +551,7 @@ static void pch_enable_backlight(const struct intel_crtc_state *crtc_state, + intel_de_write(dev_priv, BLC_PWM_CPU_CTL2, cpu_ctl2 | BLM_PWM_ENABLE); + + /* This won't stick until the above enable. */ +- intel_panel_set_pwm_level(conn_state, level); ++ intel_backlight_set_pwm_level(conn_state, level); + + pch_ctl2 = panel->backlight.pwm_level_max << 16; + intel_de_write(dev_priv, BLC_PWM_PCH_CTL2, pch_ctl2); +@@ -594,7 +594,7 @@ static void i9xx_enable_backlight(const struct intel_crtc_state *crtc_state, + intel_de_posting_read(dev_priv, BLC_PWM_CTL); + + /* XXX: combine this into above write? */ +- intel_panel_set_pwm_level(conn_state, level); ++ intel_backlight_set_pwm_level(conn_state, level); + + /* + * Needed to enable backlight on some 855gm models. BLC_HIST_CTL is +@@ -637,7 +637,7 @@ static void i965_enable_backlight(const struct intel_crtc_state *crtc_state, + intel_de_posting_read(dev_priv, BLC_PWM_CTL2); + intel_de_write(dev_priv, BLC_PWM_CTL2, ctl2 | BLM_PWM_ENABLE); + +- intel_panel_set_pwm_level(conn_state, level); ++ intel_backlight_set_pwm_level(conn_state, level); + } + + static void vlv_enable_backlight(const struct intel_crtc_state *crtc_state, +@@ -660,7 +660,7 @@ static void vlv_enable_backlight(const struct intel_crtc_state *crtc_state, + intel_de_write(dev_priv, VLV_BLC_PWM_CTL(pipe), ctl); + + /* XXX: combine this into above write? */ +- intel_panel_set_pwm_level(conn_state, level); ++ intel_backlight_set_pwm_level(conn_state, level); + + ctl2 = 0; + if (panel->backlight.active_low_pwm) +@@ -711,7 +711,7 @@ static void bxt_enable_backlight(const struct intel_crtc_state *crtc_state, + BXT_BLC_PWM_FREQ(panel->backlight.controller), + panel->backlight.pwm_level_max); + +- intel_panel_set_pwm_level(conn_state, level); ++ intel_backlight_set_pwm_level(conn_state, level); + + pwm_ctl = 0; + if (panel->backlight.active_low_pwm) +@@ -747,7 +747,7 @@ static void cnp_enable_backlight(const struct intel_crtc_state *crtc_state, + BXT_BLC_PWM_FREQ(panel->backlight.controller), + panel->backlight.pwm_level_max); + +- intel_panel_set_pwm_level(conn_state, level); ++ intel_backlight_set_pwm_level(conn_state, level); + + pwm_ctl = 0; + if (panel->backlight.active_low_pwm) +@@ -772,8 +772,8 @@ static void ext_pwm_enable_backlight(const struct intel_crtc_state *crtc_state, + pwm_apply_state(panel->backlight.pwm, &panel->backlight.pwm_state); + } + +-static void __intel_panel_enable_backlight(const struct intel_crtc_state *crtc_state, +- const struct drm_connector_state *conn_state) ++static void __intel_backlight_enable(const struct intel_crtc_state *crtc_state, ++ const struct drm_connector_state *conn_state) + { + struct intel_connector *connector = to_intel_connector(conn_state->connector); + struct intel_panel *panel = &connector->panel; +@@ -795,8 +795,8 @@ static void __intel_panel_enable_backlight(const struct intel_crtc_state *crtc_s + panel->backlight.device->props.power = FB_BLANK_UNBLANK; + } + +-void intel_panel_enable_backlight(const struct intel_crtc_state *crtc_state, +- const struct drm_connector_state *conn_state) ++void intel_backlight_enable(const struct intel_crtc_state *crtc_state, ++ const struct drm_connector_state *conn_state) + { + struct intel_connector *connector = to_intel_connector(conn_state->connector); + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +@@ -810,7 +810,7 @@ void intel_panel_enable_backlight(const struct intel_crtc_state *crtc_state, + + mutex_lock(&dev_priv->backlight_lock); + +- __intel_panel_enable_backlight(crtc_state, conn_state); ++ __intel_backlight_enable(crtc_state, conn_state); + + mutex_unlock(&dev_priv->backlight_lock); + } +@@ -1335,7 +1335,7 @@ static int i9xx_setup_backlight(struct intel_connector *connector, enum pipe unu + panel->backlight.pwm_level_min = get_backlight_min_vbt(connector); + + val = i9xx_get_backlight(connector, unused); +- val = intel_panel_invert_pwm_level(connector, val); ++ val = intel_backlight_invert_pwm_level(connector, val); + val = clamp(val, panel->backlight.pwm_level_min, panel->backlight.pwm_level_max); + + panel->backlight.pwm_enabled = val != 0; +@@ -1504,7 +1504,7 @@ static int ext_pwm_setup_backlight(struct intel_connector *connector, + + level = pwm_get_relative_duty_cycle(&panel->backlight.pwm_state, + 100); +- level = intel_panel_invert_pwm_level(connector, level); ++ level = intel_backlight_invert_pwm_level(connector, level); + panel->backlight.pwm_enabled = true; + + drm_dbg_kms(&dev_priv->drm, "PWM already enabled at freq %ld, VBT freq %d, level %d\n", +@@ -1527,14 +1527,14 @@ static void intel_pwm_set_backlight(const struct drm_connector_state *conn_state + struct intel_panel *panel = &connector->panel; + + panel->backlight.pwm_funcs->set(conn_state, +- intel_panel_invert_pwm_level(connector, level)); ++ intel_backlight_invert_pwm_level(connector, level)); + } + + static u32 intel_pwm_get_backlight(struct intel_connector *connector, enum pipe pipe) + { + struct intel_panel *panel = &connector->panel; + +- return intel_panel_invert_pwm_level(connector, ++ return intel_backlight_invert_pwm_level(connector, + panel->backlight.pwm_funcs->get(connector, pipe)); + } + +@@ -1545,7 +1545,7 @@ static void intel_pwm_enable_backlight(const struct intel_crtc_state *crtc_state + struct intel_panel *panel = &connector->panel; + + panel->backlight.pwm_funcs->enable(crtc_state, conn_state, +- intel_panel_invert_pwm_level(connector, level)); ++ intel_backlight_invert_pwm_level(connector, level)); + } + + static void intel_pwm_disable_backlight(const struct drm_connector_state *conn_state, u32 level) +@@ -1554,7 +1554,7 @@ static void intel_pwm_disable_backlight(const struct drm_connector_state *conn_s + struct intel_panel *panel = &connector->panel; + + panel->backlight.pwm_funcs->disable(conn_state, +- intel_panel_invert_pwm_level(connector, level)); ++ intel_backlight_invert_pwm_level(connector, level)); + } + + static int intel_pwm_setup_backlight(struct intel_connector *connector, enum pipe pipe) +@@ -1573,10 +1573,10 @@ static int intel_pwm_setup_backlight(struct intel_connector *connector, enum pip + return 0; + } + +-void intel_panel_update_backlight(struct intel_atomic_state *state, +- struct intel_encoder *encoder, +- const struct intel_crtc_state *crtc_state, +- const struct drm_connector_state *conn_state) ++void intel_backlight_update(struct intel_atomic_state *state, ++ struct intel_encoder *encoder, ++ const struct intel_crtc_state *crtc_state, ++ const struct drm_connector_state *conn_state) + { + struct intel_connector *connector = to_intel_connector(conn_state->connector); + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); +@@ -1587,16 +1587,15 @@ void intel_panel_update_backlight(struct intel_atomic_state *state, + + mutex_lock(&dev_priv->backlight_lock); + if (!panel->backlight.enabled) +- __intel_panel_enable_backlight(crtc_state, conn_state); ++ __intel_backlight_enable(crtc_state, conn_state); + + mutex_unlock(&dev_priv->backlight_lock); + } + +-int intel_panel_setup_backlight(struct drm_connector *connector, enum pipe pipe) ++int intel_backlight_setup(struct intel_connector *connector, enum pipe pipe) + { +- struct drm_i915_private *dev_priv = to_i915(connector->dev); +- struct intel_connector *intel_connector = to_intel_connector(connector); +- struct intel_panel *panel = &intel_connector->panel; ++ struct drm_i915_private *dev_priv = to_i915(connector->base.dev); ++ struct intel_panel *panel = &connector->panel; + int ret; + + if (!dev_priv->vbt.backlight.present) { +@@ -1616,13 +1615,13 @@ int intel_panel_setup_backlight(struct drm_connector *connector, enum pipe pipe) + + /* set level and max in panel struct */ + mutex_lock(&dev_priv->backlight_lock); +- ret = panel->backlight.funcs->setup(intel_connector, pipe); ++ ret = panel->backlight.funcs->setup(connector, pipe); + mutex_unlock(&dev_priv->backlight_lock); + + if (ret) { + drm_dbg_kms(&dev_priv->drm, + "failed to setup backlight for connector %s\n", +- connector->name); ++ connector->base.name); + return ret; + } + +@@ -1630,14 +1629,14 @@ int intel_panel_setup_backlight(struct drm_connector *connector, enum pipe pipe) + + drm_dbg_kms(&dev_priv->drm, + "Connector %s backlight initialized, %s, brightness %u/%u\n", +- connector->name, ++ connector->base.name, + enableddisabled(panel->backlight.enabled), + panel->backlight.level, panel->backlight.max); + + return 0; + } + +-void intel_panel_destroy_backlight(struct intel_panel *panel) ++void intel_backlight_destroy(struct intel_panel *panel) + { + /* dispose of the pwm */ + if (panel->backlight.pwm) +@@ -1735,8 +1734,7 @@ static const struct intel_panel_bl_funcs pwm_bl_funcs = { + }; + + /* Set up chip specific backlight functions */ +-void +-intel_panel_init_backlight_funcs(struct intel_panel *panel) ++void intel_backlight_init_funcs(struct intel_panel *panel) + { + struct intel_connector *connector = + container_of(panel, struct intel_connector, panel); +diff --git a/drivers/gpu/drm/i915/display/intel_backlight.h b/drivers/gpu/drm/i915/display/intel_backlight.h +index 282020cb47d5..339643f63897 100644 +--- a/drivers/gpu/drm/i915/display/intel_backlight.h ++++ b/drivers/gpu/drm/i915/display/intel_backlight.h +@@ -8,7 +8,6 @@ + + #include + +-struct drm_connector; + struct drm_connector_state; + struct intel_atomic_state; + struct intel_connector; +@@ -17,23 +16,25 @@ struct intel_encoder; + struct intel_panel; + enum pipe; + +-void intel_panel_init_backlight_funcs(struct intel_panel *panel); +-void intel_panel_destroy_backlight(struct intel_panel *panel); +-void intel_panel_set_backlight_acpi(const struct drm_connector_state *conn_state, +- u32 level, u32 max); +-int intel_panel_setup_backlight(struct drm_connector *connector, +- enum pipe pipe); +-void intel_panel_enable_backlight(const struct intel_crtc_state *crtc_state, +- const struct drm_connector_state *conn_state); +-void intel_panel_update_backlight(struct intel_atomic_state *state, +- struct intel_encoder *encoder, +- const struct intel_crtc_state *crtc_state, +- const struct drm_connector_state *conn_state); +-void intel_panel_disable_backlight(const struct drm_connector_state *old_conn_state); +-void intel_panel_set_pwm_level(const struct drm_connector_state *conn_state, u32 level); +-u32 intel_panel_invert_pwm_level(struct intel_connector *connector, u32 level); +-u32 intel_panel_backlight_level_to_pwm(struct intel_connector *connector, u32 level); +-u32 intel_panel_backlight_level_from_pwm(struct intel_connector *connector, u32 val); ++void intel_backlight_init_funcs(struct intel_panel *panel); ++int intel_backlight_setup(struct intel_connector *connector, enum pipe pipe); ++void intel_backlight_destroy(struct intel_panel *panel); ++ ++void intel_backlight_enable(const struct intel_crtc_state *crtc_state, ++ const struct drm_connector_state *conn_state); ++void intel_backlight_update(struct intel_atomic_state *state, ++ struct intel_encoder *encoder, ++ const struct intel_crtc_state *crtc_state, ++ const struct drm_connector_state *conn_state); ++void intel_backlight_disable(const struct drm_connector_state *old_conn_state); ++ ++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); ++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); + + #if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE) + int intel_backlight_device_register(struct intel_connector *connector); +diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c +index 8e981861699e..c06ccf00ebf7 100644 +--- a/drivers/gpu/drm/i915/display/intel_ddi.c ++++ b/drivers/gpu/drm/i915/display/intel_ddi.c +@@ -3230,7 +3230,7 @@ static void intel_ddi_update_pipe_dp(struct intel_atomic_state *state, + intel_dp_set_infoframes(encoder, true, crtc_state, conn_state); + intel_edp_drrs_update(intel_dp, crtc_state); + +- intel_panel_update_backlight(state, encoder, crtc_state, conn_state); ++ intel_backlight_update(state, encoder, crtc_state, conn_state); + } + + void intel_ddi_update_pipe(struct intel_atomic_state *state, +diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c +index 269ba112acd1..f1648a7da908 100644 +--- a/drivers/gpu/drm/i915/display/intel_dp.c ++++ b/drivers/gpu/drm/i915/display/intel_dp.c +@@ -1793,7 +1793,7 @@ void intel_edp_backlight_on(const struct intel_crtc_state *crtc_state, + + drm_dbg_kms(&i915->drm, "\n"); + +- intel_panel_enable_backlight(crtc_state, conn_state); ++ intel_backlight_enable(crtc_state, conn_state); + intel_pps_backlight_on(intel_dp); + } + +@@ -1809,7 +1809,7 @@ void intel_edp_backlight_off(const struct drm_connector_state *old_conn_state) + drm_dbg_kms(&i915->drm, "\n"); + + intel_pps_backlight_off(intel_dp); +- intel_panel_disable_backlight(old_conn_state); ++ intel_backlight_disable(old_conn_state); + } + + static bool downstream_hpd_needs_d0(struct intel_dp *intel_dp) +@@ -5255,7 +5255,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, + intel_panel_init(&intel_connector->panel, fixed_mode, downclock_mode); + if (!(dev_priv->quirks & QUIRK_NO_PPS_BACKLIGHT_POWER_HOOK)) + intel_connector->panel.backlight.power = intel_pps_backlight_power; +- intel_panel_setup_backlight(connector, pipe); ++ intel_backlight_setup(intel_connector, pipe); + + if (fixed_mode) { + drm_connector_set_panel_orientation_with_quirk(connector, +diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c +index 07c36c98ae1b..22f15e7b2ecf 100644 +--- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c ++++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c +@@ -149,7 +149,7 @@ intel_dp_aux_hdr_get_backlight(struct intel_connector *connector, enum pipe pipe + if (!panel->backlight.edp.intel.sdr_uses_aux) { + u32 pwm_level = panel->backlight.pwm_funcs->get(connector, pipe); + +- return intel_panel_backlight_level_from_pwm(connector, pwm_level); ++ return intel_backlight_level_from_pwm(connector, pwm_level); + } + + /* Assume 100% brightness if backlight controls aren't enabled yet */ +@@ -190,9 +190,9 @@ intel_dp_aux_hdr_set_backlight(const struct drm_connector_state *conn_state, u32 + if (panel->backlight.edp.intel.sdr_uses_aux) { + intel_dp_aux_hdr_set_aux_backlight(conn_state, level); + } else { +- const u32 pwm_level = intel_panel_backlight_level_to_pwm(connector, level); ++ const u32 pwm_level = intel_backlight_level_to_pwm(connector, level); + +- intel_panel_set_pwm_level(conn_state, pwm_level); ++ intel_backlight_set_pwm_level(conn_state, pwm_level); + } + } + +@@ -220,7 +220,7 @@ intel_dp_aux_hdr_enable_backlight(const struct intel_crtc_state *crtc_state, + ctrl |= INTEL_EDP_HDR_TCON_BRIGHTNESS_AUX_ENABLE; + intel_dp_aux_hdr_set_aux_backlight(conn_state, level); + } else { +- u32 pwm_level = intel_panel_backlight_level_to_pwm(connector, level); ++ u32 pwm_level = intel_backlight_level_to_pwm(connector, level); + + panel->backlight.pwm_funcs->enable(crtc_state, conn_state, pwm_level); + +@@ -243,7 +243,7 @@ intel_dp_aux_hdr_disable_backlight(const struct drm_connector_state *conn_state, + return; + + /* Note we want the actual pwm_level to be 0, regardless of pwm_min */ +- panel->backlight.pwm_funcs->disable(conn_state, intel_panel_invert_pwm_level(connector, 0)); ++ panel->backlight.pwm_funcs->disable(conn_state, intel_backlight_invert_pwm_level(connector, 0)); + } + + static int +diff --git a/drivers/gpu/drm/i915/display/intel_lvds.c b/drivers/gpu/drm/i915/display/intel_lvds.c +index 8f5741ebd58d..df8238fefdd8 100644 +--- a/drivers/gpu/drm/i915/display/intel_lvds.c ++++ b/drivers/gpu/drm/i915/display/intel_lvds.c +@@ -324,7 +324,7 @@ static void intel_enable_lvds(struct intel_atomic_state *state, + drm_err(&dev_priv->drm, + "timed out waiting for panel to power on\n"); + +- intel_panel_enable_backlight(pipe_config, conn_state); ++ intel_backlight_enable(pipe_config, conn_state); + } + + static void intel_disable_lvds(struct intel_atomic_state *state, +@@ -352,7 +352,7 @@ static void gmch_disable_lvds(struct intel_atomic_state *state, + const struct drm_connector_state *old_conn_state) + + { +- intel_panel_disable_backlight(old_conn_state); ++ intel_backlight_disable(old_conn_state); + + intel_disable_lvds(state, encoder, old_crtc_state, old_conn_state); + } +@@ -362,7 +362,7 @@ static void pch_disable_lvds(struct intel_atomic_state *state, + const struct intel_crtc_state *old_crtc_state, + const struct drm_connector_state *old_conn_state) + { +- intel_panel_disable_backlight(old_conn_state); ++ intel_backlight_disable(old_conn_state); + } + + static void pch_post_disable_lvds(struct intel_atomic_state *state, +@@ -907,7 +907,7 @@ void intel_lvds_init(struct drm_i915_private *dev_priv) + } + intel_encoder->get_hw_state = intel_lvds_get_hw_state; + intel_encoder->get_config = intel_lvds_get_config; +- intel_encoder->update_pipe = intel_panel_update_backlight; ++ intel_encoder->update_pipe = intel_backlight_update; + intel_encoder->shutdown = intel_lvds_shutdown; + intel_connector->get_hw_state = intel_connector_get_hw_state; + +@@ -1000,7 +1000,7 @@ void intel_lvds_init(struct drm_i915_private *dev_priv) + mutex_unlock(&dev->mode_config.mutex); + + intel_panel_init(&intel_connector->panel, fixed_mode, downclock_mode); +- intel_panel_setup_backlight(connector, INVALID_PIPE); ++ intel_backlight_setup(intel_connector, INVALID_PIPE); + + lvds_encoder->is_dual_link = compute_is_dual_link_lvds(lvds_encoder); + drm_dbg_kms(&dev_priv->drm, "detected %s-link lvds configuration\n", +diff --git a/drivers/gpu/drm/i915/display/intel_opregion.c b/drivers/gpu/drm/i915/display/intel_opregion.c +index 3a7a8598d1ec..0065111593a6 100644 +--- a/drivers/gpu/drm/i915/display/intel_opregion.c ++++ b/drivers/gpu/drm/i915/display/intel_opregion.c +@@ -449,7 +449,7 @@ static u32 asle_set_backlight(struct drm_i915_private *dev_priv, u32 bclp) + bclp); + drm_connector_list_iter_begin(dev, &conn_iter); + for_each_intel_connector_iter(connector, &conn_iter) +- intel_panel_set_backlight_acpi(connector->base.state, bclp, 255); ++ intel_backlight_set_acpi(connector->base.state, bclp, 255); + drm_connector_list_iter_end(&conn_iter); + asle->cblv = DIV_ROUND_UP(bclp * 100, 255) | ASLE_CBLV_VALID; + +diff --git a/drivers/gpu/drm/i915/display/intel_panel.c b/drivers/gpu/drm/i915/display/intel_panel.c +index ad54767440c1..611e32421353 100644 +--- a/drivers/gpu/drm/i915/display/intel_panel.c ++++ b/drivers/gpu/drm/i915/display/intel_panel.c +@@ -467,7 +467,7 @@ int intel_panel_init(struct intel_panel *panel, + struct drm_display_mode *fixed_mode, + struct drm_display_mode *downclock_mode) + { +- intel_panel_init_backlight_funcs(panel); ++ intel_backlight_init_funcs(panel); + + panel->fixed_mode = fixed_mode; + panel->downclock_mode = downclock_mode; +@@ -480,7 +480,7 @@ void intel_panel_fini(struct intel_panel *panel) + struct intel_connector *intel_connector = + container_of(panel, struct intel_connector, panel); + +- intel_panel_destroy_backlight(panel); ++ intel_backlight_destroy(panel); + + if (panel->fixed_mode) + drm_mode_destroy(intel_connector->base.dev, panel->fixed_mode); +diff --git a/drivers/gpu/drm/i915/display/vlv_dsi.c b/drivers/gpu/drm/i915/display/vlv_dsi.c +index b27738df447d..76910c4b20e0 100644 +--- a/drivers/gpu/drm/i915/display/vlv_dsi.c ++++ b/drivers/gpu/drm/i915/display/vlv_dsi.c +@@ -884,7 +884,7 @@ static void intel_dsi_pre_enable(struct intel_atomic_state *state, + intel_dsi_port_enable(encoder, pipe_config); + } + +- intel_panel_enable_backlight(pipe_config, conn_state); ++ intel_backlight_enable(pipe_config, conn_state); + intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_BACKLIGHT_ON); + } + +@@ -914,7 +914,7 @@ static void intel_dsi_disable(struct intel_atomic_state *state, + drm_dbg_kms(&i915->drm, "\n"); + + intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_BACKLIGHT_OFF); +- intel_panel_disable_backlight(old_conn_state); ++ intel_backlight_disable(old_conn_state); + + /* + * According to the spec we should send SHUTDOWN before +@@ -1877,7 +1877,7 @@ void vlv_dsi_init(struct drm_i915_private *dev_priv) + intel_encoder->post_disable = intel_dsi_post_disable; + intel_encoder->get_hw_state = intel_dsi_get_hw_state; + intel_encoder->get_config = intel_dsi_get_config; +- intel_encoder->update_pipe = intel_panel_update_backlight; ++ intel_encoder->update_pipe = intel_backlight_update; + intel_encoder->shutdown = intel_dsi_shutdown; + + intel_connector->get_hw_state = intel_connector_get_hw_state; +@@ -1965,7 +1965,7 @@ void vlv_dsi_init(struct drm_i915_private *dev_priv) + } + + intel_panel_init(&intel_connector->panel, fixed_mode, NULL); +- intel_panel_setup_backlight(connector, INVALID_PIPE); ++ intel_backlight_setup(intel_connector, INVALID_PIPE); + + vlv_dsi_add_properties(intel_connector); + +-- +2.33.0 + + +From 79f3ee76e2861c09d4f8afd351b4b89c331a6a30 Mon Sep 17 00:00:00 2001 +From: Lyude Paul +Date: Fri, 5 Nov 2021 14:33:38 -0400 +Subject: [PATCH 3/5] drm/i915: Add support for panels with VESA backlights + with PWM enable/disable +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This simply adds proper support for panel backlights that can be controlled +via VESA's backlight control protocol, but which also require that we +enable and disable the backlight via PWM instead of via the DPCD interface. +We also enable this by default, in order to fix some people's backlights +that were broken by not having this enabled. + +For reference, backlights that require this and use VESA's backlight +interface tend to be laptops with hybrid GPUs, but this very well may +change in the future. + +v4: +* Make sure that we call intel_backlight_level_to_pwm() in + intel_dp_aux_vesa_enable_backlight() - vsyrjala + +Signed-off-by: Lyude Paul +Link: https://gitlab.freedesktop.org/drm/intel/-/issues/3680 +Fixes: fe7d52bccab6 ("drm/i915/dp: Don't use DPCD backlights that need PWM enable/disable") +Reviewed-by: Ville Syrjälä +Cc: # v5.12+ +Message-Id: <20211105183342.130810-2-lyude@redhat.com> +(cherry-picked from commit 61e29a0956bdb09eac8aca7d9add9f902baff08b) --- - drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c | 7 +------ - 1 file changed, 1 insertion(+), 6 deletions(-) + .../drm/i915/display/intel_dp_aux_backlight.c | 27 ++++++++++++++----- + 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c -index c82f8febe730..82d1fcc095f2 100644 +index 22f15e7b2ecf..3897468140e0 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c +++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c -@@ -345,12 +345,7 @@ intel_dp_aux_supports_vesa_backlight(struct intel_connector *connector) +@@ -298,6 +298,13 @@ intel_dp_aux_vesa_enable_backlight(const struct intel_crtc_state *crtc_state, + struct intel_panel *panel = &connector->panel; + struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder); + ++ if (!panel->backlight.edp.vesa.info.aux_enable) { ++ u32 pwm_level = intel_backlight_invert_pwm_level(connector, ++ panel->backlight.pwm_level_max); ++ ++ panel->backlight.pwm_funcs->enable(crtc_state, conn_state, pwm_level); ++ } ++ + drm_edp_backlight_enable(&intel_dp->aux, &panel->backlight.edp.vesa.info, level); + } + +@@ -309,6 +316,10 @@ static void intel_dp_aux_vesa_disable_backlight(const struct drm_connector_state + struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder); + + drm_edp_backlight_disable(&intel_dp->aux, &panel->backlight.edp.vesa.info); ++ ++ if (!panel->backlight.edp.vesa.info.aux_enable) ++ panel->backlight.pwm_funcs->disable(old_conn_state, ++ intel_backlight_invert_pwm_level(connector, 0)); + } + + static int intel_dp_aux_vesa_setup_backlight(struct intel_connector *connector, enum pipe pipe) +@@ -326,6 +337,15 @@ static int intel_dp_aux_vesa_setup_backlight(struct intel_connector *connector, + if (ret < 0) + return ret; + ++ if (!panel->backlight.edp.vesa.info.aux_enable) { ++ ret = panel->backlight.pwm_funcs->setup(connector, pipe); ++ if (ret < 0) { ++ drm_err(&i915->drm, ++ "Failed to setup PWM backlight controls for eDP backlight: %d\n", ++ ret); ++ return ret; ++ } ++ } + panel->backlight.max = panel->backlight.edp.vesa.info.max; + panel->backlight.min = 0; + if (current_mode == DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD) { +@@ -345,12 +365,7 @@ intel_dp_aux_supports_vesa_backlight(struct intel_connector *connector) struct intel_dp *intel_dp = intel_attached_dp(connector); struct drm_i915_private *i915 = dp_to_i915(intel_dp); @@ -31,134 +3471,411 @@ index c82f8febe730..82d1fcc095f2 100644 2.33.0 -From 023170bb983f59dff1f249500262d15705bc4c6f Mon Sep 17 00:00:00 2001 -From: Kevin Chowski -Date: Sat, 8 Aug 2020 15:40:51 -0600 -Subject: [PATCH 2/2] CHROMIUM: Changes needed for backlight control on Eve-5.4 - - #1: Port https://crrev.com/c/439873 to the 5.4 tree - #2: Port https://crrev.com/c/440445 to the 5.4 tree - #3: Port https://crrev.com/c/456118 to the 5.4 tree - -The first two patches are needed to correctly enable the backlight for -Eve; they were submitted upstream in 2017 but were rolled back. - -The third patch was not rolled back upstream, but the code related to it -changed quite a bit between 4.4 and 5.4: the write of -DP_EDP_PWMGEN_BIT_COUNT used to happen on every screen enable via -intel_dp_aux_set_pwm_freq (that's how it works in 4.4), but in 5.4 the -write was refactored into intel_dp_aux_calc_max_backlight and only -called once per screen setup. This patch brings back the old -functionality of intel_dp_aux_set_pwm_freq to ensure we set that -register on each screen enable, but this is at the cost of duplication -between intel_dp_aux_calc_max_backlight. Unfortunately, I don't see a -better way to do this without making the cros code diverge even further -from 4.4 and 5.4. - -I'd like to submit this CL into the chromium tree, and use b/163412221 -to track its upstreaming and the ultimate revert of this change. - -Test: - * `emerge-eve-kernelnext sys-kernel/chromeos-kernel-5_4` - * `./update_kernel.sh --remote=192.168.0.22 --remote_bootarg` - * On DUT, set options `i915.enable_dpcd_backlight=1 i915.enable_dbc=1` - (using e.g. `/usr/share/vboot/bin/make_dev_ssd.sh`) - * reboot - * Change brightness on DUT - * Allow DUT screen to fall asleep - * Wake DUT screen, change brightness again - -BUG=b:162255390 -TEST=See above - -Change-Id: I9eafa28226f1c6b8332fcf9730259bea05cf7975 -Signed-off-by: Kevin Chowski -Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/2344844 -Reviewed-by: Puthikorn Voravootivat -Conflicts: - drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c -[rebase510(groeck): Picked code from continuous rebase project to resolve conflicts] -Signed-off-by: Guenter Roeck -(cherry picked from commit 37af4b996c1e25b7be4a00e5c5bcf29bc37cd51a) +From 80bfbd23a11bd193d0eb2be3af5be61fb298fc7d Mon Sep 17 00:00:00 2001 +From: Lyude Paul +Date: Fri, 5 Nov 2021 14:33:40 -0400 +Subject: [PATCH 4/5] drm/dp: Don't read back backlight mode in + drm_edp_backlight_enable() + +As it turns out, apparently some machines will actually leave additional +backlight functionality like dynamic backlight control on before the OS +loads. Currently we don't take care to disable unsupported features when +writing back the backlight mode, which can lead to some rather strange +looking behavior when adjusting the backlight. + +So, let's fix this by just not reading back the current backlight mode on +initial enable. I don't think there should really be any downsides to this, +and this will ensure we don't leave any unsupported functionality enabled. + +This should fix at least one (but not all) of the issues seen with DPCD +backlight support on fi-bdw-samus + +v5: +* Just avoid reading back DPCD register - Doug Anderson + +Signed-off-by: Lyude Paul +Fixes: 867cf9cd73c3 ("drm/dp: Extract i915's eDP backlight code into DRM helpers") +Reviewed-by: Douglas Anderson +Message-Id: <20211105183342.130810-4-lyude@redhat.com> +(cherry-picked from commit 646596485e1ed2182adf293dfd5aec4a96c46330) --- - .../drm/i915/display/intel_dp_aux_backlight.c | 57 +++++++++++++++++++ - 1 file changed, 57 insertions(+) + drivers/gpu/drm/drm_dp_helper.c | 40 ++++++++++----------------------- + 1 file changed, 12 insertions(+), 28 deletions(-) -diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c -index 82d1fcc095f2..a139b7e29aa3 100644 ---- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c -+++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c -@@ -352,6 +352,59 @@ intel_dp_aux_supports_vesa_backlight(struct intel_connector *connector) - return false; - } +diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c +index 6d0f2c447f3b..7bb24523a749 100644 +--- a/drivers/gpu/drm/drm_dp_helper.c ++++ b/drivers/gpu/drm/drm_dp_helper.c +@@ -3214,27 +3214,13 @@ int drm_edp_backlight_enable(struct drm_dp_aux *aux, const struct drm_edp_backli + const u16 level) + { + int ret; +- u8 dpcd_buf, new_dpcd_buf; ++ u8 dpcd_buf = DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD; -+/* -+ * Heuristic function whether we should use AUX for backlight adjustment or not. -+ * -+ * We should use AUX for backlight brightness adjustment if panel doesn't this -+ * via PWM pin or using AUX is better than using PWM pin. -+ * -+ * The heuristic to determine that using AUX pin is better than using PWM pin is -+ * that the panel support any of the feature list here. -+ * - Regional backlight brightness adjustment -+ * - Backlight PWM frequency set -+ * - More than 8 bits resolution of brightness level -+ * - Backlight enablement via AUX and not by BL_ENABLE pin +- ret = drm_dp_dpcd_readb(aux, DP_EDP_BACKLIGHT_MODE_SET_REGISTER, &dpcd_buf); +- if (ret != 1) { +- drm_dbg_kms(aux->drm_dev, +- "%s: Failed to read backlight mode: %d\n", aux->name, ret); +- return ret < 0 ? ret : -EIO; +- } +- +- new_dpcd_buf = dpcd_buf; +- +- if ((dpcd_buf & DP_EDP_BACKLIGHT_CONTROL_MODE_MASK) != DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD) { +- new_dpcd_buf &= ~DP_EDP_BACKLIGHT_CONTROL_MODE_MASK; +- new_dpcd_buf |= DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD; +- +- if (bl->pwmgen_bit_count) { +- ret = drm_dp_dpcd_writeb(aux, DP_EDP_PWMGEN_BIT_COUNT, bl->pwmgen_bit_count); +- if (ret != 1) +- drm_dbg_kms(aux->drm_dev, "%s: Failed to write aux pwmgen bit count: %d\n", +- aux->name, ret); +- } ++ if (bl->pwmgen_bit_count) { ++ ret = drm_dp_dpcd_writeb(aux, DP_EDP_PWMGEN_BIT_COUNT, bl->pwmgen_bit_count); ++ if (ret != 1) ++ drm_dbg_kms(aux->drm_dev, "%s: Failed to write aux pwmgen bit count: %d\n", ++ aux->name, ret); + } + + if (bl->pwm_freq_pre_divider) { +@@ -3244,16 +3230,14 @@ int drm_edp_backlight_enable(struct drm_dp_aux *aux, const struct drm_edp_backli + "%s: Failed to write aux backlight frequency: %d\n", + aux->name, ret); + else +- new_dpcd_buf |= DP_EDP_BACKLIGHT_FREQ_AUX_SET_ENABLE; ++ dpcd_buf |= DP_EDP_BACKLIGHT_FREQ_AUX_SET_ENABLE; + } + +- if (new_dpcd_buf != dpcd_buf) { +- ret = drm_dp_dpcd_writeb(aux, DP_EDP_BACKLIGHT_MODE_SET_REGISTER, new_dpcd_buf); +- if (ret != 1) { +- drm_dbg_kms(aux->drm_dev, "%s: Failed to write aux backlight mode: %d\n", +- aux->name, ret); +- return ret < 0 ? ret : -EIO; +- } ++ ret = drm_dp_dpcd_writeb(aux, DP_EDP_BACKLIGHT_MODE_SET_REGISTER, dpcd_buf); ++ if (ret != 1) { ++ drm_dbg_kms(aux->drm_dev, "%s: Failed to write aux backlight mode: %d\n", ++ aux->name, ret); ++ return ret < 0 ? ret : -EIO; + } + + ret = drm_edp_backlight_set_level(aux, bl, level); +-- +2.33.0 + + +From 51fe90de28690e72b886b936bbb69f9f107cf74c Mon Sep 17 00:00:00 2001 +From: Lyude Paul +Date: Fri, 5 Nov 2021 14:33:41 -0400 +Subject: [PATCH 5/5] drm/dp, drm/i915: Add support for VESA backlights using + PWM for brightness control + +Now that we've added support to i915 for controlling panel backlights that +need PWM to be enabled/disabled, let's finalize this and add support for +controlling brightness levels via PWM as well. This should hopefully put us +towards the path of supporting _ALL_ backlights via VESA's DPCD interface +which would allow us to finally start trusting the DPCD again. + +Note however that we still don't enable using this by default on i915 when +it's not needed, primarily because I haven't yet had a chance to confirm if +it's safe to do this on the one machine in Intel's CI that had an issue +with this: samus-fi-bdw. I have done basic testing of this on other +machines though, by manually patching i915 to force it into PWM-only mode +on some of my laptops. + +v2: +* Correct documentation (thanks Doug!) +* Get rid of backlight caps + +Signed-off-by: Lyude Paul +Reviewed-by: Doug Anderson +Cc: Rajeev Nandan +Cc: Satadru Pramanik +Message-Id: <20211105183342.130810-5-lyude@redhat.com> +(cherry-picked from commit f58a435311672305d8747f40e35235f7ed64ae69) +--- + drivers/gpu/drm/drm_dp_helper.c | 72 +++++++++++++------ + .../drm/i915/display/intel_dp_aux_backlight.c | 44 +++++++++--- + include/drm/drm_dp_helper.h | 7 +- + 3 files changed, 89 insertions(+), 34 deletions(-) + +diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c +index 7bb24523a749..0dd0c95ee22e 100644 +--- a/drivers/gpu/drm/drm_dp_helper.c ++++ b/drivers/gpu/drm/drm_dp_helper.c +@@ -3141,6 +3141,10 @@ int drm_edp_backlight_set_level(struct drm_dp_aux *aux, const struct drm_edp_bac + int ret; + u8 buf[2] = { 0 }; + ++ /* The panel uses the PWM for controlling brightness levels */ ++ if (!bl->aux_set) ++ return 0; ++ + if (bl->lsb_reg_used) { + buf[0] = (level & 0xff00) >> 8; + buf[1] = (level & 0x00ff); +@@ -3167,7 +3171,7 @@ drm_edp_backlight_set_enable(struct drm_dp_aux *aux, const struct drm_edp_backli + int ret; + u8 buf; + +- /* The panel uses something other then DPCD for enabling its backlight */ ++ /* This panel uses the EDP_BL_PWR GPIO for enablement */ + if (!bl->aux_enable) + return 0; + +@@ -3202,11 +3206,11 @@ drm_edp_backlight_set_enable(struct drm_dp_aux *aux, const struct drm_edp_backli + * restoring any important backlight state such as the given backlight level, the brightness byte + * count, backlight frequency, etc. + * +- * Note that certain panels, while supporting brightness level controls over DPCD, may not support +- * having their backlights enabled via the standard %DP_EDP_DISPLAY_CONTROL_REGISTER. On such panels +- * &drm_edp_backlight_info.aux_enable will be set to %false, this function will skip the step of +- * programming the %DP_EDP_DISPLAY_CONTROL_REGISTER, and the driver must perform the required +- * implementation specific step for enabling the backlight after calling this function. ++ * Note that certain panels do not support being enabled or disabled via DPCD, but instead require ++ * that the driver handle enabling/disabling the panel through implementation-specific means using ++ * the EDP_BL_PWR GPIO. For such panels, &drm_edp_backlight_info.aux_enable will be set to %false, ++ * this function becomes a no-op, and the driver is expected to handle powering the panel on using ++ * the EDP_BL_PWR GPIO. + * + * Returns: %0 on success, negative error code on failure. + */ +@@ -3214,7 +3218,12 @@ int drm_edp_backlight_enable(struct drm_dp_aux *aux, const struct drm_edp_backli + const u16 level) + { + int ret; +- u8 dpcd_buf = DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD; ++ u8 dpcd_buf; ++ ++ if (bl->aux_set) ++ dpcd_buf = DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD; ++ else ++ dpcd_buf = DP_EDP_BACKLIGHT_CONTROL_MODE_PWM; + + if (bl->pwmgen_bit_count) { + ret = drm_dp_dpcd_writeb(aux, DP_EDP_PWMGEN_BIT_COUNT, bl->pwmgen_bit_count); +@@ -3256,12 +3265,13 @@ EXPORT_SYMBOL(drm_edp_backlight_enable); + * @aux: The DP AUX channel to use + * @bl: Backlight capability info from drm_edp_backlight_init() + * +- * This function handles disabling DPCD backlight controls on a panel over AUX. Note that some +- * panels have backlights that are enabled/disabled by other means, despite having their brightness +- * values controlled through DPCD. On such panels &drm_edp_backlight_info.aux_enable will be set to +- * %false, this function will become a no-op (and we will skip updating +- * %DP_EDP_DISPLAY_CONTROL_REGISTER), and the driver must take care to perform it's own +- * implementation specific step for disabling the backlight. ++ * This function handles disabling DPCD backlight controls on a panel over AUX. + * -+ * If all above are not true, assume that using PWM pin is better. -+ */ -+static bool -+intel_dp_aux_display_control_heuristic(struct intel_connector *connector) -+{ -+ struct intel_dp *intel_dp = intel_attached_dp(connector); -+ struct drm_i915_private *i915 = dp_to_i915(intel_dp); -+ uint8_t reg_val; ++ * Note that certain panels do not support being enabled or disabled via DPCD, but instead require ++ * that the driver handle enabling/disabling the panel through implementation-specific means using ++ * the EDP_BL_PWR GPIO. For such panels, &drm_edp_backlight_info.aux_enable will be set to %false, ++ * this function becomes a no-op, and the driver is expected to handle powering the panel off using ++ * the EDP_BL_PWR GPIO. + * + * Returns: %0 on success or no-op, negative error code on failure. + */ +@@ -3285,6 +3295,9 @@ drm_edp_backlight_probe_max(struct drm_dp_aux *aux, struct drm_edp_backlight_inf + int ret; + u8 pn, pn_min, pn_max; + ++ if (!bl->aux_set) ++ return 0; + -+ /* Panel doesn't support adjusting backlight brightness via PWN pin */ -+ if (!(intel_dp->edp_dpcd[2] & DP_EDP_BACKLIGHT_BRIGHTNESS_PWM_PIN_CAP)) -+ return true; + ret = drm_dp_dpcd_readb(aux, DP_EDP_PWMGEN_BIT_COUNT, &pn); + if (ret != 1) { + drm_dbg_kms(aux->drm_dev, "%s: Failed to read pwmgen bit count cap: %d\n", +@@ -3370,7 +3383,7 @@ drm_edp_backlight_probe_max(struct drm_dp_aux *aux, struct drm_edp_backlight_inf + } + + static inline int +-drm_edp_backlight_probe_level(struct drm_dp_aux *aux, struct drm_edp_backlight_info *bl, ++drm_edp_backlight_probe_state(struct drm_dp_aux *aux, struct drm_edp_backlight_info *bl, + u8 *current_mode) + { + int ret; +@@ -3385,6 +3398,9 @@ drm_edp_backlight_probe_level(struct drm_dp_aux *aux, struct drm_edp_backlight_i + } + + *current_mode = (mode_reg & DP_EDP_BACKLIGHT_CONTROL_MODE_MASK); ++ if (!bl->aux_set) ++ return 0; + -+ /* Panel supports regional backlight brightness adjustment */ -+ if (drm_dp_dpcd_readb(&intel_dp->aux, DP_EDP_GENERAL_CAP_3, -+ ®_val) != 1) { -+ drm_dbg_kms(&i915->drm, "Failed to read DPCD register 0x%x\n", -+ DP_EDP_GENERAL_CAP_3); -+ return false; + if (*current_mode == DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD) { + int size = 1 + bl->lsb_reg_used; + +@@ -3415,7 +3431,7 @@ drm_edp_backlight_probe_level(struct drm_dp_aux *aux, struct drm_edp_backlight_i + * @bl: The &drm_edp_backlight_info struct to fill out with information on the backlight + * @driver_pwm_freq_hz: Optional PWM frequency from the driver in hz + * @edp_dpcd: A cached copy of the eDP DPCD +- * @current_level: Where to store the probed brightness level ++ * @current_level: Where to store the probed brightness level, if any + * @current_mode: Where to store the currently set backlight control mode + * + * Initializes a &drm_edp_backlight_info struct by probing @aux for it's backlight capabilities, +@@ -3435,24 +3451,38 @@ drm_edp_backlight_init(struct drm_dp_aux *aux, struct drm_edp_backlight_info *bl + + if (edp_dpcd[1] & DP_EDP_BACKLIGHT_AUX_ENABLE_CAP) + bl->aux_enable = true; ++ if (edp_dpcd[2] & DP_EDP_BACKLIGHT_BRIGHTNESS_AUX_SET_CAP) ++ bl->aux_set = true; + if (edp_dpcd[2] & DP_EDP_BACKLIGHT_BRIGHTNESS_BYTE_COUNT) + bl->lsb_reg_used = true; + ++ /* Sanity check caps */ ++ if (!bl->aux_set && !(edp_dpcd[2] & DP_EDP_BACKLIGHT_BRIGHTNESS_PWM_PIN_CAP)) { ++ drm_dbg_kms(aux->drm_dev, ++ "%s: Panel supports neither AUX or PWM brightness control? Aborting\n", ++ aux->name); ++ return -EINVAL; + } -+ if (reg_val > 0) -+ return true; + -+ /* Panel supports backlight PWM frequency set */ -+ if (intel_dp->edp_dpcd[2] & DP_EDP_BACKLIGHT_FREQ_AUX_SET_CAP) -+ return true; -+ -+ /* Panel supports more than 8 bits resolution of brightness level */ -+ if (intel_dp->edp_dpcd[2] & DP_EDP_BACKLIGHT_BRIGHTNESS_BYTE_COUNT) -+ return true; + ret = drm_edp_backlight_probe_max(aux, bl, driver_pwm_freq_hz, edp_dpcd); + if (ret < 0) + return ret; + +- ret = drm_edp_backlight_probe_level(aux, bl, current_mode); ++ ret = drm_edp_backlight_probe_state(aux, bl, current_mode); + if (ret < 0) + return ret; + *current_level = ret; + + drm_dbg_kms(aux->drm_dev, +- "%s: Found backlight level=%d/%d pwm_freq_pre_divider=%d mode=%x\n", +- aux->name, *current_level, bl->max, bl->pwm_freq_pre_divider, *current_mode); +- drm_dbg_kms(aux->drm_dev, +- "%s: Backlight caps: pwmgen_bit_count=%d lsb_reg_used=%d aux_enable=%d\n", +- aux->name, bl->pwmgen_bit_count, bl->lsb_reg_used, bl->aux_enable); ++ "%s: Found backlight: aux_set=%d aux_enable=%d mode=%d\n", ++ aux->name, bl->aux_set, bl->aux_enable, *current_mode); ++ if (bl->aux_set) { ++ drm_dbg_kms(aux->drm_dev, ++ "%s: Backlight caps: level=%d/%d pwm_freq_pre_divider=%d lsb_reg_used=%d\n", ++ aux->name, *current_level, bl->max, bl->pwm_freq_pre_divider, ++ bl->lsb_reg_used); ++ } + -+ /* Panel supports enabling backlight via AUX but not by BL_ENABLE pin */ -+ if ((intel_dp->edp_dpcd[1] & DP_EDP_BACKLIGHT_AUX_ENABLE_CAP) && -+ !(intel_dp->edp_dpcd[1] & DP_EDP_BACKLIGHT_PIN_ENABLE_CAP)) -+ return true; + return 0; + } + EXPORT_SYMBOL(drm_edp_backlight_init); +diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c +index 3897468140e0..dc4f30d6ccd8 100644 +--- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c ++++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c +@@ -287,6 +287,12 @@ intel_dp_aux_vesa_set_backlight(const struct drm_connector_state *conn_state, u3 + struct intel_panel *panel = &connector->panel; + struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder); + ++ if (!panel->backlight.edp.vesa.info.aux_set) { ++ const u32 pwm_level = intel_backlight_level_to_pwm(connector, level); + -+ return false; ++ intel_backlight_set_pwm_level(conn_state, pwm_level); ++ } + -+} + drm_edp_backlight_set_level(&intel_dp->aux, &panel->backlight.edp.vesa.info, level); + } + +@@ -299,8 +305,13 @@ intel_dp_aux_vesa_enable_backlight(const struct intel_crtc_state *crtc_state, + struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder); + + if (!panel->backlight.edp.vesa.info.aux_enable) { +- u32 pwm_level = intel_backlight_invert_pwm_level(connector, +- panel->backlight.pwm_level_max); ++ u32 pwm_level; + - static const struct intel_panel_bl_funcs intel_dp_hdr_bl_funcs = { - .setup = intel_dp_aux_hdr_setup_backlight, - .enable = intel_dp_aux_hdr_enable_backlight, -@@ -429,6 +482,10 @@ int intel_dp_aux_init_backlight_funcs(struct intel_connector *connector) - return 0; ++ if (!panel->backlight.edp.vesa.info.aux_set) ++ pwm_level = intel_backlight_level_to_pwm(connector, level); ++ else ++ pwm_level = intel_backlight_invert_pwm_level(connector, ++ panel->backlight.pwm_level_max); + + panel->backlight.pwm_funcs->enable(crtc_state, conn_state, pwm_level); } +@@ -337,7 +348,7 @@ static int intel_dp_aux_vesa_setup_backlight(struct intel_connector *connector, + if (ret < 0) + return ret; -+ if (i915_modparams.enable_dpcd_backlight == -1 && -+ !intel_dp_aux_display_control_heuristic(connector)) -+ return -ENODEV; +- if (!panel->backlight.edp.vesa.info.aux_enable) { ++ if (!panel->backlight.edp.vesa.info.aux_set || !panel->backlight.edp.vesa.info.aux_enable) { + ret = panel->backlight.pwm_funcs->setup(connector, pipe); + if (ret < 0) { + drm_err(&i915->drm, +@@ -346,14 +357,27 @@ static int intel_dp_aux_vesa_setup_backlight(struct intel_connector *connector, + return ret; + } + } +- panel->backlight.max = panel->backlight.edp.vesa.info.max; +- panel->backlight.min = 0; +- if (current_mode == DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD) { +- panel->backlight.level = current_level; +- panel->backlight.enabled = panel->backlight.level != 0; + - if (try_vesa_interface && intel_dp_aux_supports_vesa_backlight(connector)) { - drm_dbg_kms(dev, "Using VESA eDP backlight controls\n"); - panel->backlight.funcs = &intel_dp_vesa_bl_funcs; ++ if (panel->backlight.edp.vesa.info.aux_set) { ++ panel->backlight.max = panel->backlight.edp.vesa.info.max; ++ panel->backlight.min = 0; ++ if (current_mode == DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD) { ++ panel->backlight.level = current_level; ++ panel->backlight.enabled = panel->backlight.level != 0; ++ } else { ++ panel->backlight.level = panel->backlight.max; ++ panel->backlight.enabled = false; ++ } + } else { +- panel->backlight.level = panel->backlight.max; +- panel->backlight.enabled = false; ++ panel->backlight.max = panel->backlight.pwm_level_max; ++ panel->backlight.min = panel->backlight.pwm_level_min; ++ if (current_mode == DP_EDP_BACKLIGHT_CONTROL_MODE_PWM) { ++ panel->backlight.level = panel->backlight.pwm_funcs->get(connector, pipe); ++ panel->backlight.enabled = panel->backlight.pwm_enabled; ++ } else { ++ panel->backlight.level = panel->backlight.max; ++ panel->backlight.enabled = false; ++ } + } + + return 0; +diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h +index 1d5b3dbb6e56..2b12e2b0f372 100644 +--- a/include/drm/drm_dp_helper.h ++++ b/include/drm/drm_dp_helper.h +@@ -1825,7 +1825,7 @@ drm_dp_sink_can_do_video_without_timing_msa(const u8 dpcd[DP_RECEIVER_CAP_SIZE]) + * + * Note that currently this function will return %false for panels which support various DPCD + * backlight features but which require the brightness be set through PWM, and don't support setting +- * the brightness level via the DPCD. This is a TODO. ++ * the brightness level via the DPCD. + * + * Returns: %True if @edp_dpcd indicates that VESA backlight controls are supported, %false + * otherwise +@@ -1833,8 +1833,7 @@ drm_dp_sink_can_do_video_without_timing_msa(const u8 dpcd[DP_RECEIVER_CAP_SIZE]) + static inline bool + drm_edp_backlight_supported(const u8 edp_dpcd[EDP_DISPLAY_CTL_CAP_SIZE]) + { +- return (edp_dpcd[1] & DP_EDP_TCON_BACKLIGHT_ADJUSTMENT_CAP) && +- (edp_dpcd[2] & DP_EDP_BACKLIGHT_BRIGHTNESS_AUX_SET_CAP); ++ return !!(edp_dpcd[1] & DP_EDP_TCON_BACKLIGHT_ADJUSTMENT_CAP); + } + + /* +@@ -2195,6 +2194,7 @@ drm_dp_has_quirk(const struct drm_dp_desc *desc, enum drm_dp_quirk quirk) + * @max: The maximum backlight level that may be set + * @lsb_reg_used: Do we also write values to the DP_EDP_BACKLIGHT_BRIGHTNESS_LSB register? + * @aux_enable: Does the panel support the AUX enable cap? ++ * @aux_set: Does the panel support setting the brightness through AUX? + * + * This structure contains various data about an eDP backlight, which can be populated by using + * drm_edp_backlight_init(). +@@ -2206,6 +2206,7 @@ struct drm_edp_backlight_info { + + bool lsb_reg_used : 1; + bool aux_enable : 1; ++ bool aux_set : 1; + }; + + int -- 2.33.0 -- cgit 1.4.1