aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2009-12-01 14:56:30 -0500
committerEric Anholt <eric@anholt.net>2009-12-01 14:56:30 -0500
commitf0217c42c9ab3d772e543f635ce628b9478f70b6 (patch)
tree01dfcd607f90f250fb27cb303747b3d770879742 /drivers/gpu/drm/i915
parentd09c23de9f967a7b7dcee0ffc57222ddbd821aba (diff)
drm/i915: Fix DDC on some systems by clearing BIOS GMBUS setup.
This is a sync of a fix I made in the old UMS code. If the BIOS uses the GMBUS and doesn't clear that setup, then our bit-banging I2C can fail, leading to monitors not being detected. Signed-off-by: Eric Anholt <eric@anholt.net>
Diffstat (limited to 'drivers/gpu/drm/i915')
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h14
-rw-r--r--drivers/gpu/drm/i915/i915_suspend.c5
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h2
-rw-r--r--drivers/gpu/drm/i915/intel_i2c.c19
4 files changed, 39 insertions, 1 deletions
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 6b596020d362..c4a273513b2f 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -414,6 +414,13 @@
414# define GPIO_DATA_VAL_IN (1 << 12) 414# define GPIO_DATA_VAL_IN (1 << 12)
415# define GPIO_DATA_PULLUP_DISABLE (1 << 13) 415# define GPIO_DATA_PULLUP_DISABLE (1 << 13)
416 416
417#define GMBUS0 0x5100
418#define GMBUS1 0x5104
419#define GMBUS2 0x5108
420#define GMBUS3 0x510c
421#define GMBUS4 0x5110
422#define GMBUS5 0x5120
423
417/* 424/*
418 * Clock control & power management 425 * Clock control & power management
419 */ 426 */
@@ -2166,6 +2173,13 @@
2166#define PCH_GPIOE 0xc5020 2173#define PCH_GPIOE 0xc5020
2167#define PCH_GPIOF 0xc5024 2174#define PCH_GPIOF 0xc5024
2168 2175
2176#define PCH_GMBUS0 0xc5100
2177#define PCH_GMBUS1 0xc5104
2178#define PCH_GMBUS2 0xc5108
2179#define PCH_GMBUS3 0xc510c
2180#define PCH_GMBUS4 0xc5110
2181#define PCH_GMBUS5 0xc5120
2182
2169#define PCH_DPLL_A 0xc6014 2183#define PCH_DPLL_A 0xc6014
2170#define PCH_DPLL_B 0xc6018 2184#define PCH_DPLL_B 0xc6018
2171 2185
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c
index cd10d9b8181f..c5a6df93e1b6 100644
--- a/drivers/gpu/drm/i915/i915_suspend.c
+++ b/drivers/gpu/drm/i915/i915_suspend.c
@@ -27,7 +27,7 @@
27#include "drmP.h" 27#include "drmP.h"
28#include "drm.h" 28#include "drm.h"
29#include "i915_drm.h" 29#include "i915_drm.h"
30#include "i915_drv.h" 30#include "intel_drv.h"
31 31
32static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe) 32static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe)
33{ 33{
@@ -816,6 +816,9 @@ int i915_restore_state(struct drm_device *dev)
816 for (i = 0; i < 3; i++) 816 for (i = 0; i < 3; i++)
817 I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]); 817 I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]);
818 818
819 /* I2C state */
820 intel_i2c_reset_gmbus(dev);
821
819 return 0; 822 return 0;
820} 823}
821 824
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 8a22f2508899..9ffa31e13eb3 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -162,6 +162,8 @@ void intel_i2c_destroy(struct i2c_adapter *adapter);
162int intel_ddc_get_modes(struct intel_output *intel_output); 162int intel_ddc_get_modes(struct intel_output *intel_output);
163extern bool intel_ddc_probe(struct intel_output *intel_output); 163extern bool intel_ddc_probe(struct intel_output *intel_output);
164void intel_i2c_quirk_set(struct drm_device *dev, bool enable); 164void intel_i2c_quirk_set(struct drm_device *dev, bool enable);
165void intel_i2c_reset_gmbus(struct drm_device *dev);
166
165extern void intel_crt_init(struct drm_device *dev); 167extern void intel_crt_init(struct drm_device *dev);
166extern void intel_hdmi_init(struct drm_device *dev, int sdvox_reg); 168extern void intel_hdmi_init(struct drm_device *dev, int sdvox_reg);
167extern bool intel_sdvo_init(struct drm_device *dev, int output_device); 169extern bool intel_sdvo_init(struct drm_device *dev, int output_device);
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
index c7eab724c418..b94acc4cc05f 100644
--- a/drivers/gpu/drm/i915/intel_i2c.c
+++ b/drivers/gpu/drm/i915/intel_i2c.c
@@ -118,6 +118,23 @@ static void set_data(void *data, int state_high)
118 udelay(I2C_RISEFALL_TIME); /* wait for the line to change state */ 118 udelay(I2C_RISEFALL_TIME); /* wait for the line to change state */
119} 119}
120 120
121/* Clears the GMBUS setup. Our driver doesn't make use of the GMBUS I2C
122 * engine, but if the BIOS leaves it enabled, then that can break our use
123 * of the bit-banging I2C interfaces. This is notably the case with the
124 * Mac Mini in EFI mode.
125 */
126void
127intel_i2c_reset_gmbus(struct drm_device *dev)
128{
129 struct drm_i915_private *dev_priv = dev->dev_private;
130
131 if (IS_IGDNG(dev)) {
132 I915_WRITE(PCH_GMBUS0, 0);
133 } else {
134 I915_WRITE(GMBUS0, 0);
135 }
136}
137
121/** 138/**
122 * intel_i2c_create - instantiate an Intel i2c bus using the specified GPIO reg 139 * intel_i2c_create - instantiate an Intel i2c bus using the specified GPIO reg
123 * @dev: DRM device 140 * @dev: DRM device
@@ -168,6 +185,8 @@ struct i2c_adapter *intel_i2c_create(struct drm_device *dev, const u32 reg,
168 if(i2c_bit_add_bus(&chan->adapter)) 185 if(i2c_bit_add_bus(&chan->adapter))
169 goto out_free; 186 goto out_free;
170 187
188 intel_i2c_reset_gmbus(dev);
189
171 /* JJJ: raise SCL and SDA? */ 190 /* JJJ: raise SCL and SDA? */
172 intel_i2c_quirk_set(dev, true); 191 intel_i2c_quirk_set(dev, true);
173 set_data(chan, 1); 192 set_data(chan, 1);