On Wed, Jun 20, 2012 at 03:12:35PM -0700, St?phane Marchesin wrote: > This is an initial implementation of i915 adaptive backlight support. > The intended use for the adaptive backlight is to generate interrupts > whenever the luminance of the screen changes by some thresholds. The > main caveat with that implementation is that those additional > interrupts will wake up the CPU and consume more power. Instead, we > hook into the vblank handler and handle it from there. This makes the > implementation a little less intuitive but a lot more efficient. > We also need to compute the gamma correction from the interrupt > handler so we do this with a (new) fixed point module. > > Change-Id: I9b9631cacc7d90e2801a542a3789118521bc25f0 > Signed-off-by: St?phane Marchesin <marcheu at chromium.org> A few quick comments: - I don't like setparam for this too much. Imo exposing this as an lvds/eDP connector property makes more sense, and also makes the feature more accessible to mere mortals. btw I think we should do the same with the downclock stuff and expose a panel_downclock_freq plus a panel_downclock enable which is simply initialized at driver load time with the defaults, but could be freely changed afterwards. - With connector properties we could also expose tuneables in an easy way, at least partially addressing Jani's comment (like the display gamma and maybe also other parameters). - We need to somehow cope with front-rendering X. Yeah, I know this sucks and all, but such is life. We already mark framebuffers as busys when rendering into them directly, I guess we could hook into to that either disable this feature until the next pageflip. Or switch to a different mode. The disable needs to be gradually, obviously. - I'm unsure whether we shouldn't move the fixed-point stuff to a common place. Wrt all the fixed-point constant I think a little macro to convert double to 16.16 fixed point would massively help code readability. Yours, Daniel > --- > drivers/gpu/drm/i915/Makefile | 1 + > drivers/gpu/drm/i915/i915_dma.c | 16 ++ > drivers/gpu/drm/i915/i915_drv.h | 10 + > drivers/gpu/drm/i915/i915_irq.c | 8 +- > drivers/gpu/drm/i915/i915_reg.h | 22 ++ > drivers/gpu/drm/i915/intel_adaptive_backlight.c | 266 +++++++++++++++++++++++ > drivers/gpu/drm/i915/intel_fixedpoint.h | 140 ++++++++++++ > drivers/gpu/drm/i915/intel_panel.c | 6 + > include/drm/i915_drm.h | 2 + > 9 files changed, 469 insertions(+), 2 deletions(-) > create mode 100644 drivers/gpu/drm/i915/intel_adaptive_backlight.c > create mode 100644 drivers/gpu/drm/i915/intel_fixedpoint.h > > diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile > index ce7fc77..5c125c3 100644 > --- a/drivers/gpu/drm/i915/Makefile > +++ b/drivers/gpu/drm/i915/Makefile > @@ -13,6 +13,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o \ > i915_gem_gtt.o \ > i915_gem_tiling.o \ > i915_trace_points.o \ > + intel_adaptive_backlight.o \ > intel_display.o \ > intel_crt.o \ > intel_lvds.o \ > diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c > index ba60f3c..c2626d6 100644 > --- a/drivers/gpu/drm/i915/i915_dma.c > +++ b/drivers/gpu/drm/i915/i915_dma.c > @@ -828,6 +828,22 @@ static int i915_setparam(struct drm_device *dev, void *data, > /* Userspace can use first N regs */ > dev_priv->fence_reg_start = param->value; > break; > + case I915_SETPARAM_ADAPTIVE_BACKLIGHT_ENABLE: > + if (INTEL_INFO(dev)->gen == 6) { > + dev_priv->adaptive_backlight_enabled = param->value; > + } else { > + DRM_ERROR("No adaptive backlight on !GEN6\n"); > + return -EINVAL; > + } > + break; > + case I915_SETPARAM_PANEL_GAMMA: > + if (INTEL_INFO(dev)->gen == 6) { > + dev_priv->adaptive_backlight_panel_gamma = param->value; > + } else { > + DRM_ERROR("No adaptive backlight on !GEN6\n"); > + return -EINVAL; > + } > + break; > default: > DRM_DEBUG_DRIVER("unknown parameter %d\n", > param->param); > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h > index d89f585..f778f93 100644 > --- a/drivers/gpu/drm/i915/i915_drv.h > +++ b/drivers/gpu/drm/i915/i915_drv.h > @@ -401,6 +401,13 @@ typedef struct drm_i915_private { > struct drm_display_mode *lfp_lvds_vbt_mode; /* if any */ > struct drm_display_mode *sdvo_lvds_vbt_mode; /* if any */ > > + /* Adaptive backlight */ > + bool adaptive_backlight_enabled; > + int backlight_correction_level; > + int backlight_correction_count; > + int backlight_correction_direction; > + int adaptive_backlight_panel_gamma; > + > /* Feature bits from the VBIOS */ > unsigned int int_tv_support:1; > unsigned int lvds_dither:1; > @@ -1358,6 +1365,9 @@ extern int i915_restore_state(struct drm_device *dev); > extern int i915_save_state(struct drm_device *dev); > extern int i915_restore_state(struct drm_device *dev); > > +/* intel_adaptive_backlight.c */ > +extern void intel_adaptive_backlight(struct drm_device *dev, int pipe); > + > /* intel_i2c.c */ > extern int intel_setup_gmbus(struct drm_device *dev); > extern void intel_teardown_gmbus(struct drm_device *dev); > diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c > index afd4e03..948da6b 100644 > --- a/drivers/gpu/drm/i915/i915_irq.c > +++ b/drivers/gpu/drm/i915/i915_irq.c > @@ -619,11 +619,15 @@ static irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS) > intel_finish_page_flip_plane(dev, 1); > } > > - if (de_iir & DE_PIPEA_VBLANK) > + if (de_iir & DE_PIPEA_VBLANK) { > drm_handle_vblank(dev, 0); > + intel_adaptive_backlight(dev, 0); > + } > > - if (de_iir & DE_PIPEB_VBLANK) > + if (de_iir & DE_PIPEB_VBLANK) { > drm_handle_vblank(dev, 1); > + intel_adaptive_backlight(dev, 1); > + } > > /* check event from PCH */ > if (de_iir & DE_PCH_EVENT) { > diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h > index 552264c..2db874d 100644 > --- a/drivers/gpu/drm/i915/i915_reg.h > +++ b/drivers/gpu/drm/i915/i915_reg.h > @@ -3587,6 +3587,28 @@ > #define PWM_PIPE_B (1 << 29) > #define BLC_PWM_CPU_CTL 0x48254 > > +#define BLM_HIST_CTL 0x48260 > +#define ENH_HIST_ENABLE (1<<31) > +#define ENH_MODIF_TBL_ENABLE (1<<30) > +#define ENH_PIPE_A_SELECT (0<<29) > +#define ENH_PIPE_B_SELECT (1<<29) > +#define ENH_PIPE(pipe) _PIPE(pipe, ENH_PIPE_A_SELECT, ENH_PIPE_B_SELECT) > +#define HIST_MODE_YUV (0<<24) > +#define HIST_MODE_HSV (1<<24) > +#define ENH_MODE_DIRECT (0<<13) > +#define ENH_MODE_ADDITIVE (1<<13) > +#define ENH_MODE_MULTIPLICATIVE (2<<13) > +#define BIN_REGISTER_SET (1<<11) > +#define ENH_NUM_BINS 32 > + > +#define BLM_HIST_ENH 0x48264 > + > +#define BLM_HIST_GUARD_BAND 0x48268 > +#define BLM_HIST_INTR_ENABLE (1<<31) > +#define BLM_HIST_EVENT_STATUS (1<<30) > +#define BLM_HIST_INTR_DELAY_MASK (0xFF<<22) > +#define BLM_HIST_INTR_DELAY_SHIFT 22 > + > #define BLC_PWM_PCH_CTL1 0xc8250 > #define PWM_PCH_ENABLE (1 << 31) > #define PWM_POLARITY_ACTIVE_LOW (1 << 29) > diff --git a/drivers/gpu/drm/i915/intel_adaptive_backlight.c b/drivers/gpu/drm/i915/intel_adaptive_backlight.c > new file mode 100644 > index 0000000..4234962 > --- /dev/null > +++ b/drivers/gpu/drm/i915/intel_adaptive_backlight.c > @@ -0,0 +1,266 @@ > +/* > + * Copyright 2012 The Chromium OS Authors. > + * All Rights Reserved. > + * > + * 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, sub license, 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 NON-INFRINGEMENT. > + * 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. > + * > + */ > + > + > +#include "drmP.h" > +#include "drm.h" > +#include "i915_drm.h" > +#include "i915_drv.h" > +#include "i915_reg.h" > +#include "intel_drv.h" > +#include "intel_fixedpoint.h" > + > +/* > + * This function takes a histogram of buckets as input and determines an > + * acceptable target backlight level. > + */ > +static int histogram_find_correction_level(int *levels) > +{ > + int i, sum = 0; > + int ratio, distortion, prev_distortion = 0, off, final_ratio, target; > + > + for (i = 0; i < ENH_NUM_BINS; i++) > + sum += levels[i]; > + > + /* Allow 0.33/256 distortion per pixel, on average */ > + target = sum / 3; > + > + /* Special case where we only have less than 100 pixels > + * outside of the darkest bin. > + */ > + if (sum - levels[0] <= 100) > + return 70; > + > + for (ratio = ENH_NUM_BINS - 1; ratio >= 0 ; ratio--) { > + distortion = 0; > + for (i = ratio; i < ENH_NUM_BINS; i++) { > + int pixel_distortion = (i - ratio)*8; > + int num_pixels = levels[i]; > + distortion += num_pixels * pixel_distortion; > + } > + if (distortion > target) > + break; > + else > + prev_distortion = distortion; > + } > + > + ratio++; > + > + /* If we're not exactly at the border between two buckets, extrapolate > + * to get 3 extra bits of accuracy. > + */ > + if (distortion - prev_distortion) > + off = 8 * (target - prev_distortion) / > + (distortion - prev_distortion); > + else > + off = 0; > + > + final_ratio = ratio * 255 / 31 + off; > + > + if (final_ratio > 255) > + final_ratio = 255; > + > + /* Never aim for less than 50% of the total backlight */ > + if (final_ratio < 128) > + final_ratio = 128; > + > + return final_ratio; > +} > + > +static void histogram_get_levels(struct drm_device *dev, int pipe, int *levels) > +{ > + drm_i915_private_t *dev_priv = dev->dev_private; > + int i; > + > + for (i = 0; i < ENH_NUM_BINS; i++) { > + I915_WRITE(BLM_HIST_CTL, ENH_HIST_ENABLE | > + ENH_MODIF_TBL_ENABLE | > + ENH_PIPE(pipe) | > + HIST_MODE_YUV | > + ENH_MODE_ADDITIVE | > + i); > + levels[i] = I915_READ(BLM_HIST_ENH); > + } > +} > + > +static void histogram_set_levels(struct drm_device *dev, int pipe, int *levels) > +{ > + drm_i915_private_t *dev_priv = dev->dev_private; > + int i; > + > + for (i = 0; i < ENH_NUM_BINS; i++) { > + I915_WRITE(BLM_HIST_CTL, ENH_HIST_ENABLE | > + ENH_MODIF_TBL_ENABLE | > + ENH_PIPE(pipe) | > + HIST_MODE_YUV | > + ENH_MODE_ADDITIVE | > + BIN_REGISTER_SET | > + i); > + I915_WRITE(BLM_HIST_ENH, levels[i]); > + } > +} > + > +/* > + * This function computes the backlight correction level for an acceptable > + * distortion and fills up the correction bins adequately. > + */ > +static void > +adaptive_backlight_compute_correction(struct drm_device *dev, int *levels) > +{ > + drm_i915_private_t *dev_priv = dev->dev_private; > + int correction_level; > + int i, multiplier, one_over_gamma; > + > + /* Find the correction level for an acceptable distortion */ > + correction_level = histogram_find_correction_level(levels); > + > + /* If we're not yet at our correction target, we need to decide by how > + * much to move. > + */ > + if (dev_priv->backlight_correction_level != correction_level) { > + int delta, direction; > + > + direction = (correction_level > > + dev_priv->backlight_correction_level); > + > + if (direction == dev_priv->backlight_correction_direction) { > + dev_priv->backlight_correction_count++; > + } else { > + dev_priv->backlight_correction_count = 0; > + dev_priv->backlight_correction_direction = direction; > + } > + > + delta = abs(correction_level - > + dev_priv->backlight_correction_level)/4; > + > + if (delta < 1) > + delta = 1; > + > + /* For increasing the brightness, we do it instantly. > + * For lowering the brightness, we require at least 10 frames > + * below the current value. This avoids ping-ponging of the > + * backlight level. > + * > + * We also never increase the backlight by more than 6% per > + * frame, and never lower it by more than 3% per frame, because > + * the backlight needs time to adjust and the LCD correction > + * would be "ahead" otherwise. > + */ > + if (correction_level > dev_priv->backlight_correction_level) { > + if (delta > 15) > + delta = 15; > + dev_priv->backlight_correction_level += delta; > + } else if ((dev_priv->backlight_correction_count > 10) && > + (correction_level < dev_priv->backlight_correction_level)) { > + if (delta > 7) > + delta = 7; > + dev_priv->backlight_correction_level -= delta; > + } > + } > + > + /* We need to invert the gamma correction of the LCD values, > + * but not of the backlight which is linear. > + */ > + one_over_gamma = intel_fixed_div(FIXED_ONE, > + dev_priv->adaptive_backlight_panel_gamma); > + multiplier = intel_fixed_pow(dev_priv->backlight_correction_level * 256, > + one_over_gamma); > + > + for (i = 0; i < ENH_NUM_BINS; i++) { > + int base_value = i * 8 * 4; > + levels[i] = base_value - base_value * multiplier / 65536; > + } > +} > + > +/* > + * A quick note about the adaptive backlight implementation: > + * If we let it run as designed, it will generate a lot of interrupts which > + * tends to wake the CPU up and waste power. This is a bad idea for a power > + * saving feature. Instead, we couple it to the vblank interrupt since that > + * means we drew something. This means that we do not react to non-vsynced GL > + * updates, or updates to the front buffer, and also adds a little bit of > + * extra latency. But it is an acceptable tradeoff to make. > + */ > +void intel_adaptive_backlight(struct drm_device *dev, int pipe_vblank_event) > +{ > + drm_i915_private_t *dev_priv = dev->dev_private; > + int levels[ENH_NUM_BINS]; > + int pipe; > + struct drm_connector *connector; > + struct intel_crtc *intel_crtc; > + > + if (!dev_priv->adaptive_backlight_enabled) > + return; > + > + /* Find the connector */ > + if (dev_priv->int_lvds_connector) > + connector = dev_priv->int_lvds_connector; > + else if (dev_priv->int_edp_connector) > + connector = dev_priv->int_edp_connector; > + else > + return; > + > + if (!connector) > + return; > + > + if (!connector->encoder) > + return; > + > + if (!connector->encoder->crtc) > + return; > + > + /* Find the pipe for the panel. */ > + intel_crtc = to_intel_crtc(connector->encoder->crtc); > + pipe = intel_crtc->pipe; > + > + /* The callback happens for both pipe A & B. Now that we know which > + * pipe we're doing adaptive backlight on, check that it's the right > + * one. Bail if it isn't. > + */ > + if (pipe != pipe_vblank_event) > + return; > + > + /* Return if no event. */ > + if (I915_READ(BLM_HIST_GUARD_BAND) & BLM_HIST_EVENT_STATUS == 0) > + return; > + > + /* Make sure we ack the previous event. Even though we do not get the > + * IRQs (see above explanation), we must still ack the events otherwise > + * the histogram data doesn't get updated any more. > + */ > + I915_WRITE(BLM_HIST_GUARD_BAND, BLM_HIST_INTR_ENABLE | > + BLM_HIST_EVENT_STATUS | > + (1 << BLM_HIST_INTR_DELAY_SHIFT)); > + > + histogram_get_levels(dev, pipe, levels); > + > + adaptive_backlight_compute_correction(dev, levels); > + > + histogram_set_levels(dev, pipe, levels); > + > + intel_panel_set_backlight(dev, dev_priv->backlight_level); > +} > + > diff --git a/drivers/gpu/drm/i915/intel_fixedpoint.h b/drivers/gpu/drm/i915/intel_fixedpoint.h > new file mode 100644 > index 0000000..fff5f0b > --- /dev/null > +++ b/drivers/gpu/drm/i915/intel_fixedpoint.h > @@ -0,0 +1,140 @@ > +/* > + * Copyright 2012 The Chromium OS Authors. > + * All Rights Reserved. > + * > + * 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, sub license, 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 NON-INFRINGEMENT. > + * 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. > + * > + */ > + > +/* > + * The backlight is corrected in linear space. However the LCD correction is > + * corrected in gama space. So to be able to compute the correction value for > + * the LCD, we have to compute the inverse gamma. To do so, we carry this > + * small fixed point module which allows us to use pow() to compute inverse > + * gamma. > + * > + * The fixed point format used here is 16.16. > + */ > + > +/* intel_fixed_exp_tbl[x*32] = exp(x) * 65536 */ > +static const int intel_fixed_exp_tbl[33] = { > +0x00010000, 0x00010820, 0x00011083, 0x00011929, 0x00012216, 0x00012b4b, > +0x000134cc, 0x00013e99, 0x000148b6, 0x00015325, 0x00015de9, 0x00016905, > +0x0001747a, 0x0001804d, 0x00018c80, 0x00019916, 0x0001a613, 0x0001b378, > +0x0001c14b, 0x0001cf8e, 0x0001de45, 0x0001ed74, 0x0001fd1e, 0x00020d47, > +0x00021df4, 0x00022f28, 0x000240e8, 0x00025338, 0x0002661d, 0x0002799b, > +0x00028db8, 0x0002a278, 0x0002b7e1 > +}; > + > +/* intel_fixed_log_tbl[x*32] = log(x) * 65536 */ > +static const int intel_fixed_log_tbl[33] = { > +0x80000000, 0xfffc88c6, 0xfffd3a38, 0xfffda204, 0xfffdebaa, 0xfffe24ca, > +0xfffe5376, 0xfffe7aed, 0xfffe9d1c, 0xfffebb43, 0xfffed63c, 0xfffeeea2, > +0xffff04e8, 0xffff1966, 0xffff2c5f, 0xffff3e08, 0xffff4e8e, 0xffff5e13, > +0xffff6cb5, 0xffff7a8c, 0xffff87ae, 0xffff942b, 0xffffa014, 0xffffab75, > +0xffffb65a, 0xffffc0ce, 0xffffcad8, 0xffffd481, 0xffffddd1, 0xffffe6cd, > +0xffffef7a, 0xfffff7df, 0xffffffff > +}; > + > +/* e * 65536 */ > +#define FIXED_E (intel_fixed_exp_tbl[32]) > +/* 1 * 65536 */ > +#define FIXED_ONE 65536 > + > +static int intel_fixed_mul(int a, int b) > +{ > + return (int) ((int64_t)a * (int64_t)b / 65536LL); > +} > + > +static int intel_fixed_div(int a, int b) > +{ > + return (int) ((int64_t)a * 65536LL / (int64_t)b); > +} > + > +/* > + * Approximate fixed point log function. > + * Only works for inputs in [0,1[ > + */ > +static int intel_fixed_log(int val) > +{ > + int index = val * 32 / FIXED_ONE; > + int remainder = (val & 0x7ff) << 5; > + int v1 = intel_fixed_log_tbl[index]; > + int v2 = intel_fixed_log_tbl[index+1]; > + int final = v1 + intel_fixed_mul(v2 - v1, remainder); > + return final; > +} > + > +/* > + * Approximate fixed point exp function. > + */ > +static int intel_fixed_exp(int val) > +{ > + int count = 0; > + int index, remainder; > + int int_part = FIXED_ONE, frac_part; > + int i, v, v1, v2; > + > + while (val < 0) { > + val += FIXED_ONE; > + count--; > + } > + > + while (val > FIXED_ONE) { > + val -= FIXED_ONE; > + count++; > + } > + > + index = val * 32 / FIXED_ONE; > + remainder = (val & 0x7ff) << 5; > + > + v1 = intel_fixed_exp_tbl[index]; > + v2 = intel_fixed_exp_tbl[index+1]; > + frac_part = v1 + intel_fixed_mul(v2 - v1, remainder); > + > + if (count < 0) { > + for (i = 0; i < -count; i++) > + int_part = intel_fixed_mul(int_part, FIXED_E); > + > + v = intel_fixed_div(frac_part, int_part); > + } else { > + for (i = 0; i < count; i++) > + int_part = intel_fixed_mul(int_part, FIXED_E); > + > + v = intel_fixed_mul(frac_part, int_part); > + } > + return (v >= 0) ? v : 0; > +} > + > +/* > + * Approximate fixed point pow function. > + * Only works for x in [0,1[ > + */ > +static int intel_fixed_pow(int x, int y) > +{ > + int e, p, r; > + e = intel_fixed_log(x); > + p = intel_fixed_mul(e, y); > + r = intel_fixed_exp(p); > + return r; > +} > + > + > diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c > index 3f9249b..ae95163 100644 > --- a/drivers/gpu/drm/i915/intel_panel.c > +++ b/drivers/gpu/drm/i915/intel_panel.c > @@ -251,6 +251,8 @@ static void intel_panel_actually_set_backlight(struct drm_device *dev, u32 level > struct drm_i915_private *dev_priv = dev->dev_private; > u32 tmp; > > + level = level * dev_priv->backlight_correction_level >> 8; > + > DRM_DEBUG_DRIVER("set backlight PWM = %d\n", level); > > if (HAS_PCH_SPLIT(dev)) > @@ -306,6 +308,10 @@ static void intel_panel_init_backlight(struct drm_device *dev) > > dev_priv->backlight_level = intel_panel_get_backlight(dev); > dev_priv->backlight_enabled = dev_priv->backlight_level != 0; > + dev_priv->adaptive_backlight_enabled = 0; > + /* 2.2 as 16.16 fixed point */ > + dev_priv->adaptive_backlight_panel_gamma = 144179; > + dev_priv->backlight_correction_level = 256; > } > > enum drm_connector_status > diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h > index da929bb..70c9cfc 100644 > --- a/include/drm/i915_drm.h > +++ b/include/drm/i915_drm.h > @@ -309,6 +309,8 @@ typedef struct drm_i915_getparam { > #define I915_SETPARAM_TEX_LRU_LOG_GRANULARITY 2 > #define I915_SETPARAM_ALLOW_BATCHBUFFER 3 > #define I915_SETPARAM_NUM_USED_FENCES 4 > +#define I915_SETPARAM_ADAPTIVE_BACKLIGHT_ENABLE 5 > +#define I915_SETPARAM_PANEL_GAMMA 6 > > typedef struct drm_i915_setparam { > int param; > -- > 1.7.5.3.367.ga9930 > > _______________________________________________ > Intel-gfx mailing list > Intel-gfx at lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Daniel Vetter Mail: daniel at ffwll.ch Mobile: +41 (0)79 365 57 48