about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--overlays/patches/linux/eve-backlight.patch3963
1 files changed, 3840 insertions, 123 deletions
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 <hi@alyssa.is>
-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 <jani.nikula@intel.com>
+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 <lyude@redhat.com>
+Reviewed-by: Lyude Paul <lyude@redhat.com>
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+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 <drm/drm_mipi_dsi.h>
+ 
+ #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 <airlied@linux.ie>
+- *
+- * 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 <eric@anholt.net>
+- *      Dave Airlie <airlied@linux.ie>
+- *      Jesse Barnes <jesse.barnes@intel.com>
+- *      Chris Wilson <chris@chris-wilson.co.uk>
++ * Copyright © 2021 Intel Corporation
+  */
+ 
+-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+-
+ #include <linux/kernel.h>
+-#include <linux/moduleparam.h>
+ #include <linux/pwm.h>
+ 
++#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 <linux/types.h>
+ 
+-#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 <drm/drm_atomic_helper.h>
+ #include <drm/drm_edid.h>
+ 
+-#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 <linux/firmware.h>
+ #include <acpi/video.h>
+ 
+-#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 <chris@chris-wilson.co.uk>
+  */
+ 
+-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+-
+ #include <linux/kernel.h>
+-#include <linux/moduleparam.h>
+ #include <linux/pwm.h>
+ 
++#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 <linux/types.h>
+ 
+-#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 <jani.nikula@intel.com>
+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 <lyude@redhat.com>
+Reviewed-by: Lyude Paul <lyude@redhat.com>
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+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 <linux/types.h>
+ 
+-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 <lyude@redhat.com>
+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 <lyude@redhat.com>
+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ä <ville.syrjala@linux.intel.com>
+Cc: <stable@vger.kernel.org> # 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 <chowski@google.com>
-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 <chowski@google.com>
-Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/2344844
-Reviewed-by: Puthikorn Voravootivat <puthik@chromium.org>
-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 <groeck@chromium.org>
-(cherry picked from commit 37af4b996c1e25b7be4a00e5c5bcf29bc37cd51a)
+From 80bfbd23a11bd193d0eb2be3af5be61fb298fc7d Mon Sep 17 00:00:00 2001
+From: Lyude Paul <lyude@redhat.com>
+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 <lyude@redhat.com>
+Fixes: 867cf9cd73c3 ("drm/dp: Extract i915's eDP backlight code into DRM helpers")
+Reviewed-by: Douglas Anderson <dianders@chromium.org>
+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 <lyude@redhat.com>
+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 <lyude@redhat.com>
+Reviewed-by: Doug Anderson <dianders@chromium.org>
+Cc: Rajeev Nandan <rajeevny@codeaurora.org>
+Cc: Satadru Pramanik <satadru@gmail.com>
+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,
-+			      &reg_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