summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2006-10-04 15:00:19 -0700
committerEric Anholt <eric@anholt.net>2006-10-04 18:48:17 -0700
commit103b4edce7859ddf58f3e1fadeb427a5e85c7acd (patch)
tree3907bea3aa233a1587d075fe81bd515d8d5fa4c5 /src
parent3e6f81f70f65a5ba6b5c3a4e0eeaf67776a5f54d (diff)
Move the save, restore, and DPMS per-output settings to per-output files.
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am2
-rw-r--r--src/i830.h32
-rw-r--r--src/i830_crt.c75
-rw-r--r--src/i830_display.c6
-rw-r--r--src/i830_driver.c152
-rw-r--r--src/i830_dvo.c45
-rw-r--r--src/i830_lvds.c81
-rw-r--r--src/i830_sdvo.c26
-rw-r--r--src/i830_sdvo.h6
9 files changed, 288 insertions, 137 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 7af2dd7e..cab6fe92 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -53,6 +53,7 @@ i810_drv_la_SOURCES = \
i830_bios.c \
i830_bios.h \
i830_common.h \
+ i830_crt.c \
i830_cursor.c \
i830_debug.c \
i830_debug.h \
@@ -65,6 +66,7 @@ i810_drv_la_SOURCES = \
i830_gtf.c \
i830_i2c.c \
i830_io.c \
+ i830_lvds.c \
i830_memory.c \
i830_modes.c \
i830_video.c \
diff --git a/src/i830.h b/src/i830.h
index 7def141e..f92704b0 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -69,6 +69,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "i830_dri.h"
#endif
+typedef struct _I830OutputRec I830OutputRec, *I830OutputPtr;
+
#include "common.h"
#include "i830_sdvo.h"
#include "i2c_vid.h"
@@ -222,6 +224,23 @@ struct _I830OutputRec {
int type;
/* int pipe;
int flags;*/
+
+ /**
+ * Turns the output on/off, or sets intermediate power levels if available.
+ * Unsupported intermediate modes drop to the lower power setting.
+ */
+ void (*dpms)(ScrnInfoPtr pScrn, I830OutputPtr output, int mode);
+
+ /**
+ * Saves the output's state for restoration on VT switch.
+ */
+ void (*save)(ScrnInfoPtr pScrn, I830OutputPtr output);
+
+ /**
+ * Restore's the output's state at VT switch.
+ */
+ void (*restore)(ScrnInfoPtr pScrn, I830OutputPtr output);
+
xf86MonPtr MonInfo;
I2CBusPtr pI2CBus;
I2CBusPtr pDDCBus;
@@ -613,10 +632,23 @@ extern Bool I830FixOffset(ScrnInfoPtr pScrn, I830MemRange *mem);
extern Bool I830I2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, int i2c_reg,
char *name);
+/* i830_crt.c */
+void I830CRTDPMS(ScrnInfoPtr pScrn, I830OutputPtr output, int mode);
+void I830CRTSave(ScrnInfoPtr pScrn, I830OutputPtr output);
+void I830CRTRestore(ScrnInfoPtr pScrn, I830OutputPtr output);
+
/* i830_dvo.c */
+void I830DVODPMS(ScrnInfoPtr pScrn, I830OutputPtr output, int mode);
+void I830DVOSave(ScrnInfoPtr pScrn, I830OutputPtr output);
+void I830DVORestore(ScrnInfoPtr pScrn, I830OutputPtr output);
Bool I830I2CDetectDVOControllers(ScrnInfoPtr pScrn, I2CBusPtr pI2CBus,
struct _I830DVODriver **retdrv);
+/* i830_lvds.c */
+void I830LVDSDPMS(ScrnInfoPtr pScrn, I830OutputPtr output, int mode);
+void I830LVDSSave(ScrnInfoPtr pScrn, I830OutputPtr output);
+void I830LVDSRestore(ScrnInfoPtr pScrn, I830OutputPtr output);
+
/* i830_memory.c */
Bool I830BindAGPMemory(ScrnInfoPtr pScrn);
Bool I830UnbindAGPMemory(ScrnInfoPtr pScrn);
diff --git a/src/i830_crt.c b/src/i830_crt.c
new file mode 100644
index 00000000..1a0dd0b5
--- /dev/null
+++ b/src/i830_crt.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright © 2006 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Eric Anholt <eric@anholt.net>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "xf86.h"
+#include "i830.h"
+
+void
+I830CRTDPMS(ScrnInfoPtr pScrn, I830OutputPtr output, int mode)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ CARD32 temp;
+
+ temp = INREG(ADPA);
+ temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE);
+
+ switch(mode) {
+ case DPMSModeOn:
+ break;
+ case DPMSModeStandby:
+ temp |= ADPA_HSYNC_CNTL_DISABLE;
+ break;
+ case DPMSModeSuspend:
+ temp |= ADPA_VSYNC_CNTL_DISABLE;
+ break;
+ case DPMSModeOff:
+ temp |= ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE;
+ break;
+ }
+
+ OUTREG(ADPA, temp);
+}
+
+void
+I830CRTSave(ScrnInfoPtr pScrn, I830OutputPtr output)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+
+ pI830->saveADPA = INREG(ADPA);
+}
+
+void
+I830CRTRestore(ScrnInfoPtr pScrn, I830OutputPtr output)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+
+ OUTREG(ADPA, pI830->saveADPA);
+}
diff --git a/src/i830_display.c b/src/i830_display.c
index 2b53128c..5a0fb9d8 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -864,10 +864,10 @@ i830SetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
}
for (i = 0; i < pI830->num_outputs; i++) {
- struct _I830OutputRec *output = &pI830->output[i];
+ I830OutputPtr output = &pI830->output[i];
- if (output->sdvo_drv)
- I830SDVOPreSetMode(output->sdvo_drv, pMode);
+ if (pI830->output[i].sdvo_drv != NULL)
+ pI830->output[i].dpms(pScrn, &pI830->output[i], DPMSModeOff);
if (output->i2c_drv != NULL)
output->i2c_drv->vid_rec->Mode(output->i2c_drv->dev_priv,
diff --git a/src/i830_driver.c b/src/i830_driver.c
index d46fc1bd..93c7fc42 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -909,6 +909,9 @@ I830SetupOutputBusses(ScrnInfoPtr pScrn)
/* everyone has at least a single analog output */
pI830->output[i].type = I830_OUTPUT_ANALOG;
+ pI830->output[i].dpms = I830CRTDPMS;
+ pI830->output[i].save = I830CRTSave;
+ pI830->output[i].restore = I830CRTRestore;
/* setup the DDC bus for the analog output */
I830I2CInit(pScrn, &pI830->output[i].pDDCBus, GPIOA, "CRTDDC_A");
@@ -917,6 +920,9 @@ I830SetupOutputBusses(ScrnInfoPtr pScrn)
if (IS_MOBILE(pI830) && !IS_I830(pI830)) {
/* Set up integrated LVDS */
pI830->output[i].type = I830_OUTPUT_LVDS;
+ pI830->output[i].dpms = I830LVDSDPMS;
+ pI830->output[i].save = I830LVDSSave;
+ pI830->output[i].restore = I830LVDSRestore;
I830I2CInit(pScrn, &pI830->output[i].pDDCBus, GPIOC, "LVDSDDC_C");
i++;
}
@@ -924,18 +930,27 @@ I830SetupOutputBusses(ScrnInfoPtr pScrn)
if (IS_I9XX(pI830)) {
/* Set up SDVOB */
pI830->output[i].type = I830_OUTPUT_SDVO;
+ pI830->output[i].dpms = i830SDVODPMS;
+ pI830->output[i].save = i830SDVOSave;
+ pI830->output[i].restore = i830SDVORestore;
I830I2CInit(pScrn, &pI830->output[i].pI2CBus, GPIOE, "SDVOCTRL_E");
I830SDVOInit(pScrn, i, SDVOB);
i++;
/* Set up SDVOC */
pI830->output[i].type = I830_OUTPUT_SDVO;
+ pI830->output[i].dpms = i830SDVODPMS;
+ pI830->output[i].save = i830SDVOSave;
+ pI830->output[i].restore = i830SDVORestore;
pI830->output[i].pI2CBus = pI830->output[i-1].pI2CBus;
I830SDVOInit(pScrn, i, SDVOC);
i++;
} else {
/* set up DVO */
pI830->output[i].type = I830_OUTPUT_DVO;
+ pI830->output[i].dpms = I830DVODPMS;
+ pI830->output[i].save = I830DVOSave;
+ pI830->output[i].restore = I830DVORestore;
I830I2CInit(pScrn, &pI830->output[i].pDDCBus, GPIOD, "DVODDC_D");
I830I2CInit(pScrn, &pI830->output[i].pI2CBus, GPIOE, "DVOI2C_E");
@@ -2600,31 +2615,6 @@ SaveHWState(ScrnInfoPtr pScrn)
pI830->saveVCLK_POST_DIV = INREG(VCLK_POST_DIV);
pI830->saveVGACNTRL = INREG(VGACNTRL);
- pI830->saveADPA = INREG(ADPA);
-
- pI830->savePFIT_CONTROL = INREG(PFIT_CONTROL);
- pI830->savePP_ON = INREG(LVDSPP_ON);
- pI830->savePP_OFF = INREG(LVDSPP_OFF);
- pI830->saveLVDS = INREG(LVDS);
- pI830->savePP_CONTROL = INREG(PP_CONTROL);
- pI830->savePP_CYCLE = INREG(PP_CYCLE);
- pI830->saveBLC_PWM_CTL = INREG(BLC_PWM_CTL);
- pI830->backlight_duty_cycle = (pI830->saveBLC_PWM_CTL &
- BACKLIGHT_DUTY_CYCLE_MASK);
- /*
- * If the light is off at server startup, just make it full brightness
- */
- if (!pI830->backlight_duty_cycle)
- pI830->backlight_duty_cycle = ((pI830->saveBLC_PWM_CTL &
- BACKLIGHT_MODULATION_FREQ_MASK) >>
- BACKLIGHT_MODULATION_FREQ_SHIFT);
-
- if (!IS_I9XX(pI830)) {
- pI830->saveDVOA = INREG(DVOA);
- pI830->saveDVOB = INREG(DVOB);
- pI830->saveDVOC = INREG(DVOC);
- }
-
for(i = 0; i < 7; i++) {
pI830->saveSWF[i] = INREG(SWF0 + (i << 2));
pI830->saveSWF[i+7] = INREG(SWF00 + (i << 2));
@@ -2634,17 +2624,8 @@ SaveHWState(ScrnInfoPtr pScrn)
pI830->saveSWF[16] = INREG(SWF32);
for (i = 0; i < pI830->num_outputs; i++) {
- if (pI830->output[i].type == I830_OUTPUT_DVO &&
- pI830->output[i].i2c_drv != NULL)
- {
- pI830->output[i].i2c_drv->vid_rec->SaveRegs(
- pI830->output[i].i2c_drv->dev_priv);
- }
- if (pI830->output[i].type == I830_OUTPUT_SDVO &&
- pI830->output[i].sdvo_drv != NULL)
- {
- i830SDVOSave(pScrn, i);
- }
+ if (pI830->output[i].save != NULL)
+ pI830->output[i].save(pScrn, &pI830->output[i]);
}
vgaHWUnlock(hwp);
@@ -2670,6 +2651,11 @@ RestoreHWState(ScrnInfoPtr pScrn)
vgaHWRestore(pScrn, vgaReg, VGA_SR_FONTS);
vgaHWLock(hwp);
+ /* Disable outputs */
+ for (i = 0; i < pI830->num_outputs; i++) {
+ pI830->output[i].dpms(pScrn, &pI830->output[i], DPMSModeOff);
+ }
+
/* First, disable display planes */
temp = INREG(DSPACNTR);
OUTREG(DSPACNTR, temp & ~DISPLAY_PLANE_ENABLE);
@@ -2682,18 +2668,7 @@ RestoreHWState(ScrnInfoPtr pScrn)
temp = INREG(PIPEBCONF);
OUTREG(PIPEBCONF, temp & ~PIPEBCONF_ENABLE);
- /* XXX: Wait for a vblank */
- sleep(1);
-
- i830SetLVDSPanelPower(pScrn, FALSE);
-
- for (i = 0; i < pI830->num_outputs; i++) {
- if (pI830->output[i].type == I830_OUTPUT_SDVO &&
- pI830->output[i].sdvo_drv != NULL)
- {
- i830SDVOPreRestore(pScrn, i);
- }
- }
+ i830WaitForVblank(pScrn);
OUTREG(FPA0, pI830->saveFPA0);
OUTREG(FPA1, pI830->saveFPA1);
@@ -2738,12 +2713,6 @@ RestoreHWState(ScrnInfoPtr pScrn)
OUTREG(DSPBSURF, pI830->saveDSPBBASE);
}
- OUTREG(BLC_PWM_CTL, pI830->saveBLC_PWM_CTL);
- OUTREG(LVDSPP_ON, pI830->savePP_ON);
- OUTREG(LVDSPP_OFF, pI830->savePP_OFF);
- OUTREG(PP_CYCLE, pI830->savePP_CYCLE);
- OUTREG(PFIT_CONTROL, pI830->savePFIT_CONTROL);
-
OUTREG(VCLK_DIVISOR_VGA0, pI830->saveVCLK_DIVISOR_VGA0);
OUTREG(VCLK_DIVISOR_VGA1, pI830->saveVCLK_DIVISOR_VGA1);
OUTREG(VCLK_POST_DIV, pI830->saveVCLK_POST_DIV);
@@ -2755,30 +2724,10 @@ RestoreHWState(ScrnInfoPtr pScrn)
OUTREG(DSPACNTR, pI830->saveDSPACNTR);
OUTREG(DSPBCNTR, pI830->saveDSPBCNTR);
- OUTREG(ADPA, pI830->saveADPA);
- OUTREG(LVDS, pI830->saveLVDS);
- if (!IS_I9XX(pI830)) {
- OUTREG(DVOA, pI830->saveDVOA);
- OUTREG(DVOB, pI830->saveDVOB);
- OUTREG(DVOC, pI830->saveDVOC);
- }
-
for (i = 0; i < pI830->num_outputs; i++) {
- if (pI830->output[i].type == I830_OUTPUT_DVO &&
- pI830->output[i].i2c_drv != NULL)
- {
- pI830->output[i].i2c_drv->vid_rec->RestoreRegs(
- pI830->output[i].i2c_drv->dev_priv);
- }
- if (pI830->output[i].type == I830_OUTPUT_SDVO &&
- pI830->output[i].sdvo_drv != NULL)
- {
- i830SDVOPostRestore(pScrn, i);
- }
+ pI830->output[i].restore(pScrn, &pI830->output[i]);
}
- OUTREG(PP_CONTROL, pI830->savePP_CONTROL);
-
for(i = 0; i < 7; i++) {
OUTREG(SWF0 + (i << 2), pI830->saveSWF[i]);
OUTREG(SWF00 + (i << 2), pI830->saveSWF[i+7]);
@@ -4204,39 +4153,6 @@ I830SaveScreen(ScreenPtr pScreen, int mode)
return TRUE;
}
-static void
-I830DPMSCRT(ScrnInfoPtr pScrn, int mode)
-{
- I830Ptr pI830 = I830PTR(pScrn);
- CARD32 temp;
-
- temp = INREG(ADPA);
- temp &= ~(ADPA_HSYNC_CNTL_DISABLE|ADPA_VSYNC_CNTL_DISABLE);
- switch(mode) {
- case DPMSModeOn:
- break;
- case DPMSModeStandby:
- temp |= ADPA_HSYNC_CNTL_DISABLE;
- break;
- case DPMSModeSuspend:
- temp |= ADPA_VSYNC_CNTL_DISABLE;
- break;
- case DPMSModeOff:
- temp |= ADPA_HSYNC_CNTL_DISABLE|ADPA_VSYNC_CNTL_DISABLE;
- break;
- }
- OUTREG(ADPA, temp);
-}
-
-static void
-I830DPMSLVDS(ScrnInfoPtr pScrn, int mode)
-{
- if (mode == DPMSModeOn)
- i830SetLVDSPanelPower(pScrn, TRUE);
- else
- i830SetLVDSPanelPower(pScrn, FALSE);
-}
-
/* Use the VBE version when available. */
static void
I830DisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode,
@@ -4246,6 +4162,10 @@ I830DisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode,
int i;
CARD32 temp, ctrl, base;
+ for (i = 0; i < pI830->num_outputs; i++) {
+ pI830->output[i].dpms(pScrn, &pI830->output[i], PowerManagementMode);
+ }
+
for (i = 0; i < pI830->availablePipes; i++) {
if (i == 0) {
ctrl = DSPACNTR;
@@ -4267,22 +4187,6 @@ I830DisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode,
}
}
- if (pI830->operatingDevices & (PIPE_CRT_ACTIVE | (PIPE_CRT_ACTIVE<<8))) {
- I830DPMSCRT(pScrn, PowerManagementMode);
- }
-
- if (pI830->operatingDevices & (PIPE_LCD_ACTIVE | (PIPE_LCD_ACTIVE<<8))) {
- I830DPMSLVDS(pScrn, PowerManagementMode);
- }
-
- if (pI830->operatingDevices & (PIPE_DFP_ACTIVE | (PIPE_DFP_ACTIVE<<8))) {
- /* TBD */
- }
-
- if (pI830->operatingDevices & (PIPE_DFP2_ACTIVE | (PIPE_DFP2_ACTIVE<<8))) {
- /* TBD */
- }
-
if (pI830->CursorInfoRec && !pI830->SWCursor && pI830->cursorOn) {
if (PowerManagementMode == DPMSModeOn)
pI830->CursorInfoRec->ShowCursor(pScrn);
diff --git a/src/i830_dvo.c b/src/i830_dvo.c
index 242e3dd0..f64a8e85 100644
--- a/src/i830_dvo.c
+++ b/src/i830_dvo.c
@@ -54,6 +54,51 @@ struct _I830DVODriver i830_dvo_drivers[] =
#define I830_NUM_DVO_DRIVERS (sizeof(i830_dvo_drivers)/sizeof(struct _I830DVODriver))
+void
+I830DVODPMS(ScrnInfoPtr pScrn, I830OutputPtr output, int mode)
+{
+ if (output->i2c_drv == NULL)
+ return;
+
+ if (mode == DPMSModeOn)
+ output->i2c_drv->vid_rec->Power(output->i2c_drv->dev_priv, TRUE);
+ else
+ output->i2c_drv->vid_rec->Power(output->i2c_drv->dev_priv, FALSE);
+}
+
+void
+I830DVOSave(ScrnInfoPtr pScrn, I830OutputPtr output)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+
+ if (output->i2c_drv == NULL)
+ return;
+
+ /* Each output should probably just save the registers it touches, but for
+ * now, use more overkill.
+ */
+ pI830->saveDVOA = INREG(DVOA);
+ pI830->saveDVOB = INREG(DVOB);
+ pI830->saveDVOC = INREG(DVOC);
+
+ output->i2c_drv->vid_rec->SaveRegs(output->i2c_drv->dev_priv);
+}
+
+void
+I830DVORestore(ScrnInfoPtr pScrn, I830OutputPtr output)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+
+ if (output->i2c_drv == NULL)
+ return;
+
+ OUTREG(DVOA, pI830->saveDVOA);
+ OUTREG(DVOB, pI830->saveDVOB);
+ OUTREG(DVOC, pI830->saveDVOC);
+
+ output->i2c_drv->vid_rec->RestoreRegs(output->i2c_drv->dev_priv);
+}
+
Bool
I830I2CDetectDVOControllers(ScrnInfoPtr pScrn, I2CBusPtr pI2CBus,
struct _I830DVODriver **retdrv)
diff --git a/src/i830_lvds.c b/src/i830_lvds.c
new file mode 100644
index 00000000..fcd8fee6
--- /dev/null
+++ b/src/i830_lvds.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright © 2006 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Eric Anholt <eric@anholt.net>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "xf86.h"
+#include "i830.h"
+
+void
+I830LVDSDPMS(ScrnInfoPtr pScrn, I830OutputPtr output, int mode)
+{
+ if (mode == DPMSModeOn)
+ i830SetLVDSPanelPower(pScrn, TRUE);
+ else
+ i830SetLVDSPanelPower(pScrn, FALSE);
+}
+
+void
+I830LVDSSave(ScrnInfoPtr pScrn, I830OutputPtr output)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+
+ pI830->savePFIT_CONTROL = INREG(PFIT_CONTROL);
+ pI830->savePP_ON = INREG(LVDSPP_ON);
+ pI830->savePP_OFF = INREG(LVDSPP_OFF);
+ pI830->saveLVDS = INREG(LVDS);
+ pI830->savePP_CONTROL = INREG(PP_CONTROL);
+ pI830->savePP_CYCLE = INREG(PP_CYCLE);
+ pI830->saveBLC_PWM_CTL = INREG(BLC_PWM_CTL);
+ pI830->backlight_duty_cycle = (pI830->saveBLC_PWM_CTL &
+ BACKLIGHT_DUTY_CYCLE_MASK);
+
+ /*
+ * If the light is off at server startup, just make it full brightness
+ */
+ if (pI830->backlight_duty_cycle == 0) {
+ pI830->backlight_duty_cycle =
+ (pI830->saveBLC_PWM_CTL & BACKLIGHT_MODULATION_FREQ_MASK) >>
+ BACKLIGHT_MODULATION_FREQ_SHIFT;
+ }
+}
+
+void
+I830LVDSRestore(ScrnInfoPtr pScrn, I830OutputPtr output)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+
+ OUTREG(BLC_PWM_CTL, pI830->saveBLC_PWM_CTL);
+ OUTREG(LVDSPP_ON, pI830->savePP_ON);
+ OUTREG(LVDSPP_OFF, pI830->savePP_OFF);
+ OUTREG(PP_CYCLE, pI830->savePP_CYCLE);
+ OUTREG(PFIT_CONTROL, pI830->savePFIT_CONTROL);
+ OUTREG(LVDS, pI830->saveLVDS);
+ OUTREG(PP_CONTROL, pI830->savePP_CONTROL);
+}
diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c
index c7625419..a07e7c9d 100644
--- a/src/i830_sdvo.c
+++ b/src/i830_sdvo.c
@@ -640,10 +640,13 @@ I830SDVOPostSetMode(I830SDVOPtr s, DisplayModePtr mode)
}
void
-i830SDVOSave(ScrnInfoPtr pScrn, int output_index)
+i830SDVOSave(ScrnInfoPtr pScrn, I830OutputPtr output)
{
I830Ptr pI830 = I830PTR(pScrn);
- I830SDVOPtr sdvo = pI830->output[output_index].sdvo_drv;
+ I830SDVOPtr sdvo = output->sdvo_drv;
+
+ if (sdvo == NULL)
+ return;
sdvo->save_sdvo_mult = I830SDVOGetClockRateMult(sdvo);
I830SDVOGetActiveOutputs(sdvo, &sdvo->save_sdvo_active_1,
@@ -677,19 +680,28 @@ i830SDVOSave(ScrnInfoPtr pScrn, int output_index)
}
void
-i830SDVOPreRestore(ScrnInfoPtr pScrn, int output_index)
+i830SDVODPMS(ScrnInfoPtr pScrn, I830OutputPtr output, int mode)
{
I830Ptr pI830 = I830PTR(pScrn);
- I830SDVOPtr sdvo = pI830->output[output_index].sdvo_drv;
+ I830SDVOPtr sdvo = output->sdvo_drv;
+
+ if (sdvo == NULL)
+ return;
- I830SDVOSetActiveOutputs(sdvo, FALSE, FALSE);
+ if (mode != DPMSModeOn)
+ I830SDVOSetActiveOutputs(sdvo, FALSE, FALSE);
+ else
+ I830SDVOSetActiveOutputs(sdvo, TRUE, FALSE);
}
void
-i830SDVOPostRestore(ScrnInfoPtr pScrn, int output_index)
+i830SDVORestore(ScrnInfoPtr pScrn, I830OutputPtr output)
{
I830Ptr pI830 = I830PTR(pScrn);
- I830SDVOPtr sdvo = pI830->output[output_index].sdvo_drv;
+ I830SDVOPtr sdvo = output->sdvo_drv;
+
+ if (sdvo == NULL)
+ return;
if (sdvo->caps.caps & 0x1) {
I830SDVOSetTargetInput(sdvo, FALSE, FALSE);
diff --git a/src/i830_sdvo.h b/src/i830_sdvo.h
index 52621e03..73ecf32b 100644
--- a/src/i830_sdvo.h
+++ b/src/i830_sdvo.h
@@ -56,13 +56,13 @@ typedef struct _i830_sdvo_dtd {
} __attribute__((packed)) i830_sdvo_dtd;
void
-i830SDVOSave(ScrnInfoPtr pScrn, int output_index);
+i830SDVODPMS(ScrnInfoPtr pScrn, I830OutputPtr output, int mode);
void
-i830SDVOPreRestore(ScrnInfoPtr pScrn, int output_index);
+i830SDVOSave(ScrnInfoPtr pScrn, I830OutputPtr output);
void
-i830SDVOPostRestore(ScrnInfoPtr pScrn, int output_index);
+i830SDVORestore(ScrnInfoPtr pScrn, I830OutputPtr output);
Bool
I830DetectSDVODisplays(ScrnInfoPtr pScrn, int output_index);