drm/i915: add pipe A force quirks to i915 driver
Ported over from the old UMS list. Unfortunately they're still necessary especially on older laptop platforms. Fixes https://bugs.freedesktop.org/show_bug.cgi?id=22126. Tested-by: Xavier <shiningxc@gmail.com> Tested-by: Diego Escalante Urrelo <diegoe@gnome.org> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Eric Anholt <eric@anholt.net>
This commit is contained in:
parent
0cc4d4300c
commit
b690e96cf9
|
@ -223,6 +223,8 @@ enum intel_pch {
|
|||
PCH_CPT, /* Cougarpoint PCH */
|
||||
};
|
||||
|
||||
#define QUIRK_PIPEA_FORCE (1<<0)
|
||||
|
||||
struct intel_fbdev;
|
||||
|
||||
typedef struct drm_i915_private {
|
||||
|
@ -338,6 +340,8 @@ typedef struct drm_i915_private {
|
|||
/* PCH chipset type */
|
||||
enum intel_pch pch_type;
|
||||
|
||||
unsigned long quirks;
|
||||
|
||||
/* Register state */
|
||||
bool modeset_on_lid;
|
||||
u8 saveLBB;
|
||||
|
|
|
@ -2270,6 +2270,11 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode)
|
|||
intel_wait_for_vblank(dev);
|
||||
}
|
||||
|
||||
/* Don't disable pipe A or pipe A PLLs if needed */
|
||||
if (pipeconf_reg == PIPEACONF &&
|
||||
(dev_priv->quirks & QUIRK_PIPEA_FORCE))
|
||||
goto skip_pipe_off;
|
||||
|
||||
/* Next, disable display pipes */
|
||||
temp = I915_READ(pipeconf_reg);
|
||||
if ((temp & PIPEACONF_ENABLE) != 0) {
|
||||
|
@ -2285,7 +2290,7 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode)
|
|||
I915_WRITE(dpll_reg, temp & ~DPLL_VCO_ENABLE);
|
||||
I915_READ(dpll_reg);
|
||||
}
|
||||
|
||||
skip_pipe_off:
|
||||
/* Wait for the clocks to turn off. */
|
||||
udelay(150);
|
||||
break;
|
||||
|
@ -5526,6 +5531,66 @@ static void intel_init_display(struct drm_device *dev)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Some BIOSes insist on assuming the GPU's pipe A is enabled at suspend,
|
||||
* resume, or other times. This quirk makes sure that's the case for
|
||||
* affected systems.
|
||||
*/
|
||||
static void quirk_pipea_force (struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
|
||||
dev_priv->quirks |= QUIRK_PIPEA_FORCE;
|
||||
DRM_DEBUG_DRIVER("applying pipe a force quirk\n");
|
||||
}
|
||||
|
||||
struct intel_quirk {
|
||||
int device;
|
||||
int subsystem_vendor;
|
||||
int subsystem_device;
|
||||
void (*hook)(struct drm_device *dev);
|
||||
};
|
||||
|
||||
struct intel_quirk intel_quirks[] = {
|
||||
/* HP Compaq 2730p needs pipe A force quirk (LP: #291555) */
|
||||
{ 0x2a42, 0x103c, 0x30eb, quirk_pipea_force },
|
||||
/* HP Mini needs pipe A force quirk (LP: #322104) */
|
||||
{ 0x27ae,0x103c, 0x361a, quirk_pipea_force },
|
||||
|
||||
/* Thinkpad R31 needs pipe A force quirk */
|
||||
{ 0x3577, 0x1014, 0x0505, quirk_pipea_force },
|
||||
/* Toshiba Protege R-205, S-209 needs pipe A force quirk */
|
||||
{ 0x2592, 0x1179, 0x0001, quirk_pipea_force },
|
||||
|
||||
/* ThinkPad X30 needs pipe A force quirk (LP: #304614) */
|
||||
{ 0x3577, 0x1014, 0x0513, quirk_pipea_force },
|
||||
/* ThinkPad X40 needs pipe A force quirk */
|
||||
|
||||
/* ThinkPad T60 needs pipe A force quirk (bug #16494) */
|
||||
{ 0x2782, 0x17aa, 0x201a, quirk_pipea_force },
|
||||
|
||||
/* 855 & before need to leave pipe A & dpll A up */
|
||||
{ 0x3582, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force },
|
||||
{ 0x2562, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force },
|
||||
};
|
||||
|
||||
static void intel_init_quirks(struct drm_device *dev)
|
||||
{
|
||||
struct pci_dev *d = dev->pdev;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(intel_quirks); i++) {
|
||||
struct intel_quirk *q = &intel_quirks[i];
|
||||
|
||||
if (d->device == q->device &&
|
||||
(d->subsystem_vendor == q->subsystem_vendor ||
|
||||
q->subsystem_vendor == PCI_ANY_ID) &&
|
||||
(d->subsystem_device == q->subsystem_device ||
|
||||
q->subsystem_device == PCI_ANY_ID))
|
||||
q->hook(dev);
|
||||
}
|
||||
}
|
||||
|
||||
void intel_modeset_init(struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
|
@ -5538,6 +5603,8 @@ void intel_modeset_init(struct drm_device *dev)
|
|||
|
||||
dev->mode_config.funcs = (void *)&intel_mode_funcs;
|
||||
|
||||
intel_init_quirks(dev);
|
||||
|
||||
intel_init_display(dev);
|
||||
|
||||
if (IS_I965G(dev)) {
|
||||
|
|
Loading…
Reference in New Issue