diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/i810_reg.h | 3 | ||||
-rw-r--r-- | src/i830_display.c | 26 | ||||
-rw-r--r-- | src/i830_display.h | 1 | ||||
-rw-r--r-- | src/i830_driver.c | 38 |
4 files changed, 44 insertions, 24 deletions
diff --git a/src/i810_reg.h b/src/i810_reg.h index 1194c231..8785b069 100644 --- a/src/i810_reg.h +++ b/src/i810_reg.h @@ -756,6 +756,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define LVDS 0x61180 # define LVDS_PORT_EN (1 << 31) +# define LVDS_PIPEB_SELECT (1 << 30) +# define LVDS_CLKA_POWER_DOWN (0 << 8) +# define LVDS_CLKA_POWER_UP (3 << 8) #define PIPEACONF 0x70008 #define PIPEACONF_ENABLE (1<<31) diff --git a/src/i830_display.c b/src/i830_display.c index e4ef4775..6bf823a6 100644 --- a/src/i830_display.c +++ b/src/i830_display.c @@ -338,3 +338,29 @@ i830DetectCRT(ScrnInfoPtr pScrn) return ((INREG(PORT_HOTPLUG_STAT) & CRT_HOTPLUG_INT_STATUS)); } + +/** + * Sets the power state for the panel. + */ +void +i830SetLVDSPanelPower(ScrnInfoPtr pScrn, Bool on) +{ + I830Ptr pI830 = I830PTR(pScrn); + CARD32 pp_status, pp_control; + + if (on) { + OUTREG(PP_STATUS, INREG(PP_STATUS) | PP_ON); + OUTREG(PP_CONTROL, INREG(PP_CONTROL) | POWER_TARGET_ON); + do { + pp_status = INREG(PP_STATUS); + pp_control = INREG(PP_CONTROL); + } while (!(pp_status & PP_ON) && !(pp_control & POWER_TARGET_ON)); + } else { + OUTREG(PP_STATUS, INREG(PP_STATUS) & ~PP_ON); + OUTREG(PP_CONTROL, INREG(PP_CONTROL) & ~POWER_TARGET_ON); + do { + pp_status = INREG(PP_STATUS); + pp_control = INREG(PP_CONTROL); + } while ((pp_status & PP_ON) || (pp_control & POWER_TARGET_ON)); + } +} diff --git a/src/i830_display.h b/src/i830_display.h index 6ad150ad..894148c5 100644 --- a/src/i830_display.h +++ b/src/i830_display.h @@ -1,2 +1,3 @@ void i830SetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode); Bool i830DetectCRT(ScreenPtr pScrn); +void i830SetLVDSPanelPower(ScrnInfoPtr pScrn, Bool on); diff --git a/src/i830_driver.c b/src/i830_driver.c index 2fd391ef..88f89d14 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -1061,40 +1061,30 @@ SetDisplayDevices(ScrnInfoPtr pScrn, int devices) /* Disable LVDS */ if (singlepipe & PIPE_LFP) { /* LFP on PipeA is unlikely! */ - OUTREG(PP_STATUS, INREG(PP_STATUS) & ~PP_ON); - OUTREG(PP_CONTROL, INREG(PP_CONTROL) & ~POWER_TARGET_ON); - while ((INREG(PP_STATUS) & PP_ON) || (INREG(PP_CONTROL) & 1)); - /* Fix up LVDS */ - OUTREG(LVDS, (INREG(LVDS) & ~1<<30) | 0x80000300); - /* Enable LVDS */ - OUTREG(PP_STATUS, INREG(PP_STATUS) | PP_ON); - OUTREG(PP_CONTROL, INREG(PP_CONTROL) | POWER_TARGET_ON); - while (!(INREG(PP_STATUS) & PP_ON) && !(INREG(PP_CONTROL) & 1)); + i830SetLVDSPanelPower(pScrn, FALSE); + temp = INREG(LVDS) & ~LVDS_PIPEB_SELECT; + temp |= LVDS_PORT_EN | LVDS_CLKA_POWER_UP; + OUTREG(LVDS, temp); + i830SetLVDSPanelPower(pScrn, TRUE); xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Enabling LVDS directly. Pipe A.\n"); } else if (singlepipe & (PIPE_LFP << 8)) { - OUTREG(PP_STATUS, INREG(PP_STATUS) & ~PP_ON); - OUTREG(PP_CONTROL, INREG(PP_CONTROL) & ~POWER_TARGET_ON); - while ((INREG(PP_STATUS) & PP_ON) || (INREG(PP_CONTROL) & 1)); - /* Fix up LVDS */ - OUTREG(LVDS, (INREG(LVDS) | 1<<30) | 0x80000300); - /* Enable LVDS */ - OUTREG(PP_STATUS, INREG(PP_STATUS) | PP_ON); - OUTREG(PP_CONTROL, INREG(PP_CONTROL) | POWER_TARGET_ON); - while (!(INREG(PP_STATUS) & PP_ON) && - !(INREG(PP_CONTROL) & POWER_TARGET_ON)); + i830SetLVDSPanelPower(pScrn, FALSE); + temp = INREG(LVDS) | LVDS_PIPEB_SELECT; + temp |= LVDS_PORT_EN | LVDS_CLKA_POWER_UP; + OUTREG(LVDS, temp); + i830SetLVDSPanelPower(pScrn, TRUE); xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Enabling LVDS directly. Pipe B.\n"); } else if (!(IS_I830(pI830) || IS_845G(pI830) || IS_I865G(pI830))) { if (!(devices & (PIPE_LFP | PIPE_LFP<<8))) { - OUTREG(PP_STATUS, INREG(PP_STATUS) & ~PP_ON); - OUTREG(PP_CONTROL, INREG(PP_CONTROL) & ~POWER_TARGET_ON); - while ((INREG(PP_STATUS) & PP_ON) || - (INREG(PP_CONTROL) & POWER_TARGET_ON)); + i830SetLVDSPanelPower(pScrn, FALSE); /* Fix up LVDS */ - OUTREG(LVDS, (INREG(LVDS) | 1<<30) & ~0x80000300); + temp = INREG(LVDS) | LVDS_PIPEB_SELECT; + temp &= ~(LVDS_PORT_EN | LVDS_CLKA_POWER_UP); + OUTREG(LVDS, temp); xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Disabling LVDS directly.\n"); } |