]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/2.6.32.9/drm-i915-fix-ddc-on-some-systems-by-clearing-bios-gmbus-setup.patch
4.9-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 2.6.32.9 / drm-i915-fix-ddc-on-some-systems-by-clearing-bios-gmbus-setup.patch
1 From f0217c42c9ab3d772e543f635ce628b9478f70b6 Mon Sep 17 00:00:00 2001
2 From: Eric Anholt <eric@anholt.net>
3 Date: Tue, 1 Dec 2009 11:56:30 -0800
4 Subject: drm/i915: Fix DDC on some systems by clearing BIOS GMBUS setup.
5
6 From: Eric Anholt <eric@anholt.net>
7
8 commit f0217c42c9ab3d772e543f635ce628b9478f70b6 upstream.
9
10 This is a sync of a fix I made in the old UMS code. If the BIOS uses
11 the GMBUS and doesn't clear that setup, then our bit-banging I2C can
12 fail, leading to monitors not being detected.
13
14 Signed-off-by: Eric Anholt <eric@anholt.net>
15 Cc: maximilian attems <max@stro.at>
16 Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
17
18 ---
19 drivers/gpu/drm/i915/i915_reg.h | 14 ++++++++++++++
20 drivers/gpu/drm/i915/i915_suspend.c | 5 ++++-
21 drivers/gpu/drm/i915/intel_drv.h | 2 ++
22 drivers/gpu/drm/i915/intel_i2c.c | 19 +++++++++++++++++++
23 4 files changed, 39 insertions(+), 1 deletion(-)
24
25 --- a/drivers/gpu/drm/i915/i915_reg.h
26 +++ b/drivers/gpu/drm/i915/i915_reg.h
27 @@ -405,6 +405,13 @@
28 # define GPIO_DATA_VAL_IN (1 << 12)
29 # define GPIO_DATA_PULLUP_DISABLE (1 << 13)
30
31 +#define GMBUS0 0x5100
32 +#define GMBUS1 0x5104
33 +#define GMBUS2 0x5108
34 +#define GMBUS3 0x510c
35 +#define GMBUS4 0x5110
36 +#define GMBUS5 0x5120
37 +
38 /*
39 * Clock control & power management
40 */
41 @@ -2153,6 +2160,13 @@
42 #define PCH_GPIOE 0xc5020
43 #define PCH_GPIOF 0xc5024
44
45 +#define PCH_GMBUS0 0xc5100
46 +#define PCH_GMBUS1 0xc5104
47 +#define PCH_GMBUS2 0xc5108
48 +#define PCH_GMBUS3 0xc510c
49 +#define PCH_GMBUS4 0xc5110
50 +#define PCH_GMBUS5 0xc5120
51 +
52 #define PCH_DPLL_A 0xc6014
53 #define PCH_DPLL_B 0xc6018
54
55 --- a/drivers/gpu/drm/i915/i915_suspend.c
56 +++ b/drivers/gpu/drm/i915/i915_suspend.c
57 @@ -27,7 +27,7 @@
58 #include "drmP.h"
59 #include "drm.h"
60 #include "i915_drm.h"
61 -#include "i915_drv.h"
62 +#include "intel_drv.h"
63
64 static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe)
65 {
66 @@ -846,6 +846,9 @@ int i915_restore_state(struct drm_device
67 for (i = 0; i < 3; i++)
68 I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]);
69
70 + /* I2C state */
71 + intel_i2c_reset_gmbus(dev);
72 +
73 return 0;
74 }
75
76 --- a/drivers/gpu/drm/i915/intel_drv.h
77 +++ b/drivers/gpu/drm/i915/intel_drv.h
78 @@ -134,6 +134,8 @@ void intel_i2c_destroy(struct i2c_adapte
79 int intel_ddc_get_modes(struct intel_output *intel_output);
80 extern bool intel_ddc_probe(struct intel_output *intel_output);
81 void intel_i2c_quirk_set(struct drm_device *dev, bool enable);
82 +void intel_i2c_reset_gmbus(struct drm_device *dev);
83 +
84 extern void intel_crt_init(struct drm_device *dev);
85 extern void intel_hdmi_init(struct drm_device *dev, int sdvox_reg);
86 extern bool intel_sdvo_init(struct drm_device *dev, int output_device);
87 --- a/drivers/gpu/drm/i915/intel_i2c.c
88 +++ b/drivers/gpu/drm/i915/intel_i2c.c
89 @@ -118,6 +118,23 @@ static void set_data(void *data, int sta
90 udelay(I2C_RISEFALL_TIME); /* wait for the line to change state */
91 }
92
93 +/* Clears the GMBUS setup. Our driver doesn't make use of the GMBUS I2C
94 + * engine, but if the BIOS leaves it enabled, then that can break our use
95 + * of the bit-banging I2C interfaces. This is notably the case with the
96 + * Mac Mini in EFI mode.
97 + */
98 +void
99 +intel_i2c_reset_gmbus(struct drm_device *dev)
100 +{
101 + struct drm_i915_private *dev_priv = dev->dev_private;
102 +
103 + if (IS_IGDNG(dev)) {
104 + I915_WRITE(PCH_GMBUS0, 0);
105 + } else {
106 + I915_WRITE(GMBUS0, 0);
107 + }
108 +}
109 +
110 /**
111 * intel_i2c_create - instantiate an Intel i2c bus using the specified GPIO reg
112 * @dev: DRM device
113 @@ -168,6 +185,8 @@ struct i2c_adapter *intel_i2c_create(str
114 if(i2c_bit_add_bus(&chan->adapter))
115 goto out_free;
116
117 + intel_i2c_reset_gmbus(dev);
118 +
119 /* JJJ: raise SCL and SDA? */
120 intel_i2c_quirk_set(dev, true);
121 set_data(chan, 1);