summaryrefslogtreecommitdiff
path: root/driver
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2012-09-17 12:41:16 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2012-09-17 12:41:16 +0000
commit4afbf70e15dc636cd4f2d902ced25c1698b505a6 (patch)
tree8d8c5823bf9047f5141c102694ce72309e488abc /driver
parent54d7fea877772d4ae09bdaea6920e7b59fc23a30 (diff)
Improve hack to restore text mode on ironlake/sandy bridge.
tested by many ok jsg@, deraadt@
Diffstat (limited to 'driver')
-rw-r--r--driver/xf86-video-intel/src/i830_lvds.c13
-rw-r--r--driver/xf86-video-intel/src/intel_driver.c74
2 files changed, 55 insertions, 32 deletions
diff --git a/driver/xf86-video-intel/src/i830_lvds.c b/driver/xf86-video-intel/src/i830_lvds.c
index 8cecdfe63..588db2ebd 100644
--- a/driver/xf86-video-intel/src/i830_lvds.c
+++ b/driver/xf86-video-intel/src/i830_lvds.c
@@ -576,8 +576,8 @@ i830_lvds_save (xf86OutputPtr output)
I830OutputPrivatePtr intel_output = output->driver_private;
struct i830_lvds_priv *dev_priv = intel_output->dev_priv;
ScrnInfoPtr scrn = output->scrn;
- intel_screen_private *intel = intel_get_screen_private(scrn);
- uint32_t pp_on_reg, pp_off_reg, pp_ctl_reg, pp_div_reg, pwm_ctl_reg;
+ intel_screen_private *intel = intel_get_screen_private(scrn);
+ uint32_t pp_on_reg, pp_off_reg, pp_ctl_reg, pp_div_reg, pwm_ctl_reg;
if (HAS_PCH_SPLIT(intel)) {
pp_on_reg = PCH_PP_ON_DELAYS;
@@ -600,15 +600,17 @@ i830_lvds_save (xf86OutputPtr output)
intel->savePP_CONTROL = INREG(pp_ctl_reg);
intel->savePP_DIVISOR = INREG(pp_div_reg);
intel->saveBLC_PWM_CTL = INREG(pwm_ctl_reg);
- if ((INREG(PP_CONTROL) & POWER_TARGET_ON) && !dev_priv->dpmsoff)
+ if ((intel->savePP_CONTROL & POWER_TARGET_ON) && !dev_priv->dpmsoff)
dev_priv->backlight_duty_cycle = dev_priv->get_backlight(output);
}
static void
i830_lvds_restore(xf86OutputPtr output)
{
- ScrnInfoPtr scrn = output->scrn;
- intel_screen_private *intel = intel_get_screen_private(scrn);
+ I830OutputPrivatePtr intel_output = output->driver_private;
+ struct i830_lvds_priv *dev_priv = intel_output->dev_priv;
+ ScrnInfoPtr scrn = output->scrn;
+ intel_screen_private *intel = intel_get_screen_private(scrn);
uint32_t pp_on_reg, pp_off_reg, pp_ctl_reg, pp_div_reg;
uint32_t pwm_ctl_reg;
@@ -638,6 +640,7 @@ i830_lvds_restore(xf86OutputPtr output)
i830SetLVDSPanelPower(output, TRUE);
else
i830SetLVDSPanelPower(output, FALSE);
+ dev_priv->dpmsoff = TRUE;
}
static int
diff --git a/driver/xf86-video-intel/src/intel_driver.c b/driver/xf86-video-intel/src/intel_driver.c
index 94d2553ca..c88e07281 100644
--- a/driver/xf86-video-intel/src/intel_driver.c
+++ b/driver/xf86-video-intel/src/intel_driver.c
@@ -1552,29 +1552,29 @@ static Bool I830PreInit(ScrnInfoPtr scrn, int flags)
}
if (!intel->use_drm_mode) {
- /* console hack, stolen from G80 */
- if (IS_GEN5(intel)) {
- if (xf86LoadSubModule(scrn, "int10")) {
- intel->int10 = xf86InitInt10(pEnt->index);
- if (intel->int10) {
- intel->int10->num = 0x10;
- intel->int10->ax = 0x4f03;
- intel->int10->bx =
- intel->int10->cx =
- intel->int10->dx = 0;
- xf86ExecX86int10(intel->int10);
- intel->int10Mode = intel->int10->bx & 0x3fff;
- xf86DrvMsg(scrn->scrnIndex, X_PROBED,
- "Console VGA mode is 0x%x\n", intel->int10Mode);
- } else {
- xf86DrvMsg(scrn->scrnIndex, X_WARNING,
- "Failed int10 setup, VT switch won't work\n");
- }
- } else {
- xf86DrvMsg(scrn->scrnIndex, X_WARNING,
- "Failed to load int10module, ironlake vt switch broken");
- }
- }
+ /* console restore hack */
+ if (HAS_PCH_SPLIT(intel)) {
+ if (xf86LoadSubModule(scrn, "int10")) {
+ intel->int10 = xf86InitInt10(pEnt->index);
+ if (intel->int10) {
+ intel->int10->num = 0x10;
+ intel->int10->ax = 0x4f03;
+ intel->int10->bx =
+ intel->int10->cx =
+ intel->int10->dx = 0;
+ xf86ExecX86int10(intel->int10);
+ intel->int10Mode = intel->int10->bx & 0x3fff;
+ xf86DrvMsg(scrn->scrnIndex, X_PROBED,
+ "Console VGA mode is 0x%x\n", intel->int10Mode);
+ } else {
+ xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+ "Failed int10 setup, VT switch won't work\n");
+ }
+ } else {
+ xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+ "Failed to load int10module, ironlake vt switch broken");
+ }
+ }
I830UnmapMMIO(scrn);
@@ -1659,8 +1659,15 @@ static Bool SaveHWState(ScrnInfoPtr scrn)
vgaRegPtr vgaReg = &hwp->SavedReg;
int i;
- if (HAS_PCH_SPLIT(intel))
+ if (HAS_PCH_SPLIT(intel)) {
+ for (i = 0; i < xf86_config->num_output; i++) {
+ xf86OutputPtr output = xf86_config->output[i];
+ if (output->funcs->save)
+ (*output->funcs->save) (output);
+ }
+
return TRUE;
+ }
/* Save video mode information for native mode-setting. */
if (!DSPARB_HWCONTROL(intel))
@@ -1780,8 +1787,16 @@ static Bool RestoreHWState(ScrnInfoPtr scrn)
vgaRegPtr vgaReg = &hwp->SavedReg;
int i;
- if (HAS_PCH_SPLIT(intel))
+ if (HAS_PCH_SPLIT(intel)) {
+ /* Restore outputs */
+ for (i = 0; i < xf86_config->num_output; i++) {
+ xf86OutputPtr output = xf86_config->output[i];
+ if (output->funcs->restore)
+ output->funcs->restore(output);
+ }
+
return TRUE;
+ }
DPRINTF(PFX, "RestoreHWState\n");
@@ -2601,9 +2616,15 @@ static void I830LeaveVT(VT_FUNC_ARGS_DECL)
RestoreHWState(scrn);
/* console restore hack */
- if (IS_GEN5(intel) && intel->int10 && intel->int10Mode) {
+ if (HAS_PCH_SPLIT(intel) && intel->int10 && intel->int10Mode) {
xf86Int10InfoPtr int10 = intel->int10;
+ /* Unlock the PP_CONTROL register, otherwise the
+ * int10 call fails to turn the panel back on.
+ */
+ OUTREG(PCH_PP_CONTROL,
+ INREG(PCH_PP_CONTROL) | (0xabcd << 16));
+
/* Use int10 to restore the console mode */
int10->num = 0x10;
int10->ax = 0x4f02;
@@ -2611,7 +2632,6 @@ static void I830LeaveVT(VT_FUNC_ARGS_DECL)
int10->cx = int10->dx = 0;
xf86ExecX86int10(int10);
}
-
}
i830_unbind_all_memory(scrn);