Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/anholt/drm-intel
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/anholt/drm-intel:
drm/i915: add pipe A force quirks to i915 driver
drm/i915: Fix panel fitting regression since 734b4157
drm/i915: fix deadlock in fb teardown
drm/i915: don't free non-existent compressed llb on ILK+
agp/intel: Use the correct mask to detect i830 aperture size.
drm/i915: disable FBC when more than one pipe is active
drm/i915: Use the correct scanout alignment for fbcon.
drm/i915: make sure eDP panel is turned on
drm/i915: add PANEL_UNLOCK_REGS definition
drm/i915: Make G4X-style PLL search more permissive
drm/i915: Clear any existing dither mode prior to enabling spatial dithering
drm/i915: handle shared framebuffers when flipping
drm/i915: Explosion following OOM in do_execbuffer.
gpu/drm/i915: Add a blacklist to omit modeset on LID open
This commit is contained in:
commit
225aa01173
|
@ -1216,17 +1216,20 @@ static int intel_i915_get_gtt_size(void)
|
|||
|
||||
/* G33's GTT size defined in gmch_ctrl */
|
||||
pci_read_config_word(agp_bridge->dev, I830_GMCH_CTRL, &gmch_ctrl);
|
||||
switch (gmch_ctrl & G33_PGETBL_SIZE_MASK) {
|
||||
case G33_PGETBL_SIZE_1M:
|
||||
switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
|
||||
case I830_GMCH_GMS_STOLEN_512:
|
||||
size = 512;
|
||||
break;
|
||||
case I830_GMCH_GMS_STOLEN_1024:
|
||||
size = 1024;
|
||||
break;
|
||||
case G33_PGETBL_SIZE_2M:
|
||||
size = 2048;
|
||||
case I830_GMCH_GMS_STOLEN_8192:
|
||||
size = 8*1024;
|
||||
break;
|
||||
default:
|
||||
dev_info(&agp_bridge->dev->dev,
|
||||
"unknown page table size 0x%x, assuming 512KB\n",
|
||||
(gmch_ctrl & G33_PGETBL_SIZE_MASK));
|
||||
(gmch_ctrl & I830_GMCH_GMS_MASK));
|
||||
size = 512;
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -605,6 +605,9 @@ static int i915_fbc_status(struct seq_file *m, void *unused)
|
|||
case FBC_NOT_TILED:
|
||||
seq_printf(m, "scanout buffer not tiled");
|
||||
break;
|
||||
case FBC_MULTIPLE_PIPES:
|
||||
seq_printf(m, "multiple pipes are enabled");
|
||||
break;
|
||||
default:
|
||||
seq_printf(m, "unknown reason");
|
||||
}
|
||||
|
|
|
@ -1300,7 +1300,7 @@ static void i915_cleanup_compression(struct drm_device *dev)
|
|||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
|
||||
drm_mm_put_block(dev_priv->compressed_fb);
|
||||
if (!IS_GM45(dev))
|
||||
if (dev_priv->compressed_llb)
|
||||
drm_mm_put_block(dev_priv->compressed_llb);
|
||||
}
|
||||
|
||||
|
|
|
@ -215,6 +215,7 @@ enum no_fbc_reason {
|
|||
FBC_MODE_TOO_LARGE, /* mode too large for compression */
|
||||
FBC_BAD_PLANE, /* fbc not supported on plane */
|
||||
FBC_NOT_TILED, /* buffer not tiled */
|
||||
FBC_MULTIPLE_PIPES, /* more than one pipe active */
|
||||
};
|
||||
|
||||
enum intel_pch {
|
||||
|
@ -222,6 +223,8 @@ enum intel_pch {
|
|||
PCH_CPT, /* Cougarpoint PCH */
|
||||
};
|
||||
|
||||
#define QUIRK_PIPEA_FORCE (1<<0)
|
||||
|
||||
struct intel_fbdev;
|
||||
|
||||
typedef struct drm_i915_private {
|
||||
|
@ -337,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;
|
||||
|
|
|
@ -3647,6 +3647,7 @@ i915_gem_wait_for_pending_flip(struct drm_device *dev,
|
|||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
i915_gem_do_execbuffer(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv,
|
||||
|
@ -3794,7 +3795,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
|
|||
unsigned long long total_size = 0;
|
||||
int num_fences = 0;
|
||||
for (i = 0; i < args->buffer_count; i++) {
|
||||
obj_priv = object_list[i]->driver_private;
|
||||
obj_priv = to_intel_bo(object_list[i]);
|
||||
|
||||
total_size += object_list[i]->size;
|
||||
num_fences +=
|
||||
|
|
|
@ -2869,6 +2869,7 @@
|
|||
|
||||
#define PCH_PP_STATUS 0xc7200
|
||||
#define PCH_PP_CONTROL 0xc7204
|
||||
#define PANEL_UNLOCK_REGS (0xabcd << 16)
|
||||
#define EDP_FORCE_VDD (1 << 3)
|
||||
#define EDP_BLC_ENABLE (1 << 2)
|
||||
#define PANEL_POWER_RESET (1 << 1)
|
||||
|
|
|
@ -862,8 +862,8 @@ intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
|
|||
intel_clock_t clock;
|
||||
int max_n;
|
||||
bool found;
|
||||
/* approximately equals target * 0.00488 */
|
||||
int err_most = (target >> 8) + (target >> 10);
|
||||
/* approximately equals target * 0.00585 */
|
||||
int err_most = (target >> 8) + (target >> 9);
|
||||
found = false;
|
||||
|
||||
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
|
||||
|
@ -1180,8 +1180,12 @@ static void intel_update_fbc(struct drm_crtc *crtc,
|
|||
struct drm_framebuffer *fb = crtc->fb;
|
||||
struct intel_framebuffer *intel_fb;
|
||||
struct drm_i915_gem_object *obj_priv;
|
||||
struct drm_crtc *tmp_crtc;
|
||||
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
||||
int plane = intel_crtc->plane;
|
||||
int crtcs_enabled = 0;
|
||||
|
||||
DRM_DEBUG_KMS("\n");
|
||||
|
||||
if (!i915_powersave)
|
||||
return;
|
||||
|
@ -1199,10 +1203,21 @@ static void intel_update_fbc(struct drm_crtc *crtc,
|
|||
* If FBC is already on, we just have to verify that we can
|
||||
* keep it that way...
|
||||
* Need to disable if:
|
||||
* - more than one pipe is active
|
||||
* - changing FBC params (stride, fence, mode)
|
||||
* - new fb is too large to fit in compressed buffer
|
||||
* - going to an unsupported config (interlace, pixel multiply, etc.)
|
||||
*/
|
||||
list_for_each_entry(tmp_crtc, &dev->mode_config.crtc_list, head) {
|
||||
if (tmp_crtc->enabled)
|
||||
crtcs_enabled++;
|
||||
}
|
||||
DRM_DEBUG_KMS("%d pipes active\n", crtcs_enabled);
|
||||
if (crtcs_enabled > 1) {
|
||||
DRM_DEBUG_KMS("more than one pipe active, disabling compression\n");
|
||||
dev_priv->no_fbc_reason = FBC_MULTIPLE_PIPES;
|
||||
goto out_disable;
|
||||
}
|
||||
if (intel_fb->obj->size > dev_priv->cfb_size) {
|
||||
DRM_DEBUG_KMS("framebuffer too large, disabling "
|
||||
"compression\n");
|
||||
|
@ -1255,7 +1270,7 @@ out_disable:
|
|||
}
|
||||
}
|
||||
|
||||
static int
|
||||
int
|
||||
intel_pin_and_fence_fb_obj(struct drm_device *dev, struct drm_gem_object *obj)
|
||||
{
|
||||
struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
|
||||
|
@ -2255,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) {
|
||||
|
@ -2270,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;
|
||||
|
@ -2356,8 +2376,6 @@ static bool intel_crtc_mode_fixup(struct drm_crtc *crtc,
|
|||
if (mode->clock * 3 > 27000 * 4)
|
||||
return MODE_CLOCK_HIGH;
|
||||
}
|
||||
|
||||
drm_mode_set_crtcinfo(adjusted_mode, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -3736,6 +3754,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
|
|||
if (dev_priv->lvds_dither) {
|
||||
if (HAS_PCH_SPLIT(dev)) {
|
||||
pipeconf |= PIPE_ENABLE_DITHER;
|
||||
pipeconf &= ~PIPE_DITHER_TYPE_MASK;
|
||||
pipeconf |= PIPE_DITHER_TYPE_ST01;
|
||||
} else
|
||||
lvds |= LVDS_ENABLE_DITHER;
|
||||
|
@ -4412,7 +4431,8 @@ static void intel_increase_pllclock(struct drm_crtc *crtc, bool schedule)
|
|||
DRM_DEBUG_DRIVER("upclocking LVDS\n");
|
||||
|
||||
/* Unlock panel regs */
|
||||
I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) | (0xabcd << 16));
|
||||
I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) |
|
||||
PANEL_UNLOCK_REGS);
|
||||
|
||||
dpll &= ~DISPLAY_RATE_SELECT_FPA1;
|
||||
I915_WRITE(dpll_reg, dpll);
|
||||
|
@ -4455,7 +4475,8 @@ static void intel_decrease_pllclock(struct drm_crtc *crtc)
|
|||
DRM_DEBUG_DRIVER("downclocking LVDS\n");
|
||||
|
||||
/* Unlock panel regs */
|
||||
I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) | (0xabcd << 16));
|
||||
I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) |
|
||||
PANEL_UNLOCK_REGS);
|
||||
|
||||
dpll |= DISPLAY_RATE_SELECT_FPA1;
|
||||
I915_WRITE(dpll_reg, dpll);
|
||||
|
@ -4695,7 +4716,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
|
|||
struct drm_gem_object *obj;
|
||||
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
||||
struct intel_unpin_work *work;
|
||||
unsigned long flags;
|
||||
unsigned long flags, offset;
|
||||
int pipesrc_reg = (intel_crtc->pipe == 0) ? PIPEASRC : PIPEBSRC;
|
||||
int ret, pipesrc;
|
||||
u32 flip_mask;
|
||||
|
@ -4762,19 +4783,23 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
|
|||
while (I915_READ(ISR) & flip_mask)
|
||||
;
|
||||
|
||||
/* Offset into the new buffer for cases of shared fbs between CRTCs */
|
||||
offset = obj_priv->gtt_offset;
|
||||
offset += (crtc->y * fb->pitch) + (crtc->x * (fb->bits_per_pixel) / 8);
|
||||
|
||||
BEGIN_LP_RING(4);
|
||||
if (IS_I965G(dev)) {
|
||||
OUT_RING(MI_DISPLAY_FLIP |
|
||||
MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
|
||||
OUT_RING(fb->pitch);
|
||||
OUT_RING(obj_priv->gtt_offset | obj_priv->tiling_mode);
|
||||
OUT_RING(offset | obj_priv->tiling_mode);
|
||||
pipesrc = I915_READ(pipesrc_reg);
|
||||
OUT_RING(pipesrc & 0x0fff0fff);
|
||||
} else {
|
||||
OUT_RING(MI_DISPLAY_FLIP_I915 |
|
||||
MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
|
||||
OUT_RING(fb->pitch);
|
||||
OUT_RING(obj_priv->gtt_offset);
|
||||
OUT_RING(offset);
|
||||
OUT_RING(MI_NOOP);
|
||||
}
|
||||
ADVANCE_LP_RING();
|
||||
|
@ -5506,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;
|
||||
|
@ -5518,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)) {
|
||||
|
|
|
@ -717,6 +717,51 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
|
|||
}
|
||||
}
|
||||
|
||||
static void ironlake_edp_panel_on (struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
unsigned long timeout = jiffies + msecs_to_jiffies(5000);
|
||||
u32 pp, pp_status;
|
||||
|
||||
pp_status = I915_READ(PCH_PP_STATUS);
|
||||
if (pp_status & PP_ON)
|
||||
return;
|
||||
|
||||
pp = I915_READ(PCH_PP_CONTROL);
|
||||
pp |= PANEL_UNLOCK_REGS | POWER_TARGET_ON;
|
||||
I915_WRITE(PCH_PP_CONTROL, pp);
|
||||
do {
|
||||
pp_status = I915_READ(PCH_PP_STATUS);
|
||||
} while (((pp_status & PP_ON) == 0) && !time_after(jiffies, timeout));
|
||||
|
||||
if (time_after(jiffies, timeout))
|
||||
DRM_DEBUG_KMS("panel on wait timed out: 0x%08x\n", pp_status);
|
||||
|
||||
pp &= ~(PANEL_UNLOCK_REGS | EDP_FORCE_VDD);
|
||||
I915_WRITE(PCH_PP_CONTROL, pp);
|
||||
}
|
||||
|
||||
static void ironlake_edp_panel_off (struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
unsigned long timeout = jiffies + msecs_to_jiffies(5000);
|
||||
u32 pp, pp_status;
|
||||
|
||||
pp = I915_READ(PCH_PP_CONTROL);
|
||||
pp &= ~POWER_TARGET_ON;
|
||||
I915_WRITE(PCH_PP_CONTROL, pp);
|
||||
do {
|
||||
pp_status = I915_READ(PCH_PP_STATUS);
|
||||
} while ((pp_status & PP_ON) && !time_after(jiffies, timeout));
|
||||
|
||||
if (time_after(jiffies, timeout))
|
||||
DRM_DEBUG_KMS("panel off wait timed out\n");
|
||||
|
||||
/* Make sure VDD is enabled so DP AUX will work */
|
||||
pp |= EDP_FORCE_VDD;
|
||||
I915_WRITE(PCH_PP_CONTROL, pp);
|
||||
}
|
||||
|
||||
static void ironlake_edp_backlight_on (struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
|
@ -751,14 +796,18 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode)
|
|||
if (mode != DRM_MODE_DPMS_ON) {
|
||||
if (dp_reg & DP_PORT_EN) {
|
||||
intel_dp_link_down(intel_encoder, dp_priv->DP);
|
||||
if (IS_eDP(intel_encoder))
|
||||
if (IS_eDP(intel_encoder)) {
|
||||
ironlake_edp_backlight_off(dev);
|
||||
ironlake_edp_backlight_off(dev);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!(dp_reg & DP_PORT_EN)) {
|
||||
intel_dp_link_train(intel_encoder, dp_priv->DP, dp_priv->link_configuration);
|
||||
if (IS_eDP(intel_encoder))
|
||||
if (IS_eDP(intel_encoder)) {
|
||||
ironlake_edp_panel_on(dev);
|
||||
ironlake_edp_backlight_on(dev);
|
||||
}
|
||||
}
|
||||
}
|
||||
dp_priv->dpms_mode = mode;
|
||||
|
|
|
@ -215,6 +215,9 @@ extern void intel_init_clock_gating(struct drm_device *dev);
|
|||
extern void ironlake_enable_drps(struct drm_device *dev);
|
||||
extern void ironlake_disable_drps(struct drm_device *dev);
|
||||
|
||||
extern int intel_pin_and_fence_fb_obj(struct drm_device *dev,
|
||||
struct drm_gem_object *obj);
|
||||
|
||||
extern int intel_framebuffer_init(struct drm_device *dev,
|
||||
struct intel_framebuffer *ifb,
|
||||
struct drm_mode_fb_cmd *mode_cmd,
|
||||
|
|
|
@ -98,7 +98,7 @@ static int intelfb_create(struct intel_fbdev *ifbdev,
|
|||
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
|
||||
ret = i915_gem_object_pin(fbo, 64*1024);
|
||||
ret = intel_pin_and_fence_fb_obj(dev, fbo);
|
||||
if (ret) {
|
||||
DRM_ERROR("failed to pin fb: %d\n", ret);
|
||||
goto out_unref;
|
||||
|
@ -236,7 +236,7 @@ int intel_fbdev_destroy(struct drm_device *dev,
|
|||
|
||||
drm_framebuffer_cleanup(&ifb->base);
|
||||
if (ifb->obj)
|
||||
drm_gem_object_unreference_unlocked(ifb->obj);
|
||||
drm_gem_object_unreference(ifb->obj);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -599,6 +599,26 @@ static int intel_lvds_get_modes(struct drm_connector *connector)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int intel_no_modeset_on_lid_dmi_callback(const struct dmi_system_id *id)
|
||||
{
|
||||
DRM_DEBUG_KMS("Skipping forced modeset for %s\n", id->ident);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* The GPU hangs up on these systems if modeset is performed on LID open */
|
||||
static const struct dmi_system_id intel_no_modeset_on_lid[] = {
|
||||
{
|
||||
.callback = intel_no_modeset_on_lid_dmi_callback,
|
||||
.ident = "Toshiba Tecra A11",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "TECRA A11"),
|
||||
},
|
||||
},
|
||||
|
||||
{ } /* terminating entry */
|
||||
};
|
||||
|
||||
/*
|
||||
* Lid events. Note the use of 'modeset_on_lid':
|
||||
* - we set it on lid close, and reset it on open
|
||||
|
@ -622,6 +642,9 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val,
|
|||
*/
|
||||
if (connector)
|
||||
connector->status = connector->funcs->detect(connector);
|
||||
/* Don't force modeset on machines where it causes a GPU lockup */
|
||||
if (dmi_check_system(intel_no_modeset_on_lid))
|
||||
return NOTIFY_OK;
|
||||
if (!acpi_lid_open()) {
|
||||
dev_priv->modeset_on_lid = 1;
|
||||
return NOTIFY_OK;
|
||||
|
|
Loading…
Reference in New Issue