]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - 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
CommitLineData
4d3fdb08
GKH
1From f0217c42c9ab3d772e543f635ce628b9478f70b6 Mon Sep 17 00:00:00 2001
2From: Eric Anholt <eric@anholt.net>
3Date: Tue, 1 Dec 2009 11:56:30 -0800
4Subject: drm/i915: Fix DDC on some systems by clearing BIOS GMBUS setup.
5
6From: Eric Anholt <eric@anholt.net>
7
8commit f0217c42c9ab3d772e543f635ce628b9478f70b6 upstream.
9
10This is a sync of a fix I made in the old UMS code. If the BIOS uses
11the GMBUS and doesn't clear that setup, then our bit-banging I2C can
12fail, leading to monitors not being detected.
13
14Signed-off-by: Eric Anholt <eric@anholt.net>
15Cc: maximilian attems <max@stro.at>
16Signed-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);