diff options
author | Keith Packard <keithp@neko.keithp.com> | 2006-11-30 14:09:31 -0800 |
---|---|---|
committer | Keith Packard <keithp@neko.keithp.com> | 2006-11-30 14:09:31 -0800 |
commit | ff64bc7397cafbec94e388e1625b3a1999f1aca7 (patch) | |
tree | fdd9d519c382e39dd02be9fad341f31e668a047f | |
parent | b94b7c4bcfdb7ba59ed818f72309b5060a2ab7ee (diff) | |
parent | 16e01b117bb7ae90b150dd4f25a887dd895cf473 (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.
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/i810_reg.h | 1 | ||||
-rw-r--r-- | src/i830.h | 136 | ||||
-rw-r--r-- | src/i830_crt.c | 188 | ||||
-rw-r--r-- | src/i830_cursor.c | 104 | ||||
-rw-r--r-- | src/i830_display.c | 271 | ||||
-rw-r--r-- | src/i830_display.h | 14 | ||||
-rw-r--r-- | src/i830_dri.c | 8 | ||||
-rw-r--r-- | src/i830_driver.c | 183 | ||||
-rw-r--r-- | src/i830_dvo.c | 145 | ||||
-rw-r--r-- | src/i830_lvds.c | 93 | ||||
-rw-r--r-- | src/i830_modes.c | 73 | ||||
-rw-r--r-- | src/i830_randr.c | 407 | ||||
-rw-r--r-- | src/i830_randr.h | 37 | ||||
-rw-r--r-- | src/i830_rotate.c | 2 | ||||
-rw-r--r-- | src/i830_sdvo.c | 295 | ||||
-rw-r--r-- | src/i830_tv.c | 299 | ||||
-rw-r--r-- | src/i830_video.c | 2 | ||||
-rw-r--r-- | src/i830_xf86Crtc.c | 140 | ||||
-rw-r--r-- | src/i830_xf86Crtc.h | 310 | ||||
-rw-r--r-- | src/i830_xf86Modes.c | 24 | ||||
-rw-r--r-- | src/i830_xf86Modes.h | 7 |
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 @@ -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_ */ |