summaryrefslogtreecommitdiff
path: root/src/i830_crt.c
diff options
context:
space:
mode:
authorKeith Packard <keithp@neko.keithp.com>2006-11-30 14:09:31 -0800
committerKeith Packard <keithp@neko.keithp.com>2006-11-30 14:09:31 -0800
commitff64bc7397cafbec94e388e1625b3a1999f1aca7 (patch)
treefdd9d519c382e39dd02be9fad341f31e668a047f /src/i830_crt.c
parentb94b7c4bcfdb7ba59ed818f72309b5060a2ab7ee (diff)
parent16e01b117bb7ae90b150dd4f25a887dd895cf473 (diff)
Merge branch 'restructure-outputs' into modesetting.
Outputs and Crtcs now have a driver-independent representation which should permit generic code to control RandR 1.2 and startup configuration.
Diffstat (limited to 'src/i830_crt.c')
-rw-r--r--src/i830_crt.c188
1 files changed, 122 insertions, 66 deletions
diff --git a/src/i830_crt.c b/src/i830_crt.c
index 76a8007c..7a706d14 100644
--- a/src/i830_crt.c
+++ b/src/i830_crt.c
@@ -35,10 +35,11 @@
#include "i830_display.h"
static void
-i830_crt_dpms(ScrnInfoPtr pScrn, I830OutputPtr output, int mode)
+i830_crt_dpms(xf86OutputPtr output, int mode)
{
- I830Ptr pI830 = I830PTR(pScrn);
- CARD32 temp;
+ ScrnInfoPtr pScrn = output->scrn;
+ I830Ptr pI830 = I830PTR(pScrn);
+ CARD32 temp;
temp = INREG(ADPA);
temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE);
@@ -63,24 +64,25 @@ i830_crt_dpms(ScrnInfoPtr pScrn, I830OutputPtr output, int mode)
}
static void
-i830_crt_save(ScrnInfoPtr pScrn, I830OutputPtr output)
+i830_crt_save (xf86OutputPtr output)
{
- I830Ptr pI830 = I830PTR(pScrn);
+ ScrnInfoPtr pScrn = output->scrn;
+ I830Ptr pI830 = I830PTR(pScrn);
pI830->saveADPA = INREG(ADPA);
}
static void
-i830_crt_restore(ScrnInfoPtr pScrn, I830OutputPtr output)
+i830_crt_restore (xf86OutputPtr output)
{
- I830Ptr pI830 = I830PTR(pScrn);
+ ScrnInfoPtr pScrn = output->scrn;
+ I830Ptr pI830 = I830PTR(pScrn);
OUTREG(ADPA, pI830->saveADPA);
}
static int
-i830_crt_mode_valid(ScrnInfoPtr pScrn, I830OutputPtr output,
- DisplayModePtr pMode)
+i830_crt_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
{
if (pMode->Flags & V_DBLSCAN)
return MODE_NO_DBLESCAN;
@@ -92,19 +94,24 @@ i830_crt_mode_valid(ScrnInfoPtr pScrn, I830OutputPtr output,
}
static void
-i830_crt_pre_set_mode(ScrnInfoPtr pScrn, I830OutputPtr output,
- DisplayModePtr pMode)
+i830_crt_pre_set_mode (xf86OutputPtr output, DisplayModePtr pMode)
{
}
static void
-i830_crt_post_set_mode(ScrnInfoPtr pScrn, I830OutputPtr output,
- DisplayModePtr pMode)
+i830_crt_post_set_mode (xf86OutputPtr output, DisplayModePtr pMode)
{
- I830Ptr pI830 = I830PTR(pScrn);
- int dpll_md_reg = (output->pipe == 0) ? DPLL_A_MD : DPLL_B_MD;
- CARD32 adpa, dpll_md;
-
+ ScrnInfoPtr pScrn = output->scrn;
+ I830Ptr pI830 = I830PTR(pScrn);
+ xf86CrtcPtr crtc = output->crtc;
+ I830CrtcPrivatePtr i830_crtc = crtc->driver_private;
+ int dpll_md_reg;
+ CARD32 adpa, dpll_md;
+
+ if (i830_crtc->pipe == 0)
+ dpll_md_reg = DPLL_A_MD;
+ else
+ dpll_md_reg = DPLL_B_MD;
/*
* Disable separate mode multiplier used when cloning SDVO to CRT
* XXX this needs to be adjusted when we really are cloning
@@ -122,7 +129,7 @@ i830_crt_post_set_mode(ScrnInfoPtr pScrn, I830OutputPtr output,
if (pMode->Flags & V_PVSYNC)
adpa |= ADPA_VSYNC_ACTIVE_HIGH;
- if (output->pipe == 0)
+ if (i830_crtc->pipe == 0)
adpa |= ADPA_PIPE_A_SELECT;
else
adpa |= ADPA_PIPE_B_SELECT;
@@ -139,12 +146,13 @@ i830_crt_post_set_mode(ScrnInfoPtr pScrn, I830OutputPtr output,
* \return FALSE if CRT is disconnected.
*/
static Bool
-i830_crt_detect_hotplug(ScrnInfoPtr pScrn)
+i830_crt_detect_hotplug(xf86OutputPtr output)
{
- I830Ptr pI830 = I830PTR(pScrn);
- CARD32 temp;
- const int timeout_ms = 1000;
- int starttime, curtime;
+ ScrnInfoPtr pScrn = output->scrn;
+ I830Ptr pI830 = I830PTR(pScrn);
+ CARD32 temp;
+ const int timeout_ms = 1000;
+ int starttime, curtime;
temp = INREG(PORT_HOTPLUG_EN);
@@ -177,20 +185,25 @@ i830_crt_detect_hotplug(ScrnInfoPtr pScrn)
* \return FALSE if CRT is disconnected.
*/
static Bool
-i830_crt_detect_load(ScrnInfoPtr pScrn, I830OutputPtr output)
+i830_crt_detect_load (xf86CrtcPtr crtc,
+ xf86OutputPtr output)
{
- I830Ptr pI830 = I830PTR(pScrn);
- CARD32 save_adpa, adpa, pipeconf, bclrpat;
- CARD8 st00;
- int pipeconf_reg, bclrpat_reg, dpll_reg;
- int pipe;
-
- pipe = output->pipe;
- if (pipe == 0) {
+ ScrnInfoPtr pScrn = output->scrn;
+ I830Ptr pI830 = I830PTR(pScrn);
+ I830CrtcPrivatePtr i830_crtc = I830CrtcPrivate(crtc);
+ CARD32 save_adpa, adpa, pipeconf, bclrpat;
+ CARD8 st00;
+ int pipeconf_reg, bclrpat_reg, dpll_reg;
+ int pipe = i830_crtc->pipe;
+
+ if (pipe == 0)
+ {
bclrpat_reg = BCLRPAT_A;
pipeconf_reg = PIPEACONF;
dpll_reg = DPLL_A;
- } else {
+ }
+ else
+ {
bclrpat_reg = BCLRPAT_B;
pipeconf_reg = PIPEBCONF;
dpll_reg = DPLL_B;
@@ -244,17 +257,15 @@ i830_crt_detect_load(ScrnInfoPtr pScrn, I830OutputPtr output)
* \return FALSE if no DDC response was detected.
*/
static Bool
-i830_crt_detect_ddc(ScrnInfoPtr pScrn)
+i830_crt_detect_ddc(xf86OutputPtr output)
{
- I830Ptr pI830 = I830PTR(pScrn);
- struct _I830OutputRec *output;
+ I830OutputPrivatePtr i830_output = output->driver_private;
- output = &pI830->output[0];
/* CRT should always be at 0, but check anyway */
- if (output->type != I830_OUTPUT_ANALOG)
+ if (i830_output->type != I830_OUTPUT_ANALOG)
return FALSE;
- return xf86I2CProbeAddress(output->pDDCBus, 0x00A0);
+ return xf86I2CProbeAddress(i830_output->pDDCBus, 0x00A0);
}
/**
@@ -264,25 +275,50 @@ i830_crt_detect_ddc(ScrnInfoPtr pScrn)
* on active displays.
*/
static enum detect_status
-i830_crt_detect(ScrnInfoPtr pScrn, I830OutputPtr output)
+i830_crt_detect(xf86OutputPtr output)
{
- I830Ptr pI830 = I830PTR(pScrn);
+ ScrnInfoPtr pScrn = output->scrn;
+ I830Ptr pI830 = I830PTR(pScrn);
+ xf86CrtcPtr crtc;
if (IS_I945G(pI830) || IS_I945GM(pI830) || IS_I965G(pI830)) {
- if (i830_crt_detect_hotplug(pScrn))
+ if (i830_crt_detect_hotplug(output))
return OUTPUT_STATUS_CONNECTED;
else
return OUTPUT_STATUS_DISCONNECTED;
}
- if (i830_crt_detect_ddc(pScrn))
+ if (i830_crt_detect_ddc(output))
return OUTPUT_STATUS_CONNECTED;
/* Use the load-detect method if we have no other way of telling. */
- if (i830GetLoadDetectPipe(pScrn, output) != -1) {
- Bool connected = i830_crt_detect_load(pScrn, output);
-
- i830ReleaseLoadDetectPipe(pScrn, output);
+ crtc = i830GetLoadDetectPipe (output);
+
+ if (crtc)
+ {
+ /* VESA 640x480x72Hz mode to set on the pipe */
+ static DisplayModeRec mode = {
+ NULL, NULL, "640x480", MODE_OK, M_T_DEFAULT,
+ 31500,
+ 640, 664, 704, 832, 0,
+ 480, 489, 491, 520, 0,
+ V_NHSYNC | V_NVSYNC,
+ 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ FALSE, FALSE, 0, NULL, 0, 0.0, 0.0
+ };
+ Bool connected;
+ I830OutputPrivatePtr intel_output = output->driver_private;
+
+ if (intel_output->load_detect_temp)
+ {
+ xf86SetModeCrtc (&mode, INTERLACE_HALVE_V);
+ i830PipeSetMode (crtc, &mode, FALSE);
+ }
+ connected = i830_crt_detect_load (crtc, output);
+
+ i830ReleaseLoadDetectPipe (output);
if (connected)
return OUTPUT_STATUS_CONNECTED;
else
@@ -293,16 +329,17 @@ i830_crt_detect(ScrnInfoPtr pScrn, I830OutputPtr output)
}
static DisplayModePtr
-i830_crt_get_modes(ScrnInfoPtr pScrn, I830OutputPtr output)
+i830_crt_get_modes(xf86OutputPtr output)
{
- DisplayModePtr modes;
+ ScrnInfoPtr pScrn = output->scrn;
+ DisplayModePtr modes;
MonRec fixed_mon;
- modes = i830_ddc_get_modes(pScrn, output);
+ modes = i830_ddc_get_modes(output);
if (modes != NULL)
return modes;
- if (output->detect(pScrn, output) == OUTPUT_STATUS_DISCONNECTED)
+ if ((*output->funcs->detect)(output) == OUTPUT_STATUS_DISCONNECTED)
return NULL;
/* We've got a potentially-connected monitor that we can't DDC. Return a
@@ -323,24 +360,43 @@ i830_crt_get_modes(ScrnInfoPtr pScrn, I830OutputPtr output)
return modes;
}
+static void
+i830_crt_destroy (xf86OutputPtr output)
+{
+ if (output->driver_private)
+ xfree (output->driver_private);
+}
+
+static const xf86OutputFuncsRec i830_crt_output_funcs = {
+ .dpms = i830_crt_dpms,
+ .save = i830_crt_save,
+ .restore = i830_crt_restore,
+ .mode_valid = i830_crt_mode_valid,
+ .pre_set_mode = i830_crt_pre_set_mode,
+ .post_set_mode = i830_crt_post_set_mode,
+ .detect = i830_crt_detect,
+ .get_modes = i830_crt_get_modes,
+ .destroy = i830_crt_destroy
+};
+
void
i830_crt_init(ScrnInfoPtr pScrn)
{
- I830Ptr pI830 = I830PTR(pScrn);
-
- pI830->output[pI830->num_outputs].type = I830_OUTPUT_ANALOG;
- pI830->output[pI830->num_outputs].dpms = i830_crt_dpms;
- pI830->output[pI830->num_outputs].save = i830_crt_save;
- pI830->output[pI830->num_outputs].restore = i830_crt_restore;
- pI830->output[pI830->num_outputs].mode_valid = i830_crt_mode_valid;
- pI830->output[pI830->num_outputs].pre_set_mode = i830_crt_pre_set_mode;
- pI830->output[pI830->num_outputs].post_set_mode = i830_crt_post_set_mode;
- pI830->output[pI830->num_outputs].detect = i830_crt_detect;
- pI830->output[pI830->num_outputs].get_modes = i830_crt_get_modes;
+ xf86OutputPtr output;
+ I830OutputPrivatePtr i830_output;
+
+ output = xf86OutputCreate (pScrn, &i830_crt_output_funcs, "VGA");
+ if (!output)
+ return;
+ i830_output = xnfcalloc (sizeof (I830OutputPrivateRec), 1);
+ if (!i830_output)
+ {
+ xf86OutputDestroy (output);
+ return;
+ }
+ i830_output->type = I830_OUTPUT_ANALOG;
+ output->driver_private = i830_output;
/* Set up the DDC bus. */
- I830I2CInit(pScrn, &pI830->output[pI830->num_outputs].pDDCBus,
- GPIOA, "CRTDDC_A");
-
- pI830->num_outputs++;
+ I830I2CInit(pScrn, &i830_output->pDDCBus, GPIOA, "CRTDDC_A");
}