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>
This commit is contained in:
parent
d09c23de9f
commit
f0217c42c9
|
@ -414,6 +414,13 @@
|
||||||
# define GPIO_DATA_VAL_IN (1 << 12)
|
# define GPIO_DATA_VAL_IN (1 << 12)
|
||||||
# define GPIO_DATA_PULLUP_DISABLE (1 << 13)
|
# define GPIO_DATA_PULLUP_DISABLE (1 << 13)
|
||||||
|
|
||||||
|
#define GMBUS0 0x5100
|
||||||
|
#define GMBUS1 0x5104
|
||||||
|
#define GMBUS2 0x5108
|
||||||
|
#define GMBUS3 0x510c
|
||||||
|
#define GMBUS4 0x5110
|
||||||
|
#define GMBUS5 0x5120
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Clock control & power management
|
* Clock control & power management
|
||||||
*/
|
*/
|
||||||
|
@ -2166,6 +2173,13 @@
|
||||||
#define PCH_GPIOE 0xc5020
|
#define PCH_GPIOE 0xc5020
|
||||||
#define PCH_GPIOF 0xc5024
|
#define PCH_GPIOF 0xc5024
|
||||||
|
|
||||||
|
#define PCH_GMBUS0 0xc5100
|
||||||
|
#define PCH_GMBUS1 0xc5104
|
||||||
|
#define PCH_GMBUS2 0xc5108
|
||||||
|
#define PCH_GMBUS3 0xc510c
|
||||||
|
#define PCH_GMBUS4 0xc5110
|
||||||
|
#define PCH_GMBUS5 0xc5120
|
||||||
|
|
||||||
#define PCH_DPLL_A 0xc6014
|
#define PCH_DPLL_A 0xc6014
|
||||||
#define PCH_DPLL_B 0xc6018
|
#define PCH_DPLL_B 0xc6018
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
#include "drmP.h"
|
#include "drmP.h"
|
||||||
#include "drm.h"
|
#include "drm.h"
|
||||||
#include "i915_drm.h"
|
#include "i915_drm.h"
|
||||||
#include "i915_drv.h"
|
#include "intel_drv.h"
|
||||||
|
|
||||||
static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe)
|
static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe)
|
||||||
{
|
{
|
||||||
|
@ -816,6 +816,9 @@ int i915_restore_state(struct drm_device *dev)
|
||||||
for (i = 0; i < 3; i++)
|
for (i = 0; i < 3; i++)
|
||||||
I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]);
|
I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]);
|
||||||
|
|
||||||
|
/* I2C state */
|
||||||
|
intel_i2c_reset_gmbus(dev);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -162,6 +162,8 @@ void intel_i2c_destroy(struct i2c_adapter *adapter);
|
||||||
int intel_ddc_get_modes(struct intel_output *intel_output);
|
int intel_ddc_get_modes(struct intel_output *intel_output);
|
||||||
extern bool intel_ddc_probe(struct intel_output *intel_output);
|
extern bool intel_ddc_probe(struct intel_output *intel_output);
|
||||||
void intel_i2c_quirk_set(struct drm_device *dev, bool enable);
|
void intel_i2c_quirk_set(struct drm_device *dev, bool enable);
|
||||||
|
void intel_i2c_reset_gmbus(struct drm_device *dev);
|
||||||
|
|
||||||
extern void intel_crt_init(struct drm_device *dev);
|
extern void intel_crt_init(struct drm_device *dev);
|
||||||
extern void intel_hdmi_init(struct drm_device *dev, int sdvox_reg);
|
extern void intel_hdmi_init(struct drm_device *dev, int sdvox_reg);
|
||||||
extern bool intel_sdvo_init(struct drm_device *dev, int output_device);
|
extern bool intel_sdvo_init(struct drm_device *dev, int output_device);
|
||||||
|
|
|
@ -118,6 +118,23 @@ static void set_data(void *data, int state_high)
|
||||||
udelay(I2C_RISEFALL_TIME); /* wait for the line to change state */
|
udelay(I2C_RISEFALL_TIME); /* wait for the line to change state */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Clears the GMBUS setup. Our driver doesn't make use of the GMBUS I2C
|
||||||
|
* engine, but if the BIOS leaves it enabled, then that can break our use
|
||||||
|
* of the bit-banging I2C interfaces. This is notably the case with the
|
||||||
|
* Mac Mini in EFI mode.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
intel_i2c_reset_gmbus(struct drm_device *dev)
|
||||||
|
{
|
||||||
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||||
|
|
||||||
|
if (IS_IGDNG(dev)) {
|
||||||
|
I915_WRITE(PCH_GMBUS0, 0);
|
||||||
|
} else {
|
||||||
|
I915_WRITE(GMBUS0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* intel_i2c_create - instantiate an Intel i2c bus using the specified GPIO reg
|
* intel_i2c_create - instantiate an Intel i2c bus using the specified GPIO reg
|
||||||
* @dev: DRM device
|
* @dev: DRM device
|
||||||
|
@ -168,6 +185,8 @@ struct i2c_adapter *intel_i2c_create(struct drm_device *dev, const u32 reg,
|
||||||
if(i2c_bit_add_bus(&chan->adapter))
|
if(i2c_bit_add_bus(&chan->adapter))
|
||||||
goto out_free;
|
goto out_free;
|
||||||
|
|
||||||
|
intel_i2c_reset_gmbus(dev);
|
||||||
|
|
||||||
/* JJJ: raise SCL and SDA? */
|
/* JJJ: raise SCL and SDA? */
|
||||||
intel_i2c_quirk_set(dev, true);
|
intel_i2c_quirk_set(dev, true);
|
||||||
set_data(chan, 1);
|
set_data(chan, 1);
|
||||||
|
|
Loading…
Reference in New Issue