mirror of https://gitee.com/openkylin/linux.git
drm/i915: Don't register CRT connector when it's fused off
On some machines the CRT connector may be fused off. The weird thing about this setup is that the ADPA register works otherwise normally, except the enable bit is hardwired to 0. No one knows of any fuse register that would tell us if this is the case, so the only thing we can do (apart from a blacklist) is to try and set the enable bit and see if it sticks. If not, we don't register the connector at all. Obviously if the bit is already set when loading the driver we can just assume it works. I've smoke tested this approach on several machines (GMCH and PCH), some with actual CRT connectors, some with shadow connectors, and obviously the machine (IVB) with the fused off connector. So far I've not seen any ill effects from this probe. The main benefit is that we can actually run igt on machines with fused off connectors, without totally upsetting the state checker. Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1448051741-22771-1-git-send-email-ville.syrjala@linux.intel.com Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
parent
9bbc8258ae
commit
6c03a6bd0d
|
@ -777,11 +777,37 @@ void intel_crt_init(struct drm_device *dev)
|
||||||
struct intel_crt *crt;
|
struct intel_crt *crt;
|
||||||
struct intel_connector *intel_connector;
|
struct intel_connector *intel_connector;
|
||||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||||
|
i915_reg_t adpa_reg;
|
||||||
|
u32 adpa;
|
||||||
|
|
||||||
/* Skip machines without VGA that falsely report hotplug events */
|
/* Skip machines without VGA that falsely report hotplug events */
|
||||||
if (dmi_check_system(intel_no_crt))
|
if (dmi_check_system(intel_no_crt))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (HAS_PCH_SPLIT(dev))
|
||||||
|
adpa_reg = PCH_ADPA;
|
||||||
|
else if (IS_VALLEYVIEW(dev))
|
||||||
|
adpa_reg = VLV_ADPA;
|
||||||
|
else
|
||||||
|
adpa_reg = ADPA;
|
||||||
|
|
||||||
|
adpa = I915_READ(adpa_reg);
|
||||||
|
if ((adpa & ADPA_DAC_ENABLE) == 0) {
|
||||||
|
/*
|
||||||
|
* On some machines (some IVB at least) CRT can be
|
||||||
|
* fused off, but there's no known fuse bit to
|
||||||
|
* indicate that. On these machine the ADPA register
|
||||||
|
* works normally, except the DAC enable bit won't
|
||||||
|
* take. So the only way to tell is attempt to enable
|
||||||
|
* it and see what happens.
|
||||||
|
*/
|
||||||
|
I915_WRITE(adpa_reg, adpa | ADPA_DAC_ENABLE |
|
||||||
|
ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE);
|
||||||
|
if ((I915_READ(adpa_reg) & ADPA_DAC_ENABLE) == 0)
|
||||||
|
return;
|
||||||
|
I915_WRITE(adpa_reg, adpa);
|
||||||
|
}
|
||||||
|
|
||||||
crt = kzalloc(sizeof(struct intel_crt), GFP_KERNEL);
|
crt = kzalloc(sizeof(struct intel_crt), GFP_KERNEL);
|
||||||
if (!crt)
|
if (!crt)
|
||||||
return;
|
return;
|
||||||
|
@ -815,12 +841,7 @@ void intel_crt_init(struct drm_device *dev)
|
||||||
connector->interlace_allowed = 1;
|
connector->interlace_allowed = 1;
|
||||||
connector->doublescan_allowed = 0;
|
connector->doublescan_allowed = 0;
|
||||||
|
|
||||||
if (HAS_PCH_SPLIT(dev))
|
crt->adpa_reg = adpa_reg;
|
||||||
crt->adpa_reg = PCH_ADPA;
|
|
||||||
else if (IS_VALLEYVIEW(dev))
|
|
||||||
crt->adpa_reg = VLV_ADPA;
|
|
||||||
else
|
|
||||||
crt->adpa_reg = ADPA;
|
|
||||||
|
|
||||||
crt->base.compute_config = intel_crt_compute_config;
|
crt->base.compute_config = intel_crt_compute_config;
|
||||||
if (HAS_PCH_SPLIT(dev) && !HAS_DDI(dev)) {
|
if (HAS_PCH_SPLIT(dev) && !HAS_DDI(dev)) {
|
||||||
|
|
Loading…
Reference in New Issue