summarylogtreecommitdiffstats
path: root/0007-drm-i915-Keep-track-of-pwm-related-backlight-hooks-s.patch
diff options
context:
space:
mode:
authorVasily Khoruzhick2021-01-11 22:10:11 -0800
committerVasily Khoruzhick2021-01-11 22:10:11 -0800
commitea392e3c4019317f897e29fc9404f50205a341f4 (patch)
tree02762ebe39b074894245a10b69fa0e6b99113ca3 /0007-drm-i915-Keep-track-of-pwm-related-backlight-hooks-s.patch
parentb09b02546d3f89f0eac5e468c4a58a61006dbb5d (diff)
downloadaur-linux-oled.tar.gz
Update to 5.10.6
Update patches to v5 version from Lyude
Diffstat (limited to '0007-drm-i915-Keep-track-of-pwm-related-backlight-hooks-s.patch')
-rw-r--r--0007-drm-i915-Keep-track-of-pwm-related-backlight-hooks-s.patch876
1 files changed, 876 insertions, 0 deletions
diff --git a/0007-drm-i915-Keep-track-of-pwm-related-backlight-hooks-s.patch b/0007-drm-i915-Keep-track-of-pwm-related-backlight-hooks-s.patch
new file mode 100644
index 000000000000..2a960d10fa16
--- /dev/null
+++ b/0007-drm-i915-Keep-track-of-pwm-related-backlight-hooks-s.patch
@@ -0,0 +1,876 @@
+From 6ab532a209a7981c5bdaddd9cd31e201d1a59471 Mon Sep 17 00:00:00 2001
+From: Lyude Paul <lyude@redhat.com>
+Date: Thu, 7 Jan 2021 17:52:04 -0500
+Subject: [PATCH 07/10] drm/i915: Keep track of pwm-related backlight hooks
+ separately
+
+Currently, every different type of backlight hook that i915 supports is
+pretty straight forward - you have a backlight, probably through PWM
+(but maybe DPCD), with a single set of platform-specific hooks that are
+used for controlling it.
+
+HDR backlights, in particular VESA and Intel's HDR backlight
+implementations, can end up being more complicated. With Intel's
+proprietary interface, HDR backlight controls always run through the
+DPCD. When the backlight is in SDR backlight mode however, the driver
+may need to bypass the TCON and control the backlight directly through
+PWM.
+
+So, in order to support this we'll need to split our backlight callbacks
+into two groups: a set of high-level backlight control callbacks in
+intel_panel, and an additional set of pwm-specific backlight control
+callbacks. This also implies a functional changes for how these
+callbacks are used:
+
+* We now keep track of two separate backlight level ranges, one for the
+ high-level backlight, and one for the pwm backlight range
+* We also keep track of backlight enablement and PWM backlight
+ enablement separately
+* Since the currently set backlight level might not be the same as the
+ currently programmed PWM backlight level, we stop setting
+ panel->backlight.level with the currently programmed PWM backlight
+ level in panel->backlight.pwm_funcs->setup(). Instead, we rely
+ on the higher level backlight control functions to retrieve the
+ current PWM backlight level (in this case, intel_pwm_get_backlight()).
+ Note that there are still a few PWM backlight setup callbacks that
+ do actually need to retrieve the current PWM backlight level, although
+ we no longer save this value in panel->backlight.level like before.
+
+Additionally, we drop the call to lpt_get_backlight() in
+lpt_setup_backlight(), and avoid unconditionally writing the PWM value that
+we get from it and only write it back if we're in CPU mode, and switching
+to PCH mode. The reason for this is because in the original codepath for
+this, it was expected that the intel_panel_bl_funcs->setup() hook would be
+responsible for fetching the initial backlight level. On lpt systems, the
+only time we could ever be in PCH backlight mode is during the initial
+driver load - meaning that outside of the setup() hook, lpt_get_backlight()
+will always be the callback used for retrieving the current backlight
+level. After this patch we still need to fetch and write-back the PCH
+backlight value if we're switching from CPU mode to PCH, but because
+intel_pwm_setup_backlight() will retrieve the backlight level after setup()
+using the get() hook, which always ends up being lpt_get_backlight(). Thus
+- an additional call to lpt_get_backlight() in lpt_setup_backlight() is
+made redundant.
+
+v5:
+* Fix indenting warnings from checkpatch
+v4:
+* Fix commit message
+* Remove outdated comment in intel_panel.c
+* Rename pwm_(min|max) to pwm_level_(min|max)
+* Use intel_pwm_get_backlight() in intel_pwm_setup_backlight() instead of
+ indirection
+* Don't move intel_dp_aux_init_bcklight_funcs() call to bottom of
+ intel_panel_init_backlight_funcs() quite yet
+v3:
+* Reuse intel_panel_bl_funcs() for pwm_funcs
+* Explain why we drop lpt_get_backlight()
+
+Signed-off-by: Lyude Paul <lyude@redhat.com>
+Cc: thaytan@noraisin.net
+Cc: Vasily Khoruzhick <anarsoul@gmail.com>
+---
+ .../drm/i915/display/intel_display_types.h | 4 +
+ drivers/gpu/drm/i915/display/intel_panel.c | 333 ++++++++++--------
+ 2 files changed, 187 insertions(+), 150 deletions(-)
+
+diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
+index 6dd8f26ec3c9..1abdcc3f91b2 100644
+--- a/drivers/gpu/drm/i915/display/intel_display_types.h
++++ b/drivers/gpu/drm/i915/display/intel_display_types.h
+@@ -232,6 +232,9 @@ struct intel_panel {
+ bool alternate_pwm_increment; /* lpt+ */
+
+ /* PWM chip */
++ u32 pwm_level_min;
++ u32 pwm_level_max;
++ bool pwm_enabled;
+ bool util_pin_active_low; /* bxt+ */
+ u8 controller; /* bxt+ only */
+ struct pwm_device *pwm;
+@@ -243,6 +246,7 @@ struct intel_panel {
+ struct backlight_device *device;
+
+ const struct intel_panel_bl_funcs *funcs;
++ const struct intel_panel_bl_funcs *pwm_funcs;
+ void (*power)(struct intel_connector *, bool enable);
+ } backlight;
+ };
+diff --git a/drivers/gpu/drm/i915/display/intel_panel.c b/drivers/gpu/drm/i915/display/intel_panel.c
+index 67f81ae995c4..8c99bf404a32 100644
+--- a/drivers/gpu/drm/i915/display/intel_panel.c
++++ b/drivers/gpu/drm/i915/display/intel_panel.c
+@@ -511,25 +511,34 @@ static u32 scale_hw_to_user(struct intel_connector *connector,
+ 0, user_max);
+ }
+
+-static u32 intel_panel_compute_brightness(struct intel_connector *connector,
+- u32 val)
++static u32 intel_panel_sanitize_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.max == 0);
++ 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.max - val + panel->backlight.min;
++ return panel->backlight.pwm_level_max - val + panel->backlight.pwm_level_min;
+ }
+
+ return val;
+ }
+
++static 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);
++}
++
+ static u32 lpt_get_backlight(struct intel_connector *connector)
+ {
+ struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+@@ -624,12 +633,12 @@ static void i9xx_set_backlight(const struct drm_connector_state *conn_state, u32
+ struct intel_panel *panel = &connector->panel;
+ u32 tmp, mask;
+
+- drm_WARN_ON(&dev_priv->drm, panel->backlight.max == 0);
++ drm_WARN_ON(&dev_priv->drm, panel->backlight.pwm_level_max == 0);
+
+ if (panel->backlight.combination_mode) {
+ u8 lbpc;
+
+- lbpc = level * 0xfe / panel->backlight.max + 1;
++ lbpc = level * 0xfe / panel->backlight.pwm_level_max + 1;
+ level /= lbpc;
+ pci_write_config_byte(dev_priv->drm.pdev, LBPC, lbpc);
+ }
+@@ -681,9 +690,8 @@ intel_panel_actually_set_backlight(const struct drm_connector_state *conn_state,
+ 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", level);
++ drm_dbg_kms(&i915->drm, "set backlight level = %d\n", level);
+
+- level = intel_panel_compute_brightness(connector, level);
+ panel->backlight.funcs->set(conn_state, level);
+ }
+
+@@ -732,7 +740,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_actually_set_backlight(old_conn_state, level);
++ intel_panel_set_pwm_level(old_conn_state, level);
+
+ /*
+ * Although we don't support or enable CPU PWM with LPT/SPT based
+@@ -760,7 +768,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_actually_set_backlight(old_conn_state, val);
++ 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);
+@@ -771,7 +779,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_actually_set_backlight(old_conn_state, 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)
+@@ -779,7 +787,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_actually_set_backlight(old_conn_state, val);
++ 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);
+@@ -792,7 +800,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_actually_set_backlight(old_conn_state, val);
++ 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),
+@@ -806,7 +814,7 @@ static void bxt_disable_backlight(const struct drm_connector_state *old_conn_sta
+ struct intel_panel *panel = &connector->panel;
+ u32 tmp;
+
+- intel_panel_actually_set_backlight(old_conn_state, val);
++ intel_panel_set_pwm_level(old_conn_state, val);
+
+ tmp = intel_de_read(dev_priv,
+ BXT_BLC_PWM_CTL(panel->backlight.controller));
+@@ -827,7 +835,7 @@ static void cnp_disable_backlight(const struct drm_connector_state *old_conn_sta
+ struct intel_panel *panel = &connector->panel;
+ u32 tmp;
+
+- intel_panel_actually_set_backlight(old_conn_state, val);
++ intel_panel_set_pwm_level(old_conn_state, val);
+
+ tmp = intel_de_read(dev_priv,
+ BXT_BLC_PWM_CTL(panel->backlight.controller));
+@@ -906,7 +914,7 @@ static void lpt_enable_backlight(const struct intel_crtc_state *crtc_state,
+ intel_de_write(dev_priv, SOUTH_CHICKEN1, schicken);
+ }
+
+- pch_ctl2 = panel->backlight.max << 16;
++ pch_ctl2 = panel->backlight.pwm_level_max << 16;
+ intel_de_write(dev_priv, BLC_PWM_PCH_CTL2, pch_ctl2);
+
+ pch_ctl1 = 0;
+@@ -923,7 +931,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_actually_set_backlight(conn_state, level);
++ intel_panel_set_pwm_level(conn_state, level);
+ }
+
+ static void pch_enable_backlight(const struct intel_crtc_state *crtc_state,
+@@ -958,9 +966,9 @@ 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_actually_set_backlight(conn_state, level);
++ intel_panel_set_pwm_level(conn_state, level);
+
+- pch_ctl2 = panel->backlight.max << 16;
++ pch_ctl2 = panel->backlight.pwm_level_max << 16;
+ intel_de_write(dev_priv, BLC_PWM_PCH_CTL2, pch_ctl2);
+
+ pch_ctl1 = 0;
+@@ -987,7 +995,7 @@ static void i9xx_enable_backlight(const struct intel_crtc_state *crtc_state,
+ intel_de_write(dev_priv, BLC_PWM_CTL, 0);
+ }
+
+- freq = panel->backlight.max;
++ freq = panel->backlight.pwm_level_max;
+ if (panel->backlight.combination_mode)
+ freq /= 0xff;
+
+@@ -1001,7 +1009,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_actually_set_backlight(conn_state, level);
++ intel_panel_set_pwm_level(conn_state, level);
+
+ /*
+ * Needed to enable backlight on some 855gm models. BLC_HIST_CTL is
+@@ -1028,7 +1036,7 @@ static void i965_enable_backlight(const struct intel_crtc_state *crtc_state,
+ intel_de_write(dev_priv, BLC_PWM_CTL2, ctl2);
+ }
+
+- freq = panel->backlight.max;
++ freq = panel->backlight.pwm_level_max;
+ if (panel->backlight.combination_mode)
+ freq /= 0xff;
+
+@@ -1044,7 +1052,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_actually_set_backlight(conn_state, level);
++ intel_panel_set_pwm_level(conn_state, level);
+ }
+
+ static void vlv_enable_backlight(const struct intel_crtc_state *crtc_state,
+@@ -1063,11 +1071,11 @@ static void vlv_enable_backlight(const struct intel_crtc_state *crtc_state,
+ intel_de_write(dev_priv, VLV_BLC_PWM_CTL2(pipe), ctl2);
+ }
+
+- ctl = panel->backlight.max << 16;
++ 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_actually_set_backlight(conn_state, level);
++ intel_panel_set_pwm_level(conn_state, level);
+
+ ctl2 = 0;
+ if (panel->backlight.active_low_pwm)
+@@ -1116,9 +1124,9 @@ static void bxt_enable_backlight(const struct intel_crtc_state *crtc_state,
+
+ intel_de_write(dev_priv,
+ BXT_BLC_PWM_FREQ(panel->backlight.controller),
+- panel->backlight.max);
++ panel->backlight.pwm_level_max);
+
+- intel_panel_actually_set_backlight(conn_state, level);
++ intel_panel_set_pwm_level(conn_state, level);
+
+ pwm_ctl = 0;
+ if (panel->backlight.active_low_pwm)
+@@ -1152,9 +1160,9 @@ static void cnp_enable_backlight(const struct intel_crtc_state *crtc_state,
+
+ intel_de_write(dev_priv,
+ BXT_BLC_PWM_FREQ(panel->backlight.controller),
+- panel->backlight.max);
++ panel->backlight.pwm_level_max);
+
+- intel_panel_actually_set_backlight(conn_state, level);
++ intel_panel_set_pwm_level(conn_state, level);
+
+ pwm_ctl = 0;
+ if (panel->backlight.active_low_pwm)
+@@ -1174,7 +1182,6 @@ static void ext_pwm_enable_backlight(const struct intel_crtc_state *crtc_state,
+ struct intel_connector *connector = to_intel_connector(conn_state->connector);
+ struct intel_panel *panel = &connector->panel;
+
+- level = intel_panel_compute_brightness(connector, level);
+ 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);
+@@ -1232,10 +1239,8 @@ static u32 intel_panel_get_backlight(struct intel_connector *connector)
+
+ mutex_lock(&dev_priv->backlight_lock);
+
+- if (panel->backlight.enabled) {
++ if (panel->backlight.enabled)
+ val = panel->backlight.funcs->get(connector);
+- val = intel_panel_compute_brightness(connector, val);
+- }
+
+ mutex_unlock(&dev_priv->backlight_lock);
+
+@@ -1566,13 +1571,13 @@ static u32 get_backlight_max_vbt(struct intel_connector *connector)
+ u16 pwm_freq_hz = get_vbt_pwm_freq(dev_priv);
+ u32 pwm;
+
+- if (!panel->backlight.funcs->hz_to_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.funcs->hz_to_pwm(connector, pwm_freq_hz);
++ 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");
+@@ -1591,7 +1596,7 @@ static u32 get_backlight_min_vbt(struct intel_connector *connector)
+ struct intel_panel *panel = &connector->panel;
+ int min;
+
+- drm_WARN_ON(&dev_priv->drm, panel->backlight.max == 0);
++ 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
+@@ -1608,7 +1613,7 @@ static u32 get_backlight_min_vbt(struct intel_connector *connector)
+ }
+
+ /* vbt value is a coefficient in range [0..255] */
+- return scale(min, 0, 255, 0, panel->backlight.max);
++ return scale(min, 0, 255, 0, panel->backlight.pwm_level_max);
+ }
+
+ static int lpt_setup_backlight(struct intel_connector *connector, enum pipe unused)
+@@ -1628,37 +1633,32 @@ static int lpt_setup_backlight(struct intel_connector *connector, enum pipe unus
+ panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY;
+
+ pch_ctl2 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL2);
+- panel->backlight.max = pch_ctl2 >> 16;
++ panel->backlight.pwm_level_max = pch_ctl2 >> 16;
+
+ cpu_ctl2 = intel_de_read(dev_priv, BLC_PWM_CPU_CTL2);
+
+- if (!panel->backlight.max)
+- panel->backlight.max = get_backlight_max_vbt(connector);
++ if (!panel->backlight.pwm_level_max)
++ panel->backlight.pwm_level_max = get_backlight_max_vbt(connector);
+
+- if (!panel->backlight.max)
++ if (!panel->backlight.pwm_level_max)
+ return -ENODEV;
+
+- panel->backlight.min = get_backlight_min_vbt(connector);
++ panel->backlight.pwm_level_min = get_backlight_min_vbt(connector);
+
+- panel->backlight.enabled = pch_ctl1 & BLM_PCH_PWM_ENABLE;
++ panel->backlight.pwm_enabled = pch_ctl1 & BLM_PCH_PWM_ENABLE;
+
+- cpu_mode = panel->backlight.enabled && HAS_PCH_LPT(dev_priv) &&
++ 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);
+- else
+- val = lpt_get_backlight(connector);
+- val = intel_panel_compute_brightness(connector, val);
+- panel->backlight.level = clamp(val, panel->backlight.min,
+- panel->backlight.max);
+
+ if (cpu_mode) {
++ val = intel_panel_sanitize_pwm_level(connector, pch_get_backlight(connector));
++
+ 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, panel->backlight.level);
++ lpt_set_backlight(connector->base.state, val);
+ intel_de_write(dev_priv, BLC_PWM_PCH_CTL1,
+ pch_ctl1 | BLM_PCH_OVERRIDE_ENABLE);
+
+@@ -1673,29 +1673,24 @@ static int pch_setup_backlight(struct intel_connector *connector, enum pipe unus
+ {
+ 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;
++ 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.max = pch_ctl2 >> 16;
++ panel->backlight.pwm_level_max = pch_ctl2 >> 16;
+
+- if (!panel->backlight.max)
+- panel->backlight.max = get_backlight_max_vbt(connector);
++ if (!panel->backlight.pwm_level_max)
++ panel->backlight.pwm_level_max = get_backlight_max_vbt(connector);
+
+- if (!panel->backlight.max)
++ if (!panel->backlight.pwm_level_max)
+ return -ENODEV;
+
+- panel->backlight.min = get_backlight_min_vbt(connector);
+-
+- val = pch_get_backlight(connector);
+- val = intel_panel_compute_brightness(connector, val);
+- panel->backlight.level = clamp(val, panel->backlight.min,
+- panel->backlight.max);
++ panel->backlight.pwm_level_min = get_backlight_min_vbt(connector);
+
+ cpu_ctl2 = intel_de_read(dev_priv, BLC_PWM_CPU_CTL2);
+- panel->backlight.enabled = (cpu_ctl2 & BLM_PWM_ENABLE) &&
++ panel->backlight.pwm_enabled = (cpu_ctl2 & BLM_PWM_ENABLE) &&
+ (pch_ctl1 & BLM_PCH_PWM_ENABLE);
+
+ return 0;
+@@ -1715,27 +1710,26 @@ static int i9xx_setup_backlight(struct intel_connector *connector, enum pipe unu
+ if (IS_PINEVIEW(dev_priv))
+ panel->backlight.active_low_pwm = ctl & BLM_POLARITY_PNV;
+
+- panel->backlight.max = ctl >> 17;
++ panel->backlight.pwm_level_max = ctl >> 17;
+
+- if (!panel->backlight.max) {
+- panel->backlight.max = get_backlight_max_vbt(connector);
+- panel->backlight.max >>= 1;
++ 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.max)
++ if (!panel->backlight.pwm_level_max)
+ return -ENODEV;
+
+ if (panel->backlight.combination_mode)
+- panel->backlight.max *= 0xff;
++ panel->backlight.pwm_level_max *= 0xff;
+
+- panel->backlight.min = get_backlight_min_vbt(connector);
++ panel->backlight.pwm_level_min = get_backlight_min_vbt(connector);
+
+ val = i9xx_get_backlight(connector);
+- val = intel_panel_compute_brightness(connector, val);
+- panel->backlight.level = clamp(val, panel->backlight.min,
+- panel->backlight.max);
++ val = intel_panel_sanitize_pwm_level(connector, val);
++ val = clamp(val, panel->backlight.pwm_level_min, panel->backlight.pwm_level_max);
+
+- panel->backlight.enabled = val != 0;
++ panel->backlight.pwm_enabled = val != 0;
+
+ return 0;
+ }
+@@ -1744,32 +1738,27 @@ static int i965_setup_backlight(struct intel_connector *connector, enum pipe unu
+ {
+ struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+ struct intel_panel *panel = &connector->panel;
+- u32 ctl, ctl2, val;
++ 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.max = ctl >> 16;
++ panel->backlight.pwm_level_max = ctl >> 16;
+
+- if (!panel->backlight.max)
+- panel->backlight.max = get_backlight_max_vbt(connector);
++ if (!panel->backlight.pwm_level_max)
++ panel->backlight.pwm_level_max = get_backlight_max_vbt(connector);
+
+- if (!panel->backlight.max)
++ if (!panel->backlight.pwm_level_max)
+ return -ENODEV;
+
+ if (panel->backlight.combination_mode)
+- panel->backlight.max *= 0xff;
+-
+- panel->backlight.min = get_backlight_min_vbt(connector);
++ panel->backlight.pwm_level_max *= 0xff;
+
+- val = i9xx_get_backlight(connector);
+- val = intel_panel_compute_brightness(connector, val);
+- panel->backlight.level = clamp(val, panel->backlight.min,
+- panel->backlight.max);
++ panel->backlight.pwm_level_min = get_backlight_min_vbt(connector);
+
+- panel->backlight.enabled = ctl2 & BLM_PWM_ENABLE;
++ panel->backlight.pwm_enabled = ctl2 & BLM_PWM_ENABLE;
+
+ return 0;
+ }
+@@ -1778,7 +1767,7 @@ 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, val;
++ u32 ctl, ctl2;
+
+ if (drm_WARN_ON(&dev_priv->drm, pipe != PIPE_A && pipe != PIPE_B))
+ return -ENODEV;
+@@ -1787,22 +1776,17 @@ static int vlv_setup_backlight(struct intel_connector *connector, enum pipe pipe
+ panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965;
+
+ ctl = intel_de_read(dev_priv, VLV_BLC_PWM_CTL(pipe));
+- panel->backlight.max = ctl >> 16;
++ panel->backlight.pwm_level_max = ctl >> 16;
+
+- if (!panel->backlight.max)
+- panel->backlight.max = get_backlight_max_vbt(connector);
++ if (!panel->backlight.pwm_level_max)
++ panel->backlight.pwm_level_max = get_backlight_max_vbt(connector);
+
+- if (!panel->backlight.max)
++ if (!panel->backlight.pwm_level_max)
+ return -ENODEV;
+
+- panel->backlight.min = get_backlight_min_vbt(connector);
++ panel->backlight.pwm_level_min = get_backlight_min_vbt(connector);
+
+- val = _vlv_get_backlight(dev_priv, pipe);
+- val = intel_panel_compute_brightness(connector, val);
+- panel->backlight.level = clamp(val, panel->backlight.min,
+- panel->backlight.max);
+-
+- panel->backlight.enabled = ctl2 & BLM_PWM_ENABLE;
++ panel->backlight.pwm_enabled = ctl2 & BLM_PWM_ENABLE;
+
+ return 0;
+ }
+@@ -1827,24 +1811,18 @@ bxt_setup_backlight(struct intel_connector *connector, enum pipe unused)
+ }
+
+ panel->backlight.active_low_pwm = pwm_ctl & BXT_BLC_PWM_POLARITY;
+- panel->backlight.max =
+- intel_de_read(dev_priv,
+- BXT_BLC_PWM_FREQ(panel->backlight.controller));
++ panel->backlight.pwm_level_max =
++ intel_de_read(dev_priv, BXT_BLC_PWM_FREQ(panel->backlight.controller));
+
+- if (!panel->backlight.max)
+- panel->backlight.max = get_backlight_max_vbt(connector);
++ if (!panel->backlight.pwm_level_max)
++ panel->backlight.pwm_level_max = get_backlight_max_vbt(connector);
+
+- if (!panel->backlight.max)
++ if (!panel->backlight.pwm_level_max)
+ return -ENODEV;
+
+- panel->backlight.min = get_backlight_min_vbt(connector);
+-
+- val = bxt_get_backlight(connector);
+- val = intel_panel_compute_brightness(connector, val);
+- panel->backlight.level = clamp(val, panel->backlight.min,
+- panel->backlight.max);
++ panel->backlight.pwm_level_min = get_backlight_min_vbt(connector);
+
+- panel->backlight.enabled = pwm_ctl & BXT_BLC_PWM_ENABLE;
++ panel->backlight.pwm_enabled = pwm_ctl & BXT_BLC_PWM_ENABLE;
+
+ return 0;
+ }
+@@ -1854,7 +1832,7 @@ 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, val;
++ u32 pwm_ctl;
+
+ /*
+ * CNP has the BXT implementation of backlight, but with only one
+@@ -1867,24 +1845,18 @@ cnp_setup_backlight(struct intel_connector *connector, enum pipe unused)
+ BXT_BLC_PWM_CTL(panel->backlight.controller));
+
+ panel->backlight.active_low_pwm = pwm_ctl & BXT_BLC_PWM_POLARITY;
+- panel->backlight.max =
+- intel_de_read(dev_priv,
+- BXT_BLC_PWM_FREQ(panel->backlight.controller));
++ panel->backlight.pwm_level_max =
++ intel_de_read(dev_priv, BXT_BLC_PWM_FREQ(panel->backlight.controller));
+
+- if (!panel->backlight.max)
+- panel->backlight.max = get_backlight_max_vbt(connector);
++ if (!panel->backlight.pwm_level_max)
++ panel->backlight.pwm_level_max = get_backlight_max_vbt(connector);
+
+- if (!panel->backlight.max)
++ if (!panel->backlight.pwm_level_max)
+ return -ENODEV;
+
+- panel->backlight.min = get_backlight_min_vbt(connector);
++ panel->backlight.pwm_level_min = get_backlight_min_vbt(connector);
+
+- val = bxt_get_backlight(connector);
+- val = intel_panel_compute_brightness(connector, val);
+- panel->backlight.level = clamp(val, panel->backlight.min,
+- panel->backlight.max);
+-
+- panel->backlight.enabled = pwm_ctl & BXT_BLC_PWM_ENABLE;
++ panel->backlight.pwm_enabled = pwm_ctl & BXT_BLC_PWM_ENABLE;
+
+ return 0;
+ }
+@@ -1914,8 +1886,8 @@ static int ext_pwm_setup_backlight(struct intel_connector *connector,
+ return -ENODEV;
+ }
+
+- panel->backlight.max = 100; /* 100% */
+- panel->backlight.min = get_backlight_min_vbt(connector);
++ 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 */
+@@ -1923,10 +1895,8 @@ static int ext_pwm_setup_backlight(struct intel_connector *connector,
+
+ level = pwm_get_relative_duty_cycle(&panel->backlight.pwm_state,
+ 100);
+- level = intel_panel_compute_brightness(connector, level);
+- panel->backlight.level = clamp(level, panel->backlight.min,
+- panel->backlight.max);
+- panel->backlight.enabled = true;
++ level = intel_panel_sanitize_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,
+@@ -1942,6 +1912,58 @@ static int ext_pwm_setup_backlight(struct intel_connector *connector,
+ 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_sanitize_pwm_level(connector, level));
++}
++
++static u32 intel_pwm_get_backlight(struct intel_connector *connector)
++{
++ struct intel_panel *panel = &connector->panel;
++
++ return intel_panel_sanitize_pwm_level(connector,
++ panel->backlight.pwm_funcs->get(connector));
++}
++
++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_sanitize_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_sanitize_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);
++ 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,
+@@ -2015,7 +2037,7 @@ static void intel_panel_destroy_backlight(struct intel_panel *panel)
+ panel->backlight.present = false;
+ }
+
+-static const struct intel_panel_bl_funcs bxt_funcs = {
++static const struct intel_panel_bl_funcs bxt_pwm_funcs = {
+ .setup = bxt_setup_backlight,
+ .enable = bxt_enable_backlight,
+ .disable = bxt_disable_backlight,
+@@ -2024,7 +2046,7 @@ static const struct intel_panel_bl_funcs bxt_funcs = {
+ .hz_to_pwm = bxt_hz_to_pwm,
+ };
+
+-static const struct intel_panel_bl_funcs cnp_funcs = {
++static const struct intel_panel_bl_funcs cnp_pwm_funcs = {
+ .setup = cnp_setup_backlight,
+ .enable = cnp_enable_backlight,
+ .disable = cnp_disable_backlight,
+@@ -2033,7 +2055,7 @@ static const struct intel_panel_bl_funcs cnp_funcs = {
+ .hz_to_pwm = cnp_hz_to_pwm,
+ };
+
+-static const struct intel_panel_bl_funcs lpt_funcs = {
++static const struct intel_panel_bl_funcs lpt_pwm_funcs = {
+ .setup = lpt_setup_backlight,
+ .enable = lpt_enable_backlight,
+ .disable = lpt_disable_backlight,
+@@ -2042,7 +2064,7 @@ static const struct intel_panel_bl_funcs lpt_funcs = {
+ .hz_to_pwm = lpt_hz_to_pwm,
+ };
+
+-static const struct intel_panel_bl_funcs spt_funcs = {
++static const struct intel_panel_bl_funcs spt_pwm_funcs = {
+ .setup = lpt_setup_backlight,
+ .enable = lpt_enable_backlight,
+ .disable = lpt_disable_backlight,
+@@ -2051,7 +2073,7 @@ static const struct intel_panel_bl_funcs spt_funcs = {
+ .hz_to_pwm = spt_hz_to_pwm,
+ };
+
+-static const struct intel_panel_bl_funcs pch_funcs = {
++static const struct intel_panel_bl_funcs pch_pwm_funcs = {
+ .setup = pch_setup_backlight,
+ .enable = pch_enable_backlight,
+ .disable = pch_disable_backlight,
+@@ -2068,7 +2090,7 @@ static const struct intel_panel_bl_funcs ext_pwm_funcs = {
+ .get = ext_pwm_get_backlight,
+ };
+
+-static const struct intel_panel_bl_funcs vlv_funcs = {
++static const struct intel_panel_bl_funcs vlv_pwm_funcs = {
+ .setup = vlv_setup_backlight,
+ .enable = vlv_enable_backlight,
+ .disable = vlv_disable_backlight,
+@@ -2077,7 +2099,7 @@ static const struct intel_panel_bl_funcs vlv_funcs = {
+ .hz_to_pwm = vlv_hz_to_pwm,
+ };
+
+-static const struct intel_panel_bl_funcs i965_funcs = {
++static const struct intel_panel_bl_funcs i965_pwm_funcs = {
+ .setup = i965_setup_backlight,
+ .enable = i965_enable_backlight,
+ .disable = i965_disable_backlight,
+@@ -2086,7 +2108,7 @@ static const struct intel_panel_bl_funcs i965_funcs = {
+ .hz_to_pwm = i965_hz_to_pwm,
+ };
+
+-static const struct intel_panel_bl_funcs i9xx_funcs = {
++static const struct intel_panel_bl_funcs i9xx_pwm_funcs = {
+ .setup = i9xx_setup_backlight,
+ .enable = i9xx_enable_backlight,
+ .disable = i9xx_disable_backlight,
+@@ -2095,6 +2117,14 @@ static const struct intel_panel_bl_funcs i9xx_funcs = {
+ .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)
+@@ -2112,27 +2142,30 @@ intel_panel_init_backlight_funcs(struct intel_panel *panel)
+ return;
+
+ if (IS_GEN9_LP(dev_priv)) {
+- panel->backlight.funcs = &bxt_funcs;
++ panel->backlight.pwm_funcs = &bxt_pwm_funcs;
+ } else if (INTEL_PCH_TYPE(dev_priv) >= PCH_CNP) {
+- panel->backlight.funcs = &cnp_funcs;
++ panel->backlight.pwm_funcs = &cnp_pwm_funcs;
+ } else if (INTEL_PCH_TYPE(dev_priv) >= PCH_LPT) {
+ if (HAS_PCH_LPT(dev_priv))
+- panel->backlight.funcs = &lpt_funcs;
++ panel->backlight.pwm_funcs = &lpt_pwm_funcs;
+ else
+- panel->backlight.funcs = &spt_funcs;
++ panel->backlight.pwm_funcs = &spt_pwm_funcs;
+ } else if (HAS_PCH_SPLIT(dev_priv)) {
+- panel->backlight.funcs = &pch_funcs;
++ 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.funcs = &ext_pwm_funcs;
++ panel->backlight.pwm_funcs = &ext_pwm_funcs;
+ } else {
+- panel->backlight.funcs = &vlv_funcs;
++ panel->backlight.pwm_funcs = &vlv_pwm_funcs;
+ }
+ } else if (IS_GEN(dev_priv, 4)) {
+- panel->backlight.funcs = &i965_funcs;
++ panel->backlight.pwm_funcs = &i965_pwm_funcs;
+ } else {
+- panel->backlight.funcs = &i9xx_funcs;
++ panel->backlight.pwm_funcs = &i9xx_pwm_funcs;
+ }
++
++ /* We're using a standard PWM backlight interface */
++ panel->backlight.funcs = &pwm_bl_funcs;
+ }
+
+ enum drm_connector_status
+--
+2.29.2
+