diff --git a/src/i830_crt.c b/src/i830_crt.c index 82a774a..0907fb7 100644 --- a/src/i830_crt.c +++ b/src/i830_crt.c @@ -405,6 +405,28 @@ static const xf86OutputFuncsRec i830_crt_output_funcs = { .destroy = i830_crt_destroy }; +static void +i830_crt_get_config(ScrnInfoPtr pScrn, xf86OutputPtr output, Bool connected) +{ + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR (pScrn); + I830Ptr pI830 = I830PTR(pScrn); + int c; + int pipe = !!(INREG(ADPA) & ADPA_PIPE_SELECT_MASK); + + for (c = 0; c < config->num_crtc; c++) + { + xf86CrtcPtr crtc = config->crtc[c]; + I830CrtcPrivatePtr intel_crtc = crtc->driver_private; + + if (intel_crtc->pipe == pipe) { + output->status = i830_crt_detect(output); + if (output->status == XF86OutputStatusConnected) + output->crtc = crtc; + break; + } + } +} + void i830_crt_init(ScrnInfoPtr pScrn) { @@ -433,6 +455,7 @@ i830_crt_init(ScrnInfoPtr pScrn) output->driver_private = i830_output; output->interlaceAllowed = FALSE; output->doubleScanAllowed = FALSE; + i830_crt_get_config(pScrn, output, TRUE); /* Set up the DDC bus. */ I830I2CInit(pScrn, &i830_output->pDDCBus, GPIOA, "CRTDDC_A"); diff --git a/src/i830_display.c b/src/i830_display.c index ea6d067..4bf18fd 100644 --- a/src/i830_display.c +++ b/src/i830_display.c @@ -1816,6 +1816,22 @@ static const xf86CrtcFuncsRec i830_crtc_funcs = { .destroy = NULL, /* XXX */ }; +static void +i830_crtc_get_config(ScrnInfoPtr pScrn, xf86CrtcPtr crtc) +{ + I830Ptr pI830 = I830PTR(pScrn); + I830CrtcPrivatePtr intel_crtc = crtc->driver_private; + int pipe = intel_crtc->pipe; + int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; + + intel_crtc->dpms_mode = DPMSModeOff; + + if (INREG(pipeconf_reg) & PIPEACONF_ENABLE) { + intel_crtc->dpms_mode = DPMSModeOn; + crtc->enabled = 1; + } +} + void i830_crtc_init(ScrnInfoPtr pScrn, int pipe) { @@ -1829,7 +1845,6 @@ i830_crtc_init(ScrnInfoPtr pScrn, int pipe) intel_crtc = xnfcalloc (sizeof (I830CrtcPrivateRec), 1); intel_crtc->pipe = pipe; - intel_crtc->dpms_mode = DPMSModeOff; intel_crtc->plane = pipe; /* Initialize the LUTs for when we turn on the CRTC. */ @@ -1839,5 +1854,7 @@ i830_crtc_init(ScrnInfoPtr pScrn, int pipe) intel_crtc->lut_b[i] = i; } crtc->driver_private = intel_crtc; + + i830_crtc_get_config(pScrn, crtc); } diff --git a/src/i830_driver.c b/src/i830_driver.c index 854e377..f489945 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -970,6 +970,7 @@ PreInitCleanup(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); + RestoreHWState(pScrn); if (I830IsPrimary(pScrn)) { if (pI830->entityPrivate) pI830->entityPrivate->pScrn_1 = NULL; @@ -1547,11 +1548,9 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) if (!xf86InitialConfiguration (pScrn, FALSE)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n"); - RestoreHWState(pScrn); PreInitCleanup(pScrn); return FALSE; } - RestoreHWState(pScrn); /* XXX This should go away, replaced by xf86Crtc.c support for it */ pI830->rotation = RR_Rotate_0; @@ -3157,15 +3156,6 @@ I830EnterVT(int scrnIndex, int flags) DPRINTF(PFX, "Enter VT\n"); - /* - * Only save state once per server generation since that's what most - * drivers do. Could change this to save state at each VT enter. - */ - if (pI830->SaveGeneration != serverGeneration) { - pI830->SaveGeneration = serverGeneration; - SaveHWState(pScrn); - } - pI830->leaving = FALSE; #ifdef XF86DRI_MM @@ -3200,10 +3190,13 @@ I830EnterVT(int scrnIndex, int flags) memset(pI830->FbBase + pScrn->fbOffset, 0, pScrn->virtualY * pScrn->displayWidth * pI830->cpp); + /* If coming back from an actual VT switch we may need this? */ +#if 0 for (o = 0; o < config->num_output; o++) { - xf86OutputPtr output = config->output[o]; - output->funcs->dpms(output, DPMSModeOff); + xf86OutputPtr output = config->output[o]; + output->funcs->dpms(output, DPMSModeOff); } +#endif if (!xf86SetDesiredModes (pScrn)) return FALSE; diff --git a/src/i830_dvo.c b/src/i830_dvo.c index 81d5601..e509ee4 100644 --- a/src/i830_dvo.c +++ b/src/i830_dvo.c @@ -395,6 +395,30 @@ i830_dvo_get_current_mode (xf86OutputPtr output) return mode; } +static void +i830_dvo_get_config(ScrnInfoPtr pScrn, xf86OutputPtr output, Bool connected) +{ + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR (pScrn); + I830OutputPrivatePtr intel_output = output->driver_private; + struct _I830DVODriver *drv = intel_output->dev_priv; + I830Ptr pI830 = I830PTR(pScrn); + int c; + int pipe = !!(INREG(drv->dvo_reg) & SDVO_PIPE_B_SELECT); + + for (c = 0; c < config->num_crtc; c++) + { + xf86CrtcPtr crtc = config->crtc[c]; + I830CrtcPrivatePtr intel_crtc = crtc->driver_private; + + if (intel_crtc->pipe == pipe) { + output->status = i830_dvo_detect(output); + if (output->status == XF86OutputStatusConnected) + output->crtc = crtc; + break; + } + } +} + void i830_dvo_init(ScrnInfoPtr pScrn) { @@ -517,6 +541,7 @@ i830_dvo_init(ScrnInfoPtr pScrn) drv->panel_wants_dither = TRUE; } + i830_dvo_get_config(pScrn, output, TRUE); return; } xf86UnloadSubModule(drv->modhandle); diff --git a/src/i830_lvds.c b/src/i830_lvds.c index 8359e39..e8d7eec 100644 --- a/src/i830_lvds.c +++ b/src/i830_lvds.c @@ -412,7 +412,6 @@ i830_lvds_dpms (xf86OutputPtr output, int mode) i830SetLVDSPanelPower(output, TRUE); else i830SetLVDSPanelPower(output, FALSE); - /* XXX: We never power down the LVDS pairs. */ } @@ -618,6 +617,19 @@ i830_lvds_get_modes(xf86OutputPtr output) return NULL; } +/* LVDS doesn't need to do anything to prepare/commit */ +void +i830_lvds_prepare (xf86OutputPtr output) +{ + return; +} + +void +i830_lvds_commit (xf86OutputPtr output) +{ + return; +} + static void i830_lvds_destroy (xf86OutputPtr output) { @@ -887,9 +899,9 @@ static const xf86OutputFuncsRec i830_lvds_output_funcs = { .restore = i830_lvds_restore, .mode_valid = i830_lvds_mode_valid, .mode_fixup = i830_lvds_mode_fixup, - .prepare = i830_output_prepare, + .prepare = i830_lvds_prepare, .mode_set = i830_lvds_mode_set, - .commit = i830_output_commit, + .commit = i830_lvds_commit, .detect = i830_lvds_detect, .get_modes = i830_lvds_get_modes, #ifdef RANDR_12_INTERFACE @@ -901,6 +913,28 @@ static const xf86OutputFuncsRec i830_lvds_output_funcs = { .destroy = i830_lvds_destroy }; +static void +i830_lvds_get_config(ScrnInfoPtr pScrn, xf86OutputPtr output, Bool connected) +{ + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR (pScrn); + I830Ptr pI830 = I830PTR(pScrn); + int c; + int pipe = !!(INREG(LVDS) & LVDS_PIPEB_SELECT); + + for (c = 0; c < config->num_crtc; c++) + { + xf86CrtcPtr crtc = config->crtc[c]; + I830CrtcPrivatePtr intel_crtc = crtc->driver_private; + + if (intel_crtc->pipe == pipe) { + output->status = i830_lvds_detect(output); + if (output->status == XF86OutputStatusConnected) + output->crtc = crtc; + break; + } + } +} + void i830_lvds_init(ScrnInfoPtr pScrn) { @@ -1076,6 +1110,8 @@ i830_lvds_init(ScrnInfoPtr pScrn) dev_priv->backlight_duty_cycle = dev_priv->get_backlight(output); + i830_lvds_get_config(pScrn, output, TRUE); + return; disable_exit: diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c index c7cbfac..6d5db41 100644 --- a/src/i830_sdvo.c +++ b/src/i830_sdvo.c @@ -1158,6 +1158,30 @@ static const xf86OutputFuncsRec i830_sdvo_output_funcs = { .destroy = i830_sdvo_destroy }; +static void +i830_sdvo_get_config(ScrnInfoPtr pScrn, xf86OutputPtr output, Bool connected) +{ + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR (pScrn); + I830OutputPrivatePtr intel_output = output->driver_private; + struct i830_sdvo_priv *dev_priv = intel_output->dev_priv; + I830Ptr pI830 = I830PTR(pScrn); + int c; + int pipe = !!(INREG(dev_priv->output_device) & SDVO_PIPE_B_SELECT); + + for (c = 0; c < config->num_crtc; c++) + { + xf86CrtcPtr crtc = config->crtc[c]; + I830CrtcPrivatePtr intel_crtc = crtc->driver_private; + + if (intel_crtc->pipe == pipe) { + output->status = i830_sdvo_detect(output); + if (output->status == XF86OutputStatusConnected) + output->crtc = crtc; + break; + } + } +} + void i830_sdvo_init(ScrnInfoPtr pScrn, int output_device) { @@ -1319,7 +1343,6 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device) return; } - /* Set the input timing to the screen. Assume always input 0. */ i830_sdvo_set_target_input(output, TRUE, FALSE); @@ -1340,4 +1363,5 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device) (dev_priv->caps.sdvo_inputs_mask & 0x2) ? 'Y' : 'N', dev_priv->caps.output_flags & (SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_TMDS0) ? 'Y' : 'N', dev_priv->caps.output_flags & (SDVO_OUTPUT_RGB1 | SDVO_OUTPUT_TMDS1) ? 'Y' : 'N'); + i830_sdvo_get_config(pScrn, output, TRUE); } diff --git a/src/i830_tv.c b/src/i830_tv.c index 9add367..3885461 100644 --- a/src/i830_tv.c +++ b/src/i830_tv.c @@ -1658,6 +1658,28 @@ static const xf86OutputFuncsRec i830_tv_output_funcs = { #endif }; +static void +i830_tv_get_config(ScrnInfoPtr pScrn, xf86OutputPtr output, Bool connected) +{ + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR (pScrn); + I830Ptr pI830 = I830PTR(pScrn); + int c; + int pipe = !!(INREG(TV_CTL) & TV_ENC_PIPEB_SELECT); + + for (c = 0; c < config->num_crtc; c++) + { + xf86CrtcPtr crtc = config->crtc[c]; + I830CrtcPrivatePtr intel_crtc = crtc->driver_private; + + if (intel_crtc->pipe == pipe) { + output->status = i830_tv_detect(output); + if (output->status == XF86OutputStatusConnected) + output->crtc = crtc; + break; + } + } +} + void i830_tv_init(ScrnInfoPtr pScrn) { @@ -1737,4 +1759,5 @@ i830_tv_init(ScrnInfoPtr pScrn) output->driver_private = intel_output; output->interlaceAllowed = FALSE; output->doubleScanAllowed = FALSE; + i830_tv_get_config(pScrn, output, TRUE); }