summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKeith Packard <keithp@neko.keithp.com>2006-11-30 14:09:31 -0800
committerKeith Packard <keithp@neko.keithp.com>2006-11-30 14:09:31 -0800
commitff64bc7397cafbec94e388e1625b3a1999f1aca7 (patch)
treefdd9d519c382e39dd02be9fad341f31e668a047f /src
parentb94b7c4bcfdb7ba59ed818f72309b5060a2ab7ee (diff)
parent16e01b117bb7ae90b150dd4f25a887dd895cf473 (diff)
Merge branch 'restructure-outputs' into modesetting.
Outputs and Crtcs now have a driver-independent representation which should permit generic code to control RandR 1.2 and startup configuration.
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am2
-rw-r--r--src/i810_reg.h1
-rw-r--r--src/i830.h136
-rw-r--r--src/i830_crt.c188
-rw-r--r--src/i830_cursor.c104
-rw-r--r--src/i830_display.c271
-rw-r--r--src/i830_display.h14
-rw-r--r--src/i830_dri.c8
-rw-r--r--src/i830_driver.c183
-rw-r--r--src/i830_dvo.c145
-rw-r--r--src/i830_lvds.c93
-rw-r--r--src/i830_modes.c73
-rw-r--r--src/i830_randr.c407
-rw-r--r--src/i830_randr.h37
-rw-r--r--src/i830_rotate.c2
-rw-r--r--src/i830_sdvo.c295
-rw-r--r--src/i830_tv.c299
-rw-r--r--src/i830_video.c2
-rw-r--r--src/i830_xf86Crtc.c140
-rw-r--r--src/i830_xf86Crtc.h310
-rw-r--r--src/i830_xf86Modes.c24
-rw-r--r--src/i830_xf86Modes.h7
22 files changed, 1723 insertions, 1018 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 5246270f..976a95a4 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -82,6 +82,8 @@ i810_drv_la_SOURCES = \
i830_xf86Modes.h \
i830_xf86Modes.c \
i830_xf86cvt.c \
+ i830_xf86Crtc.h \
+ i830_xf86Crtc.c \
i915_3d.c \
i915_3d.h \
i915_reg.h \
diff --git a/src/i810_reg.h b/src/i810_reg.h
index 9c6e0dd2..e9319344 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -1103,6 +1103,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* This is used for load detection in combination with TVDAC_SENSE_MASK
*/
# define TV_TEST_MODE_MONITOR_DETECT (7 << 0)
+# define TV_TEST_MODE_MASK (7 << 0)
/** @} */
/** @defgroup TV_DAC
diff --git a/src/i830.h b/src/i830.h
index 422fdb7f..4cfed4b4 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -58,7 +58,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "xf86int10.h"
#include "vbe.h"
#include "vgaHW.h"
-#include "randrstr.h"
+#include "i830_xf86Crtc.h"
+#include "i830_randr.h"
#ifdef XF86DRI
#include "xf86drm.h"
@@ -197,99 +198,24 @@ enum detect_status {
OUTPUT_STATUS_UNKNOWN
};
-struct _I830OutputRec {
- int type;
- int pipe;
- Bool enabled;
- /**
- * Marks that the output and associated pipe is temporarily enabled for
- * load detection.
- */
- Bool load_detect_temp;
-
- /**
- * 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)(ScrnInfoPtr pScrn, I830OutputPtr output, int mode);
+typedef struct _I830CrtcPrivateRec {
+ int pipe;
+ Bool gammaEnabled;
+} I830CrtcPrivateRec, *I830CrtcPrivatePtr;
- /**
- * Saves the output's state for restoration on VT switch.
- */
- void (*save)(ScrnInfoPtr pScrn, I830OutputPtr output);
-
- /**
- * Restore's the output's state at VT switch.
- */
- void (*restore)(ScrnInfoPtr pScrn, I830OutputPtr output);
-
- /**
- * 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)(ScrnInfoPtr pScrn, I830OutputPtr output,
- DisplayModePtr pMode);
-
- /**
- * Callback for setting up a video mode before any pipe/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)(ScrnInfoPtr pScrn, I830OutputPtr output,
- DisplayModePtr pMode);
-
- /**
- * Callback for setting up a video mode after the DPLL update but before
- * the plane is enabled.
- */
- void (*post_set_mode)(ScrnInfoPtr pScrn, I830OutputPtr output,
- DisplayModePtr pMode);
-
- /**
- * Probe for a connected output, and return detect_status.
- */
- enum detect_status (*detect)(ScrnInfoPtr pScrn, I830OutputPtr 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)(ScrnInfoPtr pScrn, I830OutputPtr output);
+#define I830CrtcPrivate(c) ((I830CrtcPrivatePtr) (c)->driver_private)
- /**
- * 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 output currently attached. */
- int mm_width, mm_height;
-
- I2CBusPtr pI2CBus;
- I2CBusPtr pDDCBus;
- struct _I830DVODriver *i2c_drv;
+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;
-#ifdef RANDR_12_INTERFACE
- RROutputPtr randr_output;
-#endif
-};
+ void *dev_priv;
+} I830OutputPrivateRec, *I830OutputPrivatePtr;
+
+#define I830OutputPrivate(o) ((I830OutputPrivatePtr) (o)->driver_private)
/** enumeration of 3d consumers so some can maintain invariant state. */
enum last_3d {
@@ -314,6 +240,9 @@ typedef struct _I830PipeRec {
} I830PipeRec, *I830PipePtr;
typedef struct _I830Rec {
+ /* Must be first */
+ xf86CrtcConfigRec xf86_config;
+
unsigned char *MMIOBase;
unsigned char *FbBase;
int cpp;
@@ -330,9 +259,6 @@ typedef struct _I830Rec {
int CloneVDisplay;
I830EntPtr entityPrivate;
-#if 0
- int pipe, origPipe;
-#endif
int init;
unsigned int bufferOffset; /* for I830SelectBuffer */
@@ -495,11 +421,6 @@ typedef struct _I830Rec {
Bool checkDevices;
- /* [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];
-
/* Driver phase/state information */
Bool preinit;
Bool starting;
@@ -516,8 +437,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;
@@ -610,7 +529,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 (xf86CrtcPtr crtc, Bool force);
extern Bool I830CursorInit(ScreenPtr pScreen);
extern void IntelEmitInvarientState(ScrnInfoPtr pScrn);
extern void I830EmitInvarientState(ScrnInfoPtr pScrn);
@@ -689,7 +608,7 @@ extern Bool I830I2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, int i2c_reg,
/* i830_display.c */
Bool
-i830PipeHasType (ScrnInfoPtr pScrn, int pipe, int type);
+i830PipeHasType (xf86CrtcPtr crtc, int type);
/* i830_crt.c */
void i830_crt_init(ScrnInfoPtr pScrn);
@@ -712,16 +631,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);
-
-/* i830_randr.c */
-Bool I830RandRCreateScreenResources (ScreenPtr pScreen);
-Bool I830RandRInit(ScreenPtr pScreen, int rotation);
-Bool I830RandRSetConfig(ScreenPtr pScreen, Rotation rotation, int rate,
- RRScreenSizePtr pSize);
-Rotation I830GetRotation(ScreenPtr pScreen);
-void I830GetOriginalVirtualSize(ScrnInfoPtr pScrn, int *x, int *y);
-Bool I830RandRPreInit (ScrnInfoPtr pScrn);
+DisplayModePtr i830_ddc_get_modes(xf86OutputPtr output);
/* i830_tv.c */
void i830_tv_init(ScrnInfoPtr pScrn);
diff --git a/src/i830_crt.c b/src/i830_crt.c
index 76a8007c..7a706d14 100644
--- a/src/i830_crt.c
+++ b/src/i830_crt.c
@@ -35,10 +35,11 @@
#include "i830_display.h"
static void
-i830_crt_dpms(ScrnInfoPtr pScrn, I830OutputPtr output, int mode)
+i830_crt_dpms(xf86OutputPtr output, int mode)
{
- I830Ptr pI830 = I830PTR(pScrn);
- CARD32 temp;
+ ScrnInfoPtr pScrn = output->scrn;
+ I830Ptr pI830 = I830PTR(pScrn);
+ CARD32 temp;
temp = INREG(ADPA);
temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE);
@@ -63,24 +64,25 @@ i830_crt_dpms(ScrnInfoPtr pScrn, I830OutputPtr output, int mode)
}
static void
-i830_crt_save(ScrnInfoPtr pScrn, I830OutputPtr output)
+i830_crt_save (xf86OutputPtr output)
{
- I830Ptr pI830 = I830PTR(pScrn);
+ ScrnInfoPtr pScrn = output->scrn;
+ I830Ptr pI830 = I830PTR(pScrn);
pI830->saveADPA = INREG(ADPA);
}
static void
-i830_crt_restore(ScrnInfoPtr pScrn, I830OutputPtr output)
+i830_crt_restore (xf86OutputPtr output)
{
- I830Ptr pI830 = I830PTR(pScrn);
+ ScrnInfoPtr pScrn = output->scrn;
+ I830Ptr pI830 = I830PTR(pScrn);
OUTREG(ADPA, pI830->saveADPA);
}
static int
-i830_crt_mode_valid(ScrnInfoPtr pScrn, I830OutputPtr output,
- DisplayModePtr pMode)
+i830_crt_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
{
if (pMode->Flags & V_DBLSCAN)
return MODE_NO_DBLESCAN;
@@ -92,19 +94,24 @@ i830_crt_mode_valid(ScrnInfoPtr pScrn, I830OutputPtr output,
}
static void
-i830_crt_pre_set_mode(ScrnInfoPtr pScrn, I830OutputPtr output,
- DisplayModePtr pMode)
+i830_crt_pre_set_mode (xf86OutputPtr output, DisplayModePtr pMode)
{
}
static void
-i830_crt_post_set_mode(ScrnInfoPtr pScrn, I830OutputPtr output,
- DisplayModePtr pMode)
+i830_crt_post_set_mode (xf86OutputPtr output, DisplayModePtr pMode)
{
- I830Ptr pI830 = I830PTR(pScrn);
- int dpll_md_reg = (output->pipe == 0) ? DPLL_A_MD : DPLL_B_MD;
- CARD32 adpa, dpll_md;
-
+ ScrnInfoPtr pScrn = output->scrn;
+ I830Ptr pI830 = I830PTR(pScrn);
+ xf86CrtcPtr crtc = output->crtc;
+ I830CrtcPrivatePtr i830_crtc = crtc->driver_private;
+ int dpll_md_reg;
+ CARD32 adpa, dpll_md;
+
+ if (i830_crtc->pipe == 0)
+ dpll_md_reg = DPLL_A_MD;
+ else
+ dpll_md_reg = DPLL_B_MD;
/*
* Disable separate mode multiplier used when cloning SDVO to CRT
* XXX this needs to be adjusted when we really are cloning
@@ -122,7 +129,7 @@ i830_crt_post_set_mode(ScrnInfoPtr pScrn, I830OutputPtr output,
if (pMode->Flags & V_PVSYNC)
adpa |= ADPA_VSYNC_ACTIVE_HIGH;
- if (output->pipe == 0)
+ if (i830_crtc->pipe == 0)
adpa |= ADPA_PIPE_A_SELECT;
else
adpa |= ADPA_PIPE_B_SELECT;
@@ -139,12 +146,13 @@ i830_crt_post_set_mode(ScrnInfoPtr pScrn, I830OutputPtr output,
* \return FALSE if CRT is disconnected.
*/
static Bool
-i830_crt_detect_hotplug(ScrnInfoPtr pScrn)
+i830_crt_detect_hotplug(xf86OutputPtr output)
{
- I830Ptr pI830 = I830PTR(pScrn);
- CARD32 temp;
- const int timeout_ms = 1000;
- int starttime, curtime;
+ ScrnInfoPtr pScrn = output->scrn;
+ I830Ptr pI830 = I830PTR(pScrn);
+ CARD32 temp;
+ const int timeout_ms = 1000;
+ int starttime, curtime;
temp = INREG(PORT_HOTPLUG_EN);
@@ -177,20 +185,25 @@ i830_crt_detect_hotplug(ScrnInfoPtr pScrn)
* \return FALSE if CRT is disconnected.
*/
static Bool
-i830_crt_detect_load(ScrnInfoPtr pScrn, I830OutputPtr output)
+i830_crt_detect_load (xf86CrtcPtr crtc,
+ xf86OutputPtr output)
{
- I830Ptr pI830 = I830PTR(pScrn);
- CARD32 save_adpa, adpa, pipeconf, bclrpat;
- CARD8 st00;
- int pipeconf_reg, bclrpat_reg, dpll_reg;
- int pipe;
-
- pipe = output->pipe;
- if (pipe == 0) {
+ ScrnInfoPtr pScrn = output->scrn;
+ I830Ptr pI830 = I830PTR(pScrn);
+ I830CrtcPrivatePtr i830_crtc = I830CrtcPrivate(crtc);
+ CARD32 save_adpa, adpa, pipeconf, bclrpat;
+ CARD8 st00;
+ int pipeconf_reg, bclrpat_reg, dpll_reg;
+ int pipe = i830_crtc->pipe;
+
+ if (pipe == 0)
+ {
bclrpat_reg = BCLRPAT_A;
pipeconf_reg = PIPEACONF;
dpll_reg = DPLL_A;
- } else {
+ }
+ else
+ {
bclrpat_reg = BCLRPAT_B;
pipeconf_reg = PIPEBCONF;
dpll_reg = DPLL_B;
@@ -244,17 +257,15 @@ i830_crt_detect_load(ScrnInfoPtr pScrn, I830OutputPtr output)
* \return FALSE if no DDC response was detected.
*/
static Bool
-i830_crt_detect_ddc(ScrnInfoPtr pScrn)
+i830_crt_detect_ddc(xf86OutputPtr output)
{
- I830Ptr pI830 = I830PTR(pScrn);
- struct _I830OutputRec *output;
+ I830OutputPrivatePtr i830_output = output->driver_private;
- output = &pI830->output[0];
/* CRT should always be at 0, but check anyway */
- if (output->type != I830_OUTPUT_ANALOG)
+ if (i830_output->type != I830_OUTPUT_ANALOG)
return FALSE;
- return xf86I2CProbeAddress(output->pDDCBus, 0x00A0);
+ return xf86I2CProbeAddress(i830_output->pDDCBus, 0x00A0);
}
/**
@@ -264,25 +275,50 @@ i830_crt_detect_ddc(ScrnInfoPtr pScrn)
* on active displays.
*/
static enum detect_status
-i830_crt_detect(ScrnInfoPtr pScrn, I830OutputPtr output)
+i830_crt_detect(xf86OutputPtr output)
{
- I830Ptr pI830 = I830PTR(pScrn);
+ ScrnInfoPtr pScrn = output->scrn;
+ I830Ptr pI830 = I830PTR(pScrn);
+ xf86CrtcPtr crtc;
if (IS_I945G(pI830) || IS_I945GM(pI830) || IS_I965G(pI830)) {
- if (i830_crt_detect_hotplug(pScrn))
+ if (i830_crt_detect_hotplug(output))
return OUTPUT_STATUS_CONNECTED;
else
return OUTPUT_STATUS_DISCONNECTED;
}
- if (i830_crt_detect_ddc(pScrn))
+ if (i830_crt_detect_ddc(output))
return OUTPUT_STATUS_CONNECTED;
/* Use the load-detect method if we have no other way of telling. */
- if (i830GetLoadDetectPipe(pScrn, output) != -1) {
- Bool connected = i830_crt_detect_load(pScrn, output);
-
- i830ReleaseLoadDetectPipe(pScrn, output);
+ crtc = i830GetLoadDetectPipe (output);
+
+ if (crtc)
+ {
+ /* VESA 640x480x72Hz mode to set on the pipe */
+ static DisplayModeRec mode = {
+ NULL, NULL, "640x480", MODE_OK, M_T_DEFAULT,
+ 31500,
+ 640, 664, 704, 832, 0,
+ 480, 489, 491, 520, 0,
+ V_NHSYNC | V_NVSYNC,
+ 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ FALSE, FALSE, 0, NULL, 0, 0.0, 0.0
+ };
+ Bool connected;
+ I830OutputPrivatePtr intel_output = output->driver_private;
+
+ if (intel_output->load_detect_temp)
+ {
+ xf86SetModeCrtc (&mode, INTERLACE_HALVE_V);
+ i830PipeSetMode (crtc, &mode, FALSE);
+ }
+ connected = i830_crt_detect_load (crtc, output);
+
+ i830ReleaseLoadDetectPipe (output);
if (connected)
return OUTPUT_STATUS_CONNECTED;
else
@@ -293,16 +329,17 @@ i830_crt_detect(ScrnInfoPtr pScrn, I830OutputPtr output)
}
static DisplayModePtr
-i830_crt_get_modes(ScrnInfoPtr pScrn, I830OutputPtr output)
+i830_crt_get_modes(xf86OutputPtr output)
{
- DisplayModePtr modes;
+ ScrnInfoPtr pScrn = output->scrn;
+ DisplayModePtr modes;
MonRec fixed_mon;
- modes = i830_ddc_get_modes(pScrn, output);
+ modes = i830_ddc_get_modes(output);
if (modes != NULL)
return modes;
- if (output->detect(pScrn, output) == OUTPUT_STATUS_DISCONNECTED)
+ if ((*output->funcs->detect)(output) == OUTPUT_STATUS_DISCONNECTED)
return NULL;
/* We've got a potentially-connected monitor that we can't DDC. Return a
@@ -323,24 +360,43 @@ i830_crt_get_modes(ScrnInfoPtr pScrn, I830OutputPtr output)
return modes;
}
+static void
+i830_crt_destroy (xf86OutputPtr output)
+{
+ if (output->driver_private)
+ xfree (output->driver_private);
+}
+
+static const xf86OutputFuncsRec i830_crt_output_funcs = {
+ .dpms = i830_crt_dpms,
+ .save = i830_crt_save,
+ .restore = i830_crt_restore,
+ .mode_valid = i830_crt_mode_valid,
+ .pre_set_mode = i830_crt_pre_set_mode,
+ .post_set_mode = i830_crt_post_set_mode,
+ .detect = i830_crt_detect,
+ .get_modes = i830_crt_get_modes,
+ .destroy = i830_crt_destroy
+};
+
void
i830_crt_init(ScrnInfoPtr pScrn)
{
- I830Ptr pI830 = I830PTR(pScrn);
-
- pI830->output[pI830->num_outputs].type = I830_OUTPUT_ANALOG;
- pI830->output[pI830->num_outputs].dpms = i830_crt_dpms;
- pI830->output[pI830->num_outputs].save = i830_crt_save;
- pI830->output[pI830->num_outputs].restore = i830_crt_restore;
- pI830->output[pI830->num_outputs].mode_valid = i830_crt_mode_valid;
- pI830->output[pI830->num_outputs].pre_set_mode = i830_crt_pre_set_mode;
- pI830->output[pI830->num_outputs].post_set_mode = i830_crt_post_set_mode;
- pI830->output[pI830->num_outputs].detect = i830_crt_detect;
- pI830->output[pI830->num_outputs].get_modes = i830_crt_get_modes;
+ xf86OutputPtr output;
+ I830OutputPrivatePtr i830_output;
+
+ output = xf86OutputCreate (pScrn, &i830_crt_output_funcs, "VGA");
+ if (!output)
+ return;
+ i830_output = xnfcalloc (sizeof (I830OutputPrivateRec), 1);
+ if (!i830_output)
+ {
+ xf86OutputDestroy (output);
+ return;
+ }
+ i830_output->type = I830_OUTPUT_ANALOG;
+ output->driver_private = i830_output;
/* Set up the DDC bus. */
- I830I2CInit(pScrn, &pI830->output[pI830->num_outputs].pDDCBus,
- GPIOA, "CRTDDC_A");
-
- pI830->num_outputs++;
+ I830I2CInit(pScrn, &i830_output->pDDCBus, GPIOA, "CRTDDC_A");
}
diff --git a/src/i830_cursor.c b/src/i830_cursor.c
index 517bd3e0..e9ca8f15 100644
--- a/src/i830_cursor.c
+++ b/src/i830_cursor.c
@@ -80,13 +80,16 @@ static Bool I830UseHWCursorARGB(ScreenPtr pScrn, CursorPtr pCurs);
#endif
static void
-I830SetPipeCursorBase (ScrnInfoPtr pScrn, int pipe)
+I830SetPipeCursorBase (xf86CrtcPtr crtc)
{
- I830Ptr pI830 = I830PTR(pScrn);
- int cursor_base = (pipe == 0 ? CURSOR_A_BASE : CURSOR_B_BASE);
- I830MemRange *cursor_mem;
-
- if (pipe >= pI830->num_pipes)
+ 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->xf86_config.num_crtc)
FatalError("Bad pipe number for cursor base setting\n");
if (pI830->CursorIsARGB)
@@ -102,18 +105,20 @@ I830SetPipeCursorBase (ScrnInfoPtr pScrn, int pipe)
}
void
-I830SetPipeCursor (ScrnInfoPtr pScrn, int pipe, Bool force)
+I830SetPipeCursor (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
@@ -180,11 +185,12 @@ I830InitHWCursor(ScrnInfoPtr pScrn)
int i;
DPRINTF(PFX, "I830InitHWCursor\n");
- for (i = 0; i < pI830->num_pipes; i++)
- pI830->pipes[i].cursorShown = FALSE;
+ for (i = 0; i < pI830->xf86_config.num_crtc; i++)
+ pI830->xf86_config.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++)
+ for (i = 0; i < pI830->xf86_config.num_crtc; i++)
{
int cursor_control = i == 0 ? CURSOR_A_CONTROL : CURSOR_B_CONTROL;
temp = INREG(cursor_control);
@@ -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_config.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_config.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);
@@ -484,14 +490,14 @@ I830SetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
x -= hotspotx;
y -= hotspoty;
- for (pipe = 0; pipe < pI830->num_pipes; pipe++)
+ for (pipe = 0; pipe < pI830->xf86_config.num_crtc; pipe++)
{
- I830PipePtr pI830Pipe = &pI830->pipes[pipe];
- DisplayModePtr mode = &pI830Pipe->curMode;
- int thisx = x - pI830Pipe->x;
- int thisy = y - pI830Pipe->y;
+ xf86CrtcPtr crtc = pI830->xf86_config.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);
}
}
@@ -550,8 +556,8 @@ I830ShowCursor(ScrnInfoPtr pScrn)
pI830->CursorMemARGB->Physical, pI830->CursorMemARGB->Start);
pI830->cursorOn = TRUE;
- for (pipe = 0; pipe < pI830->num_pipes; pipe++)
- I830SetPipeCursor (pScrn, pipe, TRUE);
+ for (pipe = 0; pipe < pI830->xf86_config.num_crtc; pipe++)
+ I830SetPipeCursor (pI830->xf86_config.crtc[pipe], TRUE);
}
static void
@@ -563,14 +569,15 @@ I830HideCursor(ScrnInfoPtr pScrn)
DPRINTF(PFX, "I830HideCursor\n");
pI830->cursorOn = FALSE;
- for (pipe = 0; pipe < pI830->num_pipes; pipe++)
- I830SetPipeCursor (pScrn, pipe, TRUE);
+ for (pipe = 0; pipe < pI830->xf86_config.num_crtc; pipe++)
+ I830SetPipeCursor (pI830->xf86_config.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->xf86_config.num_crtc; 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);
+ xf86CrtcPtr crtc = pI830->xf86_config.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 e2e4b6e4..29b783bf 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 (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)
+ for (i = 0; i < pI830->xf86_config.num_output; i++)
+ {
+ xf86OutputPtr output = pI830->xf86_config.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(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(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(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(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->xf86_config.num_output; i++)
+ {
+ xf86OutputPtr output = pI830->xf86_config.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 (!xf86ModesEqual(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 (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)
+ for (i = 0; i < pI830->xf86_config.num_output; i++)
+ if (pI830->xf86_config.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(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 (xf86ModesEqual(&pI830Pipe->curMode, pMode))
+ if (xf86ModesEqual(&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->xf86_config.num_output; i++)
+ {
+ xf86OutputPtr output = pI830->xf86_config.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;
}
@@ -671,9 +694,10 @@ i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe,
OUTREG(PFIT_CONTROL, 0);
}
- 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);
+ for (i = 0; i < pI830->xf86_config.num_output; i++) {
+ xf86OutputPtr output = pI830->xf86_config.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->xf86_config.num_output; o++)
+ {
+ xf86OutputPtr output = pI830->xf86_config.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->xf86_config.num_crtc; pipe++)
+ {
+ xf86CrtcPtr crtc = pI830->xf86_config.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));
}
}
@@ -778,11 +807,12 @@ i830SetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
DPRINTF(PFX, "i830SetMode\n");
- for (i = 0; i < pI830->num_pipes; i++)
+ for (i = 0; i < pI830->xf86_config.num_crtc; i++)
{
- ok = i830PipeSetMode(pScrn,
- i830PipeFindClosestMode(pScrn, i, pMode),
- i, TRUE);
+ xf86CrtcPtr crtc = pI830->xf86_config.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->xf86_config.num_crtc >= 2 &&
+ pI830->xf86_config.crtc[0]->enabled &&
+ pI830->xf86_config.crtc[1]->enabled)
pI830->Clone = TRUE;
else
pI830->Clone = FALSE;
@@ -833,7 +865,8 @@ i830DescribeOutputConfiguration(ScrnInfoPtr pScrn)
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Output configuration:\n");
- for (i = 0; i < pI830->num_pipes; i++) {
+ for (i = 0; i < pI830->xf86_config.num_crtc; i++) {
+ xf86CrtcPtr crtc = pI830->xf86_config.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;
- }
-
+ for (i = 0; i < pI830->xf86_config.num_output; i++) {
+ xf86OutputPtr output = pI830->xf86_config.output[i];
+ 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,74 +919,46 @@ 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)
+
+xf86CrtcPtr
+i830GetLoadDetectPipe(xf86OutputPtr output)
{
- I830Ptr pI830 = I830PTR(pScrn);
- int i;
- /* VESA 640x480x72Hz mode to set on the pipe */
- DisplayModeRec mode = {
- NULL, NULL, "640x480", MODE_OK, M_T_DEFAULT,
- 31500,
- 640, 664, 704, 832, 0,
- 480, 489, 491, 520, 0,
- V_NHSYNC | V_NVSYNC,
- 0, 0,
- 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- FALSE, FALSE, 0, NULL, 0, 0.0, 0.0
- };
-
- /* 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;
+ ScrnInfoPtr pScrn = output->scrn;
+ I830Ptr pI830 = I830PTR(pScrn);
+ I830OutputPrivatePtr intel_output = output->driver_private;
+ xf86CrtcPtr crtc;
+ int i;
- 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))
+ for (i = 0; i < pI830->xf86_config.num_crtc; i++)
+ if (!i830PipeInUse(pI830->xf86_config.crtc[i]))
break;
- if (i == pI830->num_pipes)
- return -1;
-
- output->load_detect_temp = TRUE;
- output->pipe = i;
- output->enabled = TRUE;
+ if (i == pI830->xf86_config.num_crtc)
+ return NULL;
- xf86SetModeCrtc(&mode, INTERLACE_HALVE_V);
+ crtc = pI830->xf86_config.crtc[i];
- i830PipeSetMode(pScrn, &mode, i, FALSE);
+ output->crtc = crtc;
+ intel_output->load_detect_temp = TRUE;
- return i;
+ return crtc;
}
void
-i830ReleaseLoadDetectPipe(ScrnInfoPtr pScrn, I830OutputPtr output)
+i830ReleaseLoadDetectPipe(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 266d0b28..c80c3f72 100644
--- a/src/i830_display.h
+++ b/src/i830_display.h
@@ -29,17 +29,18 @@
/* i830_display.c */
DisplayModePtr
-i830PipeFindClosestMode(ScrnInfoPtr pScrn, int pipe, DisplayModePtr pMode);
-Bool i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe,
+i830PipeFindClosestMode(xf86CrtcPtr crtc, DisplayModePtr pMode);
+Bool i830PipeSetMode(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(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);
+
+xf86CrtcPtr i830GetLoadDetectPipe(xf86OutputPtr output);
+void i830ReleaseLoadDetectPipe(xf86OutputPtr output);
+Bool i830PipeInUse(xf86CrtcPtr crtc);
/** @{
*/
@@ -51,4 +52,3 @@ DisplayModePtr i830_xf86CVTMode(int HDisplay, int VDisplay, float VRefresh,
#define xf86CVTMode i830_xf86CVTMode
#endif /* XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,1,99,2) */
/** @} */
-
diff --git a/src/i830_dri.c b/src/i830_dri.c
index 6366303e..b3206336 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->xf86_config.num_crtc > 1 && pI830->xf86_config.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 61dbeea4..c5e56e5c 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -592,8 +592,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->xf86_config.num_crtc; p++)
+ {
+ xf86CrtcPtr crtc = pI830->xf86_config.crtc[p];
+ I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
if (p == 0) {
palreg = PALETTE_A;
@@ -607,10 +609,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);
@@ -709,6 +711,32 @@ I830SetupOutputs(ScrnInfoPtr pScrn)
i830_tv_init(pScrn);
}
+/**
+ * Setup the CRTCs
+ */
+
+static const xf86CrtcFuncsRec i830_crtc_funcs = {
+};
+
+static void
+I830SetupCrtcs(ScrnInfoPtr pScrn, int num_pipe)
+{
+ int p;
+
+ for (p = 0; p < num_pipe; p++)
+ {
+ xf86CrtcPtr crtc = xf86CrtcCreate (pScrn, &i830_crtc_funcs);
+ I830CrtcPrivatePtr intel_crtc;
+
+ if (!crtc)
+ break;
+ intel_crtc = xnfcalloc (sizeof (I830CrtcPrivateRec), 1);
+ intel_crtc->pipe = p;
+
+ crtc->driver_private = intel_crtc;
+ }
+}
+
static void
I830PreInitDDC(ScrnInfoPtr pScrn)
{
@@ -727,8 +755,6 @@ I830PreInitDDC(ScrnInfoPtr pScrn)
if (xf86LoadSubModule(pScrn, "i2c")) {
xf86LoaderReqSymLists(I810i2cSymbols, NULL);
- I830SetupOutputs(pScrn);
-
pI830->ddc2 = TRUE;
} else {
pI830->ddc2 = FALSE;
@@ -850,6 +876,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
pointer pVBEModule = NULL;
Bool enable;
const char *chipname;
+ int num_pipe;
#ifdef XF86DRI
unsigned long savedMMSize;
#endif
@@ -1157,14 +1184,14 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
}
if (pI830->PciInfo->chipType == PCI_CHIP_E7221_G)
- pI830->num_pipes = 1;
+ num_pipe = 1;
else
if (IS_MOBILE(pI830) || IS_I9XX(pI830))
- pI830->num_pipes = 2;
+ num_pipe = 2;
else
- pI830->num_pipes = 1;
+ num_pipe = 1;
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%d display pipe%s available.\n",
- pI830->num_pipes, pI830->num_pipes > 1 ? "s" : "");
+ num_pipe, num_pipe > 1 ? "s" : "");
/*
* Get the pre-allocated (stolen) memory size.
@@ -1311,9 +1338,11 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
}
I830PreInitDDC(pScrn);
+ I830SetupOutputs(pScrn);
+ I830SetupCrtcs(pScrn, num_pipe);
if (xf86ReturnOptValBool(pI830->Options, OPTION_CLONE, FALSE)) {
- if (pI830->num_pipes == 1) {
+ if (num_pipe == 1) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Can't enable Clone Mode because this is a single pipe device\n");
PreInitCleanup(pScrn);
@@ -1333,33 +1362,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->xf86_config.num_output; i++)
+ {
+ xf86OutputPtr output = pI830->xf86_config.output[i];
+ I830OutputPrivatePtr intel_output = output->driver_private;
+ xf86CrtcPtr crtc;
+ int p;
+
+ output->crtc = NULL;
- switch (pI830->output[i].type) {
+ 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_config.crtc[pI830->xf86_config.num_crtc - 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->xf86_config.num_crtc; p++)
+ {
+ crtc = pI830->xf86_config.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_config.crtc[0];
+ if ((*output->funcs->detect)(output) != OUTPUT_STATUS_DISCONNECTED &&
+ !i830PipeInUse(crtc))
+ {
+ output->crtc = crtc;
}
break;
default:
@@ -1368,10 +1408,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->xf86_config.num_crtc; i++)
+ {
+ xf86CrtcPtr crtc = pI830->xf86_config.crtc[i];
+ crtc->enabled = i830PipeInUse(crtc);
}
-
+
pI830->rotation = RR_Rotate_0;
if ((s = xf86GetOptValString(pI830->Options, OPTION_ROTATE))) {
pI830->InitialRotation = 0;
@@ -1614,7 +1656,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
"Maximum frambuffer space: %d kByte\n", pScrn->videoRam);
- if (!I830RandRPreInit (pScrn))
+ if (!xf86RandR12PreInit (pScrn))
{
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n");
PreInitCleanup(pScrn);
@@ -2129,7 +2171,7 @@ SaveHWState(ScrnInfoPtr pScrn)
temp = INREG(PIPEACONF);
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "PIPEACONF is 0x%08lx\n",
(unsigned long) temp);
- if (pI830->num_pipes == 2) {
+ if (pI830->xf86_config.num_crtc == 2) {
temp = INREG(PIPEBCONF);
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "PIPEBCONF is 0x%08lx\n",
(unsigned long) temp);
@@ -2161,7 +2203,7 @@ SaveHWState(ScrnInfoPtr pScrn)
pI830->savePaletteA[i] = INREG(PALETTE_A + (i << 2));
}
- if(pI830->num_pipes == 2) {
+ if(pI830->xf86_config.num_crtc == 2) {
pI830->savePIPEBCONF = INREG(PIPEBCONF);
pI830->savePIPEBSRC = INREG(PIPEBSRC);
pI830->saveDSPBCNTR = INREG(DSPBCNTR);
@@ -2205,9 +2247,10 @@ 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]);
+ for (i = 0; i < pI830->xf86_config.num_output; i++) {
+ xf86OutputPtr output = pI830->xf86_config.output[i];
+ if (output->funcs->save)
+ (*output->funcs->save) (output);
}
vgaHWUnlock(hwp);
@@ -2246,8 +2289,9 @@ RestoreHWState(ScrnInfoPtr pScrn)
OUTREG(PIPEBCONF, temp & ~PIPEBCONF_ENABLE);
/* Disable outputs if necessary */
- for (i = 0; i < pI830->num_outputs; i++) {
- pI830->output[i].pre_set_mode(pScrn, &pI830->output[i], NULL);
+ for (i = 0; i < pI830->xf86_config.num_output; i++) {
+ xf86OutputPtr output = pI830->xf86_config.output[i];
+ (*output->funcs->pre_set_mode) (output, NULL);
}
i830WaitForVblank(pScrn);
@@ -2272,7 +2316,7 @@ RestoreHWState(ScrnInfoPtr pScrn)
OUTREG(PALETTE_A + (i << 2), pI830->savePaletteA[i]);
}
- if(pI830->num_pipes == 2) {
+ if(pI830->xf86_config.num_crtc == 2) {
OUTREG(FPB0, pI830->saveFPB0);
OUTREG(FPB1, pI830->saveFPB1);
OUTREG(DPLL_B, pI830->saveDPLL_B);
@@ -2296,8 +2340,9 @@ 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]);
+ for (i = 0; i < pI830->xf86_config.num_output; i++) {
+ xf86OutputPtr output = pI830->xf86_config.output[i];
+ (*output->funcs->restore) (output);
}
if (IS_I965G(pI830)) {
@@ -2666,7 +2711,7 @@ I830CreateScreenResources (ScreenPtr pScreen)
if (!(*pScreen->CreateScreenResources)(pScreen))
return FALSE;
- if (!I830RandRCreateScreenResources (pScreen))
+ if (!xf86RandR12CreateScreenResources (pScreen))
return FALSE;
return TRUE;
@@ -3222,10 +3267,11 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
xf86DisableRandR(); /* Disable built-in RandR extension */
shadowSetup(pScreen);
/* support all rotations */
+ xf86RandR12Init (pScreen);
if (IS_I965G(pI830)) {
- I830RandRInit(pScreen, RR_Rotate_0); /* only 0 degrees for I965G */
+ xf86RandR12SetRotations (pScreen, RR_Rotate_0); /* only 0 degrees for I965G */
} else {
- I830RandRInit(pScreen, RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270);
+ xf86RandR12SetRotations (pScreen, RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270);
}
pI830->PointerMoved = pScrn->PointerMoved;
pScrn->PointerMoved = I830PointerMoved;
@@ -3344,9 +3390,12 @@ i830AdjustFrame(int scrnIndex, int x, int y, int flags)
pI830->AccelInfoRec->NeedToSync = FALSE;
}
- for (i = 0; i < pI830->num_pipes; i++)
- if (pI830->pipes[i].enabled)
- i830PipeSetBase(pScrn, i, x, y);
+ for (i = 0; i < pI830->xf86_config.num_crtc; i++)
+ {
+ xf86CrtcPtr crtc = pI830->xf86_config.crtc[i];
+ if (crtc->enabled)
+ i830PipeSetBase(crtc, x, y);
+ }
}
static void
@@ -3457,19 +3506,19 @@ I830EnterVT(int scrnIndex, int flags)
ResetState(pScrn, FALSE);
SetHWOperatingState(pScrn);
- for (i = 0; i < pI830->num_pipes; i++)
+ for (i = 0; i < pI830->xf86_config.num_crtc; i++)
{
- I830PipePtr pipe = &pI830->pipes[i];
+ xf86CrtcPtr crtc = pI830->xf86_config.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);
@@ -3624,7 +3673,7 @@ I830SaveScreen(ScreenPtr pScreen, int mode)
DPRINTF(PFX, "I830SaveScreen: %d, on is %s\n", mode, BOOLTOSTRING(on));
if (pScrn->vtSema) {
- for (i = 0; i < pI830->num_pipes; i++) {
+ for (i = 0; i < pI830->xf86_config.num_crtc; i++) {
if (i == 0) {
ctrl = DSPACNTR;
base = DSPABASE;
@@ -3634,7 +3683,7 @@ I830SaveScreen(ScreenPtr pScreen, int mode)
base = DSPBADDR;
surf = DSPBSURF;
}
- if (pI830->pipes[i].enabled) {
+ if (pI830->xf86_config.crtc[i]->enabled) {
temp = INREG(ctrl);
if (on)
temp |= DISPLAY_PLANE_ENABLE;
@@ -3671,11 +3720,16 @@ I830DisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode,
int i;
CARD32 temp, ctrl, base;
- for (i = 0; i < pI830->num_outputs; i++) {
- pI830->output[i].dpms(pScrn, &pI830->output[i], PowerManagementMode);
+ for (i = 0; i < pI830->xf86_config.num_output; i++) {
+ xf86OutputPtr output = pI830->xf86_config.output[i];
+
+ (*output->funcs->dpms) (output, PowerManagementMode);
}
- for (i = 0; i < pI830->num_pipes; i++) {
+ for (i = 0; i < pI830->xf86_config.num_crtc; i++)
+ {
+ xf86CrtcPtr crtc = pI830->xf86_config.crtc[i];
+
if (i == 0) {
ctrl = DSPACNTR;
base = DSPABASE;
@@ -3683,7 +3737,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;
@@ -3896,7 +3951,7 @@ i830MonitorDetectDebugger(ScrnInfoPtr pScrn)
if (!pScrn->vtSema)
return 1000;
- for (i = 0; i < pI830->num_outputs; i++) {
+ for (i = 0; i < pI830->xf86_config.num_output; i++) {
enum output_status ret;
char *result;
diff --git a/src/i830_dvo.c b/src/i830_dvo.c
index 31fb76ba..6fe31575 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(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(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(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(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(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(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);
+ 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(xf86OutputPtr output)
{
return OUTPUT_STATUS_UNKNOWN;
}
@@ -191,46 +201,81 @@ I830I2CDetectDVOControllers(ScrnInfoPtr pScrn, I2CBusPtr pI2CBus,
return FALSE;
}
+static void
+i830_dvo_destroy (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 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;
+ xf86OutputPtr output;
+ I830OutputPrivatePtr intel_output;
+ int ret;
+ output = xf86OutputCreate (pScrn, &i830_dvo_output_funcs,
+ "ADD AGP card");
+ if (!output)
+ return;
+ intel_output = xnfcalloc (sizeof (I830OutputPrivateRec), 1);
+ if (!intel_output)
+ {
+ xf86OutputDestroy (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)
+ {
+ xf86OutputDestroy (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)
+ {
+ xf86OutputDestroy (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
+ {
+ xf86OutputDestroy (output);
return;
}
-
- pI830->num_outputs++;
}
diff --git a/src/i830_lvds.c b/src/i830_lvds.c
index ea45420f..bfb4e148 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 (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 (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(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(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(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(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(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(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 (xf86OutputPtr output)
+{
+ I830OutputPrivatePtr intel_output = output->driver_private;
+
+ if (intel_output)
+ xfree (intel_output);
+}
+
+static const 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);
+ 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 = xf86OutputCreate (pScrn, &i830_lvds_output_funcs, "Built-in LCD panel");
+ if (!output)
+ return;
+ intel_output = xnfcalloc (sizeof (I830OutputPrivateRec), 1);
+ if (!intel_output)
+ {
+ xf86OutputDestroy (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 60bedad5..a0d79db9 100644
--- a/src/i830_modes.c
+++ b/src/i830_modes.c
@@ -113,47 +113,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->xf86_config.num_output; i++)
+ {
+ xf86OutputPtr output = pI830->xf86_config.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.
@@ -200,15 +197,15 @@ i830_set_xf86_modes_from_outputs(ScrnInfoPtr pScrn)
* pScrn->modes should only be used for XF86VidMode now, which we don't
* 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 =
- xf86DuplicateModes(pScrn, pI830->output[i].probed_modes);
+ for (i = 0; i < pI830->xf86_config.num_output; i++) {
+ xf86OutputPtr output = pI830->xf86_config.output[i];
+ if (output->probed_modes != NULL) {
+ pScrn->modes = xf86DuplicateModes(pScrn, output->probed_modes);
break;
}
}
- I830GetOriginalVirtualSize(pScrn, &originalVirtualX, &originalVirtualY);
+ xf86RandR12GetOriginalVirtualSize(pScrn, &originalVirtualX, &originalVirtualY);
/* Disable modes in the XFree86 DDX list that are larger than the current
* virtual size.
@@ -253,11 +250,11 @@ i830_set_default_screen_size(ScrnInfoPtr pScrn)
/* Set up a virtual size that will cover any clone mode we'd want to
* set for the currently-connected outputs.
*/
- for (i = 0; i < pI830->num_outputs; i++) {
+ for (i = 0; i < pI830->xf86_config.num_output; i++) {
+ xf86OutputPtr output = pI830->xf86_config.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;
@@ -304,8 +301,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(xf86OutputPtr output, void *data, int data_len)
{
Atom edid_atom = MakeAtom(EDID_ATOM_NAME, sizeof(EDID_ATOM_NAME), TRUE);
@@ -326,16 +322,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(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;
}
@@ -346,24 +344,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 = xf86DDCGetModes(pScrn->scrnIndex, 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 9def4d8d..9ac54b5b 100644
--- a/src/i830_randr.c
+++ b/src/i830_randr.c
@@ -39,11 +39,12 @@
#include <randrstr.h>
#include <X11/extensions/render.h>
-#include "i830.h"
-#include "i830_xf86Modes.h"
+#include "i830_xf86Crtc.h"
+#include "i830_randr.h"
#include "i830_display.h"
+#include "i830.h"
-typedef struct _i830RandRInfo {
+typedef struct _xf86RandR12Info {
int virtualX;
int virtualY;
int mmWidth;
@@ -52,24 +53,21 @@ 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
-static Bool I830RandRInit12 (ScreenPtr pScreen);
-static Bool I830RandRCreateScreenResources12 (ScreenPtr pScreen);
+static Bool xf86RandR12Init12 (ScreenPtr pScreen);
+static Bool xf86RandR12CreateScreenResources12 (ScreenPtr pScreen);
#endif
-static int i830RandRIndex;
-static int i830RandRGeneration;
+static int xf86RandR12Index;
+static int xf86RandR12Generation;
#define XF86RANDRINFO(p) \
- ((XF86RandRInfoPtr)(p)->devPrivates[i830RandRIndex].ptr)
+ ((XF86RandRInfoPtr)(p)->devPrivates[xf86RandR12Index].ptr)
static int
-I830RandRModeRefresh (DisplayModePtr mode)
+xf86RandR12ModeRefresh (DisplayModePtr mode)
{
if (mode->VRefresh)
return (int) (mode->VRefresh + 0.5);
@@ -78,7 +76,7 @@ I830RandRModeRefresh (DisplayModePtr mode)
}
static Bool
-I830RandRGetInfo (ScreenPtr pScreen, Rotation *rotations)
+xf86RandR12GetInfo (ScreenPtr pScreen, Rotation *rotations)
{
RRScreenSizePtr pSize;
ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
@@ -100,7 +98,7 @@ I830RandRGetInfo (ScreenPtr pScreen, Rotation *rotations)
for (mode = scrp->modes; ; mode = mode->next)
{
- int refresh = I830RandRModeRefresh (mode);
+ int refresh = xf86RandR12ModeRefresh (mode);
if (randrp->maxX == 0 || randrp->maxY == 0)
{
if (maxX < mode->HDisplay)
@@ -154,7 +152,7 @@ I830RandRGetInfo (ScreenPtr pScreen, Rotation *rotations)
}
static Bool
-I830RandRSetMode (ScreenPtr pScreen,
+xf86RandR12SetMode (ScreenPtr pScreen,
DisplayModePtr mode,
Bool useVirtual,
int mmWidth,
@@ -243,7 +241,7 @@ I830RandRSetMode (ScreenPtr pScreen,
}
Bool
-I830RandRSetConfig (ScreenPtr pScreen,
+xf86RandR12SetConfig (ScreenPtr pScreen,
Rotation rotation,
int rate,
RRScreenSizePtr pSize)
@@ -276,7 +274,7 @@ I830RandRSetConfig (ScreenPtr pScreen,
}
if (mode->HDisplay == pSize->width &&
mode->VDisplay == pSize->height &&
- (rate == 0 || I830RandRModeRefresh (mode) == rate))
+ (rate == 0 || xf86RandR12ModeRefresh (mode) == rate))
break;
if (mode->next == scrp->modes)
{
@@ -302,7 +300,7 @@ I830RandRSetConfig (ScreenPtr pScreen,
randrp->maxY = maxY;
}
- if (!I830RandRSetMode (pScreen, mode, useVirtual, pSize->mmWidth,
+ if (!xf86RandR12SetMode (pScreen, mode, useVirtual, pSize->mmWidth,
pSize->mmHeight)) {
randrp->rotation = oldRotation;
return FALSE;
@@ -325,7 +323,7 @@ I830RandRSetConfig (ScreenPtr pScreen,
}
Rotation
-I830GetRotation(ScreenPtr pScreen)
+xf86RandR12GetRotation(ScreenPtr pScreen)
{
XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
@@ -333,19 +331,23 @@ I830GetRotation(ScreenPtr pScreen)
}
Bool
-I830RandRCreateScreenResources (ScreenPtr pScreen)
+xf86RandR12CreateScreenResources (ScreenPtr pScreen)
{
+#if 0
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- I830Ptr pI830 = I830PTR(pScrn);
+ I830Ptr pI830 = I830PTR(pScrn);
+#endif
#ifdef PANORAMIX
/* XXX disable RandR when using Xinerama */
if (!noPanoramiXExtension)
return TRUE;
#endif
#if RANDR_12_INTERFACE
- if (I830RandRCreateScreenResources12 (pScreen))
+ if (xf86RandR12CreateScreenResources12 (pScreen))
return TRUE;
#endif
+#if 0
+ /* XXX deal with initial rotation */
if (pI830->rotation != RR_Rotate_0) {
RRScreenSize p;
Rotation requestedRotation = pI830->rotation;
@@ -359,15 +361,16 @@ I830RandRCreateScreenResources (ScreenPtr pScreen)
p.mmHeight = pScreen->mmHeight;
pI830->starting = TRUE; /* abuse this for dual head & rotation */
- I830RandRSetConfig (pScreen, requestedRotation, 0, &p);
+ xf86RandR12SetConfig (pScreen, requestedRotation, 0, &p);
pI830->starting = FALSE;
}
+#endif
return TRUE;
}
Bool
-I830RandRInit (ScreenPtr pScreen, int rotation)
+xf86RandR12Init (ScreenPtr pScreen)
{
rrScrPrivPtr rp;
XF86RandRInfoPtr randrp;
@@ -377,10 +380,10 @@ I830RandRInit (ScreenPtr pScreen, int rotation)
if (!noPanoramiXExtension)
return TRUE;
#endif
- if (i830RandRGeneration != serverGeneration)
+ if (xf86RandR12Generation != serverGeneration)
{
- i830RandRIndex = AllocateScreenPrivateIndex();
- i830RandRGeneration = serverGeneration;
+ xf86RandR12Index = AllocateScreenPrivateIndex();
+ xf86RandR12Generation = serverGeneration;
}
randrp = xalloc (sizeof (XF86RandRInfoRec));
@@ -393,8 +396,8 @@ I830RandRInit (ScreenPtr pScreen, int rotation)
return FALSE;
}
rp = rrGetScrPriv(pScreen);
- rp->rrGetInfo = I830RandRGetInfo;
- rp->rrSetConfig = I830RandRSetConfig;
+ rp->rrGetInfo = xf86RandR12GetInfo;
+ rp->rrSetConfig = xf86RandR12SetConfig;
randrp->virtualX = -1;
randrp->virtualY = -1;
@@ -403,25 +406,33 @@ I830RandRInit (ScreenPtr pScreen, int rotation)
randrp->rotation = RR_Rotate_0; /* initial rotated mode */
- randrp->supported_rotations = rotation;
+ randrp->supported_rotations = RR_Rotate_0;
randrp->maxX = randrp->maxY = 0;
- pScreen->devPrivates[i830RandRIndex].ptr = randrp;
+ pScreen->devPrivates[xf86RandR12Index].ptr = randrp;
#if RANDR_12_INTERFACE
- if (!I830RandRInit12 (pScreen))
+ if (!xf86RandR12Init12 (pScreen))
return FALSE;
#endif
return TRUE;
}
void
-I830GetOriginalVirtualSize(ScrnInfoPtr pScrn, int *x, int *y)
+xf86RandR12SetRotations (ScreenPtr pScreen, Rotation rotations)
+{
+ XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+
+ randrp->supported_rotations = rotations;
+}
+
+void
+xf86RandR12GetOriginalVirtualSize(ScrnInfoPtr pScrn, int *x, int *y)
{
ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
- if (i830RandRGeneration != serverGeneration ||
+ if (xf86RandR12Generation != serverGeneration ||
XF86RANDRINFO(pScreen)->virtualX == -1)
{
*x = pScrn->virtualX;
@@ -436,7 +447,7 @@ I830GetOriginalVirtualSize(ScrnInfoPtr pScrn, int *x, int *y)
#if RANDR_12_INTERFACE
static Bool
-I830RandRScreenSetSize (ScreenPtr pScreen,
+xf86RandR12ScreenSetSize (ScreenPtr pScreen,
CARD16 width,
CARD16 height,
CARD32 mmWidth,
@@ -472,155 +483,131 @@ I830RandRScreenSetSize (ScreenPtr pScreen,
}
static Bool
-I830RandRCrtcNotify (RRCrtcPtr crtc)
+xf86RandR12CrtcNotify (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;
+ xf86CrtcPtr crtc = randr_crtc->devPrivate;
+ 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;
- for (i = 0; i < pI830->num_outputs; i++)
+ randr_mode = NULL;
+ for (i = 0; i < pI830->xf86_config.num_output; i++)
{
- output = &pI830->output[i];
- if (output->enabled && output->pipe == pipe)
+ output = pI830->xf86_config.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 (xf86ModesEqual(pipeMode, outMode))
+ DisplayModePtr outMode = randr_output->modes[j]->devPrivate;
+ if (xf86ModesEqual(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,
+xf86RandR12CrtcSet (ScreenPtr pScreen,
+ 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;
+ 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;
+ xf86CrtcPtr save_crtcs[MAX_OUTPUTS];
+ Bool save_enabled = crtc->enabled;
- if (display_mode != randrp->modes[pipe])
- {
+ if (!xf86ModesEqual (&crtc->curMode, mode))
changed = TRUE;
- if (!display_mode)
- disable = TRUE;
- }
- for (o = 0; o < pI830->num_outputs; o++)
+ for (o = 0; o < pI830->xf86_config.num_output; o++)
{
- I830OutputPtr output = &pI830->output[o];
- RROutputPtr randr_output = NULL;
+ xf86OutputPtr output = pI830->xf86_config.output[o];
+ 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;
- for (o = 0; o < pI830->num_outputs; o++)
+ crtc->enabled = save_enabled;
+ for (o = 0; o < pI830->xf86_config.num_output; o++)
{
- I830OutputPtr output = &pI830->output[o];
- output->enabled = save_output[o].enabled;
- output->pipe = save_output[o].pipe;
+ xf86OutputPtr output = pI830->xf86_config.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 xf86RandR12CrtcNotify (randr_crtc);
}
static Bool
-I830RandRCrtcSetGamma (ScreenPtr pScreen,
+xf86RandR12CrtcSetGamma (ScreenPtr pScreen,
RRCrtcPtr crtc)
{
return FALSE;
@@ -690,29 +677,27 @@ I830xf86RROutputSetModes (RROutputPtr randr_output, DisplayModePtr modes)
* Mirror the current mode configuration to RandR
*/
static Bool
-I830RandRSetInfo12 (ScrnInfoPtr pScrn)
+xf86RandR12SetInfo12 (ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(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++)
+ for (o = 0; o < pI830->xf86_config.num_output; o++)
{
- output = &pI830->output[o];
- randr_output = output->randr_output;
+ xf86OutputPtr output = pI830->xf86_config.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)|
@@ -747,12 +732,12 @@ I830RandRSetInfo12 (ScrnInfoPtr pScrn)
break;
}
ncrtc = 0;
- for (p = 0; p < pI830->num_pipes; p++)
+ for (p = 0; p < pI830->xf86_config.num_crtc; p++)
if (crtc_types & (1 << p))
- crtcs[ncrtc++] = pI830->pipes[p].randr_crtc;
+ crtcs[ncrtc++] = pI830->xf86_config.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 +750,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;
@@ -783,10 +768,13 @@ I830RandRSetInfo12 (ScrnInfoPtr pScrn)
* Valid clones
*/
nclone = 0;
- for (c = 0; c < pI830->num_outputs; c++)
+ for (c = 0; c < pI830->xf86_config.num_output; c++)
{
- if (o != c && ((1 << pI830->output[c].type) & clone_types))
- clones[nclone++] = pI830->output[c].randr_output;
+ xf86OutputPtr clone = pI830->xf86_config.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;
@@ -799,53 +787,38 @@ I830RandRSetInfo12 (ScrnInfoPtr pScrn)
* that to RandR
*/
static Bool
-I830RandRGetInfo12 (ScreenPtr pScreen, Rotation *rotations)
+xf86RandR12GetInfo12 (ScreenPtr pScreen, Rotation *rotations)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
i830_reprobe_output_modes(pScrn);
- return I830RandRSetInfo12 (pScrn);
+ return xf86RandR12SetInfo12 (pScrn);
}
static Bool
-I830RandRCreateObjects12 (ScrnInfoPtr pScrn)
+xf86RandR12CreateObjects12 (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++)
+ for (p = 0; p < pI830->xf86_config.num_crtc; p++)
{
- I830PipePtr pipe = &pI830->pipes[p];
- RRCrtcPtr randr_crtc = RRCrtcCreate ((void *) p);
+ xf86CrtcPtr crtc = pI830->xf86_config.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;
}
static Bool
-I830RandRCreateScreenResources12 (ScreenPtr pScreen)
+xf86RandR12CreateScreenResources12 (ScreenPtr pScreen)
{
XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
@@ -856,27 +829,28 @@ I830RandRCreateScreenResources12 (ScreenPtr pScreen)
/*
* Attach RandR objects to screen
*/
- for (p = 0; p < pI830->num_pipes; p++)
- if (!RRCrtcAttachScreen (pI830->pipes[p].randr_crtc, pScreen))
+ for (p = 0; p < pI830->xf86_config.num_crtc; p++)
+ if (!RRCrtcAttachScreen (pI830->xf86_config.crtc[p]->randr_crtc, pScreen))
return FALSE;
- for (o = 0; o < pI830->num_outputs; o++)
- if (!RROutputAttachScreen (pI830->output[o].randr_output, pScreen))
+ for (o = 0; o < pI830->xf86_config.num_output; o++)
+ if (!RROutputAttachScreen (pI830->xf86_config.output[o]->randr_output, pScreen))
return FALSE;
/*
* Compute width of screen
*/
width = 0; height = 0;
- for (p = 0; p < pI830->num_pipes; p++)
+ for (p = 0; p < pI830->xf86_config.num_crtc; 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;
+ xf86CrtcPtr crtc = pI830->xf86_config.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)
@@ -892,15 +866,15 @@ I830RandRCreateScreenResources12 (ScreenPtr pScreen)
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Setting screen physical size to %d x %d\n",
mmWidth, mmHeight);
- I830RandRScreenSetSize (pScreen,
+ xf86RandR12ScreenSetSize (pScreen,
width,
height,
mmWidth,
mmHeight);
}
- for (p = 0; p < pI830->num_pipes; p++)
- I830RandRCrtcNotify (pI830->pipes[p].randr_crtc);
+ for (p = 0; p < pI830->xf86_config.num_crtc; p++)
+ xf86RandR12CrtcNotify (pI830->xf86_config.crtc[p]->randr_crtc);
if (randrp->virtualX == -1 || randrp->virtualY == -1)
{
@@ -914,22 +888,22 @@ I830RandRCreateScreenResources12 (ScreenPtr pScreen)
}
static void
-I830RandRPointerMoved (int scrnIndex, int x, int y)
+xf86RandR12PointerMoved (int scrnIndex, int x, int y)
{
}
static Bool
-I830RandRInit12 (ScreenPtr pScreen)
+xf86RandR12Init12 (ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
rrScrPrivPtr rp = rrGetScrPriv(pScreen);
- rp->rrGetInfo = I830RandRGetInfo12;
- rp->rrScreenSetSize = I830RandRScreenSetSize;
- rp->rrCrtcSet = I830RandRCrtcSet;
- rp->rrCrtcSetGamma = I830RandRCrtcSetGamma;
+ rp->rrGetInfo = xf86RandR12GetInfo12;
+ rp->rrScreenSetSize = xf86RandR12ScreenSetSize;
+ rp->rrCrtcSet = xf86RandR12CrtcSet;
+ rp->rrCrtcSetGamma = xf86RandR12CrtcSetGamma;
rp->rrSetConfig = NULL;
- pScrn->PointerMoved = I830RandRPointerMoved;
+ pScrn->PointerMoved = xf86RandR12PointerMoved;
return TRUE;
}
@@ -1003,7 +977,7 @@ static int
I830RRPickCrtcs (RROutputPtr *outputs,
RRCrtcPtr *best_crtcs,
RRModePtr *modes,
- int num_outputs,
+ int num_output,
int n)
{
int c, o, l;
@@ -1015,7 +989,7 @@ I830RRPickCrtcs (RROutputPtr *outputs,
int score;
int my_score;
- if (n == num_outputs)
+ if (n == num_output)
return 0;
output = outputs[n];
@@ -1024,11 +998,11 @@ I830RRPickCrtcs (RROutputPtr *outputs,
*/
best_crtcs[n] = NULL;
best_crtc = NULL;
- best_score = I830RRPickCrtcs (outputs, best_crtcs, modes, num_outputs, n+1);
+ best_score = I830RRPickCrtcs (outputs, best_crtcs, modes, num_output, n+1);
if (modes[n] == NULL)
return best_score;
- crtcs = xalloc (num_outputs * sizeof (RRCrtcPtr));
+ crtcs = xalloc (num_output * sizeof (RRCrtcPtr));
if (!crtcs)
return best_score;
@@ -1074,12 +1048,12 @@ I830RRPickCrtcs (RROutputPtr *outputs,
crtcs[n] = crtc;
memcpy (crtcs, best_crtcs, n * sizeof (RRCrtcPtr));
score = my_score + I830RRPickCrtcs (outputs, crtcs, modes,
- num_outputs, n+1);
+ num_output, n+1);
if (score >= best_score)
{
best_crtc = crtc;
best_score = score;
- memcpy (best_crtcs, crtcs, num_outputs * sizeof (RRCrtcPtr));
+ memcpy (best_crtcs, crtcs, num_output * sizeof (RRCrtcPtr));
}
}
xfree (crtcs);
@@ -1090,18 +1064,18 @@ static Bool
I830RRInitialConfiguration (RROutputPtr *outputs,
RRCrtcPtr *crtcs,
RRModePtr *modes,
- int num_outputs)
+ int num_output)
{
int o;
RRModePtr target_mode = NULL;
- for (o = 0; o < num_outputs; o++)
+ for (o = 0; o < num_output; o++)
modes[o] = NULL;
/*
* Let outputs with preferred modes drive screen size
*/
- for (o = 0; o < num_outputs; o++)
+ for (o = 0; o < num_output; o++)
{
RROutputPtr output = outputs[o];
@@ -1117,7 +1091,7 @@ I830RRInitialConfiguration (RROutputPtr *outputs,
}
if (!target_mode)
{
- for (o = 0; o < num_outputs; o++)
+ for (o = 0; o < num_output; o++)
{
RROutputPtr output = outputs[o];
if (output->connection != RR_Disconnected)
@@ -1131,7 +1105,7 @@ I830RRInitialConfiguration (RROutputPtr *outputs,
}
}
}
- for (o = 0; o < num_outputs; o++)
+ for (o = 0; o < num_output; o++)
{
RROutputPtr output = outputs[o];
@@ -1139,7 +1113,7 @@ I830RRInitialConfiguration (RROutputPtr *outputs,
modes[o] = I830ClosestMode (output, target_mode);
}
- if (!I830RRPickCrtcs (outputs, crtcs, modes, num_outputs, 0))
+ if (!I830RRPickCrtcs (outputs, crtcs, modes, num_output, 0))
return FALSE;
return TRUE;
@@ -1151,7 +1125,7 @@ I830RRInitialConfiguration (RROutputPtr *outputs,
*/
static void
-I830RRDefaultScreenLimits (RROutputPtr *outputs, int num_outputs,
+I830RRDefaultScreenLimits (RROutputPtr *outputs, int num_output,
RRCrtcPtr *crtcs, int num_crtc,
int *widthp, int *heightp)
{
@@ -1166,7 +1140,7 @@ I830RRDefaultScreenLimits (RROutputPtr *outputs, int num_outputs,
RRCrtcPtr crtc = crtcs[c];
int crtc_width = 1600, crtc_height = 1200;
- for (o = 0; o < num_outputs; o++)
+ for (o = 0; o < num_output; o++)
{
RROutputPtr output = outputs[o];
@@ -1195,7 +1169,7 @@ I830RRDefaultScreenLimits (RROutputPtr *outputs, int num_outputs,
#endif
Bool
-I830RandRPreInit (ScrnInfoPtr pScrn)
+xf86RandR12PreInit (ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(pScrn);
#if RANDR_12_INTERFACE
@@ -1208,35 +1182,35 @@ I830RandRPreInit (ScrnInfoPtr pScrn)
int c;
#endif
- if (pI830->num_outputs <= 0)
+ if (pI830->xf86_config.num_output <= 0)
return FALSE;
i830_reprobe_output_modes(pScrn);
#if RANDR_12_INTERFACE
- if (!I830RandRCreateObjects12 (pScrn))
+ if (!xf86RandR12CreateObjects12 (pScrn))
return FALSE;
/*
* Configure output modes
*/
- if (!I830RandRSetInfo12 (pScrn))
+ if (!xf86RandR12SetInfo12 (pScrn))
return FALSE;
/*
* With RandR info set up, let RandR choose
* the initial configuration
*/
- for (o = 0; o < pI830->num_outputs; o++)
- outputs[o] = pI830->output[o].randr_output;
- for (c = 0; c < pI830->num_pipes; c++)
- crtcs[c] = pI830->pipes[c].randr_crtc;
+ for (o = 0; o < pI830->xf86_config.num_output; o++)
+ outputs[o] = pI830->xf86_config.output[o]->randr_output;
+ for (c = 0; c < pI830->xf86_config.num_crtc; c++)
+ crtcs[c] = pI830->xf86_config.crtc[c]->randr_crtc;
if (!I830RRInitialConfiguration (outputs, output_crtcs, output_modes,
- pI830->num_outputs))
+ pI830->xf86_config.num_output))
return FALSE;
- I830RRDefaultScreenLimits (outputs, pI830->num_outputs,
- crtcs, pI830->num_pipes,
+ I830RRDefaultScreenLimits (outputs, pI830->xf86_config.num_output,
+ crtcs, pI830->xf86_config.num_crtc,
&width, &height);
if (width > pScrn->virtualX)
@@ -1251,32 +1225,21 @@ I830RandRPreInit (ScrnInfoPtr pScrn)
/* XXX override xf86 common frame computation code */
pScrn->display->frameX0 = 0;
pScrn->display->frameY0 = 0;
- for (o = 0; o < pI830->num_outputs; o++)
+ for (o = 0; o < pI830->xf86_config.num_output; o++)
{
- RRModePtr randr_mode = output_modes[o];
- DisplayModePtr mode;
- RRCrtcPtr randr_crtc = output_crtcs[o];
- int pipe;
- Bool enabled;
+ xf86OutputPtr output = pI830->xf86_config.output[o];
+ RRModePtr randr_mode = output_modes[o];
+ RRCrtcPtr randr_crtc = output_crtcs[o];
+ DisplayModePtr mode;
- if (randr_mode)
- mode = (DisplayModePtr) randr_mode->devPrivate;
- else
- mode = NULL;
- if (randr_crtc)
+ if (randr_mode && randr_crtc)
{
- pipe = (int) randr_crtc->devPrivate;
- enabled = TRUE;
- }
- else
- {
- pipe = 0;
- enabled = FALSE;
+ xf86CrtcPtr crtc = randr_crtc->devPrivate;
+
+ mode = (DisplayModePtr) randr_mode->devPrivate;
+ crtc->desiredMode = *mode;
+ output->crtc = crtc;
}
- if (mode)
- pI830->pipes[pipe].desiredMode = *mode;
- pI830->output[o].pipe = pipe;
- pI830->output[o].enabled = enabled;
}
#endif
i830_set_xf86_modes_from_outputs (pScrn);
diff --git a/src/i830_randr.h b/src/i830_randr.h
new file mode 100644
index 00000000..8a4668b4
--- /dev/null
+++ b/src/i830_randr.h
@@ -0,0 +1,37 @@
+/*
+ * 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 _XF86_RANDR_H_
+#define _XF86_RANDR_H_
+#include <randrstr.h>
+#include <X11/extensions/render.h>
+
+Bool xf86RandR12CreateScreenResources (ScreenPtr pScreen);
+Bool xf86RandR12Init(ScreenPtr pScreen);
+void xf86RandR12SetRotations (ScreenPtr pScreen, Rotation rotation);
+Bool xf86RandR12SetConfig(ScreenPtr pScreen, Rotation rotation, int rate,
+ RRScreenSizePtr pSize);
+Rotation xf86RandR12GetRotation(ScreenPtr pScreen);
+void xf86RandR12GetOriginalVirtualSize(ScrnInfoPtr pScrn, int *x, int *y);
+Bool xf86RandR12PreInit (ScrnInfoPtr pScrn);
+
+#endif /* _XF86_RANDR_H_ */
diff --git a/src/i830_rotate.c b/src/i830_rotate.c
index 131930e9..9fa3290a 100644
--- a/src/i830_rotate.c
+++ b/src/i830_rotate.c
@@ -677,7 +677,7 @@ I830Rotate(ScrnInfoPtr pScrn, DisplayModePtr mode)
pScrn2 = pScrn;
}
- pI830->rotation = I830GetRotation(pScrn->pScreen);
+ pI830->rotation = xf86RandR12GetRotation(pScrn->pScreen);
/* Check if we've still got the same orientation, or same mode */
if (pI830->rotation == oldRotation && pI830->currentMode == mode)
diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c
index ebf5868c..aa061828 100644
--- a/src/i830_sdvo.c
+++ b/src/i830_sdvo.c
@@ -80,39 +80,42 @@ 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(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 0x%02x.\n",
- output->pI2CBus->BusName, dev_priv->d.SlaveAddr);
+ intel_output->pI2CBus->BusName, dev_priv->d.SlaveAddr);
return FALSE;
}
return TRUE;
}
/** Read a single byte from the given address on the SDVO device. */
-static Bool i830_sdvo_read_byte_quiet(I830OutputPtr output, int addr,
+static Bool i830_sdvo_read_byte_quiet(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;
return xf86I2CReadByte(&dev_priv->d, addr, ch);
}
/** 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(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,
- "Unable to write to %s Slave %02x.\n",
- output->pI2CBus->BusName, dev_priv->d.SlaveAddr);
+ xf86DrvMsg(intel_output->pI2CBus->scrnIndex, X_ERROR,
+ "Unable to write to %s Slave 0x%02x.\n",
+ intel_output->pI2CBus->BusName, dev_priv->d.SlaveAddr);
return FALSE;
}
return TRUE;
@@ -173,16 +176,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(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++)
@@ -219,10 +223,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(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++) {
@@ -234,8 +239,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++)
@@ -267,13 +272,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(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(xf86OutputPtr output, Bool target_0, Bool target_1)
{
struct i830_sdvo_set_target_input_args targets = {0};
CARD8 status;
@@ -299,7 +304,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(xf86OutputPtr output, Bool *input_1, Bool *input_2)
{
struct i830_sdvo_get_trained_inputs_response response;
CARD8 status;
@@ -317,7 +322,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(xf86OutputPtr output,
CARD16 *outputs)
{
CARD8 status;
@@ -329,7 +334,7 @@ i830_sdvo_get_active_outputs(I830OutputPtr output,
}
static Bool
-i830_sdvo_set_active_outputs(I830OutputPtr output,
+i830_sdvo_set_active_outputs(xf86OutputPtr output,
CARD16 outputs)
{
CARD8 status;
@@ -345,7 +350,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(xf86OutputPtr output, int *clock_min,
int *clock_max)
{
struct i830_sdvo_pixel_clock_range clocks;
@@ -366,7 +371,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(xf86OutputPtr output, CARD16 outputs)
{
CARD8 status;
@@ -380,7 +385,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(xf86OutputPtr output, CARD8 cmd, struct i830_sdvo_dtd *dtd)
{
CARD8 status;
@@ -400,20 +405,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(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(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(xf86OutputPtr output, CARD8 cmd, struct i830_sdvo_dtd *dtd)
{
CARD8 status;
@@ -431,20 +436,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(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(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(xf86OutputPtr output, CARD16 clock,
CARD16 width, CARD16 height)
{
struct i830_sdvo_priv *dev_priv = output->dev_priv;
@@ -488,9 +493,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(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;
@@ -516,7 +522,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(xf86OutputPtr output, CARD8 val)
{
CARD8 status;
@@ -529,11 +535,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(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;
@@ -630,15 +637,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(xf86OutputPtr output, DisplayModePtr mode)
{
+ ScrnInfoPtr pScrn = output->scrn;
+ I830OutputPrivatePtr intel_output = output->driver_private;
+ struct i830_sdvo_priv *dev_priv = intel_output->dev_priv;
+ 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;
@@ -654,7 +664,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);
@@ -690,10 +700,12 @@ i830_sdvo_post_set_mode(ScrnInfoPtr pScrn, I830OutputPtr output,
}
static void
-i830_sdvo_dpms(ScrnInfoPtr pScrn, I830OutputPtr output, int mode)
+i830_sdvo_dpms(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);
@@ -705,11 +717,13 @@ i830_sdvo_dpms(ScrnInfoPtr pScrn, I830OutputPtr output, int mode)
}
static void
-i830_sdvo_save(ScrnInfoPtr pScrn, I830OutputPtr output)
+i830_sdvo_save(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. */
@@ -740,11 +754,13 @@ i830_sdvo_save(ScrnInfoPtr pScrn, I830OutputPtr output)
}
static void
-i830_sdvo_restore(ScrnInfoPtr pScrn, I830OutputPtr output)
+i830_sdvo_restore(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);
@@ -773,10 +789,10 @@ i830_sdvo_restore(ScrnInfoPtr pScrn, I830OutputPtr output)
}
static int
-i830_sdvo_mode_valid(ScrnInfoPtr pScrn, I830OutputPtr output,
- DisplayModePtr pMode)
+i830_sdvo_mode_valid(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;
@@ -791,7 +807,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(xf86OutputPtr output, struct i830_sdvo_caps *caps)
{
CARD8 status;
@@ -807,9 +823,10 @@ i830_sdvo_get_capabilities(I830OutputPtr output, struct i830_sdvo_caps *caps)
static Bool
i830_sdvo_ddc_i2c_get_byte(I2CDevPtr d, I2CByte *data, Bool last)
{
- I830OutputPtr output = d->pI2CBus->DriverPrivate.ptr;
- I2CBusPtr i2cbus = output->pI2CBus, savebus;
- Bool ret;
+ xf86OutputPtr output = d->DriverPrivate.ptr;
+ I830OutputPrivatePtr intel_output = output->driver_private;
+ I2CBusPtr i2cbus = intel_output->pI2CBus, savebus;
+ Bool ret;
savebus = d->pI2CBus;
d->pI2CBus = i2cbus;
@@ -823,9 +840,10 @@ i830_sdvo_ddc_i2c_get_byte(I2CDevPtr d, I2CByte *data, Bool last)
static Bool
i830_sdvo_ddc_i2c_put_byte(I2CDevPtr d, I2CByte c)
{
- I830OutputPtr output = d->pI2CBus->DriverPrivate.ptr;
- I2CBusPtr i2cbus = output->pI2CBus, savebus;
- Bool ret;
+ xf86OutputPtr output = d->DriverPrivate.ptr;
+ I830OutputPrivatePtr intel_output = output->driver_private;
+ I2CBusPtr i2cbus = intel_output->pI2CBus, savebus;
+ Bool ret;
savebus = d->pI2CBus;
d->pI2CBus = i2cbus;
@@ -845,8 +863,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;
+ 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);
@@ -856,8 +875,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;
+ xf86OutputPtr output = d->DriverPrivate.ptr;
+ I830OutputPrivatePtr intel_output = output->driver_private;
+ I2CBusPtr i2cbus = intel_output->pI2CBus, savebus;
savebus = d->pI2CBus;
d->pI2CBus = i2cbus;
@@ -892,18 +912,19 @@ i830_sdvo_ddc_i2c_address(I2CDevPtr d, I2CSlaveAddr addr)
}
static void
-i830_sdvo_dump_cmd(I830OutputPtr output, int opcode)
+i830_sdvo_dump_cmd(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(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);
@@ -935,9 +956,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->xf86_config.num_output; i++)
+ {
+ xf86OutputPtr output = pI830->xf86_config.output[i];
+ I830OutputPrivatePtr intel_output = output->driver_private;
+
+ if (intel_output->type == I830_OUTPUT_SDVO)
+ i830_sdvo_dump_device(output);
}
}
@@ -951,7 +976,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(xf86OutputPtr output)
{
CARD8 response[2];
CARD8 status;
@@ -968,25 +993,59 @@ i830_sdvo_detect(ScrnInfoPtr pScrn, I830OutputPtr output)
return OUTPUT_STATUS_DISCONNECTED;
}
+static void
+i830_sdvo_destroy (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 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;
+ xf86OutputPtr output;
+ I830OutputPrivatePtr intel_output;
+ struct i830_sdvo_priv *dev_priv;
+ int i;
+ unsigned char ch[0x40];
+ I2CBusPtr i2cbus = NULL, ddcbus;
+
+ output = xf86OutputCreate (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)
+ {
+ xf86OutputDestroy (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.
@@ -997,12 +1056,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);
+ {
+ xf86OutputDestroy (output);
return;
}
@@ -1017,17 +1072,17 @@ 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);
+ xf86OutputDestroy (output);
return;
}
- output->pI2CBus = i2cbus;
- output->dev_priv = dev_priv;
+ intel_output->pI2CBus = i2cbus;
+ intel_output->dev_priv = dev_priv;
/* Read the regs to test if we can talk to the device */
for (i = 0; i < 0x40; i++) {
@@ -1035,9 +1090,7 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"No SDVO device found on SDVO%c\n",
output_device == SDVOB ? 'B' : 'C');
- xf86DestroyI2CDevRec(&dev_priv->d, FALSE);
- xf86DestroyI2CBusRec(i2cbus, TRUE, TRUE);
- xfree(dev_priv);
+ xf86OutputDestroy (output);
return;
}
}
@@ -1048,10 +1101,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)
+ {
+ xf86OutputDestroy (output);
return;
}
if (output_device == SDVOB)
@@ -1064,14 +1116,17 @@ 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))
+ {
+ xf86OutputDestroy (output);
return;
}
- output->pDDCBus = ddcbus;
+
+ intel_output->pI2CBus = i2cbus;
+ intel_output->pDDCBus = ddcbus;
+ intel_output->dev_priv = dev_priv;
i830_sdvo_get_capabilities(output, &dev_priv->caps);
@@ -1085,7 +1140,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]);
@@ -1111,6 +1166,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..f7d92072 100644
--- a/src/i830_tv.c
+++ b/src/i830_tv.c
@@ -38,6 +38,7 @@
#include "i830_display.h"
enum tv_type {
+ TV_TYPE_NONE,
TV_TYPE_UNKNOWN,
TV_TYPE_COMPOSITE,
TV_TYPE_SVIDEO,
@@ -46,6 +47,7 @@ enum tv_type {
/** Private structure for the integrated TV support */
struct i830_tv_priv {
+ int type;
CARD32 save_TV_H_CTL_1;
CARD32 save_TV_H_CTL_2;
CARD32 save_TV_H_CTL_3;
@@ -141,67 +143,10 @@ const struct tv_mode {
}
};
-
-static int
-i830_tv_detect_type(ScrnInfoPtr pScrn, I830OutputPtr output)
-{
- 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);
-
- /* First, we have to disable the encoder but source from the right pipe,
- * which is already enabled.
- */
- tv_ctl = INREG(TV_CTL) & ~(TV_ENC_ENABLE | TV_ENC_PIPEB_SELECT);
- if (output->pipe == 1)
- tv_ctl |= TV_ENC_PIPEB_SELECT;
- OUTREG(TV_CTL, tv_ctl);
-
- /* Then set the voltage overrides. */
- tv_dac = DAC_CTL_OVERRIDE | DAC_A_0_7_V | DAC_B_0_7_V | DAC_C_0_7_V;
- OUTREG(TV_DAC, tv_dac);
-
- /* Enable sensing of the load. */
- tv_ctl |= TV_TEST_MODE_MONITOR_DETECT;
- OUTREG(TV_CTL, tv_ctl);
-
- tv_dac |= TVDAC_STATE_CHG_EN | TVDAC_A_SENSE_CTL | TVDAC_B_SENSE_CTL |
- TVDAC_C_SENSE_CTL;
- OUTREG(TV_DAC, tv_dac);
-
- /* Wait for things to take effect. */
- i830WaitForVblank(pScrn);
-
- tv_dac = INREG(TV_DAC);
-
- OUTREG(TV_DAC, save_tv_dac);
- OUTREG(TV_CTL, save_tv_ctl);
-
- if ((tv_dac & TVDAC_SENSE_MASK) == (TVDAC_B_SENSE | TVDAC_C_SENSE)) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Detected Composite TV connection\n");
- return TV_TYPE_COMPOSITE;
- } else if ((tv_dac & TVDAC_SENSE_MASK) == TVDAC_A_SENSE) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Detected S-Video TV connection\n");
- return TV_TYPE_SVIDEO;
- } else if ((tv_dac & TVDAC_SENSE_MASK) == 0) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Detected Component TV connection\n");
- return TV_TYPE_COMPONENT;
- } else {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Couldn't detect TV connection\n");
- return TV_TYPE_UNKNOWN;
- }
-}
-
static void
-i830_tv_dpms(ScrnInfoPtr pScrn, I830OutputPtr output, int mode)
+i830_tv_dpms(xf86OutputPtr output, int mode)
{
+ ScrnInfoPtr pScrn = output->scrn;
I830Ptr pI830 = I830PTR(pScrn);
switch(mode) {
@@ -217,10 +162,12 @@ i830_tv_dpms(ScrnInfoPtr pScrn, I830OutputPtr output, int mode)
}
static void
-i830_tv_save(ScrnInfoPtr pScrn, I830OutputPtr output)
+i830_tv_save(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 +188,12 @@ i830_tv_save(ScrnInfoPtr pScrn, I830OutputPtr output)
}
static void
-i830_tv_restore(ScrnInfoPtr pScrn, I830OutputPtr output)
+i830_tv_restore(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 +214,15 @@ i830_tv_restore(ScrnInfoPtr pScrn, I830OutputPtr output)
}
static int
-i830_tv_mode_valid(ScrnInfoPtr pScrn, I830OutputPtr output,
- DisplayModePtr pMode)
+i830_tv_mode_valid(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(xf86OutputPtr output, DisplayModePtr pMode)
{
+ ScrnInfoPtr pScrn = output->scrn;
I830Ptr pI830 = I830PTR(pScrn);
/* Disable the encoder while we set up the pipe. */
@@ -348,18 +296,22 @@ static const CARD32 v_chroma[43] = {
};
static void
-i830_tv_post_set_mode(ScrnInfoPtr pScrn, I830OutputPtr output,
- DisplayModePtr pMode)
+i830_tv_post_set_mode(xf86OutputPtr output, DisplayModePtr pMode)
{
- I830Ptr pI830 = I830PTR(pScrn);
- enum tv_type type;
- const struct tv_mode *tv_mode;
+ ScrnInfoPtr pScrn = output->scrn;
+ I830Ptr pI830 = I830PTR(pScrn);
+ xf86CrtcPtr crtc = output->crtc;
+ I830OutputPrivatePtr intel_output = output->driver_private;
+ I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
+ struct i830_tv_priv *dev_priv = intel_output->dev_priv;
+ enum tv_type type;
+ const struct tv_mode *tv_mode;
const struct tv_sc_mode *sc_mode;
- CARD32 tv_ctl, tv_filter_ctl;
- CARD32 hctl1, hctl2, hctl3;
- CARD32 vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7;
- CARD32 scctl1, scctl2, scctl3;
- int i;
+ CARD32 tv_ctl, tv_filter_ctl;
+ CARD32 hctl1, hctl2, hctl3;
+ CARD32 vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7;
+ CARD32 scctl1, scctl2, scctl3;
+ int i;
/* Need to actually choose or construct the appropriate
* mode. For now, just set the first one in the list, with
@@ -368,7 +320,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 = dev_priv->type;
hctl1 = (tv_mode->hsync_end << TV_HSYNC_END_SHIFT) |
(tv_mode->htotal << TV_HTOTAL_SHIFT);
@@ -408,7 +360,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) {
@@ -494,6 +446,99 @@ i830_tv_post_set_mode(ScrnInfoPtr pScrn, I830OutputPtr output,
OUTREG(TV_CTL, tv_ctl);
}
+static const DisplayModeRec tvModes[] = {
+ {
+ .name = "NTSC 480i",
+ .Clock = 108000,
+
+ .HDisplay = 1024,
+ .HSyncStart = 1048,
+ .HSyncEnd = 1184,
+ .HTotal = 1344,
+
+ .VDisplay = 768,
+ .VSyncStart = 771,
+ .VSyncEnd = 777,
+ .VTotal = 806,
+
+ .type = M_T_DEFAULT
+ }
+};
+
+/**
+ * Detects TV presence by checking for load.
+ *
+ * Requires that the current pipe's DPLL is active.
+
+ * \return TRUE if TV is connected.
+ * \return FALSE if TV is disconnected.
+ */
+static int
+i830_tv_detect_type (xf86CrtcPtr crtc,
+ xf86OutputPtr output)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ I830Ptr pI830 = I830PTR(pScrn);
+ I830OutputPrivatePtr intel_output = output->driver_private;
+ struct i830_tv_priv *dev_priv = intel_output->dev_priv;
+ CARD32 tv_ctl, save_tv_ctl;
+ CARD32 tv_dac, save_tv_dac;
+ int type = TV_TYPE_UNKNOWN;
+
+ tv_dac = INREG(TV_DAC);
+ /*
+ * Detect TV by polling)
+ */
+ if (intel_output->load_detect_temp)
+ {
+ /* TV not currently running, prod it with destructive detect */
+ save_tv_dac = tv_dac;
+ tv_ctl = INREG(TV_CTL);
+ save_tv_ctl = tv_ctl;
+ tv_ctl &= ~TV_ENC_ENABLE;
+ tv_ctl &= ~TV_TEST_MODE_MASK;
+ tv_ctl |= TV_TEST_MODE_MONITOR_DETECT;
+ tv_dac &= ~TVDAC_SENSE_MASK;
+ tv_dac |= (TVDAC_STATE_CHG_EN |
+ TVDAC_A_SENSE_CTL |
+ TVDAC_B_SENSE_CTL |
+ TVDAC_C_SENSE_CTL);
+ tv_dac = DAC_CTL_OVERRIDE | DAC_A_0_7_V | DAC_B_0_7_V | DAC_C_0_7_V;
+ OUTREG(TV_CTL, tv_ctl);
+ OUTREG(TV_DAC, tv_dac);
+ i830WaitForVblank(pScrn);
+ tv_dac = INREG(TV_DAC);
+ OUTREG(TV_DAC, save_tv_dac);
+ OUTREG(TV_CTL, save_tv_ctl);
+ }
+ /*
+ * A B C
+ * 0 1 1 Composite
+ * 1 0 X svideo
+ * 0 0 0 Component
+ */
+ if ((tv_dac & TVDAC_SENSE_MASK) == (TVDAC_B_SENSE | TVDAC_C_SENSE)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Detected Composite TV connection\n");
+ type = TV_TYPE_COMPOSITE;
+ } else if ((tv_dac & (TVDAC_A_SENSE|TVDAC_B_SENSE)) == TVDAC_A_SENSE) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Detected S-Video TV connection\n");
+ type = TV_TYPE_SVIDEO;
+ } else if ((tv_dac & TVDAC_SENSE_MASK) == 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Detected Component TV connection\n");
+ type = TV_TYPE_COMPONENT;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Couldn't detect TV connection\n");
+ type = TV_TYPE_NONE;
+ }
+
+ dev_priv->type = type;
+ return type;
+}
+
/**
* Detect the TV connection.
*
@@ -501,9 +546,34 @@ 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(xf86OutputPtr output)
{
- return OUTPUT_STATUS_CONNECTED;
+ xf86CrtcPtr crtc;
+ DisplayModeRec mode;
+ I830OutputPrivatePtr intel_output = output->driver_private;
+ int type;
+
+ crtc = i830GetLoadDetectPipe (output);
+ if (!crtc)
+ return OUTPUT_STATUS_UNKNOWN;
+
+ if (intel_output->load_detect_temp)
+ {
+ mode = tvModes[0];
+ xf86SetModeCrtc (&mode, INTERLACE_HALVE_V);
+ i830PipeSetMode (crtc, &mode, FALSE);
+ }
+ type = i830_tv_detect_type (crtc, output);
+ i830ReleaseLoadDetectPipe (output);
+
+ switch (type) {
+ case TV_TYPE_NONE:
+ return OUTPUT_STATUS_DISCONNECTED;
+ case TV_TYPE_UNKNOWN:
+ return OUTPUT_STATUS_UNKNOWN;
+ default:
+ return OUTPUT_STATUS_CONNECTED;
+ }
}
/**
@@ -513,8 +583,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(xf86OutputPtr output)
{
+ ScrnInfoPtr pScrn = output->scrn;
I830Ptr pI830 = I830PTR(pScrn);
DisplayModePtr new;
char stmp[32];
@@ -553,36 +624,52 @@ i830_tv_get_modes(ScrnInfoPtr pScrn, I830OutputPtr output)
return new;
}
+static void
+i830_tv_destroy (xf86OutputPtr output)
+{
+ if (output->driver_private)
+ xfree (output->driver_private);
+}
+
+static const 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);
+ 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 = xf86OutputCreate (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)
+ {
+ xf86OutputDestroy (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;
+ dev_priv->type = TV_TYPE_UNKNOWN;
+
+ output->driver_private = intel_output;
}
diff --git a/src/i830_video.c b/src/i830_video.c
index 5a9c9735..a3bfda8d 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -3593,7 +3593,7 @@ I830VideoSwitchModeAfter(ScrnInfoPtr pScrn, DisplayModePtr mode)
}
/* Check we have an LFP connected */
- if (i830PipeHasType (pScrn, pPriv->pipe, I830_OUTPUT_LVDS))
+ if (i830PipeHasType (pI830->xf86_config.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..2eb775bf
--- /dev/null
+++ b/src/i830_xf86Crtc.c
@@ -0,0 +1,140 @@
+/*
+ * $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_xf86Crtc.h"
+
+/*
+ * Crtc functions
+ */
+xf86CrtcPtr
+xf86CrtcCreate (ScrnInfoPtr scrn,
+ const xf86CrtcFuncsRec *funcs)
+{
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+ xf86CrtcPtr crtc;
+
+ crtc = xcalloc (sizeof (xf86CrtcRec), 1);
+ if (!crtc)
+ return NULL;
+ crtc->scrn = scrn;
+ crtc->funcs = funcs;
+#ifdef RANDR_12_INTERFACE
+ crtc->randr_crtc = RRCrtcCreate (crtc);
+ if (!crtc->randr_crtc)
+ {
+ xfree (crtc);
+ return NULL;
+ }
+#endif
+ xf86_config->crtc[xf86_config->num_crtc++] = crtc;
+ return crtc;
+}
+
+void
+xf86CrtcDestroy (xf86CrtcPtr crtc)
+{
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
+ int c;
+
+ (*crtc->funcs->destroy) (crtc);
+#ifdef RANDR_12_INTERFACE
+ RRCrtcDestroy (crtc->randr_crtc);
+#endif
+ for (c = 0; c < xf86_config->num_crtc; c++)
+ if (xf86_config->crtc[c] == crtc)
+ {
+ memmove (&xf86_config->crtc[c],
+ &xf86_config->crtc[c+1],
+ xf86_config->num_crtc - (c + 1));
+ xf86_config->num_crtc--;
+ break;
+ }
+ xfree (crtc);
+}
+
+/*
+ * Output functions
+ */
+xf86OutputPtr
+xf86OutputCreate (ScrnInfoPtr scrn,
+ const xf86OutputFuncsRec *funcs,
+ const char *name)
+{
+ xf86OutputPtr output;
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+ int len = strlen (name);
+
+ output = xcalloc (sizeof (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
+ xf86_config->output[xf86_config->num_output++] = output;
+ return output;
+}
+
+void
+xf86OutputDestroy (xf86OutputPtr output)
+{
+ ScrnInfoPtr scrn = output->scrn;
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(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 < xf86_config->num_output; o++)
+ if (xf86_config->output[o] == output)
+ {
+ memmove (&xf86_config->output[o],
+ &xf86_config->output[o+1],
+ xf86_config->num_output - (o + 1));
+ xf86_config->num_output--;
+ break;
+ }
+ xfree (output);
+}
+
diff --git a/src/i830_xf86Crtc.h b/src/i830_xf86Crtc.h
new file mode 100644
index 00000000..2952c8d5
--- /dev/null
+++ b/src/i830_xf86Crtc.h
@@ -0,0 +1,310 @@
+/*
+ * 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 _XF86CRTC_H_
+#define _XF86CRTC_H_
+
+#include <edid.h>
+#include "randrstr.h"
+#include "i830_xf86Modes.h"
+
+typedef struct _xf86Crtc xf86CrtcRec, *xf86CrtcPtr;
+
+typedef struct _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)(xf86CrtcPtr crtc,
+ int mode);
+
+ /**
+ * Saves the crtc's state for restoration on VT switch.
+ */
+ void
+ (*save)(xf86CrtcPtr crtc);
+
+ /**
+ * Restore's the crtc's state at VT switch.
+ */
+ void
+ (*restore)(xf86CrtcPtr crtc);
+
+ /**
+ * Clean up driver-specific bits of the crtc
+ */
+ void
+ (*destroy) (xf86CrtcPtr crtc);
+} xf86CrtcFuncsRec, *xf86CrtcFuncsPtr;
+
+struct _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 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 _xf86Output xf86OutputRec, *xf86OutputPtr;
+
+typedef struct _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)(xf86OutputPtr output,
+ int mode);
+
+ /**
+ * Saves the output's state for restoration on VT switch.
+ */
+ void
+ (*save)(xf86OutputPtr output);
+
+ /**
+ * Restore's the output's state at VT switch.
+ */
+ void
+ (*restore)(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)(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)(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)(xf86OutputPtr output,
+ DisplayModePtr pMode);
+
+ /**
+ * Probe for a connected output, and return detect_status.
+ */
+ enum detect_status
+ (*detect)(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)(xf86OutputPtr output);
+
+ /**
+ * Clean up driver-specific bits of the output
+ */
+ void
+ (*destroy) (xf86OutputPtr output);
+} xf86OutputFuncsRec, *xf86OutputFuncsPtr;
+
+struct _xf86Output {
+ /**
+ * Associated ScrnInfo
+ */
+ ScrnInfoPtr scrn;
+ /**
+ * Currently connected crtc (if any)
+ *
+ * If this output is not in use, this field will be NULL.
+ */
+ 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 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
+};
+
+#define XF86_MAX_CRTC 4
+#define XF86_MAX_OUTPUT 16
+
+typedef struct _xf86CrtcConfig {
+ int num_output;
+ xf86OutputPtr output[XF86_MAX_OUTPUT];
+
+ int num_crtc;
+ xf86CrtcPtr crtc[XF86_MAX_CRTC];
+} xf86CrtcConfigRec, *xf86CrtcConfigPtr;
+
+#define XF86_CRTC_CONFIG_PTR(p) ((xf86CrtcConfigPtr) ((p)->driverPrivate))
+
+/*
+ * Crtc functions
+ */
+xf86CrtcPtr
+xf86CrtcCreate (ScrnInfoPtr scrn,
+ const xf86CrtcFuncsRec *funcs);
+
+void
+xf86CrtcDestroy (xf86CrtcPtr crtc);
+
+
+/**
+ * Allocate a crtc for the specified output
+ *
+ * Find a currently unused CRTC which is suitable for
+ * the specified output
+ */
+
+xf86CrtcPtr
+xf86AllocCrtc (xf86OutputPtr output);
+
+/**
+ * Free a crtc
+ *
+ * Mark the crtc as unused by any outputs
+ */
+
+void
+xf86FreeCrtc (xf86CrtcPtr crtc);
+
+/*
+ * Output functions
+ */
+xf86OutputPtr
+xf86OutputCreate (ScrnInfoPtr scrn,
+ const xf86OutputFuncsRec *funcs,
+ const char *name);
+
+void
+xf86OutputDestroy (xf86OutputPtr output);
+
+#endif /* _XF86CRTC_H_ */
diff --git a/src/i830_xf86Modes.c b/src/i830_xf86Modes.c
index 809acf50..c091aef7 100644
--- a/src/i830_xf86Modes.c
+++ b/src/i830_xf86Modes.c
@@ -526,3 +526,27 @@ i830xf86PruneInvalidModes(ScrnInfoPtr pScrn, DisplayModePtr *modeList,
mode = next;
}
}
+
+/**
+ * Adds the new mode into the mode list, and returns the new list
+ *
+ * \param modes doubly-linked mode list.
+ */
+DisplayModePtr
+xf86ModesAdd(DisplayModePtr modes, DisplayModePtr new)
+{
+ if (modes == NULL)
+ return new;
+
+ if (new) {
+ DisplayModePtr mode = modes;
+
+ while (mode->next)
+ mode = mode->next;
+
+ mode->next = new;
+ new->prev = mode;
+ }
+
+ return modes;
+}
diff --git a/src/i830_xf86Modes.h b/src/i830_xf86Modes.h
index d057ef53..3bd8557d 100644
--- a/src/i830_xf86Modes.h
+++ b/src/i830_xf86Modes.h
@@ -25,6 +25,8 @@
*
*/
+#ifndef _I830_XF86MODES_H_
+#define _I830_XF86MODES_H_
#include "xorgVersion.h"
#if XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,1,99,2,0)
@@ -37,6 +39,8 @@ void i830_xf86SetModeDefaultName(DisplayModePtr mode);
void i830_xf86SetModeCrtc(DisplayModePtr p, int adjustFlags);
Bool i830_xf86ModesEqual(DisplayModePtr pMode1, DisplayModePtr pMode2);
void i830_xf86PrintModeline(int scrnIndex,DisplayModePtr mode);
+DisplayModePtr i830_xf86ModesAdd(DisplayModePtr modes, DisplayModePtr new);
+
#define xf86ModeHSync i830_xf86ModeHSync
#define xf86ModeVRefresh i830_xf86ModeVRefresh
#define xf86DuplicateMode i830_xf86DuplicateMode
@@ -45,6 +49,7 @@ void i830_xf86PrintModeline(int scrnIndex,DisplayModePtr mode);
#define xf86SetModeCrtc i830_xf86SetModeCrtc
#define xf86ModesEqual i830_xf86ModesEqual
#define xf86PrintModeline i830_xf86PrintModeline
+#define xf86ModesAdd i830_xf86ModesAdd
#endif /* XORG_VERSION_CURRENT <= 7.1.99.2 */
void
@@ -73,3 +78,5 @@ i830xf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList,
void
i830xf86ValidateModesUserConfig(ScrnInfoPtr pScrn, DisplayModePtr modeList);
+
+#endif /* _I830_XF86MODES_H_ */