]>
Commit | Line | Data |
---|---|---|
4d3fdb08 GKH |
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); |