Ed Grochowski's Website
Home
Articles
Desktop Computer Build
Laptop Dust Removal
Linux Migration
Linux i915 Backlight Patch
Long Hair Care
My "Quarter Century in the Making" Stereo
Reviving Your TI-59 Calculator
Slackware Linux 13.0 Review


(c) 2012
Ed Grochowski

Linux i915 Backlight Patch

Ed Grochowski

Posted 7-5-2011

Introduction

I recently purchased a HP Pavilion dv7t-6100 laptop featuring Intel's Core i7-2630QM processor (Sandy Bridge). I installed the current 64-bit version of Slackware Linux. All of the HP dv7t's hardware devices worked under the Linux 2.6.38.7 kernel except for the backlight control and discrete graphics option.

The lack of backlight control was problematic. The dv7t's screen was stuck at maximum brightness, and neither pressing the hotkeys nor writing to /sys/devices/virtual/backlight/acpi_video0/brightness changed the actual brightness. It appeared that the BIOS and the Linux kernel were unable to communicate brightness changes.

Workaround

Debugging the BIOS and ACPI subsystem is beyond my expertise, so I instead developed a simple workaround: have the kernel directly initialize the i915 backlight control registers when the i915 driver is loaded, bypassing the BIOS.

Here is a patch for the 2.6.38.7 kernel that is useful on machines with non-functional BIOS backlight controls. After patching the kernel, add the line:

i915.force_backlight=N

to the kernel boot options, where N is the desired brightness between 1 and 100. On the HP Pavilion dv7t-6100 with the super-bright 1920x1080 screen, setting N=35 results in comfortable viewing.


diff -r -w -p /usr/src/linux/drivers/gpu/drm/i915/i915_dma.c ./i915_dma.c
*** /usr/src/linux/drivers/gpu/drm/i915/i915_dma.c      2011-05-21 15:13:59.000000000 -0700
--- ./i915_dma.c        2011-07-05 05:49:19.000000000 -0700
*************** int i915_driver_load(struct drm_device *
*** 1870,1875 ****
--- 1870,1876 ----
        struct drm_i915_private *dev_priv;
        int ret = 0, mmio_bar;
        uint32_t agp_size;
+       u32 max;

        /* i915 has 4 more counters */
        dev->counters += 4;
*************** int i915_driver_load(struct drm_device *
*** 2046,2051 ****
--- 2047,2060 ----

        ips_ping_for_i915_load();

+       /* force backlight brightness
+        * this is useful if the BIOS can't control the backlight
+        */
+       if (i915_force_backlight > 0 && i915_force_backlight <= 100) {
+               max = intel_panel_get_max_backlight(dev);
+               intel_panel_set_backlight(dev, i915_force_backlight * max / 100);
+       }
+
        return 0;

  out_gem_unload:


diff -r -w -p /usr/src/linux/drivers/gpu/drm/i915/i915_drv.c ./i915_drv.c
*** /usr/src/linux/drivers/gpu/drm/i915/i915_drv.c      2011-05-21 15:13:59.000000000 -0700
--- ./i915_drv.c        2011-07-05 05:30:05.000000000 -0700
*************** module_param_named(lvds_downclock, i915_
*** 58,63 ****
--- 58,66 ----
  unsigned int i915_panel_use_ssc = 1;
  module_param_named(lvds_use_ssc, i915_panel_use_ssc, int, 0600);

+ unsigned int i915_force_backlight = 0;
+ module_param_named(force_backlight, i915_force_backlight, int, 0600);
+
  bool i915_try_reset = true;
  module_param_named(reset, i915_try_reset, bool, 0600);


diff -r -w -p /usr/src/linux/drivers/gpu/drm/i915/i915_drv.h ./i915_drv.h
*** /usr/src/linux/drivers/gpu/drm/i915/i915_drv.h      2011-05-21 15:13:59.000000000 -0700
--- ./i915_drv.h        2011-07-05 05:30:05.000000000 -0700
*************** extern unsigned int i915_powersave;
*** 959,964 ****
--- 959,965 ----
  extern unsigned int i915_semaphores;
  extern unsigned int i915_lvds_downclock;
  extern unsigned int i915_panel_use_ssc;
+ extern unsigned int i915_force_backlight;
  extern unsigned int i915_enable_rc6;

  extern int i915_suspend(struct drm_device *dev, pm_message_t state);

I will submit the patch to the kernel developers.