Skip to content

Commit

Permalink
drm/i915: add pipe A force quirks to i915 driver
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Jesse Barnes authored and Eric Anholt committed Jul 26, 2010
1 parent 0cc4d43 commit b690e96
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 1 deletion.
4 changes: 4 additions & 0 deletions drivers/gpu/drm/i915/i915_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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;
Expand Down
69 changes: 68 additions & 1 deletion drivers/gpu/drm/i915/intel_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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)) {
Expand Down

0 comments on commit b690e96

Please sign in to comment.