summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Makefile.am2
-rw-r--r--src/i830.h36
-rw-r--r--src/i830_crt.c166
-rw-r--r--src/i830_cursor.c90
-rw-r--r--src/i830_display.c246
-rw-r--r--src/i830_display.h12
-rw-r--r--src/i830_dri.c8
-rw-r--r--src/i830_driver.c111
-rw-r--r--src/i830_dvo.c145
-rw-r--r--src/i830_lvds.c93
-rw-r--r--src/i830_modes.c67
-rw-r--r--src/i830_randr.c223
-rw-r--r--src/i830_sdvo.c272
-rw-r--r--src/i830_tv.c111
-rw-r--r--src/i830_video.c2
-rw-r--r--src/i830_xf86Crtc.c126
-rw-r--r--src/i830_xf86Crtc.h296
-rw-r--r--src/i830_xf86Modes.h5
18 files changed, 1312 insertions, 699 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 0fce5e4f..0a14d1a4 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -80,6 +80,8 @@ i810_drv_la_SOURCES = \
i830_tv.c \
i830_xf86Modes.h \
i830_xf86Modes.c \
+ i830_xf86Crtc.h \
+ i830_xf86Crtc.c \
i915_3d.c \
i915_3d.h \
i915_reg.h \
diff --git a/src/i830.h b/src/i830.h
index 32a540ef..2f106c79 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -59,6 +59,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "vbe.h"
#include "vgaHW.h"
#include "randrstr.h"
+#include "i830_xf86Crtc.h"
#ifdef XF86DRI
#include "xf86drm.h"
@@ -188,6 +189,25 @@ enum detect_status {
OUTPUT_STATUS_UNKNOWN
};
+typedef struct _I830CrtcPrivateRec {
+ int pipe;
+ Bool gammaEnabled;
+} I830CrtcPrivateRec, *I830CrtcPrivatePtr;
+
+#define I830CrtcPrivate(c) ((I830CrtcPrivatePtr) (c)->driver_private)
+
+typedef struct _I830OutputPrivateRec {
+ int type;
+ I2CBusPtr pI2CBus;
+ I2CBusPtr pDDCBus;
+ struct _I830DVODriver *i2c_drv;
+ Bool load_detect_temp;
+ /** Output-private structure. Should replace i2c_drv */
+ void *dev_priv;
+} I830OutputPrivateRec, *I830OutputPrivatePtr;
+
+#define I830OutputPrivate(o) ((I830OutputPrivatePtr) (o)->driver_private)
+
struct _I830OutputRec {
int type;
int pipe;
@@ -467,10 +487,16 @@ typedef struct _I830Rec {
Bool checkDevices;
+ /* XXX outputs and crtcs need to move to ScrnInfoRec */
+ int num_outputs;
+/* struct _I830OutputRec output[MAX_OUTPUTS]; */
+ I830_xf86OutputPtr xf86_output[MAX_OUTPUTS];
+
/* [0] is Pipe A, [1] is Pipe B. */
int num_pipes;
/* [0] is display plane A, [1] is display plane B. */
- I830PipeRec pipes[MAX_DISPLAY_PIPES];
+/* I830PipeRec pipes[MAX_DISPLAY_PIPES]; */
+ I830_xf86CrtcPtr xf86_crtc[MAX_DISPLAY_PIPES];
/* Driver phase/state information */
Bool preinit;
@@ -488,8 +514,6 @@ typedef struct _I830Rec {
OsTimerPtr devicesTimer;
int ddc2;
- int num_outputs;
- struct _I830OutputRec output[MAX_OUTPUTS];
/* Panel size pulled from the BIOS */
int PanelXRes, PanelYRes;
@@ -580,7 +604,7 @@ extern void I830PrintErrorState(ScrnInfoPtr pScrn);
extern void I965PrintErrorState(ScrnInfoPtr pScrn);
extern void I830Sync(ScrnInfoPtr pScrn);
extern void I830InitHWCursor(ScrnInfoPtr pScrn);
-extern void I830SetPipeCursor (ScrnInfoPtr pScrn, int pipe, Bool force);
+extern void I830SetPipeCursor (I830_xf86CrtcPtr crtc, Bool force);
extern Bool I830CursorInit(ScreenPtr pScreen);
extern void IntelEmitInvarientState(ScrnInfoPtr pScrn);
extern void I830EmitInvarientState(ScrnInfoPtr pScrn);
@@ -661,7 +685,7 @@ extern Bool I830I2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, int i2c_reg,
/* i830_display.c */
Bool
-i830PipeHasType (ScrnInfoPtr pScrn, int pipe, int type);
+i830PipeHasType (I830_xf86CrtcPtr crtc, int type);
/* i830_crt.c */
void i830_crt_init(ScrnInfoPtr pScrn);
@@ -685,7 +709,7 @@ int I830ValidateXF86ModeList(ScrnInfoPtr pScrn, Bool first_time);
void i830_reprobe_output_modes(ScrnInfoPtr pScrn);
void i830_set_xf86_modes_from_outputs(ScrnInfoPtr pScrn);
void i830_set_default_screen_size(ScrnInfoPtr pScrn);
-DisplayModePtr i830_ddc_get_modes(ScrnInfoPtr pScrn, I830OutputPtr output);
+DisplayModePtr i830_ddc_get_modes(I830_xf86OutputPtr output);
/* i830_randr.c */
Bool I830RandRCreateScreenResources (ScreenPtr pScreen);
diff --git a/src/i830_crt.c b/src/i830_crt.c
index f067260d..615e96a3 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(I830_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 (I830_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 (I830_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(I830_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 (I830_xf86OutputPtr output, DisplayModePtr pMode)
{
}
static void
-i830_crt_post_set_mode(ScrnInfoPtr pScrn, I830OutputPtr output,
- DisplayModePtr pMode)
+i830_crt_post_set_mode (I830_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);
+ I830_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(I830_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 (I830_xf86CrtcPtr crtc,
+ I830_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(I830_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,30 @@ i830_crt_detect_ddc(ScrnInfoPtr pScrn)
* on active displays.
*/
static enum detect_status
-i830_crt_detect(ScrnInfoPtr pScrn, I830OutputPtr output)
+i830_crt_detect(I830_xf86OutputPtr output)
{
- I830Ptr pI830 = I830PTR(pScrn);
+ ScrnInfoPtr pScrn = output->scrn;
+ I830Ptr pI830 = I830PTR(pScrn);
+ I830_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);
+ crtc = i830xf86AllocCrtc (output);
+
+ if (crtc)
+ {
+ Bool connected = i830_crt_detect_load(crtc, output);
- i830ReleaseLoadDetectPipe(pScrn, output);
+ i830xf86FreeCrtc (crtc);
if (connected)
return OUTPUT_STATUS_CONNECTED;
else
@@ -293,16 +309,17 @@ i830_crt_detect(ScrnInfoPtr pScrn, I830OutputPtr output)
}
static DisplayModePtr
-i830_crt_get_modes(ScrnInfoPtr pScrn, I830OutputPtr output)
+i830_crt_get_modes(I830_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 +340,43 @@ i830_crt_get_modes(ScrnInfoPtr pScrn, I830OutputPtr output)
return modes;
}
+static void
+i830_crt_destroy (I830_xf86OutputPtr output)
+{
+ if (output->driver_private)
+ xfree (output->driver_private);
+}
+
+static const I830_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;
+ I830_xf86OutputPtr output;
+ I830OutputPrivatePtr i830_output;
+
+ output = i830xf86OutputCreate (pScrn, &i830_crt_output_funcs, "VGA");
+ if (!output)
+ return;
+ i830_output = xnfcalloc (sizeof (I830OutputPrivateRec), 1);
+ if (!i830_output)
+ {
+ i830xf86OutputDestroy (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");
}
diff --git a/src/i830_cursor.c b/src/i830_cursor.c
index 517bd3e0..a3526f87 100644
--- a/src/i830_cursor.c
+++ b/src/i830_cursor.c
@@ -80,11 +80,14 @@ static Bool I830UseHWCursorARGB(ScreenPtr pScrn, CursorPtr pCurs);
#endif
static void
-I830SetPipeCursorBase (ScrnInfoPtr pScrn, int pipe)
+I830SetPipeCursorBase (I830_xf86CrtcPtr crtc)
{
- I830Ptr pI830 = I830PTR(pScrn);
- int cursor_base = (pipe == 0 ? CURSOR_A_BASE : CURSOR_B_BASE);
- I830MemRange *cursor_mem;
+ ScrnInfoPtr pScrn = crtc->scrn;
+ I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
+ int pipe = intel_crtc->pipe;
+ I830Ptr pI830 = I830PTR(pScrn);
+ int cursor_base = (pipe == 0 ? CURSOR_A_BASE : CURSOR_B_BASE);
+ I830MemRange *cursor_mem;
if (pipe >= pI830->num_pipes)
FatalError("Bad pipe number for cursor base setting\n");
@@ -102,18 +105,20 @@ I830SetPipeCursorBase (ScrnInfoPtr pScrn, int pipe)
}
void
-I830SetPipeCursor (ScrnInfoPtr pScrn, int pipe, Bool force)
+I830SetPipeCursor (I830_xf86CrtcPtr crtc, Bool force)
{
- I830Ptr pI830 = I830PTR(pScrn);
- I830PipePtr pI830Pipe = &pI830->pipes[pipe];
- CARD32 temp;
- Bool show;
+ ScrnInfoPtr pScrn = crtc->scrn;
+ I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
+ int pipe = intel_crtc->pipe;
+ I830Ptr pI830 = I830PTR(pScrn);
+ CARD32 temp;
+ Bool show;
- if (!pI830Pipe->enabled)
+ if (!crtc->enabled)
return;
- show = pI830->cursorOn && pI830Pipe->cursorInRange;
- if (show && (force || !pI830Pipe->cursorShown))
+ show = pI830->cursorOn && crtc->cursorInRange;
+ if (show && (force || !crtc->cursorShown))
{
if (IS_MOBILE(pI830) || IS_I9XX(pI830)) {
int cursor_control;
@@ -125,7 +130,7 @@ I830SetPipeCursor (ScrnInfoPtr pScrn, int pipe, Bool force)
temp &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT);
if (pI830->CursorIsARGB) {
temp |= CURSOR_MODE_64_ARGB_AX;
- if (pI830Pipe->gammaEnabled)
+ if (intel_crtc->gammaEnabled)
temp |= MCURSOR_GAMMA_ENABLE;
} else
temp |= CURSOR_MODE_64_4C_AX;
@@ -139,15 +144,15 @@ I830SetPipeCursor (ScrnInfoPtr pScrn, int pipe, Bool force)
temp |= CURSOR_ENABLE;
if (pI830->CursorIsARGB) {
temp |= CURSOR_FORMAT_ARGB;
- if (pI830Pipe->gammaEnabled)
+ if (intel_crtc->gammaEnabled)
temp |= CURSOR_GAMMA_ENABLE;
} else
temp |= CURSOR_FORMAT_3C;
OUTREG(CURSOR_CONTROL, temp);
}
- pI830Pipe->cursorShown = TRUE;
+ crtc->cursorShown = TRUE;
}
- else if (!show && (force || pI830Pipe->cursorShown))
+ else if (!show && (force || crtc->cursorShown))
{
if (IS_MOBILE(pI830) || IS_I9XX(pI830))
{
@@ -165,11 +170,11 @@ I830SetPipeCursor (ScrnInfoPtr pScrn, int pipe, Bool force)
temp &= ~(CURSOR_ENABLE|CURSOR_GAMMA_ENABLE);
OUTREG(CURSOR_CONTROL, temp);
}
- pI830Pipe->cursorShown = FALSE;
+ crtc->cursorShown = FALSE;
}
/* Flush cursor changes. */
- I830SetPipeCursorBase(pScrn, pipe);
+ I830SetPipeCursorBase(crtc);
}
void
@@ -181,7 +186,8 @@ I830InitHWCursor(ScrnInfoPtr pScrn)
DPRINTF(PFX, "I830InitHWCursor\n");
for (i = 0; i < pI830->num_pipes; i++)
- pI830->pipes[i].cursorShown = FALSE;
+ pI830->xf86_crtc[i]->cursorShown = FALSE;
+
/* Initialise the HW cursor registers, leaving the cursor hidden. */
if (IS_MOBILE(pI830) || IS_I9XX(pI830)) {
for (i = 0; i < pI830->num_pipes; i++)
@@ -198,7 +204,7 @@ I830InitHWCursor(ScrnInfoPtr pScrn)
temp |= CURSOR_MODE_64_4C_AX;
/* Need to set control, then address. */
OUTREG(cursor_control, temp);
- I830SetPipeCursorBase(pScrn, i);
+ I830SetPipeCursorBase(pI830->xf86_crtc[i]);
}
} else {
temp = INREG(CURSOR_CONTROL);
@@ -211,7 +217,7 @@ I830InitHWCursor(ScrnInfoPtr pScrn)
/* This initialises the format and leave the cursor disabled. */
OUTREG(CURSOR_CONTROL, temp);
/* Need to set address and size after disabling. */
- I830SetPipeCursorBase(pScrn, 0);
+ I830SetPipeCursorBase(pI830->xf86_crtc[0]);
temp = ((I810_CURSOR_X & CURSOR_SIZE_MASK) << CURSOR_SIZE_HSHIFT) |
((I810_CURSOR_Y & CURSOR_SIZE_MASK) << CURSOR_SIZE_VSHIFT);
OUTREG(CURSOR_SIZE, temp);
@@ -486,12 +492,12 @@ I830SetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
for (pipe = 0; pipe < pI830->num_pipes; pipe++)
{
- I830PipePtr pI830Pipe = &pI830->pipes[pipe];
- DisplayModePtr mode = &pI830Pipe->curMode;
- int thisx = x - pI830Pipe->x;
- int thisy = y - pI830Pipe->y;
+ I830_xf86CrtcPtr crtc = pI830->xf86_crtc[pipe];
+ DisplayModePtr mode = &crtc->curMode;
+ int thisx = x - crtc->x;
+ int thisy = y - crtc->y;
- if (!pI830Pipe->enabled)
+ if (!crtc->enabled)
continue;
/*
@@ -527,9 +533,9 @@ I830SetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
if (pipe == 1)
OUTREG(CURSOR_B_POSITION, temp);
- pI830Pipe->cursorInRange = inrange;
+ crtc->cursorInRange = inrange;
- I830SetPipeCursor (pScrn, pipe, FALSE);
+ I830SetPipeCursor (crtc, FALSE);
}
}
@@ -551,7 +557,7 @@ I830ShowCursor(ScrnInfoPtr pScrn)
pI830->cursorOn = TRUE;
for (pipe = 0; pipe < pI830->num_pipes; pipe++)
- I830SetPipeCursor (pScrn, pipe, TRUE);
+ I830SetPipeCursor (pI830->xf86_crtc[pipe], TRUE);
}
static void
@@ -564,13 +570,14 @@ I830HideCursor(ScrnInfoPtr pScrn)
pI830->cursorOn = FALSE;
for (pipe = 0; pipe < pI830->num_pipes; pipe++)
- I830SetPipeCursor (pScrn, pipe, TRUE);
+ I830SetPipeCursor (pI830->xf86_crtc[pipe], TRUE);
}
static void
I830SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
{
I830Ptr pI830 = I830PTR(pScrn);
+ int pipe;
#ifdef ARGB_CURSOR
/* Don't recolour cursors set with SetCursorARGB. */
@@ -580,18 +587,17 @@ I830SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
DPRINTF(PFX, "I830SetCursorColors\n");
- if (pI830->pipes[0].enabled)
+ for (pipe = 0; pipe < pI830->num_pipes; pipe++)
{
- OUTREG(CURSOR_A_PALETTE0, bg & 0x00ffffff);
- OUTREG(CURSOR_A_PALETTE1, fg & 0x00ffffff);
- OUTREG(CURSOR_A_PALETTE2, fg & 0x00ffffff);
- OUTREG(CURSOR_A_PALETTE3, bg & 0x00ffffff);
- }
- if (pI830->pipes[1].enabled)
- {
- OUTREG(CURSOR_B_PALETTE0, bg & 0x00ffffff);
- OUTREG(CURSOR_B_PALETTE1, fg & 0x00ffffff);
- OUTREG(CURSOR_B_PALETTE2, fg & 0x00ffffff);
- OUTREG(CURSOR_B_PALETTE3, bg & 0x00ffffff);
+ I830_xf86CrtcPtr crtc = pI830->xf86_crtc[pipe];
+ int pal0 = pipe == 0 ? CURSOR_A_PALETTE0 : CURSOR_B_PALETTE0;
+
+ if (crtc->enabled)
+ {
+ OUTREG(pal0 + 0, bg & 0x00ffffff);
+ OUTREG(pal0 + 4, fg & 0x00ffffff);
+ OUTREG(pal0 + 8, fg & 0x00ffffff);
+ OUTREG(pal0 + 12, bg & 0x00ffffff);
+ }
}
}
diff --git a/src/i830_display.c b/src/i830_display.c
index 04f85cc2..9baa39ba 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -61,20 +61,25 @@ i830PrintPll(char *prefix, int refclk, int m1, int m2, int n, int p1, int p2)
}
/**
- * Returns whether any output on the specified pipe is an LVDS output
+ * Returns whether any output on the specified pipe is of the specified type
*/
Bool
-i830PipeHasType (ScrnInfoPtr pScrn, int pipe, int type)
+i830PipeHasType (I830_xf86CrtcPtr crtc, int type)
{
- I830Ptr pI830 = I830PTR(pScrn);
- int i;
+ ScrnInfoPtr pScrn = crtc->scrn;
+ I830Ptr pI830 = I830PTR(pScrn);
+ int i;
for (i = 0; i < pI830->num_outputs; i++)
- if (pI830->output[i].enabled && pI830->output[i].pipe == pipe)
+ {
+ I830_xf86OutputPtr output = pI830->xf86_output[i];
+ if (output->crtc == crtc)
{
- if (pI830->output[i].type == type)
+ I830OutputPrivatePtr intel_output = output->driver_private;
+ if (intel_output->type == type)
return TRUE;
}
+ }
return FALSE;
}
@@ -86,9 +91,10 @@ i830PipeHasType (ScrnInfoPtr pScrn, int pipe, int type)
* clk = refclk * (5 * m1 + m2) / n / (p1 * p2)
*/
static Bool
-i830PllIsValid(ScrnInfoPtr pScrn, int pipe, int refclk, int m1, int m2,
+i830PllIsValid(I830_xf86CrtcPtr crtc, int refclk, int m1, int m2,
int n, int p1, int p2)
{
+ ScrnInfoPtr pScrn = crtc->scrn;
I830Ptr pI830 = I830PTR(pScrn);
int p, m, vco, dotclock;
int min_m1, max_m1, min_m2, max_m2, min_m, max_m, min_n, max_n;
@@ -105,7 +111,7 @@ i830PllIsValid(ScrnInfoPtr pScrn, int pipe, int refclk, int m1, int m2,
max_n = 8;
min_p1 = 1;
max_p1 = 8;
- if (i830PipeHasType (pScrn, pipe, I830_OUTPUT_LVDS)) {
+ if (i830PipeHasType (crtc, I830_OUTPUT_LVDS)) {
min_p = 7;
max_p = 98;
} else {
@@ -171,9 +177,10 @@ i830PllIsValid(ScrnInfoPtr pScrn, int pipe, int refclk, int m1, int m2,
* clk = refclk * (5 * m1 + m2) / n / (p1 * p2)
*/
static Bool
-i830FindBestPLL(ScrnInfoPtr pScrn, int pipe, int target, int refclk,
+i830FindBestPLL(I830_xf86CrtcPtr crtc, int target, int refclk,
int *outm1, int *outm2, int *outn, int *outp1, int *outp2)
{
+ ScrnInfoPtr pScrn = crtc->scrn;
I830Ptr pI830 = I830PTR(pScrn);
int m1, m2, n, p1, p2;
int err = target;
@@ -188,7 +195,7 @@ i830FindBestPLL(ScrnInfoPtr pScrn, int pipe, int target, int refclk,
max_n = 8;
min_p1 = 1;
max_p1 = 8;
- if (i830PipeHasType (pScrn, pipe, I830_OUTPUT_LVDS)) {
+ if (i830PipeHasType (crtc, I830_OUTPUT_LVDS)) {
/* The single-channel range is 25-112Mhz, and dual-channel
* is 80-224Mhz. Prefer single channel as much as possible.
*/
@@ -224,7 +231,7 @@ i830FindBestPLL(ScrnInfoPtr pScrn, int pipe, int target, int refclk,
for (p1 = min_p1; p1 <= max_p1; p1++) {
int clock, this_err;
- if (!i830PllIsValid(pScrn, pipe, refclk, m1, m2, n,
+ if (!i830PllIsValid(crtc, refclk, m1, m2, n,
p1, p2)) {
continue;
}
@@ -255,10 +262,12 @@ i830WaitForVblank(ScrnInfoPtr pScreen)
}
void
-i830PipeSetBase(ScrnInfoPtr pScrn, int pipe, int x, int y)
+i830PipeSetBase(I830_xf86CrtcPtr crtc, int x, int y)
{
+ ScrnInfoPtr pScrn = crtc->scrn;
I830Ptr pI830 = I830PTR(pScrn);
- I830PipePtr pI830Pipe = &pI830->pipes[pipe];
+ I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
+ int pipe = intel_crtc->pipe;
unsigned long Start;
int dspbase = (pipe == 0 ? DSPABASE : DSPBBASE);
int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF);
@@ -277,8 +286,8 @@ i830PipeSetBase(ScrnInfoPtr pScrn, int pipe, int x, int y)
OUTREG(dspbase, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
}
- pI830Pipe->x = x;
- pI830Pipe->y = y;
+ crtc->x = x;
+ crtc->y = y;
}
/**
@@ -291,19 +300,21 @@ i830PipeSetBase(ScrnInfoPtr pScrn, int pipe, int x, int y)
* - Closer in refresh rate to the requested mode.
*/
DisplayModePtr
-i830PipeFindClosestMode(ScrnInfoPtr pScrn, int pipe, DisplayModePtr pMode)
+i830PipeFindClosestMode(I830_xf86CrtcPtr crtc, DisplayModePtr pMode)
{
+ ScrnInfoPtr pScrn = crtc->scrn;
I830Ptr pI830 = I830PTR(pScrn);
DisplayModePtr pBest = NULL, pScan = NULL;
int i;
/* Assume that there's only one output connected to the given CRTC. */
- for (i = 0; i < pI830->num_outputs; i++) {
- if (pI830->output[i].pipe == pipe &&
- pI830->output[i].enabled &&
- pI830->output[i].probed_modes != NULL)
+ for (i = 0; i < pI830->num_outputs; i++)
+ {
+ I830_xf86OutputPtr output = pI830->xf86_output[i];
+ if (output->crtc == crtc && output->probed_modes != NULL)
{
- pScan = pI830->output[i].probed_modes;
+ pScan = output->probed_modes;
+ break;
}
}
@@ -311,9 +322,10 @@ i830PipeFindClosestMode(ScrnInfoPtr pScrn, int pipe, DisplayModePtr pMode)
* spam the desired mode in.
*/
if (pScan == NULL) {
+ I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"No pipe mode list for pipe %d,"
- "continuing with desired mode\n", pipe);
+ "continuing with desired mode\n", intel_crtc->pipe);
return pMode;
}
@@ -367,6 +379,8 @@ i830PipeFindClosestMode(ScrnInfoPtr pScrn, int pipe, DisplayModePtr pMode)
" continuing with desired mode %dx%d@%.1f\n",
pMode->HDisplay, pMode->VDisplay, pMode->VRefresh);
} else if (!I830ModesEqual(pBest, pMode)) {
+ I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
+ int pipe = intel_crtc->pipe;
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Choosing pipe %d's mode %dx%d@%.1f instead of xf86 "
"mode %dx%d@%.1f\n", pipe,
@@ -382,13 +396,14 @@ i830PipeFindClosestMode(ScrnInfoPtr pScrn, int pipe, DisplayModePtr pMode)
*/
Bool
-i830PipeInUse (ScrnInfoPtr pScrn, int pipe)
+i830PipeInUse (I830_xf86CrtcPtr crtc)
{
+ ScrnInfoPtr pScrn = crtc->scrn;
I830Ptr pI830 = I830PTR(pScrn);
int i;
for (i = 0; i < pI830->num_outputs; i++)
- if (pI830->output[i].enabled && pI830->output[i].pipe == pipe)
+ if (pI830->xf86_output[i]->crtc == crtc)
return TRUE;
return FALSE;
}
@@ -402,11 +417,13 @@ i830PipeInUse (ScrnInfoPtr pScrn, int pipe)
* display data.
*/
Bool
-i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe,
+i830PipeSetMode(I830_xf86CrtcPtr crtc, DisplayModePtr pMode,
Bool plane_enable)
{
+ ScrnInfoPtr pScrn = crtc->scrn;
I830Ptr pI830 = I830PTR(pScrn);
- I830PipePtr pI830Pipe = &pI830->pipes[pipe];
+ I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
+ int pipe = intel_crtc->pipe;
int m1 = 0, m2 = 0, n = 0, p1 = 0, p2 = 0;
CARD32 dpll = 0, fp = 0, temp;
CARD32 htot, hblank, hsync, vtot, vblank, vsync, dspcntr;
@@ -434,28 +451,34 @@ i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe,
Bool didLock = FALSE;
#endif
- if (I830ModesEqual(&pI830Pipe->curMode, pMode))
+ if (I830ModesEqual(&crtc->curMode, pMode))
return TRUE;
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Requested pix clock: %d\n",
pMode->Clock);
- pI830->pipes[pipe].enabled = i830PipeInUse (pScrn, pipe);
+ crtc->enabled = i830PipeInUse (crtc);
- if (!pI830->pipes[pipe].enabled)
+ if (!crtc->enabled)
+ {
+ /* XXX disable crtc? */
return TRUE;
+ }
#ifdef XF86DRI
didLock = I830DRILock(pScrn);
#endif
- for (i = 0; i < pI830->num_outputs; i++) {
- if (pI830->output[i].pipe != pipe || !pI830->output[i].enabled)
+ for (i = 0; i < pI830->num_outputs; i++)
+ {
+ I830_xf86OutputPtr output = pI830->xf86_output[i];
+ I830OutputPrivatePtr intel_output = output->driver_private;
+ if (output->crtc != crtc)
continue;
- pI830->output[i].pre_set_mode(pScrn, &pI830->output[i], pMode);
+ (*output->funcs->pre_set_mode)(output, pMode);
- switch (pI830->output[i].type) {
+ switch (intel_output->type) {
case I830_OUTPUT_LVDS:
is_lvds = TRUE;
break;
@@ -549,7 +572,7 @@ i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe,
} else {
refclk = 48000;
}
- ok = i830FindBestPLL(pScrn, pipe, pixel_clock, refclk, &m1, &m2, &n,
+ ok = i830FindBestPLL(crtc, pixel_clock, refclk, &m1, &m2, &n,
&p1, &p2);
if (!ok) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
@@ -636,7 +659,7 @@ i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe,
FatalError("unknown display bpp\n");
}
- if (pI830Pipe->gammaEnabled) {
+ if (intel_crtc->gammaEnabled) {
dspcntr |= DISPPLANE_GAMMA_ENABLE;
}
@@ -672,8 +695,9 @@ i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe,
}
for (i = 0; i < pI830->num_outputs; i++) {
- if (pI830->output[i].pipe == pipe)
- pI830->output[i].post_set_mode(pScrn, &pI830->output[i], pMode);
+ I830_xf86OutputPtr output = pI830->xf86_output[i];
+ if (output->crtc == crtc)
+ (*output->funcs->post_set_mode)(output, pMode);
}
OUTREG(htot_reg, htot);
@@ -685,7 +709,7 @@ i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe,
OUTREG(dspstride_reg, pScrn->displayWidth * pI830->cpp);
OUTREG(dspsize_reg, dspsize);
OUTREG(dsppos_reg, 0);
- i830PipeSetBase(pScrn, pipe, pI830Pipe->x, pI830Pipe->y);
+ i830PipeSetBase(crtc, crtc->x, crtc->y);
OUTREG(pipesrc_reg, pipesrc);
/* Then, turn the pipe on first */
@@ -697,7 +721,7 @@ i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe,
OUTREG(dspcntr_reg, dspcntr);
}
- pI830Pipe->curMode = *pMode;
+ crtc->curMode = *pMode;
ret = TRUE;
done:
@@ -712,28 +736,33 @@ void
i830DisableUnusedFunctions(ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(pScrn);
- int output, pipe;
+ int o, pipe;
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling unused functions\n");
- for (output = 0; output < pI830->num_outputs; output++) {
- if (!pI830->output[output].enabled)
- pI830->output[output].dpms(pScrn, &pI830->output[output], DPMSModeOff);
+ for (o = 0; o < pI830->num_outputs; o++)
+ {
+ I830_xf86OutputPtr output = pI830->xf86_output[o];
+ if (!output->crtc)
+ (*output->funcs->dpms)(output, DPMSModeOff);
}
/* Now, any unused plane, pipe, and DPLL (FIXME: except for DVO, i915
* internal TV) should have no outputs trying to pull data out of it, so
* we're ready to turn those off.
*/
- for (pipe = 0; pipe < pI830->num_pipes; pipe++) {
- I830PipePtr pI830Pipe = &pI830->pipes[pipe];
+ for (pipe = 0; pipe < pI830->num_pipes; pipe++)
+ {
+ I830_xf86CrtcPtr crtc = pI830->xf86_crtc[pipe];
+ I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
+ int pipe = intel_crtc->pipe;
int dspcntr_reg = pipe == 0 ? DSPACNTR : DSPBCNTR;
int pipeconf_reg = pipe == 0 ? PIPEACONF : PIPEBCONF;
int dpll_reg = pipe == 0 ? DPLL_A : DPLL_B;
CARD32 dspcntr, pipeconf, dpll;
char *pipe_name = pipe == 0 ? "A" : "B";
- if (pI830Pipe->enabled)
+ if (crtc->enabled)
continue;
dspcntr = INREG(dspcntr_reg);
@@ -761,7 +790,7 @@ i830DisableUnusedFunctions(ScrnInfoPtr pScrn)
OUTREG(dpll_reg, dpll & ~DPLL_VCO_ENABLE);
}
- memset(&pI830Pipe->curMode, 0, sizeof(pI830Pipe->curMode));
+ memset(&crtc->curMode, 0, sizeof(crtc->curMode));
}
}
@@ -780,9 +809,10 @@ i830SetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
for (i = 0; i < pI830->num_pipes; i++)
{
- ok = i830PipeSetMode(pScrn,
- i830PipeFindClosestMode(pScrn, i, pMode),
- i, TRUE);
+ I830_xf86CrtcPtr crtc = pI830->xf86_crtc[i];
+ ok = i830PipeSetMode(crtc,
+ i830PipeFindClosestMode(crtc, pMode),
+ TRUE);
if (!ok)
goto done;
}
@@ -802,7 +832,9 @@ i830SetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
/* If we might have enabled/disabled some pipes, we need to reset
* cloning mode support.
*/
- if (pI830->pipes[0].enabled && pI830->pipes[1].enabled)
+ if (pI830->num_pipes >= 2 &&
+ pI830->xf86_crtc[0]->enabled &&
+ pI830->xf86_crtc[1]->enabled)
pI830->Clone = TRUE;
else
pI830->Clone = FALSE;
@@ -834,6 +866,7 @@ i830DescribeOutputConfiguration(ScrnInfoPtr pScrn)
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Output configuration:\n");
for (i = 0; i < pI830->num_pipes; i++) {
+ I830_xf86CrtcPtr crtc = pI830->xf86_crtc[i];
CARD32 dspcntr = INREG(DSPACNTR + (DSPBCNTR - DSPACNTR) * i);
CARD32 pipeconf = INREG(PIPEACONF + (PIPEBCONF - PIPEACONF) * i);
Bool hw_plane_enable = (dspcntr & DISPLAY_PLANE_ENABLE) != 0;
@@ -841,53 +874,37 @@ i830DescribeOutputConfiguration(ScrnInfoPtr pScrn)
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
" Pipe %c is %s\n",
- 'A' + i, pI830->pipes[i].enabled ? "on" : "off");
+ 'A' + i, crtc->enabled ? "on" : "off");
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
" Display plane %c is now %s and connected to pipe %c.\n",
'A' + i,
- pI830->pipes[i].enabled ? "enabled" : "disabled",
+ crtc->enabled ? "enabled" : "disabled",
dspcntr & DISPPLANE_SEL_PIPE_MASK ? 'B' : 'A');
- if (hw_pipe_enable != pI830->pipes[i].enabled) {
+ if (hw_pipe_enable != crtc->enabled) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
" Hardware claims pipe %c is %s while software "
"believes it is %s\n",
'A' + i, hw_pipe_enable ? "on" : "off",
- pI830->pipes[i].enabled ? "on" : "off");
+ crtc->enabled ? "on" : "off");
}
- if (hw_plane_enable != pI830->pipes[i].enabled) {
+ if (hw_plane_enable != crtc->enabled) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
" Hardware claims plane %c is %s while software "
"believes it is %s\n",
'A' + i, hw_plane_enable ? "on" : "off",
- pI830->pipes[i].enabled ? "on" : "off");
+ crtc->enabled ? "on" : "off");
}
}
for (i = 0; i < pI830->num_outputs; i++) {
- const char *name = NULL;
-
- switch (pI830->output[i].type) {
- case I830_OUTPUT_ANALOG:
- name = "CRT";
- break;
- case I830_OUTPUT_LVDS:
- name = "LVDS";
- break;
- case I830_OUTPUT_SDVO:
- name = "SDVO";
- break;
- case I830_OUTPUT_DVO:
- name = "DVO";
- break;
- case I830_OUTPUT_TVOUT:
- name = "TV";
- break;
- }
-
+ I830_xf86OutputPtr output = pI830->xf86_output[i];
+ I830_xf86CrtcPtr crtc = output->crtc;
+ I830CrtcPrivatePtr intel_crtc = crtc ? crtc->driver_private : NULL;
+
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- " Output %s is %sabled and connected to pipe %c\n",
- name, pI830->output[i].enabled ? "en" : "dis",
- pI830->output[i].pipe == 0 ? 'A' : 'B');
+ " Output %s is connected to pipe %s\n",
+ output->name, intel_crtc == NULL ? "none" :
+ (intel_crtc->pipe == 0 ? "A" : "B"));
}
}
@@ -902,15 +919,19 @@ i830DescribeOutputConfiguration(ScrnInfoPtr pScrn)
* configured for it. In the future, it could choose to temporarily disable
* some outputs to free up a pipe for its use.
*
- * \return monitor number, or -1 if no pipes are available.
+ * \return crtc, or NULL if no pipes are available.
*/
-int
-i830GetLoadDetectPipe(ScrnInfoPtr pScrn, I830OutputPtr output)
+
+I830_xf86CrtcPtr
+i830GetLoadDetectPipe(I830_xf86OutputPtr output)
{
- I830Ptr pI830 = I830PTR(pScrn);
- int i;
+ ScrnInfoPtr pScrn = output->scrn;
+ I830Ptr pI830 = I830PTR(pScrn);
+ I830OutputPrivatePtr intel_output = output->driver_private;
+ I830_xf86CrtcPtr crtc;
+ int i;
/* VESA 640x480x72Hz mode to set on the pipe */
- DisplayModeRec mode = {
+ static DisplayModeRec mode = {
NULL, NULL, "640x480", MODE_OK, M_T_DEFAULT,
31500,
640, 664, 704, 832, 0,
@@ -922,54 +943,37 @@ i830GetLoadDetectPipe(ScrnInfoPtr pScrn, I830OutputPtr output)
FALSE, FALSE, 0, NULL, 0, 0.0, 0.0
};
- /* If the output is not marked disabled, check if it's already assigned
- * to an active pipe, and is alone on that pipe. If so, we're done.
- */
- if (output->enabled) {
- int pipeconf_reg = (output->pipe == 0) ? PIPEACONF : PIPEBCONF;
-
- if (INREG(pipeconf_reg) & PIPEACONF_ENABLE) {
- /* Actually, maybe we don't need to be all alone on the pipe.
- * The worst that should happen is false positives. Need to test,
- * but actually fixing this during server startup is messy.
- */
-#if 0
- for (i = 0; i < pI830->num_outputs; i++) {
- if (&pI830->output[i] != output &&
- pI830->output[i].pipe == output->pipe)
- {
- return -1;
- }
- }
-#endif
- return output->pipe;
- }
- }
+ if (output->crtc)
+ return output->crtc;
for (i = 0; i < pI830->num_pipes; i++)
- if (!i830PipeInUse(pScrn, i))
+ if (!i830PipeInUse(pI830->xf86_crtc[i]))
break;
if (i == pI830->num_pipes)
- return -1;
+ return NULL;
- output->load_detect_temp = TRUE;
- output->pipe = i;
- output->enabled = TRUE;
+ crtc = pI830->xf86_crtc[i];
- I830xf86SetModeCrtc(&mode, INTERLACE_HALVE_V);
+ output->crtc = crtc;
+ intel_output->load_detect_temp = TRUE;
- i830PipeSetMode(pScrn, &mode, i, FALSE);
+ I830xf86SetModeCrtc(&mode, INTERLACE_HALVE_V);
+ i830PipeSetMode(crtc, &mode, FALSE);
- return i;
+ return crtc;
}
void
-i830ReleaseLoadDetectPipe(ScrnInfoPtr pScrn, I830OutputPtr output)
+i830ReleaseLoadDetectPipe(I830_xf86OutputPtr output)
{
- if (output->load_detect_temp) {
- output->enabled = FALSE;
+ ScrnInfoPtr pScrn = output->scrn;
+ I830OutputPrivatePtr intel_output = output->driver_private;
+
+ if (intel_output->load_detect_temp)
+ {
+ output->crtc = NULL;
+ intel_output->load_detect_temp = FALSE;
i830DisableUnusedFunctions(pScrn);
- output->load_detect_temp = FALSE;
}
}
diff --git a/src/i830_display.h b/src/i830_display.h
index 361a3c67..4409728d 100644
--- a/src/i830_display.h
+++ b/src/i830_display.h
@@ -27,14 +27,14 @@
/* i830_display.c */
DisplayModePtr
-i830PipeFindClosestMode(ScrnInfoPtr pScrn, int pipe, DisplayModePtr pMode);
-Bool i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe,
+i830PipeFindClosestMode(I830_xf86CrtcPtr crtc, DisplayModePtr pMode);
+Bool i830PipeSetMode(I830_xf86CrtcPtr crtc, DisplayModePtr pMode,
Bool plane_enable);
void i830DisableUnusedFunctions(ScrnInfoPtr pScrn);
Bool i830SetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode);
-void i830PipeSetBase(ScrnInfoPtr pScrn, int pipe, int x, int y);
+void i830PipeSetBase(I830_xf86CrtcPtr crtc, int x, int y);
void i830WaitForVblank(ScrnInfoPtr pScrn);
void i830DescribeOutputConfiguration(ScrnInfoPtr pScrn);
-int i830GetLoadDetectPipe(ScrnInfoPtr pScrn, I830OutputPtr output);
-void i830ReleaseLoadDetectPipe(ScrnInfoPtr pScrn, I830OutputPtr output);
-Bool i830PipeInUse(ScrnInfoPtr pScrn, int pipe);
+I830_xf86CrtcPtr i830GetLoadDetectPipe(I830_xf86OutputPtr output);
+void i830ReleaseLoadDetectPipe(I830_xf86OutputPtr output);
+Bool i830PipeInUse(I830_xf86CrtcPtr crtc);
diff --git a/src/i830_dri.c b/src/i830_dri.c
index 3b029185..af34afc5 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -1513,13 +1513,9 @@ I830DRISetVBlankInterrupt (ScrnInfoPtr pScrn, Bool on)
if (pI830->directRenderingEnabled && pI830->drmMinor >= 5) {
if (on) {
- if (pI830->pipes[1].enabled) {
- if (pI830->drmMinor >= 6)
- pipe.pipe = DRM_I830_VBLANK_PIPE_A | DRM_I830_VBLANK_PIPE_B;
- else
- pipe.pipe = DRM_I830_VBLANK_PIPE_B;
+ if (pI830->num_pipes > 1 && pI830->xf86_crtc[1]->enabled)
pipe.pipe = DRM_I830_VBLANK_PIPE_B;
- } else
+ else
pipe.pipe = DRM_I830_VBLANK_PIPE_A;
} else {
pipe.pipe = 0;
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 0ae1ee6a..d4d5fbc3 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -548,8 +548,10 @@ I830LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
DPRINTF(PFX, "I830LoadPalette: numColors: %d\n", numColors);
pI830 = I830PTR(pScrn);
- for(p=0; p < pI830->num_pipes; p++) {
- I830PipePtr pI830Pipe = &pI830->pipes[p];
+ for(p=0; p < pI830->num_pipes; p++)
+ {
+ I830_xf86CrtcPtr crtc = pI830->xf86_crtc[p];
+ I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
if (p == 0) {
palreg = PALETTE_A;
@@ -563,10 +565,10 @@ I830LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
dspsurf = DSPBSURF;
}
- if (pI830Pipe->enabled == 0)
+ if (crtc->enabled == 0)
continue;
- pI830Pipe->gammaEnabled = 1;
+ intel_crtc->gammaEnabled = 1;
/* To ensure gamma is enabled we need to turn off and on the plane */
temp = INREG(dspreg);
@@ -1261,33 +1263,44 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
/* Perform the pipe assignment of outputs. This is a kludge until
* we have better configuration support in the generic RandR code
*/
- for (i = 0; i < pI830->num_outputs; i++) {
- pI830->output[i].enabled = FALSE;
+ for (i = 0; i < pI830->num_outputs; i++)
+ {
+ I830_xf86OutputPtr output = pI830->xf86_output[i];
+ I830OutputPrivatePtr intel_output = output->driver_private;
+ I830_xf86CrtcPtr crtc;
+ int p;
- switch (pI830->output[i].type) {
+ output->crtc = NULL;
+
+ switch (intel_output->type) {
case I830_OUTPUT_LVDS:
/* LVDS must live on pipe B for two-pipe devices */
- pI830->output[i].pipe = pI830->num_pipes - 1;
- pI830->output[i].enabled = TRUE;
+ crtc = pI830->xf86_crtc[pI830->num_pipes - 1];
+ if (!i830PipeInUse (crtc))
+ output->crtc = crtc;
break;
case I830_OUTPUT_ANALOG:
case I830_OUTPUT_DVO:
case I830_OUTPUT_SDVO:
- if (pI830->output[i].detect(pScrn, &pI830->output[i]) !=
- OUTPUT_STATUS_DISCONNECTED) {
- if (!i830PipeInUse(pScrn, 0)) {
- pI830->output[i].pipe = 0;
- pI830->output[i].enabled = TRUE;
- } else if (!i830PipeInUse(pScrn, 1)) {
- pI830->output[i].pipe = 1;
- pI830->output[i].enabled = TRUE;
+ if ((*output->funcs->detect)(output) != OUTPUT_STATUS_DISCONNECTED)
+ {
+ for (p = 0; p < pI830->num_pipes; p++)
+ {
+ crtc = pI830->xf86_crtc[p];
+ if (!i830PipeInUse(crtc))
+ {
+ output->crtc = crtc;
+ break;
+ }
}
}
break;
case I830_OUTPUT_TVOUT:
- if (!i830PipeInUse(pScrn, 0)) {
- pI830->output[i].pipe = 0;
- pI830->output[i].enabled = TRUE;
+ crtc = pI830->xf86_crtc[0];
+ if ((*output->funcs->detect)(output) != OUTPUT_STATUS_DISCONNECTED &&
+ !i830PipeInUse(crtc))
+ {
+ output->crtc = crtc;
}
break;
default:
@@ -1296,10 +1309,12 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
}
}
- for (i = 0; i < pI830->num_pipes; i++) {
- pI830->pipes[i].enabled = i830PipeInUse(pScrn, i);
+ for (i = 0; i < pI830->num_pipes; i++)
+ {
+ I830_xf86CrtcPtr crtc = pI830->xf86_crtc[i];
+ crtc->enabled = i830PipeInUse(crtc);
}
-
+
pI830->rotation = RR_Rotate_0;
if ((s = xf86GetOptValString(pI830->Options, OPTION_ROTATE))) {
pI830->InitialRotation = 0;
@@ -2108,8 +2123,9 @@ SaveHWState(ScrnInfoPtr pScrn)
pI830->savePFIT_CONTROL = INREG(PFIT_CONTROL);
for (i = 0; i < pI830->num_outputs; i++) {
- if (pI830->output[i].save != NULL)
- pI830->output[i].save(pScrn, &pI830->output[i]);
+ I830_xf86OutputPtr output = pI830->xf86_output[i];
+ if (output->funcs->save)
+ (*output->funcs->save) (output);
}
vgaHWUnlock(hwp);
@@ -2149,7 +2165,8 @@ RestoreHWState(ScrnInfoPtr pScrn)
/* Disable outputs if necessary */
for (i = 0; i < pI830->num_outputs; i++) {
- pI830->output[i].pre_set_mode(pScrn, &pI830->output[i], NULL);
+ I830_xf86OutputPtr output = pI830->xf86_output[i];
+ (*output->funcs->pre_set_mode) (output, NULL);
}
i830WaitForVblank(pScrn);
@@ -2199,7 +2216,8 @@ RestoreHWState(ScrnInfoPtr pScrn)
OUTREG(PFIT_CONTROL, pI830->savePFIT_CONTROL);
for (i = 0; i < pI830->num_outputs; i++) {
- pI830->output[i].restore(pScrn, &pI830->output[i]);
+ I830_xf86OutputPtr output = pI830->xf86_output[i];
+ (*output->funcs->restore) (output);
}
if (IS_I965G(pI830)) {
@@ -3235,8 +3253,11 @@ i830AdjustFrame(int scrnIndex, int x, int y, int flags)
}
for (i = 0; i < pI830->num_pipes; i++)
- if (pI830->pipes[i].enabled)
- i830PipeSetBase(pScrn, i, x, y);
+ {
+ I830_xf86CrtcPtr crtc = pI830->xf86_crtc[i];
+ if (crtc->enabled)
+ i830PipeSetBase(crtc, x, y);
+ }
}
static void
@@ -3349,17 +3370,17 @@ I830EnterVT(int scrnIndex, int flags)
for (i = 0; i < pI830->num_pipes; i++)
{
- I830PipePtr pipe = &pI830->pipes[i];
+ I830_xf86CrtcPtr crtc = pI830->xf86_crtc[i];
+
/* Mark that we'll need to re-set the mode for sure */
- memset(&pipe->curMode, 0, sizeof(pipe->curMode));
- if (!pipe->desiredMode.CrtcHDisplay)
- {
- pipe->desiredMode = *i830PipeFindClosestMode (pScrn, i,
- pScrn->currentMode);
- }
- if (!i830PipeSetMode (pScrn, &pipe->desiredMode, i, TRUE))
+ memset(&crtc->curMode, 0, sizeof(crtc->curMode));
+ if (!crtc->desiredMode.CrtcHDisplay)
+ crtc->desiredMode = *i830PipeFindClosestMode (crtc, pScrn->currentMode);
+
+ if (!i830PipeSetMode (crtc, &crtc->desiredMode, TRUE))
return FALSE;
- i830PipeSetBase(pScrn, i, pipe->x, pipe->y);
+
+ i830PipeSetBase(crtc, crtc->x, crtc->y);
}
i830DisableUnusedFunctions(pScrn);
@@ -3527,7 +3548,7 @@ I830SaveScreen(ScreenPtr pScreen, int mode)
base = DSPBADDR;
surf = DSPBSURF;
}
- if (pI830->pipes[i].enabled) {
+ if (pI830->xf86_crtc[i]->enabled) {
temp = INREG(ctrl);
if (on)
temp |= DISPLAY_PLANE_ENABLE;
@@ -3565,10 +3586,15 @@ I830DisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode,
CARD32 temp, ctrl, base;
for (i = 0; i < pI830->num_outputs; i++) {
- pI830->output[i].dpms(pScrn, &pI830->output[i], PowerManagementMode);
+ I830_xf86OutputPtr output = pI830->xf86_output[i];
+
+ (*output->funcs->dpms) (output, PowerManagementMode);
}
- for (i = 0; i < pI830->num_pipes; i++) {
+ for (i = 0; i < pI830->num_pipes; i++)
+ {
+ I830_xf86CrtcPtr crtc = pI830->xf86_crtc[i];
+
if (i == 0) {
ctrl = DSPACNTR;
base = DSPABASE;
@@ -3576,7 +3602,8 @@ I830DisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode,
ctrl = DSPBCNTR;
base = DSPBADDR;
}
- if (pI830->pipes[i].enabled) {
+ /* XXX pipe disable too? */
+ if (crtc->enabled) {
temp = INREG(ctrl);
if (PowerManagementMode == DPMSModeOn)
temp |= DISPLAY_PLANE_ENABLE;
diff --git a/src/i830_dvo.c b/src/i830_dvo.c
index 31fb76ba..b2921902 100644
--- a/src/i830_dvo.c
+++ b/src/i830_dvo.c
@@ -57,18 +57,21 @@ struct _I830DVODriver i830_dvo_drivers[] =
#define I830_NUM_DVO_DRIVERS (sizeof(i830_dvo_drivers)/sizeof(struct _I830DVODriver))
static void
-i830_dvo_dpms(ScrnInfoPtr pScrn, I830OutputPtr output, int mode)
+i830_dvo_dpms(I830_xf86OutputPtr output, int mode)
{
+ I830OutputPrivatePtr intel_output = output->driver_private;
if (mode == DPMSModeOn)
- output->i2c_drv->vid_rec->Power(output->i2c_drv->dev_priv, TRUE);
+ (*intel_output->i2c_drv->vid_rec->Power)(intel_output->i2c_drv->dev_priv, TRUE);
else
- output->i2c_drv->vid_rec->Power(output->i2c_drv->dev_priv, FALSE);
+ (*intel_output->i2c_drv->vid_rec->Power)(intel_output->i2c_drv->dev_priv, FALSE);
}
static void
-i830_dvo_save(ScrnInfoPtr pScrn, I830OutputPtr output)
+i830_dvo_save(I830_xf86OutputPtr output)
{
- I830Ptr pI830 = I830PTR(pScrn);
+ ScrnInfoPtr pScrn = output->scrn;
+ I830Ptr pI830 = I830PTR(pScrn);
+ I830OutputPrivatePtr intel_output = output->driver_private;
/* Each output should probably just save the registers it touches, but for
* now, use more overkill.
@@ -77,61 +80,68 @@ i830_dvo_save(ScrnInfoPtr pScrn, I830OutputPtr output)
pI830->saveDVOB = INREG(DVOB);
pI830->saveDVOC = INREG(DVOC);
- output->i2c_drv->vid_rec->SaveRegs(output->i2c_drv->dev_priv);
+ (*intel_output->i2c_drv->vid_rec->SaveRegs)(intel_output->i2c_drv->dev_priv);
}
static void
-i830_dvo_restore(ScrnInfoPtr pScrn, I830OutputPtr output)
+i830_dvo_restore(I830_xf86OutputPtr output)
{
- I830Ptr pI830 = I830PTR(pScrn);
+ ScrnInfoPtr pScrn = output->scrn;
+ I830Ptr pI830 = I830PTR(pScrn);
+ I830OutputPrivatePtr intel_output = output->driver_private;
OUTREG(DVOA, pI830->saveDVOA);
OUTREG(DVOB, pI830->saveDVOB);
OUTREG(DVOC, pI830->saveDVOC);
- output->i2c_drv->vid_rec->RestoreRegs(output->i2c_drv->dev_priv);
+ (*intel_output->i2c_drv->vid_rec->RestoreRegs)(intel_output->i2c_drv->dev_priv);
}
static int
-i830_dvo_mode_valid(ScrnInfoPtr pScrn, I830OutputPtr output,
- DisplayModePtr pMode)
+i830_dvo_mode_valid(I830_xf86OutputPtr output, DisplayModePtr pMode)
{
+ I830OutputPrivatePtr intel_output = output->driver_private;
+
if (pMode->Flags & V_DBLSCAN)
return MODE_NO_DBLESCAN;
/* XXX: Validate clock range */
- if (output->i2c_drv->vid_rec->ModeValid(output->i2c_drv->dev_priv, pMode))
+ if ((*intel_output->i2c_drv->vid_rec->ModeValid)(intel_output->i2c_drv->dev_priv, pMode))
return MODE_OK;
else
return MODE_BAD;
}
static void
-i830_dvo_pre_set_mode(ScrnInfoPtr pScrn, I830OutputPtr output,
- DisplayModePtr pMode)
+i830_dvo_pre_set_mode(I830_xf86OutputPtr output, DisplayModePtr pMode)
{
- I830Ptr pI830 = I830PTR(pScrn);
+ ScrnInfoPtr pScrn = output->scrn;
+ I830Ptr pI830 = I830PTR(pScrn);
+ I830OutputPrivatePtr intel_output = output->driver_private;
- output->i2c_drv->vid_rec->Mode(output->i2c_drv->dev_priv, pMode);
+ (*intel_output->i2c_drv->vid_rec->Mode)(intel_output->i2c_drv->dev_priv, pMode);
OUTREG(DVOC, INREG(DVOC) & ~DVO_ENABLE);
}
static void
-i830_dvo_post_set_mode(ScrnInfoPtr pScrn, I830OutputPtr output,
- DisplayModePtr pMode)
+i830_dvo_post_set_mode(I830_xf86OutputPtr output, DisplayModePtr pMode)
{
- I830Ptr pI830 = I830PTR(pScrn);
- CARD32 dvo;
- int dpll_reg = (output->pipe == 0) ? DPLL_A : DPLL_B;
+ ScrnInfoPtr pScrn = output->scrn;
+ I830Ptr pI830 = I830PTR(pScrn);
+ I830_xf86CrtcPtr crtc = output->crtc;
+ I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
+ int pipe = intel_crtc->pipe;
+ CARD32 dvo;
+ int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
/* Save the data order, since I don't know what it should be set to. */
dvo = INREG(DVOC) & (DVO_PRESERVE_MASK | DVO_DATA_ORDER_GBRG);
dvo |= DVO_ENABLE;
dvo |= DVO_DATA_ORDER_FP | DVO_BORDER_ENABLE | DVO_BLANK_ACTIVE_HIGH;
- if (output->pipe == 1)
+ if (pipe == 1)
dvo |= DVO_PIPE_B_SELECT;
if (pMode->Flags & V_PHSYNC)
@@ -155,7 +165,7 @@ i830_dvo_post_set_mode(ScrnInfoPtr pScrn, I830OutputPtr output,
* Unimplemented.
*/
static enum detect_status
-i830_dvo_detect(ScrnInfoPtr pScrn, I830OutputPtr output)
+i830_dvo_detect(I830_xf86OutputPtr output)
{
return OUTPUT_STATUS_UNKNOWN;
}
@@ -191,46 +201,81 @@ I830I2CDetectDVOControllers(ScrnInfoPtr pScrn, I2CBusPtr pI2CBus,
return FALSE;
}
+static void
+i830_dvo_destroy (I830_xf86OutputPtr output)
+{
+ I830OutputPrivatePtr intel_output = output->driver_private;
+
+ if (intel_output)
+ {
+ if (intel_output->pI2CBus)
+ xf86DestroyI2CBusRec (intel_output->pI2CBus, TRUE, TRUE);
+ if (intel_output->pDDCBus)
+ xf86DestroyI2CBusRec (intel_output->pDDCBus, TRUE, TRUE);
+ /* XXX sub module cleanup? */
+ xfree (intel_output);
+ }
+}
+
+static const I830_xf86OutputFuncsRec i830_dvo_output_funcs = {
+ .dpms = i830_dvo_dpms,
+ .save = i830_dvo_save,
+ .restore = i830_dvo_restore,
+ .mode_valid = i830_dvo_mode_valid,
+ .pre_set_mode = i830_dvo_pre_set_mode,
+ .post_set_mode = i830_dvo_post_set_mode,
+ .detect = i830_dvo_detect,
+ .get_modes = i830_ddc_get_modes,
+ .destroy = i830_dvo_destroy
+};
+
void
i830_dvo_init(ScrnInfoPtr pScrn)
{
- I830Ptr pI830 = I830PTR(pScrn);
- Bool ret;
- int i = pI830->num_outputs;
-
- pI830->output[i].type = I830_OUTPUT_DVO;
- pI830->output[i].dpms = i830_dvo_dpms;
- pI830->output[i].save = i830_dvo_save;
- pI830->output[i].restore = i830_dvo_restore;
- pI830->output[i].mode_valid = i830_dvo_mode_valid;
- pI830->output[i].pre_set_mode = i830_dvo_pre_set_mode;
- pI830->output[i].post_set_mode = i830_dvo_post_set_mode;
- pI830->output[i].detect = i830_dvo_detect;
- pI830->output[i].get_modes = i830_ddc_get_modes;
+ I830_xf86OutputPtr output;
+ I830OutputPrivatePtr intel_output;
+ int ret;
+ output = i830xf86OutputCreate (pScrn, &i830_dvo_output_funcs,
+ "ADD AGP card");
+ if (!output)
+ return;
+ intel_output = xnfcalloc (sizeof (I830OutputPrivateRec), 1);
+ if (!intel_output)
+ {
+ i830xf86OutputDestroy (output);
+ return;
+ }
+ intel_output->type = I830_OUTPUT_DVO;
+ output->driver_private = intel_output;
+
/* Set up the I2C and DDC buses */
- ret = I830I2CInit(pScrn, &pI830->output[i].pI2CBus, GPIOE, "DVOI2C_E");
+ ret = I830I2CInit(pScrn, &intel_output->pI2CBus, GPIOE, "DVOI2C_E");
if (!ret)
+ {
+ i830xf86OutputDestroy (output);
return;
+ }
- ret = I830I2CInit(pScrn, &pI830->output[i].pDDCBus, GPIOD, "DVODDC_D");
- if (!ret) {
- xf86DestroyI2CBusRec(pI830->output[i].pI2CBus, TRUE, TRUE);
+ ret = I830I2CInit(pScrn, &intel_output->pDDCBus, GPIOD, "DVODDC_D");
+ if (!ret)
+ {
+ i830xf86OutputDestroy (output);
return;
}
/* Now, try to find a controller */
- ret = I830I2CDetectDVOControllers(pScrn, pI830->output[i].pI2CBus,
- &pI830->output[i].i2c_drv);
- if (ret) {
+ ret = I830I2CDetectDVOControllers(pScrn, intel_output->pI2CBus,
+ &intel_output->i2c_drv);
+ if (ret)
+ {
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Found i2c %s on %08lX\n",
- pI830->output[i].i2c_drv->modulename,
- pI830->output[i].pI2CBus->DriverPrivate.uval);
- } else {
- xf86DestroyI2CBusRec(pI830->output[i].pI2CBus, TRUE, TRUE);
- xf86DestroyI2CBusRec(pI830->output[i].pDDCBus, TRUE, TRUE);
+ intel_output->i2c_drv->modulename,
+ intel_output->pI2CBus->DriverPrivate.uval);
+ }
+ else
+ {
+ i830xf86OutputDestroy (output);
return;
}
-
- pI830->num_outputs++;
}
diff --git a/src/i830_lvds.c b/src/i830_lvds.c
index ea45420f..e72b9e87 100644
--- a/src/i830_lvds.c
+++ b/src/i830_lvds.c
@@ -73,8 +73,10 @@ i830SetLVDSPanelPower(ScrnInfoPtr pScrn, Bool on)
}
static void
-i830_lvds_dpms(ScrnInfoPtr pScrn, I830OutputPtr output, int mode)
+i830_lvds_dpms (I830_xf86OutputPtr output, int mode)
{
+ ScrnInfoPtr pScrn = output->scrn;
+
if (mode == DPMSModeOn)
i830SetLVDSPanelPower(pScrn, TRUE);
else
@@ -82,9 +84,10 @@ i830_lvds_dpms(ScrnInfoPtr pScrn, I830OutputPtr output, int mode)
}
static void
-i830_lvds_save(ScrnInfoPtr pScrn, I830OutputPtr output)
+i830_lvds_save (I830_xf86OutputPtr output)
{
- I830Ptr pI830 = I830PTR(pScrn);
+ ScrnInfoPtr pScrn = output->scrn;
+ I830Ptr pI830 = I830PTR(pScrn);
pI830->savePP_ON = INREG(LVDSPP_ON);
pI830->savePP_OFF = INREG(LVDSPP_OFF);
@@ -106,9 +109,10 @@ i830_lvds_save(ScrnInfoPtr pScrn, I830OutputPtr output)
}
static void
-i830_lvds_restore(ScrnInfoPtr pScrn, I830OutputPtr output)
+i830_lvds_restore(I830_xf86OutputPtr output)
{
- I830Ptr pI830 = I830PTR(pScrn);
+ ScrnInfoPtr pScrn = output->scrn;
+ I830Ptr pI830 = I830PTR(pScrn);
OUTREG(BLC_PWM_CTL, pI830->saveBLC_PWM_CTL);
OUTREG(LVDSPP_ON, pI830->savePP_ON);
@@ -123,16 +127,15 @@ i830_lvds_restore(ScrnInfoPtr pScrn, I830OutputPtr output)
}
static int
-i830_lvds_mode_valid(ScrnInfoPtr pScrn, I830OutputPtr output,
- DisplayModePtr pMode)
+i830_lvds_mode_valid(I830_xf86OutputPtr output, DisplayModePtr pMode)
{
return MODE_OK;
}
static void
-i830_lvds_pre_set_mode(ScrnInfoPtr pScrn, I830OutputPtr output,
- DisplayModePtr pMode)
+i830_lvds_pre_set_mode(I830_xf86OutputPtr output, DisplayModePtr pMode)
{
+ ScrnInfoPtr pScrn = output->scrn;
/* Always make sure the LVDS is off before we play with DPLLs and pipe
* configuration. We can skip this in some cases (for example, going
* between hi-res modes with automatic panel scaling are fine), but be
@@ -142,11 +145,11 @@ i830_lvds_pre_set_mode(ScrnInfoPtr pScrn, I830OutputPtr output,
}
static void
-i830_lvds_post_set_mode(ScrnInfoPtr pScrn, I830OutputPtr output,
- DisplayModePtr pMode)
+i830_lvds_post_set_mode(I830_xf86OutputPtr output, DisplayModePtr pMode)
{
- I830Ptr pI830 = I830PTR(pScrn);
- CARD32 pfit_control;
+ ScrnInfoPtr pScrn = output->scrn;
+ I830Ptr pI830 = I830PTR(pScrn);
+ CARD32 pfit_control;
/* Enable automatic panel scaling so that non-native modes fill the
* screen. Should be enabled before the pipe is enabled, according to
@@ -182,7 +185,7 @@ i830_lvds_post_set_mode(ScrnInfoPtr pScrn, I830OutputPtr output,
* been set up if the LVDS was actually connected anyway.
*/
static enum detect_status
-i830_lvds_detect(ScrnInfoPtr pScrn, I830OutputPtr output)
+i830_lvds_detect(I830_xf86OutputPtr output)
{
return OUTPUT_STATUS_CONNECTED;
}
@@ -191,13 +194,14 @@ i830_lvds_detect(ScrnInfoPtr pScrn, I830OutputPtr output)
* Return the list of DDC modes if available, or the BIOS fixed mode otherwise.
*/
static DisplayModePtr
-i830_lvds_get_modes(ScrnInfoPtr pScrn, I830OutputPtr output)
+i830_lvds_get_modes(I830_xf86OutputPtr output)
{
- I830Ptr pI830 = I830PTR(pScrn);
- DisplayModePtr modes, new;
- char stmp[32];
+ ScrnInfoPtr pScrn = output->scrn;
+ I830Ptr pI830 = I830PTR(pScrn);
+ DisplayModePtr modes, new;
+ char stmp[32];
- modes = i830_ddc_get_modes(pScrn, output);
+ modes = i830_ddc_get_modes(output);
if (modes != NULL)
return modes;
@@ -220,10 +224,34 @@ i830_lvds_get_modes(ScrnInfoPtr pScrn, I830OutputPtr output)
return new;
}
+static void
+i830_lvds_destroy (I830_xf86OutputPtr output)
+{
+ I830OutputPrivatePtr intel_output = output->driver_private;
+
+ if (intel_output)
+ xfree (intel_output);
+}
+
+static const I830_xf86OutputFuncsRec i830_lvds_output_funcs = {
+ .dpms = i830_lvds_dpms,
+ .save = i830_lvds_save,
+ .restore = i830_lvds_restore,
+ .mode_valid = i830_lvds_mode_valid,
+ .pre_set_mode = i830_lvds_pre_set_mode,
+ .post_set_mode = i830_lvds_post_set_mode,
+ .detect = i830_lvds_detect,
+ .get_modes = i830_lvds_get_modes,
+ .destroy = i830_lvds_destroy
+};
+
void
i830_lvds_init(ScrnInfoPtr pScrn)
{
- I830Ptr pI830 = I830PTR(pScrn);
+ I830Ptr pI830 = I830PTR(pScrn);
+ I830_xf86OutputPtr output;
+ I830OutputPrivatePtr intel_output;
+
/* Get the LVDS fixed mode out of the BIOS. We should support LVDS with
* the BIOS being unavailable or broken, but lack the configuration options
@@ -258,21 +286,20 @@ i830_lvds_init(ScrnInfoPtr pScrn)
}
}
- pI830->output[pI830->num_outputs].type = I830_OUTPUT_LVDS;
- pI830->output[pI830->num_outputs].dpms = i830_lvds_dpms;
- pI830->output[pI830->num_outputs].save = i830_lvds_save;
- pI830->output[pI830->num_outputs].restore = i830_lvds_restore;
- pI830->output[pI830->num_outputs].mode_valid = i830_lvds_mode_valid;
- pI830->output[pI830->num_outputs].pre_set_mode = i830_lvds_pre_set_mode;
- pI830->output[pI830->num_outputs].post_set_mode = i830_lvds_post_set_mode;
- pI830->output[pI830->num_outputs].detect = i830_lvds_detect;
- pI830->output[pI830->num_outputs].get_modes = i830_lvds_get_modes;
+ output = i830xf86OutputCreate (pScrn, &i830_lvds_output_funcs, "Built-in LCD panel");
+ if (!output)
+ return;
+ intel_output = xnfcalloc (sizeof (I830OutputPrivateRec), 1);
+ if (!intel_output)
+ {
+ i830xf86OutputDestroy (output);
+ return;
+ }
+ intel_output->type = I830_OUTPUT_LVDS;
+ output->driver_private = intel_output;
/* Set up the LVDS DDC channel. Most panels won't support it, but it can
* be useful if available.
*/
- I830I2CInit(pScrn, &pI830->output[pI830->num_outputs].pDDCBus,
- GPIOC, "LVDSDDC_C");
-
- pI830->num_outputs++;
+ I830I2CInit(pScrn, &intel_output->pDDCBus, GPIOC, "LVDSDDC_C");
}
diff --git a/src/i830_modes.c b/src/i830_modes.c
index 7fdd40ed..7d4bcbae 100644
--- a/src/i830_modes.c
+++ b/src/i830_modes.c
@@ -427,47 +427,44 @@ i830_reprobe_output_modes(ScrnInfoPtr pScrn)
int i;
/* Re-probe the list of modes for each output. */
- for (i = 0; i < pI830->num_outputs; i++) {
+ for (i = 0; i < pI830->num_outputs; i++)
+ {
+ I830_xf86OutputPtr output = pI830->xf86_output[i];
DisplayModePtr mode;
- while (pI830->output[i].probed_modes != NULL) {
- xf86DeleteMode(&pI830->output[i].probed_modes,
- pI830->output[i].probed_modes);
- }
+ while (output->probed_modes != NULL)
+ xf86DeleteMode(&output->probed_modes, output->probed_modes);
- pI830->output[i].probed_modes =
- pI830->output[i].get_modes(pScrn, &pI830->output[i]);
+ output->probed_modes = (*output->funcs->get_modes) (output);
/* Set the DDC properties to whatever first output has DDC information.
*/
- if (pI830->output[i].MonInfo != NULL && !properties_set) {
- xf86SetDDCproperties(pScrn, pI830->output[i].MonInfo);
+ if (output->MonInfo != NULL && !properties_set) {
+ xf86SetDDCproperties(pScrn, output->MonInfo);
properties_set = TRUE;
}
- if (pI830->output[i].probed_modes != NULL) {
+ if (output->probed_modes != NULL)
+ {
/* silently prune modes down to ones matching the user's
* configuration.
*/
- i830xf86ValidateModesUserConfig(pScrn,
- pI830->output[i].probed_modes);
- i830xf86PruneInvalidModes(pScrn, &pI830->output[i].probed_modes,
- FALSE);
+ i830xf86ValidateModesUserConfig(pScrn, output->probed_modes);
+ i830xf86PruneInvalidModes(pScrn, &output->probed_modes, FALSE);
}
#ifdef DEBUG_REPROBE
- if (pI830->output[i].probed_modes != NULL) {
+ if (output->probed_modes != NULL) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Printing probed modes for output %s\n",
- i830_output_type_names[pI830->output[i].type]);
+ output->name);
} else {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"No remaining probed modes for output %s\n",
- i830_output_type_names[pI830->output[i].type]);
+ output->name);
}
#endif
- for (mode = pI830->output[i].probed_modes; mode != NULL;
- mode = mode->next)
+ for (mode = output->probed_modes; mode != NULL; mode = mode->next)
{
/* The code to choose the best mode per pipe later on will require
* VRefresh to be set.
@@ -515,9 +512,9 @@ i830_set_xf86_modes_from_outputs(ScrnInfoPtr pScrn)
* care about enough to make some sort of unioned list.
*/
for (i = 0; i < pI830->num_outputs; i++) {
- if (pI830->output[i].probed_modes != NULL) {
- pScrn->modes =
- i830xf86DuplicateModes(pScrn, pI830->output[i].probed_modes);
+ I830_xf86OutputPtr output = pI830->xf86_output[i];
+ if (output->probed_modes != NULL) {
+ pScrn->modes = i830xf86DuplicateModes(pScrn, output->probed_modes);
break;
}
}
@@ -568,10 +565,10 @@ i830_set_default_screen_size(ScrnInfoPtr pScrn)
* set for the currently-connected outputs.
*/
for (i = 0; i < pI830->num_outputs; i++) {
+ I830_xf86OutputPtr output = pI830->xf86_output[i];
DisplayModePtr mode;
- for (mode = pI830->output[i].probed_modes; mode != NULL;
- mode = mode->next)
+ for (mode = output->probed_modes; mode != NULL; mode = mode->next)
{
if (mode->HDisplay > maxX)
maxX = mode->HDisplay;
@@ -618,8 +615,7 @@ I830ValidateXF86ModeList(ScrnInfoPtr pScrn, Bool first_time)
#define EDID_ATOM_NAME "EDID_DATA"
static void
-i830_ddc_set_edid_property(ScrnInfoPtr pScrn, I830OutputPtr output,
- void *data, int data_len)
+i830_ddc_set_edid_property(I830_xf86OutputPtr output, void *data, int data_len)
{
Atom edid_atom = MakeAtom(EDID_ATOM_NAME, sizeof(EDID_ATOM_NAME), TRUE);
@@ -640,16 +636,18 @@ i830_ddc_set_edid_property(ScrnInfoPtr pScrn, I830OutputPtr output,
* Generic get_modes function using DDC, used by many outputs.
*/
DisplayModePtr
-i830_ddc_get_modes(ScrnInfoPtr pScrn, I830OutputPtr output)
+i830_ddc_get_modes(I830_xf86OutputPtr output)
{
+ ScrnInfoPtr pScrn = output->scrn;
+ I830OutputPrivatePtr intel_output = output->driver_private;
xf86MonPtr ddc_mon;
DisplayModePtr ddc_modes, mode;
int i;
- ddc_mon = xf86DoEDID_DDC2(pScrn->scrnIndex, output->pDDCBus);
+ ddc_mon = xf86DoEDID_DDC2(pScrn->scrnIndex, intel_output->pDDCBus);
if (ddc_mon == NULL) {
#ifdef RANDR_12_INTERFACE
- i830_ddc_set_edid_property(pScrn, output, NULL, 0);
+ i830_ddc_set_edid_property(output, NULL, 0);
#endif
return NULL;
}
@@ -660,24 +658,23 @@ i830_ddc_get_modes(ScrnInfoPtr pScrn, I830OutputPtr output)
#ifdef RANDR_12_INTERFACE
if (output->MonInfo->ver.version == 1) {
- i830_ddc_set_edid_property(pScrn, output, ddc_mon->rawData, 128);
+ i830_ddc_set_edid_property(output, ddc_mon->rawData, 128);
} else if (output->MonInfo->ver.version == 2) {
- i830_ddc_set_edid_property(pScrn, output, ddc_mon->rawData, 256);
+ i830_ddc_set_edid_property(output, ddc_mon->rawData, 256);
} else {
- i830_ddc_set_edid_property(pScrn, output, NULL, 0);
+ i830_ddc_set_edid_property(output, NULL, 0);
}
#endif
/* Debug info for now, at least */
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID for output %s\n",
- i830_output_type_names[output->type]);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID for output %s\n", output->name);
xf86PrintEDID(output->MonInfo);
ddc_modes = i830GetDDCModes(pScrn, ddc_mon);
/* Strip out any modes that can't be supported on this output. */
for (mode = ddc_modes; mode != NULL; mode = mode->next) {
- int status = output->mode_valid(pScrn, output, mode);
+ int status = (*output->funcs->mode_valid)(output, mode);
if (status != MODE_OK)
mode->status = status;
diff --git a/src/i830_randr.c b/src/i830_randr.c
index a530ffbf..d6a3131c 100644
--- a/src/i830_randr.c
+++ b/src/i830_randr.c
@@ -52,9 +52,6 @@ typedef struct _i830RandRInfo {
int maxY;
Rotation rotation; /* current mode */
Rotation supported_rotations; /* driver supported */
-#ifdef RANDR_12_INTERFACE
- DisplayModePtr modes[MAX_DISPLAY_PIPES];
-#endif
} XF86RandRInfoRec, *XF86RandRInfoPtr;
#ifdef RANDR_12_INTERFACE
@@ -472,151 +469,127 @@ I830RandRScreenSetSize (ScreenPtr pScreen,
}
static Bool
-I830RandRCrtcNotify (RRCrtcPtr crtc)
+I830RandRCrtcNotify (RRCrtcPtr randr_crtc)
{
- ScreenPtr pScreen = crtc->pScreen;
+ ScreenPtr pScreen = randr_crtc->pScreen;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
I830Ptr pI830 = I830PTR(pScrn);
- RRModePtr mode = NULL;
+ RRModePtr randr_mode = NULL;
int x;
int y;
Rotation rotation;
int numOutputs;
- RROutputPtr outputs[MAX_OUTPUTS];
- struct _I830OutputRec *output;
- RROutputPtr rrout;
- int pipe = (int) crtc->devPrivate;
- I830PipePtr pI830Pipe = &pI830->pipes[pipe];
+ RROutputPtr randr_outputs[MAX_OUTPUTS];
+ RROutputPtr randr_output;
+ I830_xf86CrtcPtr crtc = randr_crtc->devPrivate;
+ I830_xf86OutputPtr output;
int i, j;
- DisplayModePtr pipeMode = &pI830Pipe->curMode;
+ DisplayModePtr curMode = &crtc->curMode;
- x = pI830Pipe->x;
- y = pI830Pipe->y;
+ x = crtc->x;
+ y = crtc->y;
rotation = RR_Rotate_0;
numOutputs = 0;
- mode = NULL;
+ randr_mode = NULL;
for (i = 0; i < pI830->num_outputs; i++)
{
- output = &pI830->output[i];
- if (output->enabled && output->pipe == pipe)
+ output = pI830->xf86_output[i];
+ if (output->crtc == crtc)
{
- rrout = output->randr_output;
- outputs[numOutputs++] = rrout;
+ randr_output = output->randr_output;
+ randr_outputs[numOutputs++] = randr_output;
/*
* We make copies of modes, so pointer equality
* isn't sufficient
*/
- for (j = 0; j < rrout->numModes; j++)
+ for (j = 0; j < randr_output->numModes; j++)
{
- DisplayModePtr outMode = rrout->modes[j]->devPrivate;
- if (I830ModesEqual(pipeMode, outMode))
+ DisplayModePtr outMode = randr_output->modes[j]->devPrivate;
+ if (I830ModesEqual(curMode, outMode))
{
- mode = rrout->modes[j];
+ randr_mode = randr_output->modes[j];
break;
}
}
}
}
- return RRCrtcNotify (crtc, mode, x, y, rotation, numOutputs, outputs);
+ return RRCrtcNotify (randr_crtc, randr_mode, x, y,
+ rotation, numOutputs, randr_outputs);
}
static Bool
I830RandRCrtcSet (ScreenPtr pScreen,
- RRCrtcPtr crtc,
- RRModePtr mode,
+ RRCrtcPtr randr_crtc,
+ RRModePtr randr_mode,
int x,
int y,
Rotation rotation,
int num_randr_outputs,
RROutputPtr *randr_outputs)
{
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
I830Ptr pI830 = I830PTR(pScrn);
- int pipe = (int) (crtc->devPrivate);
- I830PipePtr pI830Pipe = &pI830->pipes[pipe];
- DisplayModePtr display_mode = mode ? mode->devPrivate : NULL;
+ I830_xf86CrtcPtr crtc = randr_crtc->devPrivate;
+ DisplayModePtr mode = randr_mode ? randr_mode->devPrivate : NULL;
Bool changed = FALSE;
- Bool disable = FALSE;
int o, ro;
- struct {
- int pipe;
- int enabled;
- } save_output[MAX_OUTPUTS];
- Bool save_enabled = pI830Pipe->enabled;
+ I830_xf86CrtcPtr save_crtcs[MAX_OUTPUTS];
+ Bool save_enabled = crtc->enabled;
- if (display_mode != randrp->modes[pipe])
- {
+ if (!I830ModesEqual (&crtc->curMode, mode))
changed = TRUE;
- if (!display_mode)
- disable = TRUE;
- }
for (o = 0; o < pI830->num_outputs; o++)
{
- I830OutputPtr output = &pI830->output[o];
- RROutputPtr randr_output = NULL;
+ I830_xf86OutputPtr output = pI830->xf86_output[o];
+ I830_xf86CrtcPtr new_crtc;
+
+ save_crtcs[o] = output->crtc;
- save_output[o].enabled = output->enabled;
- save_output[o].pipe = output->pipe;
+ if (output->crtc == crtc)
+ new_crtc = NULL;
+ else
+ new_crtc = output->crtc;
for (ro = 0; ro < num_randr_outputs; ro++)
- {
if (output->randr_output == randr_outputs[ro])
{
- randr_output = randr_outputs[ro];
+ new_crtc = crtc;
break;
}
- }
- if (randr_output)
- {
- if (output->pipe != pipe || !output->enabled)
- {
- output->pipe = pipe;
- output->enabled = TRUE;
- changed = TRUE;
- }
- }
- else
+ if (new_crtc != output->crtc)
{
- /* Disable outputs which were on this pipe */
- if (output->enabled && output->pipe == pipe)
- {
- output->enabled = FALSE;
- changed = TRUE;
- disable = TRUE;
- }
+ changed = TRUE;
+ output->crtc = new_crtc;
}
}
if (changed)
{
- pI830Pipe->enabled = mode != NULL;
+ crtc->enabled = mode != NULL;
+
/* Sync the engine before adjust mode */
if (pI830->AccelInfoRec && pI830->AccelInfoRec->NeedToSync) {
(*pI830->AccelInfoRec->Sync)(pScrn);
pI830->AccelInfoRec->NeedToSync = FALSE;
}
- if (display_mode)
+ if (mode)
{
- if (!i830PipeSetMode (pScrn, display_mode, pipe, TRUE))
+ if (!i830PipeSetMode (crtc, mode, TRUE))
{
- pI830Pipe->enabled = save_enabled;
+ crtc->enabled = save_enabled;
for (o = 0; o < pI830->num_outputs; o++)
{
- I830OutputPtr output = &pI830->output[o];
- output->enabled = save_output[o].enabled;
- output->pipe = save_output[o].pipe;
+ I830_xf86OutputPtr output = pI830->xf86_output[o];
+ output->crtc = save_crtcs[o];
}
return FALSE;
}
- pI830Pipe->desiredMode = *display_mode;
- i830PipeSetBase(pScrn, pipe, x, y);
+ crtc->desiredMode = *mode;
+ i830PipeSetBase(crtc, x, y);
}
- randrp->modes[pipe] = display_mode;
- if (disable)
- i830DisableUnusedFunctions (pScrn);
+ i830DisableUnusedFunctions (pScrn);
}
- return I830RandRCrtcNotify (crtc);
+ return I830RandRCrtcNotify (randr_crtc);
}
static Bool
@@ -696,23 +669,21 @@ I830RandRSetInfo12 (ScrnInfoPtr pScrn)
RROutputPtr clones[MAX_OUTPUTS];
RRCrtcPtr crtcs[MAX_DISPLAY_PIPES];
int ncrtc;
- I830OutputPtr output;
int o, c, p;
int clone_types;
int crtc_types;
int subpixel;
RRCrtcPtr randr_crtc;
- RROutputPtr randr_output;
int nclone;
for (o = 0; o < pI830->num_outputs; o++)
{
- output = &pI830->output[o];
- randr_output = output->randr_output;
+ I830_xf86OutputPtr output = pI830->xf86_output[o];
+ I830OutputPrivatePtr intel_output = output->driver_private;
/*
* Valid crtcs
*/
- switch (output->type) {
+ switch (intel_output->type) {
case I830_OUTPUT_DVO:
case I830_OUTPUT_SDVO:
crtc_types = ((1 << 0)|
@@ -749,10 +720,10 @@ I830RandRSetInfo12 (ScrnInfoPtr pScrn)
ncrtc = 0;
for (p = 0; p < pI830->num_pipes; p++)
if (crtc_types & (1 << p))
- crtcs[ncrtc++] = pI830->pipes[p].randr_crtc;
+ crtcs[ncrtc++] = pI830->xf86_crtc[p]->randr_crtc;
- if (output->enabled)
- randr_crtc = pI830->pipes[output->pipe].randr_crtc;
+ if (output->crtc)
+ randr_crtc = output->crtc->randr_crtc;
else
randr_crtc = NULL;
@@ -765,7 +736,7 @@ I830RandRSetInfo12 (ScrnInfoPtr pScrn)
output->mm_height);
I830xf86RROutputSetModes (output->randr_output, output->probed_modes);
- switch (output->detect(pScrn, output)) {
+ switch ((*output->funcs->detect)(output)) {
case OUTPUT_STATUS_CONNECTED:
RROutputSetConnection (output->randr_output, RR_Connected);
break;
@@ -785,8 +756,11 @@ I830RandRSetInfo12 (ScrnInfoPtr pScrn)
nclone = 0;
for (c = 0; c < pI830->num_outputs; c++)
{
- if (o != c && ((1 << pI830->output[c].type) & clone_types))
- clones[nclone++] = pI830->output[c].randr_output;
+ I830_xf86OutputPtr clone = pI830->xf86_output[c];
+ I830OutputPrivatePtr intel_clone = clone->driver_private;
+
+ if (o != c && ((1 << intel_clone->type) & clone_types))
+ clones[nclone++] = clone->randr_output;
}
if (!RROutputSetClones (output->randr_output, clones, nclone))
return FALSE;
@@ -812,35 +786,20 @@ I830RandRCreateObjects12 (ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(pScrn);
int p;
- int o;
if (!RRInit ())
return FALSE;
/*
- * Create RandR resources, then probe them
+ * Configure crtcs
*/
for (p = 0; p < pI830->num_pipes; p++)
{
- I830PipePtr pipe = &pI830->pipes[p];
- RRCrtcPtr randr_crtc = RRCrtcCreate ((void *) p);
+ I830_xf86CrtcPtr crtc = pI830->xf86_crtc[p];
- if (!randr_crtc)
- return FALSE;
- RRCrtcGammaSetSize (randr_crtc, 256);
- pipe->randr_crtc = randr_crtc;
+ RRCrtcGammaSetSize (crtc->randr_crtc, 256);
}
- for (o = 0; o < pI830->num_outputs; o++)
- {
- I830OutputPtr output = &pI830->output[o];
- const char *name = i830_output_type_names[output->type];
- RROutputPtr randr_output = RROutputCreate (name, strlen (name),
- (void *) o);
- if (!randr_output)
- return FALSE;
- output->randr_output = randr_output;
- }
return TRUE;
}
@@ -857,11 +816,11 @@ I830RandRCreateScreenResources12 (ScreenPtr pScreen)
* Attach RandR objects to screen
*/
for (p = 0; p < pI830->num_pipes; p++)
- if (!RRCrtcAttachScreen (pI830->pipes[p].randr_crtc, pScreen))
+ if (!RRCrtcAttachScreen (pI830->xf86_crtc[p]->randr_crtc, pScreen))
return FALSE;
for (o = 0; o < pI830->num_outputs; o++)
- if (!RROutputAttachScreen (pI830->output[o].randr_output, pScreen))
+ if (!RROutputAttachScreen (pI830->xf86_output[o]->randr_output, pScreen))
return FALSE;
/*
@@ -870,13 +829,14 @@ I830RandRCreateScreenResources12 (ScreenPtr pScreen)
width = 0; height = 0;
for (p = 0; p < pI830->num_pipes; p++)
{
- I830PipePtr pipe = &pI830->pipes[p];
- int pipe_width = pipe->x + pipe->curMode.HDisplay;
- int pipe_height = pipe->y + pipe->curMode.VDisplay;
- if (pipe->enabled && pipe_width > width)
- width = pipe_width;
- if (pipe->enabled && pipe_height > height)
- height = pipe_height;
+ I830_xf86CrtcPtr crtc = pI830->xf86_crtc[p];
+ int crtc_width = crtc->x + crtc->curMode.HDisplay;
+ int crtc_height = crtc->y + crtc->curMode.VDisplay;
+
+ if (crtc->enabled && crtc_width > width)
+ width = crtc_width;
+ if (crtc->enabled && crtc_height > height)
+ height = crtc_height;
}
if (width && height)
@@ -900,7 +860,7 @@ I830RandRCreateScreenResources12 (ScreenPtr pScreen)
}
for (p = 0; p < pI830->num_pipes; p++)
- I830RandRCrtcNotify (pI830->pipes[p].randr_crtc);
+ I830RandRCrtcNotify (pI830->xf86_crtc[p]->randr_crtc);
if (randrp->virtualX == -1 || randrp->virtualY == -1)
{
@@ -1227,9 +1187,9 @@ I830RandRPreInit (ScrnInfoPtr pScrn)
* the initial configuration
*/
for (o = 0; o < pI830->num_outputs; o++)
- outputs[o] = pI830->output[o].randr_output;
+ outputs[o] = pI830->xf86_output[o]->randr_output;
for (c = 0; c < pI830->num_pipes; c++)
- crtcs[c] = pI830->pipes[c].randr_crtc;
+ crtcs[c] = pI830->xf86_crtc[c]->randr_crtc;
if (!I830RRInitialConfiguration (outputs, output_crtcs, output_modes,
pI830->num_outputs))
@@ -1253,30 +1213,19 @@ I830RandRPreInit (ScrnInfoPtr pScrn)
pScrn->display->frameY0 = 0;
for (o = 0; o < pI830->num_outputs; o++)
{
- RRModePtr randr_mode = output_modes[o];
- DisplayModePtr mode;
- RRCrtcPtr randr_crtc = output_crtcs[o];
- int pipe;
- Bool enabled;
+ I830_xf86OutputPtr output = pI830->xf86_output[o];
+ RRModePtr randr_mode = output_modes[o];
+ DisplayModePtr mode;
+ RRCrtcPtr randr_crtc = output_crtcs[o];
+ I830_xf86CrtcPtr crtc = randr_crtc->devPrivate;
if (randr_mode)
mode = (DisplayModePtr) randr_mode->devPrivate;
else
mode = NULL;
- if (randr_crtc)
- {
- pipe = (int) randr_crtc->devPrivate;
- enabled = TRUE;
- }
- else
- {
- pipe = 0;
- enabled = FALSE;
- }
if (mode)
- pI830->pipes[pipe].desiredMode = *mode;
- pI830->output[o].pipe = pipe;
- pI830->output[o].enabled = enabled;
+ crtc->desiredMode = *mode;
+ output->crtc = crtc;
}
#endif
i830_set_xf86_modes_from_outputs (pScrn);
diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c
index fedb8a6a..a8eba4c0 100644
--- a/src/i830_sdvo.c
+++ b/src/i830_sdvo.c
@@ -80,30 +80,32 @@ struct i830_sdvo_priv {
};
/** Read a single byte from the given address on the SDVO device. */
-static Bool i830_sdvo_read_byte(I830OutputPtr output, int addr,
+static Bool i830_sdvo_read_byte(I830_xf86OutputPtr output, int addr,
unsigned char *ch)
{
- struct i830_sdvo_priv *dev_priv = output->dev_priv;
+ I830OutputPrivatePtr intel_output = output->driver_private;
+ struct i830_sdvo_priv *dev_priv = intel_output->dev_priv;
if (!xf86I2CReadByte(&dev_priv->d, addr, ch)) {
- xf86DrvMsg(output->pI2CBus->scrnIndex, X_ERROR,
+ xf86DrvMsg(intel_output->pI2CBus->scrnIndex, X_ERROR,
"Unable to read from %s slave %d.\n",
- output->pI2CBus->BusName, dev_priv->d.SlaveAddr);
+ intel_output->pI2CBus->BusName, dev_priv->d.SlaveAddr);
return FALSE;
}
return TRUE;
}
/** Write a single byte to the given address on the SDVO device. */
-static Bool i830_sdvo_write_byte(I830OutputPtr output,
+static Bool i830_sdvo_write_byte(I830_xf86OutputPtr output,
int addr, unsigned char ch)
{
- struct i830_sdvo_priv *dev_priv = output->dev_priv;
+ I830OutputPrivatePtr intel_output = output->driver_private;
+ struct i830_sdvo_priv *dev_priv = intel_output->dev_priv;
if (!xf86I2CWriteByte(&dev_priv->d, addr, ch)) {
- xf86DrvMsg(output->pI2CBus->scrnIndex, X_ERROR,
+ xf86DrvMsg(intel_output->pI2CBus->scrnIndex, X_ERROR,
"Unable to write to %s Slave %d.\n",
- output->pI2CBus->BusName, dev_priv->d.SlaveAddr);
+ intel_output->pI2CBus->BusName, dev_priv->d.SlaveAddr);
return FALSE;
}
return TRUE;
@@ -164,16 +166,17 @@ static I2CSlaveAddr slaveAddr;
* Writes out the data given in args (up to 8 bytes), followed by the opcode.
*/
static void
-i830_sdvo_write_cmd(I830OutputPtr output, CARD8 cmd, void *args, int args_len)
+i830_sdvo_write_cmd(I830_xf86OutputPtr output, CARD8 cmd, void *args, int args_len)
{
- int i;
- struct i830_sdvo_priv *dev_priv = output->dev_priv;
+ I830OutputPrivatePtr intel_output = output->driver_private;
+ struct i830_sdvo_priv *dev_priv = intel_output->dev_priv;
+ int i;
if (slaveAddr && slaveAddr != dev_priv->d.SlaveAddr)
ErrorF ("Mismatch slave addr %x != %x\n", slaveAddr, dev_priv->d.SlaveAddr);
/* Write the SDVO command logging */
- xf86DrvMsg(output->pI2CBus->scrnIndex, X_INFO, "%s: W: %02X ", SDVO_NAME(dev_priv), cmd);
+ xf86DrvMsg(intel_output->pI2CBus->scrnIndex, X_INFO, "%s: W: %02X ", SDVO_NAME(dev_priv), cmd);
for (i = 0; i < args_len; i++)
LogWrite(1, "%02X ", ((CARD8 *)args)[i]);
for (; i < 8; i++)
@@ -210,10 +213,11 @@ static const char *cmd_status_names[] = {
* Reads back response_len bytes from the SDVO device, and returns the status.
*/
static CARD8
-i830_sdvo_read_response(I830OutputPtr output, void *response, int response_len)
+i830_sdvo_read_response(I830_xf86OutputPtr output, void *response, int response_len)
{
- int i;
- CARD8 status;
+ I830OutputPrivatePtr intel_output = output->driver_private;
+ int i;
+ CARD8 status;
/* Read the command response */
for (i = 0; i < response_len; i++) {
@@ -225,8 +229,8 @@ i830_sdvo_read_response(I830OutputPtr output, void *response, int response_len)
i830_sdvo_read_byte(output, SDVO_I2C_CMD_STATUS, &status);
/* Write the SDVO command logging */
- xf86DrvMsg(output->pI2CBus->scrnIndex, X_INFO,
- "%s: R: ", SDVO_NAME(SDVO_PRIV(output)));
+ xf86DrvMsg(intel_output->pI2CBus->scrnIndex, X_INFO,
+ "%s: R: ", SDVO_NAME(SDVO_PRIV(intel_output)));
for (i = 0; i < response_len; i++)
LogWrite(1, "%02X ", ((CARD8 *)response)[i]);
for (; i < 8; i++)
@@ -258,13 +262,13 @@ i830_sdvo_get_pixel_multiplier(DisplayModePtr pMode)
* STOP. PROM access is terminated by accessing an internal register.
*/
static void
-i830_sdvo_set_control_bus_switch(I830OutputPtr output, CARD8 target)
+i830_sdvo_set_control_bus_switch(I830_xf86OutputPtr output, CARD8 target)
{
i830_sdvo_write_cmd(output, SDVO_CMD_SET_CONTROL_BUS_SWITCH, &target, 1);
}
static Bool
-i830_sdvo_set_target_input(I830OutputPtr output, Bool target_0, Bool target_1)
+i830_sdvo_set_target_input(I830_xf86OutputPtr output, Bool target_0, Bool target_1)
{
struct i830_sdvo_set_target_input_args targets = {0};
CARD8 status;
@@ -290,7 +294,7 @@ i830_sdvo_set_target_input(I830OutputPtr output, Bool target_0, Bool target_1)
* which should be checked against the docs.
*/
static Bool
-i830_sdvo_get_trained_inputs(I830OutputPtr output, Bool *input_1, Bool *input_2)
+i830_sdvo_get_trained_inputs(I830_xf86OutputPtr output, Bool *input_1, Bool *input_2)
{
struct i830_sdvo_get_trained_inputs_response response;
CARD8 status;
@@ -308,7 +312,7 @@ i830_sdvo_get_trained_inputs(I830OutputPtr output, Bool *input_1, Bool *input_2)
}
static Bool
-i830_sdvo_get_active_outputs(I830OutputPtr output,
+i830_sdvo_get_active_outputs(I830_xf86OutputPtr output,
CARD16 *outputs)
{
CARD8 status;
@@ -320,7 +324,7 @@ i830_sdvo_get_active_outputs(I830OutputPtr output,
}
static Bool
-i830_sdvo_set_active_outputs(I830OutputPtr output,
+i830_sdvo_set_active_outputs(I830_xf86OutputPtr output,
CARD16 outputs)
{
CARD8 status;
@@ -336,7 +340,7 @@ i830_sdvo_set_active_outputs(I830OutputPtr output,
* Returns the pixel clock range limits of the current target input in kHz.
*/
static Bool
-i830_sdvo_get_input_pixel_clock_range(I830OutputPtr output, int *clock_min,
+i830_sdvo_get_input_pixel_clock_range(I830_xf86OutputPtr output, int *clock_min,
int *clock_max)
{
struct i830_sdvo_pixel_clock_range clocks;
@@ -357,7 +361,7 @@ i830_sdvo_get_input_pixel_clock_range(I830OutputPtr output, int *clock_min,
}
static Bool
-i830_sdvo_set_target_output(I830OutputPtr output, CARD16 outputs)
+i830_sdvo_set_target_output(I830_xf86OutputPtr output, CARD16 outputs)
{
CARD8 status;
@@ -371,7 +375,7 @@ i830_sdvo_set_target_output(I830OutputPtr output, CARD16 outputs)
/** Fetches either input or output timings to *dtd, depending on cmd. */
static Bool
-i830_sdvo_get_timing(I830OutputPtr output, CARD8 cmd, struct i830_sdvo_dtd *dtd)
+i830_sdvo_get_timing(I830_xf86OutputPtr output, CARD8 cmd, struct i830_sdvo_dtd *dtd)
{
CARD8 status;
@@ -391,20 +395,20 @@ i830_sdvo_get_timing(I830OutputPtr output, CARD8 cmd, struct i830_sdvo_dtd *dtd)
}
static Bool
-i830_sdvo_get_input_timing(I830OutputPtr output, struct i830_sdvo_dtd *dtd)
+i830_sdvo_get_input_timing(I830_xf86OutputPtr output, struct i830_sdvo_dtd *dtd)
{
return i830_sdvo_get_timing(output, SDVO_CMD_GET_INPUT_TIMINGS_PART1, dtd);
}
static Bool
-i830_sdvo_get_output_timing(I830OutputPtr output, struct i830_sdvo_dtd *dtd)
+i830_sdvo_get_output_timing(I830_xf86OutputPtr output, struct i830_sdvo_dtd *dtd)
{
return i830_sdvo_get_timing(output, SDVO_CMD_GET_OUTPUT_TIMINGS_PART1, dtd);
}
/** Sets either input or output timings from *dtd, depending on cmd. */
static Bool
-i830_sdvo_set_timing(I830OutputPtr output, CARD8 cmd, struct i830_sdvo_dtd *dtd)
+i830_sdvo_set_timing(I830_xf86OutputPtr output, CARD8 cmd, struct i830_sdvo_dtd *dtd)
{
CARD8 status;
@@ -422,20 +426,20 @@ i830_sdvo_set_timing(I830OutputPtr output, CARD8 cmd, struct i830_sdvo_dtd *dtd)
}
static Bool
-i830_sdvo_set_input_timing(I830OutputPtr output, struct i830_sdvo_dtd *dtd)
+i830_sdvo_set_input_timing(I830_xf86OutputPtr output, struct i830_sdvo_dtd *dtd)
{
return i830_sdvo_set_timing(output, SDVO_CMD_SET_INPUT_TIMINGS_PART1, dtd);
}
static Bool
-i830_sdvo_set_output_timing(I830OutputPtr output, struct i830_sdvo_dtd *dtd)
+i830_sdvo_set_output_timing(I830_xf86OutputPtr output, struct i830_sdvo_dtd *dtd)
{
return i830_sdvo_set_timing(output, SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd);
}
#if 0
static Bool
-i830_sdvo_create_preferred_input_timing(I830OutputPtr output, CARD16 clock,
+i830_sdvo_create_preferred_input_timing(I830_xf86OutputPtr output, CARD16 clock,
CARD16 width, CARD16 height)
{
struct i830_sdvo_priv *dev_priv = output->dev_priv;
@@ -479,9 +483,10 @@ i830_sdvo_get_preferred_input_timing(I830OutputPtr output,
/** Returns the SDVO_CLOCK_RATE_MULT_* for the current clock multiplier */
static int
-i830_sdvo_get_clock_rate_mult(I830OutputPtr output)
+i830_sdvo_get_clock_rate_mult(I830_xf86OutputPtr output)
{
- struct i830_sdvo_priv *dev_priv = output->dev_priv;
+ I830OutputPrivatePtr intel_output = output->driver_private;
+ struct i830_sdvo_priv *dev_priv = intel_output->dev_priv;
CARD8 response;
CARD8 status;
@@ -507,7 +512,7 @@ i830_sdvo_get_clock_rate_mult(I830OutputPtr output)
* is actually turned on.
*/
static Bool
-i830_sdvo_set_clock_rate_mult(I830OutputPtr output, CARD8 val)
+i830_sdvo_set_clock_rate_mult(I830_xf86OutputPtr output, CARD8 val)
{
CARD8 status;
@@ -520,11 +525,12 @@ i830_sdvo_set_clock_rate_mult(I830OutputPtr output, CARD8 val)
}
static void
-i830_sdvo_pre_set_mode(ScrnInfoPtr pScrn, I830OutputPtr output,
- DisplayModePtr mode)
+i830_sdvo_pre_set_mode(I830_xf86OutputPtr output, DisplayModePtr mode)
{
+ ScrnInfoPtr pScrn = output->scrn;
I830Ptr pI830 = I830PTR(pScrn);
- struct i830_sdvo_priv *dev_priv = output->dev_priv;
+ I830OutputPrivatePtr intel_output = output->driver_private;
+ struct i830_sdvo_priv *dev_priv = intel_output->dev_priv;
CARD16 width;
CARD16 height;
CARD16 h_blank_len, h_sync_len, v_blank_len, v_sync_len;
@@ -621,15 +627,18 @@ i830_sdvo_pre_set_mode(ScrnInfoPtr pScrn, I830OutputPtr output,
}
static void
-i830_sdvo_post_set_mode(ScrnInfoPtr pScrn, I830OutputPtr output,
- DisplayModePtr mode)
+i830_sdvo_post_set_mode(I830_xf86OutputPtr output, DisplayModePtr mode)
{
+ ScrnInfoPtr pScrn = output->scrn;
+ I830OutputPrivatePtr intel_output = output->driver_private;
+ struct i830_sdvo_priv *dev_priv = intel_output->dev_priv;
+ I830_xf86CrtcPtr crtc = output->crtc;
+ I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
I830Ptr pI830 = I830PTR(pScrn);
- struct i830_sdvo_priv *dev_priv = output->dev_priv;
Bool input1, input2;
CARD32 dpll, sdvox;
- int dpll_reg = (output->pipe == 0) ? DPLL_A : DPLL_B;
- int dpll_md_reg = (output->pipe == 0) ? DPLL_A_MD : DPLL_B_MD;
+ int dpll_reg = (intel_crtc->pipe == 0) ? DPLL_A : DPLL_B;
+ int dpll_md_reg = (intel_crtc->pipe == 0) ? DPLL_A_MD : DPLL_B_MD;
int sdvo_pixel_multiply;
int i;
CARD8 status;
@@ -645,7 +654,7 @@ i830_sdvo_post_set_mode(ScrnInfoPtr pScrn, I830OutputPtr output,
break;
}
sdvox |= SDVO_ENABLE | (9 << 19) | SDVO_BORDER_ENABLE;
- if (output->pipe == 1)
+ if (intel_crtc->pipe == 1)
sdvox |= SDVO_PIPE_B_SELECT;
dpll = INREG(dpll_reg);
@@ -681,10 +690,12 @@ i830_sdvo_post_set_mode(ScrnInfoPtr pScrn, I830OutputPtr output,
}
static void
-i830_sdvo_dpms(ScrnInfoPtr pScrn, I830OutputPtr output, int mode)
+i830_sdvo_dpms(I830_xf86OutputPtr output, int mode)
{
+ ScrnInfoPtr pScrn = output->scrn;
+ I830OutputPrivatePtr intel_output = output->driver_private;
+ struct i830_sdvo_priv *dev_priv = intel_output->dev_priv;
I830Ptr pI830 = I830PTR(pScrn);
- struct i830_sdvo_priv *dev_priv = output->dev_priv;
if (mode != DPMSModeOn) {
i830_sdvo_set_active_outputs(output, 0);
@@ -696,11 +707,13 @@ i830_sdvo_dpms(ScrnInfoPtr pScrn, I830OutputPtr output, int mode)
}
static void
-i830_sdvo_save(ScrnInfoPtr pScrn, I830OutputPtr output)
+i830_sdvo_save(I830_xf86OutputPtr output)
{
- I830Ptr pI830 = I830PTR(pScrn);
- struct i830_sdvo_priv *dev_priv = output->dev_priv;
- int o;
+ ScrnInfoPtr pScrn = output->scrn;
+ I830OutputPrivatePtr intel_output = output->driver_private;
+ struct i830_sdvo_priv *dev_priv = intel_output->dev_priv;
+ I830Ptr pI830 = I830PTR(pScrn);
+ int o;
/* XXX: We should save the in/out mapping. */
@@ -731,11 +744,13 @@ i830_sdvo_save(ScrnInfoPtr pScrn, I830OutputPtr output)
}
static void
-i830_sdvo_restore(ScrnInfoPtr pScrn, I830OutputPtr output)
+i830_sdvo_restore(I830_xf86OutputPtr output)
{
- I830Ptr pI830 = I830PTR(pScrn);
- struct i830_sdvo_priv *dev_priv = output->dev_priv;
- int o;
+ ScrnInfoPtr pScrn = output->scrn;
+ I830OutputPrivatePtr intel_output = output->driver_private;
+ struct i830_sdvo_priv *dev_priv = intel_output->dev_priv;
+ I830Ptr pI830 = I830PTR(pScrn);
+ int o;
if (dev_priv->caps.sdvo_inputs_mask & 0x1) {
i830_sdvo_set_target_input(output, TRUE, FALSE);
@@ -764,10 +779,10 @@ i830_sdvo_restore(ScrnInfoPtr pScrn, I830OutputPtr output)
}
static int
-i830_sdvo_mode_valid(ScrnInfoPtr pScrn, I830OutputPtr output,
- DisplayModePtr pMode)
+i830_sdvo_mode_valid(I830_xf86OutputPtr output, DisplayModePtr pMode)
{
- struct i830_sdvo_priv *dev_priv = output->dev_priv;
+ I830OutputPrivatePtr intel_output = output->driver_private;
+ struct i830_sdvo_priv *dev_priv = intel_output->dev_priv;
if (pMode->Flags & V_DBLSCAN)
return MODE_NO_DBLESCAN;
@@ -782,7 +797,7 @@ i830_sdvo_mode_valid(ScrnInfoPtr pScrn, I830OutputPtr output,
}
static Bool
-i830_sdvo_get_capabilities(I830OutputPtr output, struct i830_sdvo_caps *caps)
+i830_sdvo_get_capabilities(I830_xf86OutputPtr output, struct i830_sdvo_caps *caps)
{
CARD8 status;
@@ -836,8 +851,9 @@ i830_sdvo_ddc_i2c_put_byte(I2CDevPtr d, I2CByte c)
static Bool
i830_sdvo_ddc_i2c_start(I2CBusPtr b, int timeout)
{
- I830OutputPtr output = b->DriverPrivate.ptr;
- I2CBusPtr i2cbus = output->pI2CBus;
+ I830_xf86OutputPtr output = b->DriverPrivate.ptr;
+ I830OutputPrivatePtr intel_output = output->driver_private;
+ I2CBusPtr i2cbus = intel_output->pI2CBus;
i830_sdvo_set_control_bus_switch(output, SDVO_CONTROL_BUS_DDC2);
return i2cbus->I2CStart(i2cbus, timeout);
@@ -847,8 +863,9 @@ i830_sdvo_ddc_i2c_start(I2CBusPtr b, int timeout)
static void
i830_sdvo_ddc_i2c_stop(I2CDevPtr d)
{
- I830OutputPtr output = d->pI2CBus->DriverPrivate.ptr;
- I2CBusPtr i2cbus = output->pI2CBus, savebus;
+ I830_xf86OutputPtr output = d->DriverPrivate.ptr;
+ I830OutputPrivatePtr intel_output = output->driver_private;
+ I2CBusPtr i2cbus = intel_output->pI2CBus, savebus;
savebus = d->pI2CBus;
d->pI2CBus = i2cbus;
@@ -883,18 +900,19 @@ i830_sdvo_ddc_i2c_address(I2CDevPtr d, I2CSlaveAddr addr)
}
static void
-i830_sdvo_dump_cmd(I830OutputPtr output, int opcode)
+i830_sdvo_dump_cmd(I830_xf86OutputPtr output, int opcode)
{
- CARD8 response[8];
+ CARD8 response[8];
i830_sdvo_write_cmd(output, opcode, NULL, 0);
i830_sdvo_read_response(output, response, 8);
}
static void
-i830_sdvo_dump_device(I830OutputPtr output)
+i830_sdvo_dump_device(I830_xf86OutputPtr output)
{
- struct i830_sdvo_priv *dev_priv = output->dev_priv;
+ I830OutputPrivatePtr intel_output = output->driver_private;
+ struct i830_sdvo_priv *dev_priv = intel_output->dev_priv;
ErrorF("Dump %s\n", dev_priv->d.DevName);
i830_sdvo_dump_cmd(output, SDVO_CMD_GET_DEVICE_CAPS);
@@ -926,9 +944,13 @@ i830_sdvo_dump(ScrnInfoPtr pScrn)
I830Ptr pI830 = I830PTR(pScrn);
int i;
- for (i = 0; i < pI830->num_outputs; i++) {
- if (pI830->output[i].type == I830_OUTPUT_SDVO)
- i830_sdvo_dump_device(&pI830->output[i]);
+ for (i = 0; i < pI830->num_outputs; i++)
+ {
+ I830_xf86OutputPtr output = pI830->xf86_output[i];
+ I830OutputPrivatePtr intel_output = output->driver_private;
+
+ if (intel_output->type == I830_OUTPUT_SDVO)
+ i830_sdvo_dump_device(output);
}
}
@@ -942,7 +964,7 @@ i830_sdvo_dump(ScrnInfoPtr pScrn)
* Takes 14ms on average on my i945G.
*/
static enum detect_status
-i830_sdvo_detect(ScrnInfoPtr pScrn, I830OutputPtr output)
+i830_sdvo_detect(I830_xf86OutputPtr output)
{
CARD8 response[2];
CARD8 status;
@@ -959,25 +981,59 @@ i830_sdvo_detect(ScrnInfoPtr pScrn, I830OutputPtr output)
return OUTPUT_STATUS_DISCONNECTED;
}
+static void
+i830_sdvo_destroy (I830_xf86OutputPtr output)
+{
+ I830OutputPrivatePtr intel_output = output->driver_private;
+
+ if (intel_output)
+ {
+ struct i830_sdvo_priv *dev_priv = intel_output->dev_priv;
+
+ xf86DestroyI2CBusRec (intel_output->pDDCBus, FALSE, FALSE);
+ xf86DestroyI2CDevRec (&dev_priv->d, FALSE);
+ xf86DestroyI2CBusRec (dev_priv->d.pI2CBus, TRUE, TRUE);
+ xfree (intel_output);
+ }
+}
+
+static const I830_xf86OutputFuncsRec i830_sdvo_output_funcs = {
+ .dpms = i830_sdvo_dpms,
+ .save = i830_sdvo_save,
+ .restore = i830_sdvo_restore,
+ .mode_valid = i830_sdvo_mode_valid,
+ .pre_set_mode = i830_sdvo_pre_set_mode,
+ .post_set_mode = i830_sdvo_post_set_mode,
+ .detect = i830_sdvo_detect,
+ .get_modes = i830_ddc_get_modes,
+ .destroy = i830_sdvo_destroy
+};
+
void
i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
{
- I830Ptr pI830 = I830PTR(pScrn);
- I830OutputPtr output = &pI830->output[pI830->num_outputs];
- struct i830_sdvo_priv *dev_priv;
- int i;
- unsigned char ch[0x40];
- I2CBusPtr i2cbus = NULL, ddcbus;
-
- output->type = I830_OUTPUT_SDVO;
- output->dpms = i830_sdvo_dpms;
- output->save = i830_sdvo_save;
- output->restore = i830_sdvo_restore;
- output->mode_valid = i830_sdvo_mode_valid;
- output->pre_set_mode = i830_sdvo_pre_set_mode;
- output->post_set_mode = i830_sdvo_post_set_mode;
- output->detect = i830_sdvo_detect;
- output->get_modes = i830_ddc_get_modes;
+ I830_xf86OutputPtr output;
+ I830OutputPrivatePtr intel_output;
+ struct i830_sdvo_priv *dev_priv;
+ int i;
+ unsigned char ch[0x40];
+ I2CBusPtr i2cbus = NULL, ddcbus;
+
+ output = i830xf86OutputCreate (pScrn, &i830_sdvo_output_funcs,
+ "ADD2 PCIE card");
+ if (!output)
+ return;
+ intel_output = xnfcalloc (sizeof (I830OutputPrivateRec) +
+ sizeof (struct i830_sdvo_priv), 1);
+ if (!intel_output)
+ {
+ i830xf86OutputDestroy (output);
+ return;
+ }
+ output->driver_private = intel_output;
+
+ dev_priv = (struct i830_sdvo_priv *) (intel_output + 1);
+ intel_output->type = I830_OUTPUT_SDVO;
/* While it's the same bus, we just initialize a new copy to avoid trouble
* with tracking refcounting ourselves, since the XFree86 DDX bits don't.
@@ -988,12 +1044,8 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
I830I2CInit(pScrn, &i2cbus, GPIOE, "SDVOCTRL_E for SDVOC");
if (i2cbus == NULL)
- return;
-
- /* Allocate the SDVO output private data */
- dev_priv = xcalloc(1, sizeof(struct i830_sdvo_priv));
- if (dev_priv == NULL) {
- xf86DestroyI2CBusRec(i2cbus, TRUE, TRUE);
+ {
+ i830xf86OutputDestroy (output);
return;
}
@@ -1008,12 +1060,12 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
dev_priv->d.DriverPrivate.ptr = output;
dev_priv->output_device = output_device;
- if (!xf86I2CDevInit(&dev_priv->d)) {
+ if (!xf86I2CDevInit(&dev_priv->d))
+ {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Failed to initialize %s I2C device\n",
SDVO_NAME(dev_priv));
- xf86DestroyI2CBusRec(i2cbus, TRUE, TRUE);
- xfree(dev_priv);
+ i830xf86OutputDestroy (output);
return;
}
@@ -1023,10 +1075,9 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
* Start, extra attempts should be harmless.
*/
ddcbus = xf86CreateI2CBusRec();
- if (ddcbus == NULL) {
- xf86DestroyI2CDevRec(&dev_priv->d, FALSE);
- xf86DestroyI2CBusRec(i2cbus, TRUE, TRUE);
- xfree(dev_priv);
+ if (ddcbus == NULL)
+ {
+ i830xf86OutputDestroy (output);
return;
}
if (output_device == SDVOB)
@@ -1039,25 +1090,22 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
ddcbus->I2CStart = i830_sdvo_ddc_i2c_start;
ddcbus->I2CStop = i830_sdvo_ddc_i2c_stop;
ddcbus->I2CAddress = i830_sdvo_ddc_i2c_address;
- ddcbus->DriverPrivate.ptr = &pI830->output[pI830->num_outputs];
- if (!xf86I2CBusInit(ddcbus)) {
- xf86DestroyI2CDevRec(&dev_priv->d, FALSE);
- xf86DestroyI2CBusRec(i2cbus, TRUE, TRUE);
- xfree(dev_priv);
+ ddcbus->DriverPrivate.ptr = output;
+
+ if (!xf86I2CBusInit(ddcbus))
+ {
+ i830xf86OutputDestroy (output);
return;
}
- output->pI2CBus = i2cbus;
- output->pDDCBus = ddcbus;
- output->dev_priv = dev_priv;
+ intel_output->pI2CBus = i2cbus;
+ intel_output->pDDCBus = ddcbus;
+ intel_output->dev_priv = dev_priv;
/* Read the regs to test if we can talk to the device */
for (i = 0; i < 0x40; i++) {
if (!i830_sdvo_read_byte(output, i, &ch[i])) {
- xf86DestroyI2CBusRec(output->pDDCBus, FALSE, FALSE);
- xf86DestroyI2CDevRec(&dev_priv->d, FALSE);
- xf86DestroyI2CBusRec(i2cbus, TRUE, TRUE);
- xfree(dev_priv);
+ i830xf86OutputDestroy (output);
return;
}
}
@@ -1074,7 +1122,7 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
unsigned char bytes[2];
memcpy (bytes, &dev_priv->caps.output_flags, 2);
- xf86DrvMsg(output->pI2CBus->scrnIndex, X_ERROR,
+ xf86DrvMsg(intel_output->pI2CBus->scrnIndex, X_ERROR,
"%s: No active TMDS outputs (0x%02x%02x)\n",
SDVO_NAME(dev_priv),
bytes[0], bytes[1]);
@@ -1100,6 +1148,4 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
(dev_priv->caps.sdvo_inputs_mask & 0x2) ? 'Y' : 'N',
dev_priv->caps.output_flags & SDVO_OUTPUT_TMDS0 ? 'Y' : 'N',
dev_priv->caps.output_flags & SDVO_OUTPUT_TMDS1 ? 'Y' : 'N');
-
- pI830->num_outputs++;
}
diff --git a/src/i830_tv.c b/src/i830_tv.c
index f938d5cc..ec78337a 100644
--- a/src/i830_tv.c
+++ b/src/i830_tv.c
@@ -143,11 +143,14 @@ const struct tv_mode {
static int
-i830_tv_detect_type(ScrnInfoPtr pScrn, I830OutputPtr output)
+i830_tv_detect_type(I830_xf86OutputPtr output)
{
+ ScrnInfoPtr pScrn = output->scrn;
+ I830Ptr pI830 = I830PTR(pScrn);
+ I830_xf86CrtcPtr crtc = output->crtc;
+ I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
CARD32 save_tv_ctl, save_tv_dac;
CARD32 tv_ctl, tv_dac;
- I830Ptr pI830 = I830PTR(pScrn);
save_tv_ctl = INREG(TV_CTL);
save_tv_dac = INREG(TV_DAC);
@@ -156,7 +159,7 @@ i830_tv_detect_type(ScrnInfoPtr pScrn, I830OutputPtr output)
* which is already enabled.
*/
tv_ctl = INREG(TV_CTL) & ~(TV_ENC_ENABLE | TV_ENC_PIPEB_SELECT);
- if (output->pipe == 1)
+ if (intel_crtc->pipe == 1)
tv_ctl |= TV_ENC_PIPEB_SELECT;
OUTREG(TV_CTL, tv_ctl);
@@ -200,8 +203,9 @@ i830_tv_detect_type(ScrnInfoPtr pScrn, I830OutputPtr output)
}
static void
-i830_tv_dpms(ScrnInfoPtr pScrn, I830OutputPtr output, int mode)
+i830_tv_dpms(I830_xf86OutputPtr output, int mode)
{
+ ScrnInfoPtr pScrn = output->scrn;
I830Ptr pI830 = I830PTR(pScrn);
switch(mode) {
@@ -217,10 +221,12 @@ i830_tv_dpms(ScrnInfoPtr pScrn, I830OutputPtr output, int mode)
}
static void
-i830_tv_save(ScrnInfoPtr pScrn, I830OutputPtr output)
+i830_tv_save(I830_xf86OutputPtr output)
{
- I830Ptr pI830 = I830PTR(pScrn);
- struct i830_tv_priv *dev_priv = output->dev_priv;
+ ScrnInfoPtr pScrn = output->scrn;
+ I830Ptr pI830 = I830PTR(pScrn);
+ I830OutputPrivatePtr intel_output = output->driver_private;
+ struct i830_tv_priv *dev_priv = intel_output->dev_priv;
dev_priv->save_TV_H_CTL_1 = INREG(TV_H_CTL_1);
dev_priv->save_TV_H_CTL_2 = INREG(TV_H_CTL_2);
@@ -241,10 +247,12 @@ i830_tv_save(ScrnInfoPtr pScrn, I830OutputPtr output)
}
static void
-i830_tv_restore(ScrnInfoPtr pScrn, I830OutputPtr output)
+i830_tv_restore(I830_xf86OutputPtr output)
{
- I830Ptr pI830 = I830PTR(pScrn);
- struct i830_tv_priv *dev_priv = output->dev_priv;
+ ScrnInfoPtr pScrn = output->scrn;
+ I830Ptr pI830 = I830PTR(pScrn);
+ I830OutputPrivatePtr intel_output = output->driver_private;
+ struct i830_tv_priv *dev_priv = intel_output->dev_priv;
OUTREG(TV_H_CTL_1, dev_priv->save_TV_H_CTL_1);
OUTREG(TV_H_CTL_2, dev_priv->save_TV_H_CTL_2);
@@ -265,16 +273,15 @@ i830_tv_restore(ScrnInfoPtr pScrn, I830OutputPtr output)
}
static int
-i830_tv_mode_valid(ScrnInfoPtr pScrn, I830OutputPtr output,
- DisplayModePtr pMode)
+i830_tv_mode_valid(I830_xf86OutputPtr output, DisplayModePtr pMode)
{
return MODE_OK;
}
static void
-i830_tv_pre_set_mode(ScrnInfoPtr pScrn, I830OutputPtr output,
- DisplayModePtr pMode)
+i830_tv_pre_set_mode(I830_xf86OutputPtr output, DisplayModePtr pMode)
{
+ ScrnInfoPtr pScrn = output->scrn;
I830Ptr pI830 = I830PTR(pScrn);
/* Disable the encoder while we set up the pipe. */
@@ -348,10 +355,12 @@ static const CARD32 v_chroma[43] = {
};
static void
-i830_tv_post_set_mode(ScrnInfoPtr pScrn, I830OutputPtr output,
- DisplayModePtr pMode)
+i830_tv_post_set_mode(I830_xf86OutputPtr output, DisplayModePtr pMode)
{
+ ScrnInfoPtr pScrn = output->scrn;
I830Ptr pI830 = I830PTR(pScrn);
+ I830_xf86CrtcPtr crtc = output->crtc;
+ I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
enum tv_type type;
const struct tv_mode *tv_mode;
const struct tv_sc_mode *sc_mode;
@@ -368,7 +377,7 @@ i830_tv_post_set_mode(ScrnInfoPtr pScrn, I830OutputPtr output,
tv_mode = &tv_modes[0];
sc_mode = &tv_sc_modes[TV_SC_NTSC_MJ];
- type = i830_tv_detect_type(pScrn, output);
+ type = i830_tv_detect_type(output);
hctl1 = (tv_mode->hsync_end << TV_HSYNC_END_SHIFT) |
(tv_mode->htotal << TV_HTOTAL_SHIFT);
@@ -408,7 +417,7 @@ i830_tv_post_set_mode(ScrnInfoPtr pScrn, I830OutputPtr output,
(tv_mode->vburst_end_f4 << TV_VBURST_END_F4_SHIFT);
tv_ctl = TV_ENC_ENABLE;
- if (output->pipe == 1)
+ if (intel_crtc->pipe == 1)
tv_ctl |= TV_ENC_PIPEB_SELECT;
switch (type) {
@@ -501,8 +510,9 @@ i830_tv_post_set_mode(ScrnInfoPtr pScrn, I830OutputPtr output,
* we have a pipe programmed in order to probe the TV.
*/
static enum detect_status
-i830_tv_detect(ScrnInfoPtr pScrn, I830OutputPtr output)
+i830_tv_detect(I830_xf86OutputPtr output)
{
+ /* XXX need to load-detect */
return OUTPUT_STATUS_CONNECTED;
}
@@ -513,8 +523,9 @@ i830_tv_detect(ScrnInfoPtr pScrn, I830OutputPtr output)
* how to probe modes off of TV connections.
*/
static DisplayModePtr
-i830_tv_get_modes(ScrnInfoPtr pScrn, I830OutputPtr output)
+i830_tv_get_modes(I830_xf86OutputPtr output)
{
+ ScrnInfoPtr pScrn = output->scrn;
I830Ptr pI830 = I830PTR(pScrn);
DisplayModePtr new;
char stmp[32];
@@ -553,36 +564,52 @@ i830_tv_get_modes(ScrnInfoPtr pScrn, I830OutputPtr output)
return new;
}
+static void
+i830_tv_destroy (I830_xf86OutputPtr output)
+{
+ if (output->driver_private)
+ xfree (output->driver_private);
+}
+
+static const I830_xf86OutputFuncsRec i830_tv_output_funcs = {
+ .dpms = i830_tv_dpms,
+ .save = i830_tv_save,
+ .restore = i830_tv_restore,
+ .mode_valid = i830_tv_mode_valid,
+ .pre_set_mode = i830_tv_pre_set_mode,
+ .post_set_mode = i830_tv_post_set_mode,
+ .detect = i830_tv_detect,
+ .get_modes = i830_tv_get_modes,
+ .destroy = i830_tv_destroy
+};
+
void
i830_tv_init(ScrnInfoPtr pScrn)
{
- I830Ptr pI830 = I830PTR(pScrn);
- I830OutputPtr output = &pI830->output[pI830->num_outputs];
- struct i830_tv_priv *dev_priv;
+ I830Ptr pI830 = I830PTR(pScrn);
+ I830_xf86OutputPtr output;
+ I830OutputPrivatePtr intel_output;
+ struct i830_tv_priv *dev_priv;
if ((INREG(TV_CTL) & TV_FUSE_STATE_MASK) == TV_FUSE_STATE_DISABLED)
return;
- output->type = I830_OUTPUT_TVOUT;
- output->pipe = 0;
- output->enabled = FALSE;
- output->load_detect_temp = FALSE;
+ output = i830xf86OutputCreate (pScrn, &i830_tv_output_funcs,
+ "TV");
- output->dpms = i830_tv_dpms;
- output->save = i830_tv_save;
- output->restore = i830_tv_restore;
- output->mode_valid = i830_tv_mode_valid;
- output->pre_set_mode = i830_tv_pre_set_mode;
- output->post_set_mode = i830_tv_post_set_mode;
- output->detect = i830_tv_detect;
- output->get_modes = i830_tv_get_modes;
-
- dev_priv = xnfcalloc(1, sizeof(struct i830_tv_priv));
+ if (!output)
+ return;
- if (dev_priv == NULL)
+ intel_output = xnfcalloc (sizeof (I830OutputPrivateRec) +
+ sizeof (struct i830_tv_priv), 1);
+ if (!intel_output)
+ {
+ i830xf86OutputDestroy (output);
return;
-
- output->dev_priv = dev_priv;
- ErrorF ("TV out is output %d\n", pI830->num_outputs);
- pI830->num_outputs++;
+ }
+ dev_priv = (struct i830_tv_priv *) (intel_output + 1);
+ intel_output->type = I830_OUTPUT_SDVO;
+ intel_output->dev_priv = dev_priv;
+
+ output->driver_private = intel_output;
}
diff --git a/src/i830_video.c b/src/i830_video.c
index d84c1c97..5ce2b5d3 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -3595,7 +3595,7 @@ I830VideoSwitchModeAfter(ScrnInfoPtr pScrn, DisplayModePtr mode)
}
/* Check we have an LFP connected */
- if (i830PipeHasType (pScrn, pPriv->pipe, I830_OUTPUT_LVDS))
+ if (i830PipeHasType (pI830->xf86_crtc[pPriv->pipe], I830_OUTPUT_LVDS))
{
size = pPriv->pipe ? INREG(PIPEBSRC) : INREG(PIPEASRC);
hsize = (size >> 16) & 0x7FF;
diff --git a/src/i830_xf86Crtc.c b/src/i830_xf86Crtc.c
new file mode 100644
index 00000000..d0a3119e
--- /dev/null
+++ b/src/i830_xf86Crtc.c
@@ -0,0 +1,126 @@
+/*
+ * $Id: $
+ *
+ * Copyright © 2006 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stddef.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "xf86.h"
+#include "i830.h"
+#include "i830_xf86Modes.h"
+#include "i830_xf86Crtc.h"
+
+/*
+ * Crtc functions
+ */
+I830_xf86CrtcPtr
+i830xf86CrtcCreate (ScrnInfoPtr scrn,
+ I830_xf86CrtcFuncsPtr funcs)
+{
+ I830_xf86CrtcPtr xf86_crtc;
+
+ xf86_crtc = xcalloc (sizeof (I830_xf86CrtcRec), 1);
+ if (!xf86_crtc)
+ return NULL;
+ xf86_crtc->scrn = scrn;
+ xf86_crtc->funcs = funcs;
+#ifdef RANDR_12_INTERFACE
+ xf86_crtc->randr_crtc = RRCrtcCreate (xf86_crtc);
+ if (!xf86_crtc->randr_crtc)
+ {
+ xfree (xf86_crtc);
+ return NULL;
+ }
+#endif
+ return xf86_crtc;
+}
+
+void
+i830xf86CrtcDestroy (I830_xf86CrtcPtr xf86_crtc)
+{
+#ifdef RANDR_12_INTERFACE
+ RRCrtcDestroy (xf86_crtc->randr_crtc);
+#endif
+ xfree (xf86_crtc);
+}
+
+/*
+ * Output functions
+ */
+I830_xf86OutputPtr
+i830xf86OutputCreate (ScrnInfoPtr scrn,
+ const I830_xf86OutputFuncsRec *funcs,
+ const char *name)
+{
+ I830_xf86OutputPtr output;
+ I830Ptr pI830 = I830PTR(scrn);
+ int len = strlen (name);
+
+ output = xcalloc (sizeof (I830_xf86OutputRec) + len + 1, 1);
+ if (!output)
+ return NULL;
+ output->scrn = scrn;
+ output->funcs = funcs;
+ output->name = (char *) (output + 1);
+ strcpy (output->name, name);
+#ifdef RANDR_12_INTERFACE
+ output->randr_output = RROutputCreate (name, strlen (name), output);
+ if (!output->randr_output)
+ {
+ xfree (output);
+ return NULL;
+ }
+#endif
+ pI830->xf86_output[pI830->num_outputs++] = output;
+ return output;
+}
+
+void
+i830xf86OutputDestroy (I830_xf86OutputPtr output)
+{
+ ScrnInfoPtr scrn = output->scrn;
+ I830Ptr pI830 = I830PTR(scrn);
+ int o;
+
+ (*output->funcs->destroy) (output);
+#ifdef RANDR_12_INTERFACE
+ RROutputDestroy (output->randr_output);
+#endif
+ while (output->probed_modes)
+ xf86DeleteMode (&output->probed_modes, output->probed_modes);
+ for (o = 0; o < pI830->num_outputs; o++)
+ if (pI830->xf86_output[o] == output)
+ {
+ memmove (&pI830->xf86_output[o],
+ &pI830->xf86_output[o+1],
+ pI830->num_outputs - (o + 1));
+ break;
+ }
+ xfree (output);
+}
+
diff --git a/src/i830_xf86Crtc.h b/src/i830_xf86Crtc.h
new file mode 100644
index 00000000..6a525179
--- /dev/null
+++ b/src/i830_xf86Crtc.h
@@ -0,0 +1,296 @@
+/*
+ * Copyright © 2006 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+#ifndef _I830_XF86CRTC_H_
+#define _I830_XF86CRTC_H_
+
+#include <edid.h>
+#include "i830_xf86Modes.h"
+
+typedef struct _I830_xf86Crtc I830_xf86CrtcRec, *I830_xf86CrtcPtr;
+
+typedef struct _I830_xf86CrtcFuncs {
+ /**
+ * Turns the crtc on/off, or sets intermediate power levels if available.
+ *
+ * Unsupported intermediate modes drop to the lower power setting. If the
+ * mode is DPMSModeOff, the crtc must be disabled, as the DPLL may be
+ * disabled afterwards.
+ */
+ void
+ (*dpms)(I830_xf86CrtcPtr crtc,
+ int mode);
+
+ /**
+ * Saves the crtc's state for restoration on VT switch.
+ */
+ void
+ (*save)(I830_xf86CrtcPtr crtc);
+
+ /**
+ * Restore's the crtc's state at VT switch.
+ */
+ void
+ (*restore)(I830_xf86CrtcPtr crtc);
+
+ /**
+ * Clean up driver-specific bits of the crtc
+ */
+ void
+ (*destroy) (I830_xf86CrtcPtr crtc);
+} I830_xf86CrtcFuncsRec, *I830_xf86CrtcFuncsPtr;
+
+struct _I830_xf86Crtc {
+ /**
+ * Associated ScrnInfo
+ */
+ ScrnInfoPtr scrn;
+
+ /**
+ * Active state of this CRTC
+ *
+ * Set when this CRTC is driving one or more outputs
+ */
+ Bool enabled;
+
+ /**
+ * Position on screen
+ *
+ * Locates this CRTC within the frame buffer
+ */
+ int x, y;
+
+ /** Track whether cursor is within CRTC range */
+ Bool cursorInRange;
+
+ /** Track state of cursor associated with this CRTC */
+ Bool cursorShown;
+
+ /**
+ * Active mode
+ *
+ * This reflects the mode as set in the CRTC currently
+ * It will be cleared when the VT is not active or
+ * during server startup
+ */
+ DisplayModeRec curMode;
+
+ /**
+ * Desired mode
+ *
+ * This is set to the requested mode, independent of
+ * whether the VT is active. In particular, it receives
+ * the startup configured mode and saves the active mode
+ * on VT switch.
+ */
+ DisplayModeRec desiredMode;
+
+ /** crtc-specific functions */
+ const I830_xf86CrtcFuncsRec *funcs;
+
+ /**
+ * Driver private
+ *
+ * Holds driver-private information
+ */
+ void *driver_private;
+
+#ifdef RANDR_12_INTERFACE
+ /**
+ * RandR crtc
+ *
+ * When RandR 1.2 is available, this
+ * points at the associated crtc object
+ */
+ RRCrtcPtr randr_crtc;
+#else
+ void *randr_crtc;
+#endif
+};
+
+typedef struct _I830_xf86Output I830_xf86OutputRec, *I830_xf86OutputPtr;
+
+typedef struct _I830_xf86OutputFuncs {
+ /**
+ * Turns the output on/off, or sets intermediate power levels if available.
+ *
+ * Unsupported intermediate modes drop to the lower power setting. If the
+ * mode is DPMSModeOff, the output must be disabled, as the DPLL may be
+ * disabled afterwards.
+ */
+ void
+ (*dpms)(I830_xf86OutputPtr output,
+ int mode);
+
+ /**
+ * Saves the output's state for restoration on VT switch.
+ */
+ void
+ (*save)(I830_xf86OutputPtr output);
+
+ /**
+ * Restore's the output's state at VT switch.
+ */
+ void
+ (*restore)(I830_xf86OutputPtr output);
+
+ /**
+ * Callback for testing a video mode for a given output.
+ *
+ * This function should only check for cases where a mode can't be supported
+ * on the pipe specifically, and not represent generic CRTC limitations.
+ *
+ * \return MODE_OK if the mode is valid, or another MODE_* otherwise.
+ */
+ int
+ (*mode_valid)(I830_xf86OutputPtr output,
+ DisplayModePtr pMode);
+
+ /**
+ * Callback for setting up a video mode before any crtc/dpll changes.
+ *
+ * \param pMode the mode that will be set, or NULL if the mode to be set is
+ * unknown (such as the restore path of VT switching).
+ */
+ void
+ (*pre_set_mode)(I830_xf86OutputPtr output,
+ DisplayModePtr pMode);
+
+ /**
+ * Callback for setting up a video mode after the DPLL update but before
+ * the plane is enabled.
+ */
+ void
+ (*post_set_mode)(I830_xf86OutputPtr output,
+ DisplayModePtr pMode);
+
+ /**
+ * Probe for a connected output, and return detect_status.
+ */
+ enum detect_status
+ (*detect)(I830_xf86OutputPtr output);
+
+ /**
+ * Query the device for the modes it provides.
+ *
+ * This function may also update MonInfo, mm_width, and mm_height.
+ *
+ * \return singly-linked list of modes or NULL if no modes found.
+ */
+ DisplayModePtr
+ (*get_modes)(I830_xf86OutputPtr output);
+
+ /**
+ * Clean up driver-specific bits of the output
+ */
+ void
+ (*destroy) (I830_xf86OutputPtr output);
+} I830_xf86OutputFuncsRec, *I830_xf86OutputFuncsPtr;
+
+struct _I830_xf86Output {
+ /**
+ * Associated ScrnInfo
+ */
+ ScrnInfoPtr scrn;
+ /**
+ * Currently connected crtc (if any)
+ *
+ * If this output is not in use, this field will be NULL.
+ */
+ I830_xf86CrtcPtr crtc;
+ /**
+ * List of available modes on this output.
+ *
+ * This should be the list from get_modes(), plus perhaps additional
+ * compatible modes added later.
+ */
+ DisplayModePtr probed_modes;
+
+ /** EDID monitor information */
+ xf86MonPtr MonInfo;
+
+ /** Physical size of the currently attached output device. */
+ int mm_width, mm_height;
+
+ /** Output name */
+ char *name;
+
+ /** output-specific functions */
+ const I830_xf86OutputFuncsRec *funcs;
+
+ /** driver private information */
+ void *driver_private;
+
+#ifdef RANDR_12_INTERFACE
+ /**
+ * RandR 1.2 output structure.
+ *
+ * When RandR 1.2 is available, this points at the associated
+ * RandR output structure and is created when this output is created
+ */
+ RROutputPtr randr_output;
+#else
+ void *randr_output;
+#endif
+};
+
+/*
+ * Crtc functions
+ */
+I830_xf86CrtcPtr
+i830xf86CrtcCreate (ScrnInfoPtr scrn,
+ const I830_xf86CrtcFuncsPtr funcs);
+
+void
+i830xf86CrtcDestroy (I830_xf86CrtcPtr xf86_crtc);
+
+
+/**
+ * Allocate a crtc for the specified output
+ *
+ * Find a currently unused CRTC which is suitable for
+ * the specified output
+ */
+
+I830_xf86CrtcPtr
+i830xf86AllocCrtc (I830_xf86OutputPtr output);
+
+/**
+ * Free a crtc
+ *
+ * Mark the crtc as unused by any outputs
+ */
+
+void
+i830xf86FreeCrtc (I830_xf86CrtcPtr crtc);
+
+/*
+ * Output functions
+ */
+I830_xf86OutputPtr
+i830xf86OutputCreate (ScrnInfoPtr scrn,
+ const I830_xf86OutputFuncsRec *funcs,
+ const char *name);
+
+void
+i830xf86OutputDestroy (I830_xf86OutputPtr xf86_output);
+
+#endif /* _I830_XF86CRTC_H_ */
diff --git a/src/i830_xf86Modes.h b/src/i830_xf86Modes.h
index 5a26c0e4..30b926a7 100644
--- a/src/i830_xf86Modes.h
+++ b/src/i830_xf86Modes.h
@@ -25,6 +25,9 @@
*
*/
+#ifndef _I830_XF86MODES_H_
+#define _I830_XF86MODES_H_
+
double
i830xf86ModeHSync(DisplayModePtr mode);
@@ -77,3 +80,5 @@ void
PrintModeline(int scrnIndex,DisplayModePtr mode);
extern DisplayModeRec I830xf86DefaultModes[];
+
+#endif /* _I830_XF86MODES_H_ */