diff options
-rw-r--r-- | src/Makefile.am | 8 | ||||
-rw-r--r-- | src/local_xf86Rename.h | 23 | ||||
-rw-r--r-- | src/radeon.h | 52 | ||||
-rw-r--r-- | src/radeon_cursor.c | 204 | ||||
-rw-r--r-- | src/radeon_display.c | 1197 | ||||
-rw-r--r-- | src/radeon_driver.c | 1329 | ||||
-rw-r--r-- | src/radeon_mergedfb.c | 2089 | ||||
-rw-r--r-- | src/radeon_mergedfb.h | 121 | ||||
-rw-r--r-- | src/radeon_modes.c | 595 | ||||
-rw-r--r-- | src/radeon_probe.h | 49 | ||||
-rw-r--r-- | src/radeon_video.c | 103 |
11 files changed, 1345 insertions, 4425 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index f31c018..b2361f1 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -79,9 +79,10 @@ radeon_drv_la_LTLIBRARIES = radeon_drv.la radeon_drv_la_LDFLAGS = -module -avoid-version radeon_drv_ladir = @moduledir@/drivers radeon_drv_la_SOURCES = \ - radeon_accel.c radeon_mergedfb.c radeon_cursor.c radeon_dga.c \ + radeon_accel.c radeon_cursor.c radeon_dga.c \ radeon_driver.c radeon_video.c radeon_bios.c radeon_mm_i2c.c \ - radeon_vip.c radeon_misc.c radeon_display.c radeon_modes.c $(RADEON_DRI_SRCS) $(RADEON_EXA_SOURCES) + radeon_vip.c radeon_misc.c radeon_display.c radeon_modes.c \ + $(RADEON_DRI_SRCS) $(RADEON_EXA_SOURCES) theatre_detect_drv_la_LTLIBRARIES = theatre_detect_drv.la theatre_detect_drv_la_LDFLAGS = -module -avoid-version @@ -178,12 +179,13 @@ EXTRA_DIST = \ radeon_exa_funcs.c \ radeon.h \ radeon_macros.h \ - radeon_mergedfb.h \ radeon_probe.h \ radeon_reg.h \ radeon_sarea.h \ radeon_version.h \ radeon_video.h \ + radeon_xf86Modes.h \ + radeon_xf86Crtc.h \ theatre200.h \ theatre_detect.h \ theatre.h \ diff --git a/src/local_xf86Rename.h b/src/local_xf86Rename.h new file mode 100644 index 0000000..5102170 --- /dev/null +++ b/src/local_xf86Rename.h @@ -0,0 +1,23 @@ +/* + * 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. + */ + +#define XF86NAME(x) radeon_##x diff --git a/src/radeon.h b/src/radeon.h index 37ca67d..383a1c7 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -77,6 +77,8 @@ #endif #endif +#include "xf86Crtc.h" + /* Render support */ #ifdef RENDER #include "picturestr.h" @@ -439,11 +441,6 @@ typedef struct { framebuffer */ int Flags; /* Saved copy of mode flags */ - /* VE/M6 support */ - RADEONMonitorType DisplayType; /* Monitor connected on */ - RADEONDDCType DDCType; - RADEONConnectorType ConnectorType; - Bool IsMobility; /* Mobile chips for laptops */ Bool IsIGP; /* IGP chips */ Bool HasSingleDAC; /* only TVDAC on chip */ @@ -475,8 +472,6 @@ typedef struct { Bool ddc_bios; Bool ddc1; Bool ddc2; - I2CBusPtr pI2CBus; - CARD32 DDCReg; RADEONPLLRec pll; RADEONTMDSPll tmds_pll[4]; @@ -772,42 +767,13 @@ typedef struct { /* X itself has the 3D context */ Bool XInited3D; + DisplayModePtr currentMode, savedCurrentMode; /* merged fb stuff, also covers clone modes */ - Bool MergedFB; - RADEONScrn2Rel CRT2Position; - char * CRT2HSync; - char * CRT2VRefresh; - char * MetaModes; - ScrnInfoPtr CRT2pScrn; - DisplayModePtr CRT1Modes; - DisplayModePtr CRT1CurrentMode; - int CRT1frameX0; - int CRT1frameY0; - int CRT1frameX1; - int CRT1frameY1; - RADEONMonitorType MergeType; - RADEONDDCType MergeDDCType; void (*PointerMoved)(int index, int x, int y); - /* pseudo xinerama support for mergedfb */ - int maxCRT1_X1, maxCRT1_X2, maxCRT1_Y1, maxCRT1_Y2; - int maxCRT2_X1, maxCRT2_X2, maxCRT2_Y1, maxCRT2_Y2; - int maxClone_X1, maxClone_X2, maxClone_Y1, maxClone_Y2; - Bool UseRADEONXinerama; - Bool CRT2IsScrn0; - ExtensionEntry *XineramaExtEntry; - int RADEONXineramaVX, RADEONXineramaVY; - Bool AtLeastOneNonClone; - int MergedFBXDPI, MergedFBYDPI; Bool NoVirtual; - int CRT1XOffs, CRT1YOffs, CRT2XOffs, CRT2YOffs; - int MBXNR1XMAX, MBXNR1YMAX, MBXNR2XMAX, MBXNR2YMAX; - Bool NonRect, HaveNonRect, HaveOffsRegions, MouseRestrictions; - region NonRectDead, OffDead1, OffDead2; int constantDPI; /* -1 = auto, 0 = off, 1 = on */ int RADEONDPIVX, RADEONDPIVY; - RADEONScrn2Rel MergedDPISRel; - int RADEONMergedDPIVX, RADEONMergedDPIVY, RADEONMergedDPIRot; /* special handlings for DELL triple-head server */ Bool IsDellServer; @@ -819,6 +785,7 @@ typedef struct { CARD32 tv_dac_adj; + CreateScreenResourcesProcPtr CreateScreenResources; } RADEONInfoRec, *RADEONInfoPtr; #define RADEONWaitForFifo(pScrn, entries) \ @@ -898,7 +865,7 @@ extern Bool RADEONI2cInit(ScrnInfoPtr pScrn); extern void RADEONSetSyncRangeFromEdid(ScrnInfoPtr pScrn, int flag); extern void RADEONSetupConnectors(ScrnInfoPtr pScrn); extern Bool RADEONMapControllers(ScrnInfoPtr pScrn); -extern void RADEONEnableDisplay(ScrnInfoPtr pScrn, RADEONConnector* pPort, BOOL bEnable); +extern void RADEONEnableDisplay(ScrnInfoPtr pScrn, xf86OutputPtr pPort, BOOL bEnable); extern void RADEONDisableDisplays(ScrnInfoPtr pScrn); extern void RADEONGetPanelInfo(ScrnInfoPtr pScrn); extern void RADEONGetTVDacAdjInfo(ScrnInfoPtr pScrn); @@ -909,13 +876,18 @@ extern void RADEONDisplayPowerManagementSet(ScrnInfoPtr pScrn, int flags); extern Bool RADEONAllocateControllers(ScrnInfoPtr pScrn); extern Bool RADEONAllocateConnectors(ScrnInfoPtr pScrn); -extern RADEONConnector *RADEONGetCrtcConnector(ScrnInfoPtr pScrn, int crtc_num); +extern xf86OutputPtr RADEONGetCrtcConnector(ScrnInfoPtr pScrn, int crtc_num); extern int RADEONValidateMergeModes(ScrnInfoPtr pScrn); extern int RADEONValidateDDCModes(ScrnInfoPtr pScrn1, char **ppModeName, RADEONMonitorType DisplayType, int crtc2); -extern int RADEONValidateFPModes(ScrnInfoPtr pScrn, char **ppModeName); +extern int RADEONValidateFPModes(ScrnInfoPtr pScrn, char **ppModeName, DisplayModePtr *modeList); extern void RADEONSetPitch (ScrnInfoPtr pScrn); +DisplayModePtr +RADEONProbeOutputModes(xf86OutputPtr output); +extern Bool RADEONInit2(ScrnInfoPtr pScrn, DisplayModePtr crtc1, + DisplayModePtr crtc2, int crtc_mask, + RADEONSavePtr save, RADEONMonitorType montype); #ifdef XF86DRI #ifdef USE_XAA diff --git a/src/radeon_cursor.c b/src/radeon_cursor.c index a45198a..6d61b07 100644 --- a/src/radeon_cursor.c +++ b/src/radeon_cursor.c @@ -31,7 +31,7 @@ #endif #define RADEONCTRACE(x) -/* #define RADEONCTRACE(x) RADEONTRACE(x) */ +/*#define RADEONCTRACE(x) RADEONTRACE(x) */ /* * Authors: @@ -55,7 +55,6 @@ #include "radeon_version.h" #include "radeon_reg.h" #include "radeon_macros.h" -#include "radeon_mergedfb.h" /* X and server generic header files */ #include "xf86.h" @@ -104,6 +103,43 @@ static CARD32 mono_cursor_color[] = { #endif +static void +RADEONCrtcCursor(xf86CrtcPtr crtc, Bool force) +{ + ScrnInfoPtr pScrn = crtc->scrn; + RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private; + int crtc_id = radeon_crtc->crtc_id; + RADEONInfoPtr info = RADEONPTR(pScrn); + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + Bool show; + unsigned char *RADEONMMIO = info->MMIO; + CARD32 save1 = 0, save2 = 0; + + if (!crtc->enabled && !crtc->cursorShown) + return; + + + show = crtc->cursorInRange && crtc->enabled; + if (show && (force || !crtc->cursorShown)) + { + if (crtc_id == 0) + OUTREGP(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_CUR_EN, + ~RADEON_CRTC_CUR_EN); + else if (crtc_id == 1) + OUTREGP(RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_CUR_EN, + ~RADEON_CRTC2_CUR_EN); + crtc->cursorShown = TRUE; + } else if (!show && (force || crtc->cursorShown)) { + + if (crtc_id == 0) + OUTREGP(RADEON_CRTC_GEN_CNTL, 0, ~RADEON_CRTC_CUR_EN); + else if (crtc_id == 1) + OUTREGP(RADEON_CRTC2_GEN_CNTL, 0, ~RADEON_CRTC2_CUR_EN); + + crtc->cursorShown = FALSE; + } + +} /* Set cursor foreground and background colors */ static void RADEONSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) @@ -143,57 +179,91 @@ static void RADEONSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) info->cursor_bg = bg; } - -/* Set cursor position to (x,y) with offset into cursor bitmap at - * (xorigin,yorigin) - */ -static void RADEONSetCursorPosition(ScrnInfoPtr pScrn, int x, int y) +static void +RADEONRandrSetCursorPosition(ScrnInfoPtr pScrn, int x, int y) { + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; xf86CursorInfoPtr cursor = info->cursor; - int xorigin = 0; - int yorigin = 0; - int total_y = pScrn->frameY1 - pScrn->frameY0; + Bool inrange; + int temp; + int oldx = x, oldy = y; + int hotspotx = 0, hotspoty = 0; + int c; + int xorigin, yorigin; int stride = 256; - if(info->MergedFB) { - RADEONCTRACE(("RADEONSetCursorPositionMerged\n")); - RADEONSetCursorPositionMerged(pScrn, x, y); - return; - } - - RADEONCTRACE(("RADEONSetCursorPosition\n")); + oldx += pScrn->frameX0; /* undo what xf86HWCurs did */ + oldy += pScrn->frameY0; + + x = oldx; + y = oldy; + + for (c = 0 ; c < xf86_config->num_crtc; c++) { + xf86CrtcPtr crtc = xf86_config->crtc[c]; + DisplayModePtr mode = &crtc->mode; + int thisx = x - crtc->x; + int thisy = y - crtc->y; + + if (!crtc->enabled && !crtc->cursorShown) + continue; + + /* + * There is a screen display problem when the cursor position is set + * wholely outside of the viewport. We trap that here, turning the + * cursor off when that happens, and back on when it comes back into + * the viewport. + */ + inrange = TRUE; + if (thisx >= mode->HDisplay || + thisy >= mode->VDisplay || + thisx <= -cursor->MaxWidth || thisy <= -cursor->MaxHeight) + { + inrange = FALSE; + thisx = 0; + thisy = 0; + } - if (x < 0) xorigin = -x+1; - if (y < 0) yorigin = -y+1; - if (y > total_y) y = total_y; - if (info->Flags & V_DBLSCAN) y *= 2; - if (xorigin >= cursor->MaxWidth) xorigin = cursor->MaxWidth - 1; - if (yorigin >= cursor->MaxHeight) yorigin = cursor->MaxHeight - 1; + temp = 0; + xorigin = 0; + yorigin = 0; + if (thisx < 0) xorigin = -thisx+1; + if (thisy < 0) yorigin = -thisy+1; + if (xorigin >= cursor->MaxWidth) xorigin = cursor->MaxWidth - 1; + if (yorigin >= cursor->MaxHeight) yorigin = cursor->MaxHeight - 1; + + temp |= (xorigin ? 0 : thisx) << 16; + temp |= (yorigin ? 0 : thisy); + + if (c == 0) { + OUTREG(RADEON_CUR_HORZ_VERT_OFF, (RADEON_CUR_LOCK + | (xorigin << 16) + | yorigin)); + OUTREG(RADEON_CUR_HORZ_VERT_POSN, (RADEON_CUR_LOCK | + temp)); + RADEONCTRACE(("cursor_offset: 0x%x, yorigin: %d, stride: %d, temp %08X\n", + info->cursor_offset + pScrn->fbOffset, yorigin, stride, temp)); + OUTREG(RADEON_CUR_OFFSET, + info->cursor_offset + pScrn->fbOffset + yorigin * stride); + } + if (c == 1) { + OUTREG(RADEON_CUR2_HORZ_VERT_OFF, (RADEON_CUR2_LOCK + | (xorigin << 16) + | yorigin)); + OUTREG(RADEON_CUR2_HORZ_VERT_POSN, (RADEON_CUR2_LOCK | + temp)); + RADEONCTRACE(("cursor_offset2: 0x%x, yorigin: %d, stride: %d, temp %08X\n", + info->cursor_offset + pScrn->fbOffset, yorigin, stride, temp)); + OUTREG(RADEON_CUR2_OFFSET, + info->cursor_offset + pScrn->fbOffset + yorigin * stride); + } + crtc->cursorInRange = inrange; - if (!info->IsSecondary) { - OUTREG(RADEON_CUR_HORZ_VERT_OFF, (RADEON_CUR_LOCK - | (xorigin << 16) - | yorigin)); - OUTREG(RADEON_CUR_HORZ_VERT_POSN, (RADEON_CUR_LOCK - | ((xorigin ? 0 : x) << 16) - | (yorigin ? 0 : y))); - RADEONCTRACE(("cursor_offset: 0x%x, yorigin: %d, stride: %d\n", - info->cursor_offset + pScrn->fbOffset, yorigin, stride)); - OUTREG(RADEON_CUR_OFFSET, - info->cursor_offset + pScrn->fbOffset + yorigin * stride); - } else { - OUTREG(RADEON_CUR2_HORZ_VERT_OFF, (RADEON_CUR2_LOCK - | (xorigin << 16) - | yorigin)); - OUTREG(RADEON_CUR2_HORZ_VERT_POSN, (RADEON_CUR2_LOCK - | ((xorigin ? 0 : x) << 16) - | (yorigin ? 0 : y))); - OUTREG(RADEON_CUR2_OFFSET, - info->cursor_offset + pScrn->fbOffset + yorigin * stride); + RADEONCrtcCursor(crtc, FALSE); } + } /* Copy cursor image from `image' to video memory. RADEONSetCursorPosition @@ -203,6 +273,7 @@ static void RADEONLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *image) { RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; + RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); CARD8 *s = (CARD8 *)(pointer)image; CARD32 *d = (CARD32 *)(pointer)(info->FB + info->cursor_offset + pScrn->fbOffset); CARD32 save1 = 0; @@ -212,13 +283,20 @@ static void RADEONLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *image) RADEONCTRACE(("RADEONLoadCursorImage (at %x)\n", info->cursor_offset)); + if (!info->IsSecondary) { save1 = INREG(RADEON_CRTC_GEN_CNTL) & ~(CARD32) (3 << 20); save1 |= (CARD32) (2 << 20); OUTREG(RADEON_CRTC_GEN_CNTL, save1 & (CARD32)~RADEON_CRTC_CUR_EN); + + if (pRADEONEnt->HasCRTC2) { + save2 = INREG(RADEON_CRTC2_GEN_CNTL) & ~(CARD32) (3 << 20); + save2 |= (CARD32) (2 << 20); + OUTREG(RADEON_CRTC2_GEN_CNTL, save2 & (CARD32)~RADEON_CRTC2_CUR_EN); + } } - if (info->IsSecondary || info->MergedFB) { + if (info->IsSecondary) { save2 = INREG(RADEON_CRTC2_GEN_CNTL) & ~(CARD32) (3 << 20); save2 |= (CARD32) (2 << 20); OUTREG(RADEON_CRTC2_GEN_CNTL, save2 & (CARD32)~RADEON_CRTC2_CUR_EN); @@ -251,8 +329,7 @@ static void RADEONLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *image) if (!info->IsSecondary) OUTREG(RADEON_CRTC_GEN_CNTL, save1); - if (info->IsSecondary || info->MergedFB) - OUTREG(RADEON_CRTC2_GEN_CNTL, save2); + OUTREG(RADEON_CRTC2_GEN_CNTL, save2); } @@ -261,14 +338,12 @@ static void RADEONHideCursor(ScrnInfoPtr pScrn) { RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; - + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + int c; RADEONCTRACE(("RADEONHideCursor\n")); - if (info->IsSecondary || info->MergedFB) - OUTREGP(RADEON_CRTC2_GEN_CNTL, 0, ~RADEON_CRTC2_CUR_EN); - - if (!info->IsSecondary) - OUTREGP(RADEON_CRTC_GEN_CNTL, 0, ~RADEON_CRTC_CUR_EN); + for (c = 0; c < xf86_config->num_crtc; c++) + RADEONCrtcCursor(xf86_config->crtc[c], TRUE); } /* Show hardware cursor. */ @@ -276,16 +351,13 @@ static void RADEONShowCursor(ScrnInfoPtr pScrn) { RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + int c; RADEONCTRACE(("RADEONShowCursor\n")); - if (info->IsSecondary || info->MergedFB) - OUTREGP(RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_CUR_EN, - ~RADEON_CRTC2_CUR_EN); - - if (!info->IsSecondary) - OUTREGP(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_CUR_EN, - ~RADEON_CRTC_CUR_EN); + for (c = 0; c < xf86_config->num_crtc; c++) + RADEONCrtcCursor(xf86_config->crtc[c], FALSE); } /* Determine if hardware cursor is in use. */ @@ -311,6 +383,7 @@ static Bool RADEONUseHWCursorARGB (ScreenPtr pScreen, CursorPtr pCurs) static void RADEONLoadCursorARGB (ScrnInfoPtr pScrn, CursorPtr pCurs) { RADEONInfoPtr info = RADEONPTR(pScrn); + RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); unsigned char *RADEONMMIO = info->MMIO; CARD32 *d = (CARD32 *)(pointer)(info->FB + info->cursor_offset + pScrn->fbOffset); int x, y, w, h; @@ -325,9 +398,15 @@ static void RADEONLoadCursorARGB (ScrnInfoPtr pScrn, CursorPtr pCurs) save1 = INREG(RADEON_CRTC_GEN_CNTL) & ~(CARD32) (3 << 20); save1 |= (CARD32) (2 << 20); OUTREG(RADEON_CRTC_GEN_CNTL, save1 & (CARD32)~RADEON_CRTC_CUR_EN); + + if (pRADEONEnt->HasCRTC2) { + save2 = INREG(RADEON_CRTC2_GEN_CNTL) & ~(CARD32) (3 << 20); + save2 |= (CARD32) (2 << 20); + OUTREG(RADEON_CRTC2_GEN_CNTL, save2 & (CARD32)~RADEON_CRTC2_CUR_EN); + } } - if (info->IsSecondary || info->MergedFB) { + if (info->IsSecondary) { save2 = INREG(RADEON_CRTC2_GEN_CNTL) & ~(CARD32) (3 << 20); save2 |= (CARD32) (2 << 20); OUTREG(RADEON_CRTC2_GEN_CNTL, save2 & (CARD32)~RADEON_CRTC2_CUR_EN); @@ -365,8 +444,7 @@ static void RADEONLoadCursorARGB (ScrnInfoPtr pScrn, CursorPtr pCurs) if (!info->IsSecondary) OUTREG(RADEON_CRTC_GEN_CNTL, save1); - if (info->IsSecondary || info->MergedFB) - OUTREG(RADEON_CRTC2_GEN_CNTL, save2); + OUTREG(RADEON_CRTC2_GEN_CNTL, save2); } @@ -401,7 +479,7 @@ Bool RADEONCursorInit(ScreenPtr pScreen) | HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1); cursor->SetCursorColors = RADEONSetCursorColors; - cursor->SetCursorPosition = RADEONSetCursorPosition; + cursor->SetCursorPosition = RADEONRandrSetCursorPosition; cursor->LoadCursorImage = RADEONLoadCursorImage; cursor->HideCursor = RADEONHideCursor; cursor->ShowCursor = RADEONShowCursor; diff --git a/src/radeon_display.c b/src/radeon_display.c index d661c17..e9890d9 100644 --- a/src/radeon_display.c +++ b/src/radeon_display.c @@ -38,6 +38,7 @@ #include "xf86_OSproc.h" #include "fbdevhw.h" #include "vgaHW.h" +#include "xf86Modes.h" /* Driver data structures */ #include "radeon.h" @@ -45,8 +46,9 @@ #include "radeon_macros.h" #include "radeon_probe.h" #include "radeon_version.h" -#include "radeon_mergedfb.h" +void RADEONSetOutputType(ScrnInfoPtr pScrn, RADEONOutputPrivatePtr radeon_output); +void radeon_crtc_load_lut(xf86CrtcPtr crtc); extern int getRADEONEntityIndex(void); const char *MonTypeName[7] = { @@ -113,6 +115,15 @@ const char *ConnectorTypeNameATOM[10] = { "Unsupported" }; +const char *OutputType[10] = { + "None", + "VGA", + "DVI", + "LVDS", + "S-video", + "Composite", +}; + static const RADEONTMDSPll default_tmds_pll[CHIP_FAMILY_LAST][4] = { @@ -166,7 +177,7 @@ static void RADEONI2CGetBits(I2CBusPtr b, int *Clock, int *data) unsigned char *RADEONMMIO = info->MMIO; /* Get the result */ - val = INREG(info->DDCReg); + val = INREG(b->DriverPrivate.uval); *Clock = (val & RADEON_GPIO_Y_1) != 0; *data = (val & RADEON_GPIO_Y_0) != 0; @@ -179,29 +190,32 @@ static void RADEONI2CPutBits(I2CBusPtr b, int Clock, int data) unsigned long val; unsigned char *RADEONMMIO = info->MMIO; - val = INREG(info->DDCReg) & (CARD32)~(RADEON_GPIO_EN_0 | RADEON_GPIO_EN_1); + val = INREG(b->DriverPrivate.uval) & (CARD32)~(RADEON_GPIO_EN_0 | RADEON_GPIO_EN_1); val |= (Clock ? 0:RADEON_GPIO_EN_1); val |= (data ? 0:RADEON_GPIO_EN_0); - OUTREG(info->DDCReg, val); + OUTREG(b->DriverPrivate.uval, val); /* read back to improve reliability on some cards. */ - val = INREG(info->DDCReg); + val = INREG(b->DriverPrivate.uval); } -Bool RADEONI2cInit(ScrnInfoPtr pScrn) +Bool RADEONI2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, int i2c_reg, char *name) { - RADEONInfoPtr info = RADEONPTR(pScrn); + I2CBusPtr pI2CBus; - info->pI2CBus = xf86CreateI2CBusRec(); - if (!info->pI2CBus) return FALSE; + pI2CBus = xf86CreateI2CBusRec(); + if (!pI2CBus) return FALSE; - info->pI2CBus->BusName = "DDC"; - info->pI2CBus->scrnIndex = pScrn->scrnIndex; - info->pI2CBus->I2CPutBits = RADEONI2CPutBits; - info->pI2CBus->I2CGetBits = RADEONI2CGetBits; - info->pI2CBus->AcknTimeout = 5; + pI2CBus->BusName = name; + pI2CBus->scrnIndex = pScrn->scrnIndex; + pI2CBus->I2CPutBits = RADEONI2CPutBits; + pI2CBus->I2CGetBits = RADEONI2CGetBits; + pI2CBus->AcknTimeout = 5; + pI2CBus->DriverPrivate.uval = i2c_reg; - if (!xf86I2CBusInit(info->pI2CBus)) return FALSE; + if (!xf86I2CBusInit(pI2CBus)) return FALSE; + + *bus_ptr = pI2CBus; return TRUE; } @@ -532,93 +546,78 @@ RADEONCrtIsPhysicallyConnected(ScrnInfoPtr pScrn, int IsCrtDac) OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, ulOrigTV_PRE_DAC_MUX_CNTL); } #endif + return MT_UNKNOWN; } return(bConnected ? MT_CRT : MT_NONE); } -static RADEONMonitorType RADEONDisplayDDCConnected(ScrnInfoPtr pScrn, RADEONDDCType DDCType, RADEONConnector* port) +static RADEONMonitorType RADEONDisplayDDCConnected(ScrnInfoPtr pScrn, RADEONDDCType DDCType, xf86OutputPtr output) { RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; unsigned long DDCReg; RADEONMonitorType MonType = MT_NONE; - xf86MonPtr* MonInfo = &port->MonInfo; + xf86MonPtr* MonInfo = &output->MonInfo; + RADEONOutputPrivatePtr radeon_output = output->driver_private; int i, j; - DDCReg = info->DDCReg; - switch(DDCType) - { - case DDC_MONID: - info->DDCReg = RADEON_GPIO_MONID; - break; - case DDC_DVI: - info->DDCReg = RADEON_GPIO_DVI_DDC; - break; - case DDC_VGA: - info->DDCReg = RADEON_GPIO_VGA_DDC; - break; - case DDC_CRT2: - info->DDCReg = RADEON_GPIO_CRT2_DDC; - break; - default: - info->DDCReg = DDCReg; - return MT_NONE; - } + DDCReg = radeon_output->DDCReg; /* Read and output monitor info using DDC2 over I2C bus */ - if (info->pI2CBus && info->ddc2) { - OUTREG(info->DDCReg, INREG(info->DDCReg) & + if (radeon_output->pI2CBus && info->ddc2) { + + OUTREG(DDCReg, INREG(DDCReg) & (CARD32)~(RADEON_GPIO_A_0 | RADEON_GPIO_A_1)); /* For some old monitors (like Compaq Presario FP500), we need * following process to initialize/stop DDC */ - OUTREG(info->DDCReg, INREG(info->DDCReg) & ~(RADEON_GPIO_EN_1)); + OUTREG(DDCReg, INREG(DDCReg) & ~(RADEON_GPIO_EN_1)); for (j = 0; j < 3; j++) { - OUTREG(info->DDCReg, - INREG(info->DDCReg) & ~(RADEON_GPIO_EN_0)); + OUTREG(DDCReg, + INREG(DDCReg) & ~(RADEON_GPIO_EN_0)); usleep(13000); - OUTREG(info->DDCReg, - INREG(info->DDCReg) & ~(RADEON_GPIO_EN_1)); + OUTREG(DDCReg, + INREG(DDCReg) & ~(RADEON_GPIO_EN_1)); for (i = 0; i < 10; i++) { usleep(15000); - if (INREG(info->DDCReg) & RADEON_GPIO_Y_1) + if (INREG(DDCReg) & RADEON_GPIO_Y_1) break; } if (i == 10) continue; usleep(15000); - OUTREG(info->DDCReg, INREG(info->DDCReg) | RADEON_GPIO_EN_0); + OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_0); usleep(15000); - OUTREG(info->DDCReg, INREG(info->DDCReg) | RADEON_GPIO_EN_1); + OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_1); usleep(15000); - OUTREG(info->DDCReg, - INREG(info->DDCReg) & ~(RADEON_GPIO_EN_0)); + OUTREG(DDCReg, + INREG(DDCReg) & ~(RADEON_GPIO_EN_0)); usleep(15000); - *MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex, info->pI2CBus); + *MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex, radeon_output->pI2CBus); - OUTREG(info->DDCReg, INREG(info->DDCReg) | RADEON_GPIO_EN_1); - OUTREG(info->DDCReg, INREG(info->DDCReg) | RADEON_GPIO_EN_0); + OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_1); + OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_0); usleep(15000); - OUTREG(info->DDCReg, - INREG(info->DDCReg) & ~(RADEON_GPIO_EN_1)); + OUTREG(DDCReg, + INREG(DDCReg) & ~(RADEON_GPIO_EN_1)); for (i = 0; i < 5; i++) { usleep(15000); - if (INREG(info->DDCReg) & RADEON_GPIO_Y_1) + if (INREG(DDCReg) & RADEON_GPIO_Y_1) break; } usleep(15000); - OUTREG(info->DDCReg, - INREG(info->DDCReg) & ~(RADEON_GPIO_EN_0)); + OUTREG(DDCReg, + INREG(DDCReg) & ~(RADEON_GPIO_EN_0)); usleep(15000); - OUTREG(info->DDCReg, INREG(info->DDCReg) | RADEON_GPIO_EN_1); - OUTREG(info->DDCReg, INREG(info->DDCReg) | RADEON_GPIO_EN_0); + OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_1); + OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_0); usleep(15000); if(*MonInfo) break; } @@ -627,7 +626,7 @@ static RADEONMonitorType RADEONDisplayDDCConnected(ScrnInfoPtr pScrn, RADEONDDCT MonType = MT_NONE; } - OUTREG(info->DDCReg, INREG(info->DDCReg) & + OUTREG(DDCReg, INREG(DDCReg) & ~(RADEON_GPIO_EN_0 | RADEON_GPIO_EN_1)); if (*MonInfo) { @@ -639,7 +638,7 @@ static RADEONMonitorType RADEONDisplayDDCConnected(ScrnInfoPtr pScrn, RADEONDDCT * Also for laptop, when X starts with lid closed (no DVI connection) * both LDVS and TMDS are disable, we still need to treat it as a LVDS panel. */ - if (port->TMDSType == TMDS_EXT) MonType = MT_DFP; + if (radeon_output->TMDSType == TMDS_EXT) MonType = MT_DFP; else { if ((INREG(RADEON_FP_GEN_CNTL) & RADEON_FP_EN_TMDS) || !info->IsMobility) MonType = MT_DFP; @@ -649,8 +648,6 @@ static RADEONMonitorType RADEONDisplayDDCConnected(ScrnInfoPtr pScrn, RADEONDDCT } else MonType = MT_CRT; } else MonType = MT_NONE; - info->DDCReg = DDCReg; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "DDC Type: %d, Detected Type: %d\n", DDCType, MonType); @@ -850,7 +847,7 @@ static Bool RADEONGetLVDSInfo (ScrnInfoPtr pScrn) tmp_mode = tmp_mode->next; } } - if ((info->DotClock == 0) && !pRADEONEnt->PortInfo[0]->MonInfo) { + if ((info->DotClock == 0) && !pRADEONEnt->pOutput[0]->MonInfo) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Panel size is not correctly detected.\n" "Please try to use PanelSize option for correct settings.\n"); @@ -890,21 +887,7 @@ void RADEONGetPanelInfo (ScrnInfoPtr pScrn) xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Invalid PanelSize option: %s\n", s); RADEONGetPanelInfoFromReg(pScrn); } - } else { - - if(info->DisplayType == MT_LCD) { - RADEONGetLVDSInfo(pScrn); - if (info->MergeType == MT_DFP) { - RADEONGetTMDSInfo(pScrn); - } - } else if ((info->DisplayType == MT_DFP) || (info->MergeType == MT_DFP)) { - RADEONGetTMDSInfo(pScrn); - if (!pScrn->monitor->DDC) - RADEONGetHardCodedEDIDFromBIOS(pScrn); - else if (!info->IsSecondary) - RADEONUpdatePanelSize(pScrn); - } - } + } } void RADEONGetTVDacAdjInfo(ScrnInfoPtr pScrn) @@ -919,6 +902,20 @@ void RADEONGetTVDacAdjInfo(ScrnInfoPtr pScrn) } } +static void RADEONSwapOutputs(ScrnInfoPtr pScrn) +{ + RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); + xf86OutputPtr connector; + RADEONOutputPrivatePtr conn_priv; + + connector = pRADEONEnt->pOutput[0]; + pRADEONEnt->pOutput[0] = pRADEONEnt->pOutput[1]; + pRADEONEnt->pOutput[1] = connector; + + conn_priv = pRADEONEnt->PortInfo[0]; + pRADEONEnt->PortInfo[0] = pRADEONEnt->PortInfo[1]; + pRADEONEnt->PortInfo[1] = conn_priv; +} /* * initialise the static data sos we don't have to re-do at randr change */ void RADEONSetupConnectors(ScrnInfoPtr pScrn) @@ -926,7 +923,6 @@ void RADEONSetupConnectors(ScrnInfoPtr pScrn) RADEONInfoPtr info = RADEONPTR(pScrn); RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); const char *s; - Bool ignore_edid = FALSE; int i = 0, second = 0, max_mt = 5; /* We first get the information about all connectors from BIOS. @@ -936,30 +932,23 @@ void RADEONSetupConnectors(ScrnInfoPtr pScrn) */ for (i = 0; i < 2; i++) { pRADEONEnt->PortInfo[i]->MonType = MT_UNKNOWN; - pRADEONEnt->PortInfo[i]->MonInfo = NULL; pRADEONEnt->PortInfo[i]->DDCType = DDC_NONE_DETECTED; pRADEONEnt->PortInfo[i]->DACType = DAC_UNKNOWN; pRADEONEnt->PortInfo[i]->TMDSType = TMDS_UNKNOWN; pRADEONEnt->PortInfo[i]->ConnectorType = CONNECTOR_NONE; } - pRADEONEnt->Controller[0]->IsUsed = FALSE; - pRADEONEnt->Controller[1]->IsUsed = FALSE; - pRADEONEnt->Controller[0]->IsActive = FALSE; - pRADEONEnt->Controller[1]->IsActive = FALSE; if (!RADEONGetConnectorInfoFromBIOS(pScrn) || ((pRADEONEnt->PortInfo[0]->DDCType == 0) && (pRADEONEnt->PortInfo[1]->DDCType == 0))) { /* Below is the most common setting, but may not be true */ pRADEONEnt->PortInfo[0]->MonType = MT_UNKNOWN; - pRADEONEnt->PortInfo[0]->MonInfo = NULL; pRADEONEnt->PortInfo[0]->DDCType = DDC_DVI; pRADEONEnt->PortInfo[0]->DACType = DAC_TVDAC; pRADEONEnt->PortInfo[0]->TMDSType = TMDS_INT; pRADEONEnt->PortInfo[0]->ConnectorType = CONNECTOR_DVI_I; pRADEONEnt->PortInfo[1]->MonType = MT_UNKNOWN; - pRADEONEnt->PortInfo[1]->MonInfo = NULL; pRADEONEnt->PortInfo[1]->DDCType = DDC_VGA; pRADEONEnt->PortInfo[1]->DACType = DAC_PRIMARY; pRADEONEnt->PortInfo[1]->TMDSType = TMDS_EXT; @@ -977,10 +966,7 @@ void RADEONSetupConnectors(ScrnInfoPtr pScrn) /* always make TMDS_INT port first*/ if (pRADEONEnt->PortInfo[1]->TMDSType == TMDS_INT) { - RADEONConnector *connector; - connector = pRADEONEnt->PortInfo[0]; - pRADEONEnt->PortInfo[0] = pRADEONEnt->PortInfo[1]; - pRADEONEnt->PortInfo[1] = connector; + RADEONSwapOutputs(pScrn); } else if ((pRADEONEnt->PortInfo[0]->TMDSType != TMDS_INT && pRADEONEnt->PortInfo[1]->TMDSType != TMDS_INT)) { /* no TMDS_INT port, make primary DAC port first */ @@ -989,10 +975,7 @@ void RADEONSetupConnectors(ScrnInfoPtr pScrn) swap when the first port is not DAC_PRIMARY */ if ((!(pRADEONEnt->PortInfo[0]->ConnectorType == CONNECTOR_PROPRIETARY)) && (pRADEONEnt->PortInfo[1]->DACType == DAC_PRIMARY) && (pRADEONEnt->PortInfo[0]->DACType != DAC_PRIMARY)) { - RADEONConnector *connector; - connector = pRADEONEnt->PortInfo[0]; - pRADEONEnt->PortInfo[0] = pRADEONEnt->PortInfo[1]; - pRADEONEnt->PortInfo[1] = connector; + RADEONSwapOutputs(pScrn); } } @@ -1009,18 +992,6 @@ void RADEONSetupConnectors(ScrnInfoPtr pScrn) pRADEONEnt->PortInfo[0]->DACType = DAC_PRIMARY; } - /* IgnoreEDID option is different from the NoDDCxx options used by DDC module - * When IgnoreEDID is used, monitor detection will still use DDC - * detection, but all EDID data will not be used in mode validation. - * You can use this option when you have a DDC monitor but want specify your own - * monitor timing parameters by using HSync, VRefresh and Modeline, - */ - if (xf86GetOptValBool(info->Options, OPTION_IGNORE_EDID, &ignore_edid)) { - if (ignore_edid) - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "IgnoreEDID is specified, EDID data will be ignored\n"); - } - /* * MonitorLayout option takes a string for two monitors connected in following format: * Option "MonitorLayout" "primary-port-display, secondary-port-display" @@ -1136,17 +1107,56 @@ void RADEONSetupConnectors(ScrnInfoPtr pScrn) pRADEONEnt->PortInfo[1]->ConnectorType = CONNECTOR_DVI_I; pRADEONEnt->PortInfo[0]->TMDSType = TMDS_UNKNOWN; } + } + + for (i = 0; i < 2; i++) { + RADEONOutputPrivatePtr radeon_output = pRADEONEnt->PortInfo[i]; + + int DDCReg = 0; + char *names[] = { "DDC1", "DDC2" }; + + RADEONSetOutputType(pScrn, radeon_output); + switch(radeon_output->DDCType) { + case DDC_MONID: DDCReg = RADEON_GPIO_MONID; break; + case DDC_DVI : DDCReg = RADEON_GPIO_DVI_DDC; break; + case DDC_VGA: DDCReg = RADEON_GPIO_VGA_DDC; break; + case DDC_CRT2: DDCReg = RADEON_GPIO_CRT2_DDC; break; + default: break; + } + + if (DDCReg) { + radeon_output->DDCReg = DDCReg; + RADEONI2CInit(pScrn, &radeon_output->pI2CBus, DDCReg, names[i]); + } + + if (radeon_output->type == OUTPUT_LVDS) { + RADEONGetLVDSInfo(pScrn); + } + + if (radeon_output->type == OUTPUT_DVI) { + RADEONGetTMDSInfo(pScrn); + + if (i == 0) + RADEONGetHardCodedEDIDFromBios(pScrn); + + RADEONUpdatePanelSize(pScrn); + + } + } + + } -static RADEONMonitorType RADEONPortCheckNonDDC(ScrnInfoPtr pScrn, int connector) +static RADEONMonitorType RADEONPortCheckNonDDC(ScrnInfoPtr pScrn, xf86OutputPtr output) { RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; + RADEONOutputPrivatePtr radeon_output = output->driver_private; if (info->IsMobility) { - switch(connector) { + switch(radeon_output->num) { case 0: /* non-DDC laptop panel connected on primary */ if (INREG(RADEON_BIOS_4_SCRATCH) & 4) @@ -1167,22 +1177,22 @@ static RADEONMonitorType RADEONPortCheckNonDDC(ScrnInfoPtr pScrn, int connector) /* Primary Head (DVI or Laptop Int. panel)*/ /* A ddc capable display connected on DVI port */ /* Secondary Head (mostly VGA, can be DVI on some OEM boards)*/ -void RADEONConnectorFindMonitor(ScrnInfoPtr pScrn, int connector) +void RADEONConnectorFindMonitor(ScrnInfoPtr pScrn, xf86OutputPtr output) { RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); - RADEONConnector *pPort = pRADEONEnt->PortInfo[connector]; + RADEONOutputPrivatePtr radeon_output = output->driver_private; - if (pPort->MonType == MT_UNKNOWN) { - if ((pPort->MonType = RADEONDisplayDDCConnected(pScrn, - pPort->DDCType, - pPort))); - else if((pPort->MonType = RADEONPortCheckNonDDC(pScrn, connector))); + if (radeon_output->MonType == MT_UNKNOWN) { + if ((radeon_output->MonType = RADEONDisplayDDCConnected(pScrn, + radeon_output->DDCType, + output))); + else if((radeon_output->MonType = RADEONPortCheckNonDDC(pScrn, output))); else - pPort->MonType = RADEONCrtIsPhysicallyConnected(pScrn, !(pPort->DACType)); + radeon_output->MonType = RADEONCrtIsPhysicallyConnected(pScrn, !(radeon_output->DACType)); } } -static void RADEONQueryConnectedDisplays(ScrnInfoPtr pScrn) +void RADEONQueryConnectedDisplays(ScrnInfoPtr pScrn) { RADEONInfoPtr info = RADEONPTR(pScrn); @@ -1207,11 +1217,11 @@ static void RADEONQueryConnectedDisplays(ScrnInfoPtr pScrn) if ((pRADEONEnt->PortInfo[0]->MonType > MT_NONE) && (pRADEONEnt->PortInfo[0]->MonType < MT_STV)) RADEONDisplayDDCConnected(pScrn, pRADEONEnt->PortInfo[0]->DDCType, - pRADEONEnt->PortInfo[0]); + pRADEONEnt->pOutput[0]); if ((pRADEONEnt->PortInfo[1]->MonType > MT_NONE) && (pRADEONEnt->PortInfo[1]->MonType < MT_STV)) RADEONDisplayDDCConnected(pScrn, pRADEONEnt->PortInfo[1]->DDCType, - pRADEONEnt->PortInfo[1]); + pRADEONEnt->pOutput[1]); } } else { @@ -1225,24 +1235,24 @@ static void RADEONQueryConnectedDisplays(ScrnInfoPtr pScrn) if ((!pRADEONEnt->HasCRTC2) && (pRADEONEnt->PortInfo[0]->MonType == MT_UNKNOWN)) { if((pRADEONEnt->PortInfo[0]->MonType = RADEONDisplayDDCConnected(pScrn, DDC_DVI, - pRADEONEnt->PortInfo[0]))); + pRADEONEnt->pOutput[0]))); else if((pRADEONEnt->PortInfo[0]->MonType = RADEONDisplayDDCConnected(pScrn, DDC_VGA, - pRADEONEnt->PortInfo[0]))); + pRADEONEnt->pOutput[0]))); else if((pRADEONEnt->PortInfo[0]->MonType = RADEONDisplayDDCConnected(pScrn, DDC_CRT2, - pRADEONEnt->PortInfo[0]))); + pRADEONEnt->pOutput[0]))); else pRADEONEnt->PortInfo[0]->MonType = MT_CRT; if (!ignore_edid) { - if (pRADEONEnt->PortInfo[0]->MonInfo) { + if (pRADEONEnt->pOutput[0]->MonInfo) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Monitor1 EDID data ---------------------------\n"); - xf86PrintEDID(pRADEONEnt->PortInfo[0]->MonInfo ); + xf86PrintEDID(pRADEONEnt->pOutput[0]->MonInfo ); xf86DrvMsg(pScrn->scrnIndex, X_INFO, "End of Monitor1 EDID data --------------------\n"); } } pRADEONEnt->PortInfo[1]->MonType = MT_NONE; - pRADEONEnt->PortInfo[1]->MonInfo = NULL; + pRADEONEnt->pOutput[1]->MonInfo = NULL; pRADEONEnt->PortInfo[1]->DDCType = DDC_NONE_DETECTED; pRADEONEnt->PortInfo[1]->DACType = DAC_UNKNOWN; pRADEONEnt->PortInfo[1]->TMDSType = TMDS_UNKNOWN; @@ -1254,23 +1264,23 @@ static void RADEONQueryConnectedDisplays(ScrnInfoPtr pScrn) return; } - RADEONConnectorFindMonitor(pScrn, 0); - RADEONConnectorFindMonitor(pScrn, 1); + RADEONConnectorFindMonitor(pScrn, pRADEONEnt->pOutput[0]); + RADEONConnectorFindMonitor(pScrn, pRADEONEnt->pOutput[1]); } if(ignore_edid) { - pRADEONEnt->PortInfo[0]->MonInfo = NULL; - pRADEONEnt->PortInfo[1]->MonInfo = NULL; + pRADEONEnt->pOutput[0]->MonInfo = NULL; + pRADEONEnt->pOutput[1]->MonInfo = NULL; } else { - if (pRADEONEnt->PortInfo[0]->MonInfo) { + if (pRADEONEnt->pOutput[0]->MonInfo) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID data from the display on 1st port ----------------------\n"); - xf86PrintEDID( pRADEONEnt->PortInfo[0]->MonInfo ); + xf86PrintEDID( pRADEONEnt->pOutput[0]->MonInfo ); } - if (pRADEONEnt->PortInfo[1]->MonInfo) { + if (pRADEONEnt->pOutput[1]->MonInfo) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID data from the display on 2nd port -----------------------\n"); - xf86PrintEDID( pRADEONEnt->PortInfo[1]->MonInfo ); + xf86PrintEDID( pRADEONEnt->pOutput[1]->MonInfo ); } } @@ -1285,13 +1295,10 @@ Bool RADEONMapControllers(ScrnInfoPtr pScrn) RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); unsigned char *RADEONMMIO = info->MMIO; Bool head_reversed = FALSE; - RADEONConnector *connector; - - info->MergeType = MT_NONE; + xf86OutputPtr output; + RADEONOutputPrivatePtr radeon_output; if (!info->IsSecondary) { - RADEONQueryConnectedDisplays(pScrn); - pRADEONEnt->PortInfo[0]->crtc_num = 1; pRADEONEnt->PortInfo[1]->crtc_num = 2; @@ -1364,61 +1371,49 @@ Bool RADEONMapControllers(ScrnInfoPtr pScrn) if(pRADEONEnt->HasCRTC2) { if(info->IsSecondary) { - connector = RADEONGetCrtcConnector(pScrn, 2); + output = RADEONGetCrtcConnector(pScrn, 2); + radeon_output = output->driver_private; pRADEONEnt->Controller[1]->binding = 2; - if (connector) { - info->DisplayType = connector->MonType; - pScrn->monitor->DDC = connector->MonInfo; + if (output) { + pScrn->monitor->DDC = output->MonInfo; } } else { - connector = RADEONGetCrtcConnector(pScrn, 1); + output = RADEONGetCrtcConnector(pScrn, 1); + radeon_output = output->driver_private; pRADEONEnt->Controller[0]->binding = 1; - if (connector) { - info->DisplayType = connector->MonType; - pScrn->monitor->DDC = connector->MonInfo; + if (output) { + pScrn->monitor->DDC = output->MonInfo; } } if(!pRADEONEnt->HasSecondary) { - connector = RADEONGetCrtcConnector(pScrn, 2); - if (connector) - info->MergeType = connector->MonType; - if (info->MergeType) - pRADEONEnt->Controller[1]->binding = 1; + pRADEONEnt->Controller[1]->binding = 1; } } else { - connector = RADEONGetCrtcConnector(pScrn, 1); - if (connector) { - if (connector->MonType == MT_NONE) - connector->MonType = MT_CRT; - info->DisplayType = connector->MonType; - pScrn->monitor->DDC = connector->MonInfo; + output = RADEONGetCrtcConnector(pScrn, 1); + radeon_output = output->driver_private; + if (output) { + if (radeon_output->MonType == MT_NONE) + radeon_output->MonType = MT_CRT; + pScrn->monitor->DDC = output->MonInfo; } - connector = RADEONGetCrtcConnector(pScrn, 2); - if (connector) - connector->MonType = MT_NONE; + output = RADEONGetCrtcConnector(pScrn, 2); + radeon_output = output->driver_private; + if (output) + radeon_output->MonType = MT_NONE; pRADEONEnt->Controller[1]->binding = 1; } if (!info->IsSecondary) { - connector = RADEONGetCrtcConnector(pScrn, 2); + output = RADEONGetCrtcConnector(pScrn, 2); + radeon_output = output->driver_private; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "---- Primary Head: Port%d ---- \n", head_reversed?2:1); - if (connector->MonType != MT_NONE) + if (radeon_output->MonType != MT_NONE) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "---- Secondary Head: Port%d ----\n", head_reversed?1:2); else xf86DrvMsg(pScrn->scrnIndex, X_INFO, "---- Secondary Head: Not used ----\n"); } - info->HBlank = 0; - info->HOverPlus = 0; - info->HSyncWidth = 0; - info->VBlank = 0; - info->VOverPlus = 0; - info->VSyncWidth = 0; - info->DotClock = 0; - info->UseBiosDividers = FALSE; - - info->OverlayOnCRTC2 = FALSE; return TRUE; } @@ -1436,7 +1431,7 @@ static void RADEONDacPowerSet(ScrnInfoPtr pScrn, Bool IsOn, Bool IsPrimaryDAC) CARD32 dac_cntl; CARD32 dac_macro_cntl = 0; dac_cntl = INREG(RADEON_DAC_CNTL); - if ((!info->IsMobility) || (info->ChipFamily == CHIP_FAMILY_RV350)) + if ((!info->IsMobility) || (info->ChipFamily >= CHIP_FAMILY_RV350)) dac_macro_cntl = INREG(RADEON_DAC_MACRO_CNTL); if (IsOn) { dac_cntl &= ~RADEON_DAC_PDWN; @@ -1449,8 +1444,9 @@ static void RADEONDacPowerSet(ScrnInfoPtr pScrn, Bool IsOn, Bool IsPrimaryDAC) RADEON_DAC_PDWN_G | RADEON_DAC_PDWN_B); } + ErrorF("Setting IsOn %d DAC CNTL %08X and DAC MACRO_CNTL %08X\n", IsOn, dac_cntl, dac_macro_cntl); OUTREG(RADEON_DAC_CNTL, dac_cntl); - if ((!info->IsMobility) || (info->ChipFamily == CHIP_FAMILY_RV350)) + if ((!info->IsMobility) || (info->ChipFamily >= CHIP_FAMILY_RV350)) OUTREG(RADEON_DAC_MACRO_CNTL, dac_macro_cntl); } else { CARD32 tv_dac_cntl; @@ -1557,21 +1553,23 @@ void RADEONDisableDisplays(ScrnInfoPtr pScrn) { } /* This is to be used enable/disable displays dynamically */ -void RADEONEnableDisplay(ScrnInfoPtr pScrn, RADEONConnector* pPort, BOOL bEnable) +void RADEONEnableDisplay(ScrnInfoPtr pScrn, xf86OutputPtr output, BOOL bEnable) { RADEONInfoPtr info = RADEONPTR(pScrn); RADEONSavePtr save = &info->ModeReg; unsigned char * RADEONMMIO = info->MMIO; unsigned long tmp; + RADEONOutputPrivatePtr radeon_output; + radeon_output = output->driver_private; if (bEnable) { - if (pPort->MonType == MT_CRT) { - if (pPort->DACType == DAC_PRIMARY) { + if (radeon_output->MonType == MT_CRT) { + if (radeon_output->DACType == DAC_PRIMARY) { tmp = INREG(RADEON_CRTC_EXT_CNTL); tmp |= RADEON_CRTC_CRT_ON; OUTREG(RADEON_CRTC_EXT_CNTL, tmp); save->crtc_ext_cntl |= RADEON_CRTC_CRT_ON; - } else if (pPort->DACType == DAC_TVDAC) { + } else if (radeon_output->DACType == DAC_TVDAC) { if (info->ChipFamily == CHIP_FAMILY_R200) { tmp = INREG(RADEON_FP2_GEN_CNTL); tmp |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN); @@ -1584,20 +1582,20 @@ void RADEONEnableDisplay(ScrnInfoPtr pScrn, RADEONConnector* pPort, BOOL bEnable save->crtc2_gen_cntl |= RADEON_CRTC2_CRT2_ON; } } - RADEONDacPowerSet(pScrn, bEnable, (pPort->DACType == DAC_PRIMARY)); - } else if (pPort->MonType == MT_DFP) { - if (pPort->TMDSType == TMDS_INT) { + RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY)); + } else if (radeon_output->MonType == MT_DFP) { + if (radeon_output->TMDSType == TMDS_INT) { tmp = INREG(RADEON_FP_GEN_CNTL); tmp |= (RADEON_FP_FPON | RADEON_FP_TMDS_EN); OUTREG(RADEON_FP_GEN_CNTL, tmp); save->fp_gen_cntl |= (RADEON_FP_FPON | RADEON_FP_TMDS_EN); - } else if (pPort->TMDSType == TMDS_EXT) { + } else if (radeon_output->TMDSType == TMDS_EXT) { tmp = INREG(RADEON_FP2_GEN_CNTL); tmp |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN); OUTREG(RADEON_FP2_GEN_CNTL, tmp); save->fp2_gen_cntl |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN); } - } else if (pPort->MonType == MT_LCD) { + } else if (radeon_output->MonType == MT_LCD) { tmp = INREG(RADEON_LVDS_GEN_CNTL); tmp |= (RADEON_LVDS_ON | RADEON_LVDS_BLON); tmp &= ~(RADEON_LVDS_DISPLAY_DIS); @@ -1607,13 +1605,13 @@ void RADEONEnableDisplay(ScrnInfoPtr pScrn, RADEONConnector* pPort, BOOL bEnable save->lvds_gen_cntl &= ~(RADEON_LVDS_DISPLAY_DIS); } } else { - if (pPort->MonType == MT_CRT || pPort->MonType == NONE) { - if (pPort->DACType == DAC_PRIMARY) { + if (radeon_output->MonType == MT_CRT || radeon_output->MonType == NONE) { + if (radeon_output->DACType == DAC_PRIMARY) { tmp = INREG(RADEON_CRTC_EXT_CNTL); tmp &= ~RADEON_CRTC_CRT_ON; OUTREG(RADEON_CRTC_EXT_CNTL, tmp); save->crtc_ext_cntl &= ~RADEON_CRTC_CRT_ON; - } else if (pPort->DACType == DAC_TVDAC) { + } else if (radeon_output->DACType == DAC_TVDAC) { if (info->ChipFamily == CHIP_FAMILY_R200) { tmp = INREG(RADEON_FP2_GEN_CNTL); tmp &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN); @@ -1626,16 +1624,16 @@ void RADEONEnableDisplay(ScrnInfoPtr pScrn, RADEONConnector* pPort, BOOL bEnable save->crtc2_gen_cntl &= ~RADEON_CRTC2_CRT2_ON; } } - RADEONDacPowerSet(pScrn, bEnable, (pPort->DACType == DAC_PRIMARY)); + RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY)); } - if (pPort->MonType == MT_DFP || pPort->MonType == NONE) { - if (pPort->TMDSType == TMDS_INT) { + if (radeon_output->MonType == MT_DFP || radeon_output->MonType == NONE) { + if (radeon_output->TMDSType == TMDS_INT) { tmp = INREG(RADEON_FP_GEN_CNTL); tmp &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN); OUTREG(RADEON_FP_GEN_CNTL, tmp); save->fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN); - } else if (pPort->TMDSType == TMDS_EXT) { + } else if (radeon_output->TMDSType == TMDS_EXT) { tmp = INREG(RADEON_FP2_GEN_CNTL); tmp &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN); OUTREG(RADEON_FP2_GEN_CNTL, tmp); @@ -1643,8 +1641,8 @@ void RADEONEnableDisplay(ScrnInfoPtr pScrn, RADEONConnector* pPort, BOOL bEnable } } - if (pPort->MonType == MT_LCD || - (pPort->MonType == NONE && pPort->ConnectorType == CONNECTOR_PROPRIETARY)) { + if (radeon_output->MonType == MT_LCD || + (radeon_output->MonType == NONE && radeon_output->ConnectorType == CONNECTOR_PROPRIETARY)) { unsigned long tmpPixclksCntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL); if (info->IsMobility || info->IsIGP) { /* Asic bug, when turning off LVDS_ON, we have to make sure @@ -1666,8 +1664,7 @@ void RADEONEnableDisplay(ScrnInfoPtr pScrn, RADEONConnector* pPort, BOOL bEnable } /* Calculate display buffer watermark to prevent buffer underflow */ -void RADEONInitDispBandwidth2(ScrnInfoPtr pScrn, RADEONInfoPtr info, RADEONInfoPtr info2, - DisplayModePtr mode1, DisplayModePtr mode2) +void RADEONInitDispBandwidth2(ScrnInfoPtr pScrn, RADEONInfoPtr info, int pixel_bytes2, DisplayModePtr mode1, DisplayModePtr mode2) { RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); unsigned char *RADEONMMIO = info->MMIO; @@ -1705,7 +1702,7 @@ void RADEONInitDispBandwidth2(ScrnInfoPtr pScrn, RADEONInfoPtr info, RADEONInfoP */ if ((info->DispPriority == 2) && IS_R300_VARIANT) { CARD32 mc_init_misc_lat_timer = INREG(R300_MC_INIT_MISC_LAT_TIMER); - if (pRADEONEnt->Controller[1]->IsActive) { + if (pRADEONEnt->pCrtc[1]->enabled) { mc_init_misc_lat_timer |= 0x1100; /* display 0 and 1 */ } else { mc_init_misc_lat_timer |= 0x0100; /* display 0 only */ @@ -1717,11 +1714,6 @@ void RADEONInitDispBandwidth2(ScrnInfoPtr pScrn, RADEONInfoPtr info, RADEONInfoP /* R420 and RV410 family not supported yet */ if (info->ChipFamily == CHIP_FAMILY_R420 || info->ChipFamily == CHIP_FAMILY_RV410) return; - if (pRADEONEnt->pSecondaryScrn) { - if (info->IsSecondary) return; - info2 = RADEONPTR(pRADEONEnt->pSecondaryScrn); - } else if (pRADEONEnt->Controller[1]->binding == 1) info2 = info; - /* * Determine if there is enough bandwidth for current display mode */ @@ -1734,8 +1726,8 @@ void RADEONInitDispBandwidth2(ScrnInfoPtr pScrn, RADEONInfoPtr info, RADEONInfoP pix_clk2 = 0; peak_disp_bw = (pix_clk * info->CurrentLayout.pixel_bytes); - if (info2) - peak_disp_bw += (pix_clk2 * info2->CurrentLayout.pixel_bytes); + if (pixel_bytes2) + peak_disp_bw += (pix_clk2 * pixel_bytes2); if (peak_disp_bw >= mem_bw * min_mem_eff) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, @@ -1875,8 +1867,8 @@ void RADEONInitDispBandwidth2(ScrnInfoPtr pScrn, RADEONInfoPtr info, RADEONInfoP Find the drain rate of the display buffer. */ disp_drain_rate = pix_clk / (16.0/info->CurrentLayout.pixel_bytes); - if (info2) - disp_drain_rate2 = pix_clk2 / (16.0/info2->CurrentLayout.pixel_bytes); + if (pixel_bytes2) + disp_drain_rate2 = pix_clk2 / (16.0/pixel_bytes2); else disp_drain_rate2 = 0; @@ -1929,7 +1921,7 @@ void RADEONInitDispBandwidth2(ScrnInfoPtr pScrn, RADEONInfoPtr info, RADEONInfoP (unsigned int)info->SavedReg.grph_buffer_cntl, INREG(RADEON_GRPH_BUFFER_CNTL))); if (mode2) { - stop_req = mode2->HDisplay * info2->CurrentLayout.pixel_bytes / 16; + stop_req = mode2->HDisplay * pixel_bytes2 / 16; if (stop_req > max_stop_req) stop_req = max_stop_req; @@ -1982,8 +1974,11 @@ void RADEONInitDispBandwidth(ScrnInfoPtr pScrn) { RADEONInfoPtr info = RADEONPTR(pScrn); RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); DisplayModePtr mode1, mode2; RADEONInfoPtr info2 = NULL; + xf86CrtcPtr crtc; + int pixel_bytes2 = 0; if (pRADEONEnt->pSecondaryScrn) { if (info->IsSecondary) return; @@ -1991,179 +1986,98 @@ void RADEONInitDispBandwidth(ScrnInfoPtr pScrn) } else if (pRADEONEnt->Controller[1]->binding == 1) info2 = info; mode1 = info->CurrentLayout.mode; - if (info->MergedFB) { - mode1 = ((RADEONMergedDisplayModePtr)info->CurrentLayout.mode->Private)->CRT1; - mode2 = ((RADEONMergedDisplayModePtr)info->CurrentLayout.mode->Private)->CRT2; - } else if ((pRADEONEnt->HasSecondary) && info2) { + if ((pRADEONEnt->HasSecondary) && info2) { mode2 = info2->CurrentLayout.mode; } else { mode2 = NULL; } - RADEONInitDispBandwidth2(pScrn, info, info2, mode1, mode2); -} - -static void RADEONBlankSet(ScrnInfoPtr pScrn, RADEONConnector *pPort) -{ - RADEONInfoPtr info = RADEONPTR(pScrn); - unsigned char *RADEONMMIO = info->MMIO; - - switch(pPort->MonType) { - case MT_LCD: - OUTREGP(RADEON_LVDS_GEN_CNTL, RADEON_LVDS_DISPLAY_DIS, ~RADEON_LVDS_DISPLAY_DIS); - break; + if (info2) + pixel_bytes2 = info2->CurrentLayout.pixel_bytes; + + + if (xf86_config->num_crtc == 2) { + pixel_bytes2 = 0; + mode2 = NULL; + + if (xf86_config->crtc[1]->enabled && xf86_config->crtc[0]->enabled) { + pixel_bytes2 = info->CurrentLayout.pixel_bytes; + mode1 = &xf86_config->crtc[0]->mode; + mode2 = &xf86_config->crtc[1]->mode; + } else if (xf86_config->crtc[0]->enabled) { + mode1 = &xf86_config->crtc[0]->mode; + } else if (xf86_config->crtc[1]->enabled) { + mode1 = &xf86_config->crtc[1]->mode; + } else + return; + } - case MT_CRT: - if ((info->ChipFamily == CHIP_FAMILY_R200) && - (pPort->DACType == DAC_TVDAC)) - OUTREGP(RADEON_FP2_GEN_CNTL, RADEON_FP2_BLANK_EN, ~RADEON_FP2_BLANK_EN); - - break; - case MT_DFP: - if (pPort->TMDSType == TMDS_EXT) - OUTREGP(RADEON_FP2_GEN_CNTL, RADEON_FP2_BLANK_EN, ~RADEON_FP2_BLANK_EN); - else - OUTREGP(RADEON_FP_GEN_CNTL, RADEON_FP_BLANK_EN, ~RADEON_FP_BLANK_EN); - - break; - case MT_NONE: - default: - break; - } + RADEONInitDispBandwidth2(pScrn, info, pixel_bytes2, mode1, mode2); } -/* Blank screen */ void RADEONBlank(ScrnInfoPtr pScrn) { RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); - RADEONConnector *pPort; - - if (!pRADEONEnt->HasSecondary || - (pRADEONEnt->HasSecondary && !info->IsSwitching) || - (info->IsSwitching && (!info->IsSecondary))) { - pPort = RADEONGetCrtcConnector(pScrn, 1); - if (pPort) - RADEONBlankSet(pScrn, pPort); - OUTREGP (RADEON_CRTC_EXT_CNTL, - RADEON_CRTC_DISPLAY_DIS | - RADEON_CRTC_VSYNC_DIS | - RADEON_CRTC_HSYNC_DIS, - ~(RADEON_CRTC_DISPLAY_DIS | - RADEON_CRTC_VSYNC_DIS | - RADEON_CRTC_HSYNC_DIS)); - - if (!pRADEONEnt->HasCRTC2) return; - - if (pRADEONEnt->Controller[1]->binding == 1) { - pPort = RADEONGetCrtcConnector(pScrn, 2); - if (pPort) - RADEONBlankSet(pScrn, pPort); - OUTREGP (RADEON_CRTC2_GEN_CNTL, - RADEON_CRTC2_DISP_DIS | - RADEON_CRTC2_VSYNC_DIS | - RADEON_CRTC2_HSYNC_DIS, - ~(RADEON_CRTC2_DISP_DIS | - RADEON_CRTC2_VSYNC_DIS | - RADEON_CRTC2_HSYNC_DIS)); + xf86OutputPtr output; + xf86CrtcPtr crtc; + int o, c; + + for (c = 0; c < xf86_config->num_crtc; c++) { + crtc = xf86_config->crtc[c]; + for (o = 0; o < xf86_config->num_output; o++) { + output = xf86_config->output[o]; + if (output->crtc != crtc) + continue; + + output->funcs->dpms(output, DPMSModeOff); } - } - - if ((pRADEONEnt->HasSecondary && !info->IsSwitching) || - (info->IsSwitching && info->IsSecondary)) { - pPort = RADEONGetCrtcConnector(pScrn, 2); - if (pPort) - RADEONBlankSet(pScrn, pPort); - OUTREGP (RADEON_CRTC2_GEN_CNTL, - RADEON_CRTC2_DISP_DIS | - RADEON_CRTC2_VSYNC_DIS | - RADEON_CRTC2_HSYNC_DIS, - ~(RADEON_CRTC2_DISP_DIS | - RADEON_CRTC2_VSYNC_DIS | - RADEON_CRTC2_HSYNC_DIS)); + crtc->funcs->dpms(crtc, DPMSModeOff); } } -static void RADEONUnblankSet(ScrnInfoPtr pScrn, RADEONConnector *pPort) -{ - RADEONInfoPtr info = RADEONPTR (pScrn); - unsigned char *RADEONMMIO = info->MMIO; - - switch(pPort->MonType) { - case MT_LCD: - OUTREGP(RADEON_LVDS_GEN_CNTL, 0, ~RADEON_LVDS_DISPLAY_DIS); - break; - case MT_CRT: - if ((info->ChipFamily == CHIP_FAMILY_R200) && - (pPort->DACType == DAC_TVDAC)) - OUTREGP(RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_BLANK_EN); - break; - case MT_DFP: - if (pPort->TMDSType == TMDS_EXT) - OUTREGP(RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_BLANK_EN); - else - OUTREGP(RADEON_FP_GEN_CNTL, 0, ~RADEON_FP_BLANK_EN); - break; - case MT_NONE: - default: - break; - } -} - -/* Unblank screen */ void RADEONUnblank(ScrnInfoPtr pScrn) { RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); - RADEONConnector *pPort; - - if (!pRADEONEnt->HasSecondary || (info->IsSwitching && !info->IsSecondary)) { - pPort = RADEONGetCrtcConnector(pScrn, 1); - if (pPort) - RADEONUnblankSet(pScrn, pPort); - OUTREGP(RADEON_CRTC_EXT_CNTL, - 0, - ~(RADEON_CRTC_DISPLAY_DIS | - RADEON_CRTC_VSYNC_DIS | - RADEON_CRTC_HSYNC_DIS)); - - if (!pRADEONEnt->HasCRTC2) return; - - if (pRADEONEnt->Controller[1]->binding == 1) { - pPort = RADEONGetCrtcConnector(pScrn, 2); - if (pPort) - RADEONUnblankSet(pScrn, pPort); - OUTREGP(RADEON_CRTC2_GEN_CNTL, 0, - ~(RADEON_CRTC2_DISP_DIS | - RADEON_CRTC2_VSYNC_DIS | - RADEON_CRTC2_HSYNC_DIS)); - } - } - - if (info->IsSwitching && info->IsSecondary) { - pPort = RADEONGetCrtcConnector(pScrn, 2); - if (pPort) - RADEONUnblankSet(pScrn, pPort); - OUTREGP(RADEON_CRTC2_GEN_CNTL, 0, - ~(RADEON_CRTC2_DISP_DIS | - RADEON_CRTC2_VSYNC_DIS | - RADEON_CRTC2_HSYNC_DIS)); + xf86OutputPtr output; + xf86CrtcPtr crtc; + int o, c; + + for (c = 0; c < xf86_config->num_crtc; c++) { + crtc = xf86_config->crtc[c]; + if(!crtc->enabled) + continue; + crtc->funcs->dpms(crtc, DPMSModeOn); + for (o = 0; o < xf86_config->num_output; o++) { + output = xf86_config->output[o]; + if (output->crtc != crtc) + continue; + + output->funcs->dpms(output, DPMSModeOn); + } } } -static void RADEONDPMSSetOn(ScrnInfoPtr pScrn, RADEONConnector *pPort) +static void RADEONDPMSSetOn(xf86OutputPtr output) { + ScrnInfoPtr pScrn = output->scrn; RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; RADEONMonitorType MonType; RADEONTmdsType TmdsType; RADEONDacType DacType; + RADEONOutputPrivatePtr radeon_output = output->driver_private; + + MonType = radeon_output->MonType; + TmdsType = radeon_output->TMDSType; + DacType = radeon_output->DACType; - MonType = pPort->MonType; - TmdsType = pPort->TMDSType; - DacType = pPort->DACType; + ErrorF("radeon_dpms_on %d %d %d\n", radeon_output->num, MonType, DacType); switch(MonType) { case MT_LCD: @@ -2190,18 +2104,20 @@ static void RADEONDPMSSetOn(ScrnInfoPtr pScrn, RADEONConnector *pPort) } } -static void RADEONDPMSSetOff(ScrnInfoPtr pScrn, RADEONConnector *pPort) +static void RADEONDPMSSetOff(xf86OutputPtr output) { + ScrnInfoPtr pScrn = output->scrn; RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; RADEONMonitorType MonType; RADEONTmdsType TmdsType; RADEONDacType DacType; unsigned long tmpPixclksCntl; + RADEONOutputPrivatePtr radeon_output = output->driver_private; - MonType = pPort->MonType; - TmdsType = pPort->TMDSType; - DacType = pPort->DACType; + MonType = radeon_output->MonType; + TmdsType = radeon_output->TMDSType; + DacType = radeon_output->DACType; switch(MonType) { case MT_LCD: @@ -2236,118 +2152,276 @@ static void RADEONDPMSSetOff(ScrnInfoPtr pScrn, RADEONConnector *pPort) } -/* Sets VESA Display Power Management Signaling (DPMS) Mode */ -void RADEONDisplayPowerManagementSet(ScrnInfoPtr pScrn, - int PowerManagementMode, - int flags) +static void +radeon_crtc_dpms(xf86CrtcPtr crtc, int mode) { - RADEONInfoPtr info = RADEONPTR(pScrn); - RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); + int mask; + ScrnInfoPtr pScrn = crtc->scrn; + RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private; + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + mask = radeon_crtc->crtc_id ? (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS | RADEON_CRTC2_HSYNC_DIS) : (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS | RADEON_CRTC_VSYNC_DIS); + + switch(mode) { + case DPMSModeOn: + if (radeon_crtc->crtc_id) { + OUTREGP(RADEON_CRTC2_GEN_CNTL, 0, ~mask); + } else { + OUTREGP(RADEON_CRTC_EXT_CNTL, 0, ~mask); + } + break; + case DPMSModeStandby: + if (radeon_crtc->crtc_id) { + OUTREGP(RADEON_CRTC2_GEN_CNTL, (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_HSYNC_DIS), ~mask); + } else { + OUTREGP(RADEON_CRTC_EXT_CNTL, (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS), ~mask); + } + break; + case DPMSModeSuspend: + if (radeon_crtc->crtc_id) { + OUTREGP(RADEON_CRTC2_GEN_CNTL, (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS), ~mask); + } else { + OUTREGP(RADEON_CRTC_EXT_CNTL, (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_VSYNC_DIS), ~mask); + } + break; + case DPMSModeOff: + if (radeon_crtc->crtc_id) { + OUTREGP(RADEON_CRTC2_GEN_CNTL, mask, ~mask); + } else { + OUTREGP(RADEON_CRTC_EXT_CNTL, mask, ~mask); + } + break; + } + + if (mode != DPMSModeOff) + radeon_crtc_load_lut(crtc); +} + +static Bool +radeon_crtc_mode_fixup(xf86CrtcPtr crtc, DisplayModePtr mode, + DisplayModePtr adjusted_mode) +{ + return TRUE; +} + +static void +radeon_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, + DisplayModePtr adjusted_mode, int x, int y) +{ + ScrnInfoPtr pScrn = crtc->scrn; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private; + RADEONInfoPtr info = RADEONPTR(pScrn); + RADEONMonitorType montype; + int i = 0; + + for (i = 0; i < xf86_config->num_output; i++) { + xf86OutputPtr output = xf86_config->output[i]; + RADEONOutputPrivatePtr radeon_output = output->driver_private; + + if (output->crtc == crtc) { + montype = radeon_output->MonType; + } + } + + switch (radeon_crtc->crtc_id) { + case 0: + RADEONInit2(pScrn, mode, NULL, 1, &info->ModeReg, montype); + break; + case 1: + RADEONInit2(pScrn, NULL, mode, 2, &info->ModeReg, montype); + break; + } + + RADEONBlank(pScrn); + RADEONRestoreMode(pScrn, &info->ModeReg); + if (info->DispPriority) + RADEONInitDispBandwidth(pScrn); + RADEONUnblank(pScrn); +} + +void radeon_crtc_load_lut(xf86CrtcPtr crtc) +{ + ScrnInfoPtr pScrn = crtc->scrn; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private; + RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; - RADEONConnector *pPort; - if (!pScrn->vtSema) return; + int i; - RADEONTRACE(("RADEONDisplayPowerManagementSet(%d,0x%x)\n", PowerManagementMode, flags)); + if (!crtc->enabled) + return; + + PAL_SELECT(radeon_crtc->crtc_id); + + for (i = 0; i < 256; i++) { + OUTPAL(i, radeon_crtc->lut_r[i], radeon_crtc->lut_g[i], radeon_crtc->lut_b[i]); + } +} -#ifdef XF86DRI - if (info->CPStarted) DRILock(pScrn->pScreen, 0); -#endif + +static void +radeon_crtc_gamma_set(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green, + CARD16 *blue, int size) +{ + ScrnInfoPtr pScrn = crtc->scrn; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private; + RADEONInfoPtr info = RADEONPTR(pScrn); + int i; + + for (i = 0; i < 256; i++) { + radeon_crtc->lut_r[i] = red[i] >> 8; + radeon_crtc->lut_g[i] = green[i] >> 8; + radeon_crtc->lut_b[i] = blue[i] >> 8; + } + + radeon_crtc_load_lut(crtc); +} + +static Bool +radeon_crtc_lock(xf86CrtcPtr crtc) +{ + ScrnInfoPtr pScrn = crtc->scrn; + RADEONInfoPtr info = RADEONPTR(pScrn); + Bool CPStarted = info->CPStarted; if (info->accelOn) RADEON_SYNC(info, pScrn); + return FALSE; +} - if (info->FBDev) { - fbdevHWDPMSSet(pScrn, PowerManagementMode, flags); - } else { - int mask1 = (RADEON_CRTC_DISPLAY_DIS | - RADEON_CRTC_HSYNC_DIS | - RADEON_CRTC_VSYNC_DIS); - int mask2 = (RADEON_CRTC2_DISP_DIS | - RADEON_CRTC2_VSYNC_DIS | - RADEON_CRTC2_HSYNC_DIS); - - switch (PowerManagementMode) { - case DPMSModeOn: - /* Screen: On; HSync: On, VSync: On */ - if (info->IsSecondary) - OUTREGP(RADEON_CRTC2_GEN_CNTL, 0, ~mask2); - else { - if (pRADEONEnt->Controller[1]->binding == 1) - OUTREGP(RADEON_CRTC2_GEN_CNTL, 0, ~mask2); - OUTREGP(RADEON_CRTC_EXT_CNTL, 0, ~mask1); - } - break; +static void +radeon_crtc_unlock(xf86CrtcPtr crtc) +{ + ScrnInfoPtr pScrn = crtc->scrn; + RADEONInfoPtr info = RADEONPTR(pScrn); - case DPMSModeStandby: - /* Screen: Off; HSync: Off, VSync: On */ - if (info->IsSecondary) - OUTREGP(RADEON_CRTC2_GEN_CNTL, - (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_HSYNC_DIS), - ~mask2); - else { - if (pRADEONEnt->Controller[1]->binding == 1) - OUTREGP(RADEON_CRTC2_GEN_CNTL, - (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_HSYNC_DIS), - ~mask2); - OUTREGP(RADEON_CRTC_EXT_CNTL, - (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS), - ~mask1); - } - break; + if (info->accelOn) + RADEON_SYNC(info, pScrn); +} - case DPMSModeSuspend: - /* Screen: Off; HSync: On, VSync: Off */ - if (info->IsSecondary) - OUTREGP(RADEON_CRTC2_GEN_CNTL, - (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS), - ~mask2); - else { - if (pRADEONEnt->Controller[1]->binding == 1) - OUTREGP(RADEON_CRTC2_GEN_CNTL, - (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS), - ~mask2); - OUTREGP(RADEON_CRTC_EXT_CNTL, - (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_VSYNC_DIS), - ~mask1); - } - break; +static const xf86CrtcFuncsRec radeon_crtc_funcs = { + .dpms = radeon_crtc_dpms, + .save = NULL, /* XXX */ + .restore = NULL, /* XXX */ + .mode_fixup = radeon_crtc_mode_fixup, + .mode_set = radeon_crtc_mode_set, + .gamma_set = radeon_crtc_gamma_set, + .lock = radeon_crtc_lock, + .unlock = radeon_crtc_unlock, + .destroy = NULL, /* XXX */ +}; - case DPMSModeOff: - /* Screen: Off; HSync: Off, VSync: Off */ - if (info->IsSecondary) - OUTREGP(RADEON_CRTC2_GEN_CNTL, mask2, ~mask2); - else { - if (pRADEONEnt->Controller[1]->binding == 1) - OUTREGP(RADEON_CRTC2_GEN_CNTL, mask2, ~mask2); - OUTREGP(RADEON_CRTC_EXT_CNTL, mask1, ~mask1); - } - break; - } +static void +radeon_dpms(xf86OutputPtr output, int mode) +{ + switch(mode) { + case DPMSModeOn: + RADEONDPMSSetOn(output); + break; + case DPMSModeOff: + case DPMSModeSuspend: + case DPMSModeStandby: + RADEONDPMSSetOff(output); + break; + } +} - if (PowerManagementMode == DPMSModeOn) { - pPort = RADEONGetCrtcConnector(pScrn, info->IsSecondary ? 2 : 1); - RADEONDPMSSetOn(pScrn, pPort); - if (pRADEONEnt->Controller[1]->binding == 1) { - pPort = RADEONGetCrtcConnector(pScrn, 2); - RADEONDPMSSetOn(pScrn, pPort); - } - } else if ((PowerManagementMode == DPMSModeOff) || - (PowerManagementMode == DPMSModeSuspend) || - (PowerManagementMode == DPMSModeStandby)) { - pPort = RADEONGetCrtcConnector(pScrn, info->IsSecondary ? 2 : 1); - RADEONDPMSSetOff(pScrn, pPort); - if (pRADEONEnt->Controller[1]->binding == 1) { - pPort = RADEONGetCrtcConnector(pScrn, 2); - RADEONDPMSSetOff(pScrn, pPort); - } - } +static void +radeon_save(xf86OutputPtr output) +{ + +} + +static void +radeon_restore(xf86OutputPtr restore) +{ + +} + +static int +radeon_mode_valid(xf86OutputPtr output, DisplayModePtr pMode) +{ + return MODE_OK; +} + +static Bool +radeon_mode_fixup(xf86OutputPtr output, DisplayModePtr mode, + DisplayModePtr adjusted_mode) +{ + return TRUE; + +} + +static void +radeon_mode_set(xf86OutputPtr output, DisplayModePtr mode, + DisplayModePtr adjusted_mode) +{ + ScrnInfoPtr pScrn = output->scrn; + RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); + RADEONOutputPrivatePtr radeon_output = output->driver_private; + + // RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->pOutput[0], ); +} + +static xf86OutputStatus +radeon_detect(xf86OutputPtr output) +{ + ScrnInfoPtr pScrn = output->scrn; + RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); + RADEONOutputPrivatePtr radeon_output = output->driver_private; + + radeon_output->MonType = MT_UNKNOWN; + RADEONConnectorFindMonitor(pScrn, output); + if (radeon_output->MonType == MT_UNKNOWN) { + output->subpixel_order = SubPixelUnknown; + return XF86OutputStatusUnknown; + } + else if (radeon_output->MonType == MT_NONE) { + output->subpixel_order = SubPixelUnknown; + return XF86OutputStatusDisconnected; + } else { + + switch(radeon_output->MonType) { + case MT_LCD: + case MT_DFP: output->subpixel_order = SubPixelHorizontalRGB; break; + default: output->subpixel_order = SubPixelNone; break; + } + + return XF86OutputStatusConnected; } -#ifdef XF86DRI - if (info->CPStarted) DRIUnlock(pScrn->pScreen); -#endif } +static DisplayModePtr +radeon_get_modes(xf86OutputPtr output) +{ + DisplayModePtr modes; + modes = RADEONProbeOutputModes(output); + return modes; +} + +static void +radeon_destroy (xf86OutputPtr output) +{ + if(output->driver_private) + xfree(output->driver_private); +} + +static const xf86OutputFuncsRec radeon_output_funcs = { + .dpms = radeon_dpms, + .save = radeon_save, + .restore = radeon_restore, + .mode_valid = radeon_mode_valid, + .mode_fixup = radeon_mode_fixup, + .mode_set = radeon_mode_set, + .detect = radeon_detect, + .get_modes = radeon_get_modes, + .destroy = radeon_destroy +}; + Bool RADEONAllocateControllers(ScrnInfoPtr pScrn) { RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); @@ -2355,45 +2429,256 @@ Bool RADEONAllocateControllers(ScrnInfoPtr pScrn) if (pRADEONEnt->Controller[0]) return TRUE; - pRADEONEnt->Controller[0] = xcalloc(sizeof(RADEONController), 1); + pRADEONEnt->pCrtc[0] = xf86CrtcCreate(pScrn, &radeon_crtc_funcs); + if (!pRADEONEnt->pCrtc[0]) + return FALSE; + + pRADEONEnt->Controller[0] = xnfcalloc(sizeof(RADEONCrtcPrivateRec), 1); if (!pRADEONEnt->Controller[0]) return FALSE; - - pRADEONEnt->Controller[1] = xcalloc(sizeof(RADEONController), 1); + + pRADEONEnt->pCrtc[0]->driver_private = pRADEONEnt->Controller[0]; + pRADEONEnt->Controller[0]->crtc_id = 0; + + if (!pRADEONEnt->HasCRTC2) + return TRUE; + + pRADEONEnt->pCrtc[1] = xf86CrtcCreate(pScrn, &radeon_crtc_funcs); + if (!pRADEONEnt->pCrtc[1]) + return FALSE; + + pRADEONEnt->Controller[1] = xnfcalloc(sizeof(RADEONCrtcPrivateRec), 1); if (!pRADEONEnt->Controller[1]) { xfree(pRADEONEnt->Controller[0]); return FALSE; } + pRADEONEnt->pCrtc[1]->driver_private = pRADEONEnt->Controller[1]; + pRADEONEnt->Controller[1]->crtc_id = 1; return TRUE; } -Bool RADEONAllocateConnectors(ScrnInfoPtr pScrn) +Bool RADEONAllocatePortInfo(ScrnInfoPtr pScrn) { RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); + int num_connectors; int i; if (pRADEONEnt->PortInfo[0]) + return TRUE; + + /* for now always allocate max connectors */ + for (i = 0 ; i < RADEON_MAX_CONNECTOR; i++) { + + pRADEONEnt->PortInfo[i] = xnfcalloc(sizeof(RADEONOutputPrivateRec), 1); + if (!pRADEONEnt->PortInfo[i]) + return FALSE; + } + return TRUE; +} + +void RADEONSetOutputType(ScrnInfoPtr pScrn, RADEONOutputPrivatePtr radeon_output) +{ + RADEONInfoPtr info = RADEONPTR (pScrn); + RADEONOutputType output; + if (info->IsAtomBios) { + switch(radeon_output->ConnectorType) { + case 0: output = OUTPUT_NONE; break; + case 1: output = OUTPUT_VGA; break; + case 2: + case 3: + case 4: output = OUTPUT_DVI; break; + case 5: output = OUTPUT_STV; break; + case 6: output = OUTPUT_CTV; break; + case 7: + case 8: output = OUTPUT_LVDS; break; + case 9: + default: + output = OUTPUT_NONE; break; + } + } + else { + switch(radeon_output->ConnectorType) { + case 0: output = OUTPUT_NONE; break; + case 1: output = OUTPUT_LVDS; break; + case 2: output = OUTPUT_VGA; break; + case 3: + case 4: output = OUTPUT_DVI; break; + case 5: output = OUTPUT_STV; break; + case 6: output = OUTPUT_CTV; break; + default: output = OUTPUT_NONE; break; + } + } + radeon_output->type = output; +} + +Bool RADEONAllocateConnectors(ScrnInfoPtr pScrn) +{ + RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); + int i; + + if (pRADEONEnt->pOutput[0]) return TRUE; /* for now always allocate max connectors */ for (i = 0 ; i < RADEON_MAX_CONNECTOR; i++) { - pRADEONEnt->PortInfo[i] = xcalloc(sizeof(RADEONConnector), 1); - if (!pRADEONEnt->PortInfo[i]) - return FALSE; + + + pRADEONEnt->pOutput[i] = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[pRADEONEnt->PortInfo[i]->type]); + if (!pRADEONEnt->pOutput[i]) + return FALSE; + + pRADEONEnt->pOutput[i]->driver_private = pRADEONEnt->PortInfo[i]; + pRADEONEnt->PortInfo[i]->num = i; + + pRADEONEnt->pOutput[i]->possible_crtcs = (1<<0); + if (pRADEONEnt->PortInfo[i]->type != OUTPUT_LVDS) + pRADEONEnt->pOutput[i]->possible_crtcs |= (1<<1); + + pRADEONEnt->pOutput[i]->possible_clones = 0; } return TRUE; } -RADEONConnector *RADEONGetCrtcConnector(ScrnInfoPtr pScrn, int crtc_num) + + +xf86OutputPtr RADEONGetCrtcConnector(ScrnInfoPtr pScrn, int crtc_num) { RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); if (pRADEONEnt->PortInfo[0]->crtc_num == crtc_num) - return pRADEONEnt->PortInfo[0]; + return pRADEONEnt->pOutput[0]; else if (pRADEONEnt->PortInfo[1]->crtc_num == crtc_num) - return pRADEONEnt->PortInfo[1]; + return pRADEONEnt->pOutput[1]; return NULL; } + + +/** + * In the current world order, there are lists of modes per output, which may + * or may not include the mode that was asked to be set by XFree86's mode + * selection. Find the closest one, in the following preference order: + * + * - Equality + * - Closer in size to the requested mode, but no larger + * - Closer in refresh rate to the requested mode. + */ +DisplayModePtr +RADEONCrtcFindClosestMode(xf86CrtcPtr crtc, DisplayModePtr pMode) +{ + ScrnInfoPtr pScrn = crtc->scrn; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + DisplayModePtr pBest = NULL, pScan = NULL; + int i; + + /* Assume that there's only one output connected to the given CRTC. */ + for (i = 0; i < xf86_config->num_output; i++) + { + xf86OutputPtr output = xf86_config->output[i]; + if (output->crtc == crtc && output->probed_modes != NULL) + { + pScan = output->probed_modes; + break; + } + } + + /* If the pipe doesn't have any detected modes, just let the system try to + * spam the desired mode in. + */ + if (pScan == NULL) { + RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "No crtc mode list for crtc %d," + "continuing with desired mode\n", radeon_crtc->crtc_id); + return pMode; + } + + for (; pScan != NULL; pScan = pScan->next) { + assert(pScan->VRefresh != 0.0); + + /* If there's an exact match, we're done. */ + if (xf86ModesEqual(pScan, pMode)) { + pBest = pMode; + break; + } + + /* Reject if it's larger than the desired mode. */ + if (pScan->HDisplay > pMode->HDisplay || + pScan->VDisplay > pMode->VDisplay) + { + continue; + } + + if (pBest == NULL) { + pBest = pScan; + continue; + } + + /* Find if it's closer to the right size than the current best + * option. + */ + if ((pScan->HDisplay > pBest->HDisplay && + pScan->VDisplay >= pBest->VDisplay) || + (pScan->HDisplay >= pBest->HDisplay && + pScan->VDisplay > pBest->VDisplay)) + { + pBest = pScan; + continue; + } + + /* Find if it's still closer to the right refresh than the current + * best resolution. + */ + if (pScan->HDisplay == pBest->HDisplay && + pScan->VDisplay == pBest->VDisplay && + (fabs(pScan->VRefresh - pMode->VRefresh) < + fabs(pBest->VRefresh - pMode->VRefresh))) { + pBest = pScan; + } + } + + if (pBest == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "No suitable mode found to program for the pipe.\n" + " continuing with desired mode %dx%d@%.1f\n", + pMode->HDisplay, pMode->VDisplay, pMode->VRefresh); + } else if (!xf86ModesEqual(pBest, pMode)) { + RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private; + int crtc = radeon_crtc->crtc_id; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Choosing pipe %d's mode %dx%d@%.1f instead of xf86 " + "mode %dx%d@%.1f\n", crtc, + pBest->HDisplay, pBest->VDisplay, pBest->VRefresh, + pMode->HDisplay, pMode->VDisplay, pMode->VRefresh); + pMode = pBest; + } + return pMode; +} + +void +RADEONChooseOverlayCRTC(ScrnInfoPtr pScrn, BoxPtr dstBox) +{ + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + RADEONInfoPtr info = RADEONPTR(pScrn); + int c; + int highx = 0, highy = 0; + int crtc_num; + + for (c = 0; c < xf86_config->num_crtc; c++) + { + xf86CrtcPtr crtc = xf86_config->crtc[c]; + + if (!crtc->enabled) + continue; + + if ((dstBox->x1 >= crtc->x) && (dstBox->y1 >= crtc->y)) + crtc_num = c; + } + + if (crtc_num == 1) + info->OverlayOnCRTC2 = TRUE; + else + info->OverlayOnCRTC2 = FALSE; +} diff --git a/src/radeon_driver.c b/src/radeon_driver.c index d1cd790..8de9eef 100644 --- a/src/radeon_driver.c +++ b/src/radeon_driver.c @@ -74,7 +74,6 @@ #include "radeon_macros.h" #include "radeon_probe.h" #include "radeon_version.h" -#include "radeon_mergedfb.h" #ifdef XF86DRI #define _XF86DRI_SERVER_ @@ -113,13 +112,13 @@ /* Forward definitions for driver functions */ +void RADEONRestoreMode(ScrnInfoPtr pScrn, RADEONSavePtr restore); static Bool RADEONCloseScreen(int scrnIndex, ScreenPtr pScreen); static Bool RADEONSaveScreen(ScreenPtr pScreen, int mode); static void RADEONSave(ScrnInfoPtr pScrn); -static void RADEONRestore(ScrnInfoPtr pScrn); +//static void RADEONRestore(ScrnInfoPtr pScrn); static Bool RADEONModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode); -static void RADEONGetMergedFBOptions(ScrnInfoPtr pScrn); static void RADEONSetDynamicClock(ScrnInfoPtr pScrn, int mode); static void RADEONForceSomeClocks(ScrnInfoPtr pScrn); static void RADEONSaveMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save); @@ -128,6 +127,8 @@ static void RADEONSaveMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save); static void RADEONAdjustMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save); #endif +DisplayModePtr +RADEONCrtcFindClosestMode(xf86CrtcPtr crtc, DisplayModePtr pMode); /* psuedo xinerama support */ extern Bool RADEONnoPanoramiXExtension; @@ -161,16 +162,6 @@ static const OptionInfoRec RADEONOptions[] = { { OPTION_MONITOR_LAYOUT, "MonitorLayout", OPTV_ANYSTR, {0}, FALSE }, { OPTION_IGNORE_EDID, "IgnoreEDID", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_FBDEV, "UseFBDev", OPTV_BOOLEAN, {0}, FALSE }, - { OPTION_MERGEDFB, "MergedFB", OPTV_BOOLEAN, {0}, FALSE }, - { OPTION_CRT2HSYNC, "CRT2HSync", OPTV_ANYSTR, {0}, FALSE }, - { OPTION_CRT2VREFRESH, "CRT2VRefresh", OPTV_ANYSTR, {0}, FALSE }, - { OPTION_CRT2POS, "CRT2Position", OPTV_ANYSTR, {0}, FALSE }, - { OPTION_METAMODES, "MetaModes", OPTV_ANYSTR, {0}, FALSE }, - { OPTION_MERGEDDPI, "MergedDPI", OPTV_ANYSTR, {0}, FALSE }, - { OPTION_RADEONXINERAMA, "MergedXinerama", OPTV_BOOLEAN, {0}, FALSE }, - { OPTION_CRT2ISSCRN0, "MergedXineramaCRT2IsScreen0", OPTV_BOOLEAN, {0}, FALSE }, - { OPTION_MERGEDFBNONRECT, "MergedNonRectangular", OPTV_BOOLEAN, {0}, FALSE }, - { OPTION_MERGEDFBMOUSER, "MergedMouseRestriction", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_DISP_PRIORITY, "DisplayPriority", OPTV_ANYSTR, {0}, FALSE }, { OPTION_PANEL_SIZE, "PanelSize", OPTV_ANYSTR, {0}, FALSE }, { OPTION_MIN_DOTCLOCK, "ForceMinDotClock", OPTV_FREQ, {0}, FALSE }, @@ -440,6 +431,22 @@ struct RADEONInt10Save { static Bool RADEONMapMMIO(ScrnInfoPtr pScrn); static Bool RADEONUnmapMMIO(ScrnInfoPtr pScrn); +static Bool +RADEONCreateScreenResources (ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + + pScreen->CreateScreenResources = info->CreateScreenResources; + if (!(*pScreen->CreateScreenResources)(pScreen)) + return FALSE; + + if (!xf86RandR12CreateScreenResources(pScreen)) + return FALSE; + + return TRUE; +} + RADEONEntPtr RADEONEntPriv(ScrnInfoPtr pScrn) { DevUnion *pPriv; @@ -534,46 +541,6 @@ static Bool RADEONGetRec(ScrnInfoPtr pScrn) static void RADEONFreeRec(ScrnInfoPtr pScrn) { RADEONInfoPtr info = RADEONPTR(pScrn); - if(info->CRT2HSync) xfree(info->CRT2HSync); - info->CRT2HSync = NULL; - if(info->CRT2VRefresh) xfree(info->CRT2VRefresh); - info->CRT2VRefresh = NULL; - if(info->MetaModes) xfree(info->MetaModes); - info->MetaModes = NULL; - if(info->CRT2pScrn) { - if(info->CRT2pScrn->modes) { - while(info->CRT2pScrn->modes) - xf86DeleteMode(&info->CRT2pScrn->modes, info->CRT2pScrn->modes); - } - if(info->CRT2pScrn->monitor) { - if(info->CRT2pScrn->monitor->Modes) { - while(info->CRT2pScrn->monitor->Modes) - xf86DeleteMode(&info->CRT2pScrn->monitor->Modes, info->CRT2pScrn->monitor->Modes); - } - if(info->CRT2pScrn->monitor->DDC) xfree(info->CRT2pScrn->monitor->DDC); - xfree(info->CRT2pScrn->monitor); - } - xfree(info->CRT2pScrn); - info->CRT2pScrn = NULL; - } - if(info->CRT1Modes) { - if(info->CRT1Modes != pScrn->modes) { - if(pScrn->modes) { - pScrn->currentMode = pScrn->modes; - do { - DisplayModePtr p = pScrn->currentMode->next; - if(pScrn->currentMode->Private) - xfree(pScrn->currentMode->Private); - xfree(pScrn->currentMode); - pScrn->currentMode = p; - } while(pScrn->currentMode != pScrn->modes); - } - pScrn->currentMode = info->CRT1CurrentMode; - pScrn->modes = info->CRT1Modes; - info->CRT1CurrentMode = NULL; - info->CRT1Modes = NULL; - } - } if (!pScrn || !pScrn->driverPrivate) return; xfree(pScrn->driverPrivate); @@ -1462,7 +1429,6 @@ static Bool RADEONPreInitVRAM(ScrnInfoPtr pScrn) * be able to be adjusted by user with a config option. */ if (info->IsPrimary) { pScrn->videoRam /= 2; - info->MergedFB = FALSE; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using %dk of videoram for primary head\n", pScrn->videoRam); @@ -1955,9 +1921,7 @@ static void RADEONPreInitDDC(ScrnInfoPtr pScrn) if (info->ddc2) { if (xf86LoadSubModule(pScrn, "i2c")) { xf86LoaderReqSymLists(i2cSymbols,NULL); - info->ddc2 = RADEONI2cInit(pScrn); } - else info->ddc2 = FALSE; } } @@ -1970,398 +1934,6 @@ static Bool RADEONPreInitGamma(ScrnInfoPtr pScrn) return TRUE; } -/* This is called by RADEONPreInit to validate modes and compute - * parameters for all of the valid modes. - */ -static Bool RADEONPreInitModes(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10) -{ - RADEONInfoPtr info = RADEONPTR(pScrn); - ClockRangePtr clockRanges; - int modesFound; - RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); - char *s; - RADEONConnector *connector; - /* This option has two purposes: - * - * 1. For CRT, if this option is on, xf86ValidateModes (to - * LOOKUP_BEST_REFRESH) is not going to be used for mode - * validation. Instead, we'll validate modes by matching exactly - * the modes supported from the DDC data. This option can be - * used (a) to enable non-standard modes listed in the Detailed - * Timings block of EDID, like 2048x1536 (not included in - * xf86DefModes), (b) to avoid unstable modes for some flat - * panels working in analog mode (some modes validated by - * xf86ValidateModes don't really work with these panels). - * - * 2. For DFP on primary head, with this option on, the validation - * routine will try to use supported modes from DDC data first - * before trying on-chip RMX streching. By default, native mode - * + RMX streching is used for all non-native modes, it appears - * more reliable. Some non-native modes listed in the DDC data - * may not work properly if they are used directly. This seems to - * only happen to a few panels (haven't nailed this down yet, it - * may related to the incorrect setting in TMDS_PLL_CNTL when - * pixel clock is changed). Use this option may give you better - * refresh rate for some non-native modes. The 2nd DVI port will - * always use DDC modes directly (only have one on-chip RMX - * unit). - * - * Note: This option will be dismissed if no DDC data is available. - */ - - if (info->MergedFB) { - if (!(pScrn->display->virtualX)) - info->NoVirtual = TRUE; - else - info->NoVirtual = FALSE; - } - - info->ddc_mode = - xf86ReturnOptValBool(info->Options, OPTION_DDC_MODE, FALSE); - - /* don't use RMX if we have a dual-tmds panels */ - - if ((connector = RADEONGetCrtcConnector(pScrn, 2))) - if (connector->MonType == MT_DFP) - info->ddc_mode = TRUE; - /* don't use RMX if we are Dell Server */ - if (info->IsDellServer) - { - info->ddc_mode = TRUE; - } - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Validating modes on %s head ---------\n", - info->IsSecondary ? "Secondary" : "Primary"); - - if (!pRADEONEnt->PortInfo[0]->MonInfo && !pRADEONEnt->PortInfo[1]->MonInfo && info->ddc_mode) { - info->ddc_mode = FALSE; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "No DDC data available, DDCMode option is dismissed\n"); - } - - if ((info->DisplayType == MT_DFP) || - (info->DisplayType == MT_LCD)) { - if ((s = xf86GetOptValString(info->Options, OPTION_PANEL_SIZE))) { - int PanelX, PanelY; - DisplayModePtr tmp_mode = NULL; - if (sscanf(s, "%dx%d", &PanelX, &PanelY) == 2) { - info->PanelXRes = PanelX; - info->PanelYRes = PanelY; - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Panel size is forced to: %s\n", s); - - /* We can't trust BIOS or DDC timings anymore, - Use whatever specified in the Modeline. - If no Modeline specified, we'll just pick the VESA mode at - 60Hz refresh rate which is likely to be the best for a flat panel. - */ - info->ddc_mode = FALSE; - pScrn->monitor->DDC = NULL; - tmp_mode = pScrn->monitor->Modes; - while(tmp_mode) { - if ((tmp_mode->HDisplay == PanelX) && - (tmp_mode->VDisplay == PanelY)) { - - float refresh = - (float)tmp_mode->Clock * 1000.0 / tmp_mode->HTotal / tmp_mode->VTotal; - if ((abs(60.0 - refresh) < 1.0) || - (tmp_mode->type == 0)) { - info->HBlank = tmp_mode->HTotal - tmp_mode->HDisplay; - info->HOverPlus = tmp_mode->HSyncStart - tmp_mode->HDisplay; - info->HSyncWidth = tmp_mode->HSyncEnd - tmp_mode->HSyncStart; - info->VBlank = tmp_mode->VTotal - tmp_mode->VDisplay; - info->VOverPlus = tmp_mode->VSyncStart - tmp_mode->VDisplay; - info->VSyncWidth = tmp_mode->VSyncEnd - tmp_mode->VSyncStart; - info->DotClock = tmp_mode->Clock; - info->Flags = 0; - break; - } - } - tmp_mode = tmp_mode->next; - } - if (info->DotClock == 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "No valid timing info for specified panel size.\n" - "Please specify the Modeline for this panel\n"); - return FALSE; - } - } else { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Invalid PanelSize value: %s\n", s); - } - } else - RADEONGetPanelInfo(pScrn); - } - - if (pScrn->monitor->DDC) { - /* If we still don't know sync range yet, let's try EDID. - * - * Note that, since we can have dual heads, Xconfigurator - * may not be able to probe both monitors correctly through - * vbe probe function (RADEONProbeDDC). Here we provide an - * additional way to auto-detect sync ranges if they haven't - * been added to XF86Config manually. - */ - if (pScrn->monitor->nHsync <= 0) - RADEONSetSyncRangeFromEdid(pScrn, 1); - if (pScrn->monitor->nVrefresh <= 0) - RADEONSetSyncRangeFromEdid(pScrn, 0); - } - - /* Get mode information */ - pScrn->progClock = TRUE; - clockRanges = xnfcalloc(sizeof(*clockRanges), 1); - clockRanges->next = NULL; - clockRanges->minClock = info->pll.min_pll_freq; - clockRanges->maxClock = info->pll.max_pll_freq * 10; - clockRanges->clockIndex = -1; - clockRanges->interlaceAllowed = (info->DisplayType == MT_CRT); - clockRanges->doubleScanAllowed = (info->DisplayType == MT_CRT); - - /* We'll use our own mode validation routine for DFP/LCD, since - * xf86ValidateModes does not work correctly with the DFP/LCD modes - * 'stretched' from their native mode. - */ - if (info->DisplayType == MT_CRT && !info->ddc_mode) { - - modesFound = - xf86ValidateModes(pScrn, - pScrn->monitor->Modes, - pScrn->display->modes, - clockRanges, - NULL, /* linePitches */ - 8 * 64, /* minPitch */ - 8 * 1024, /* maxPitch */ - info->allowColorTiling ? 2048 : - 64 * pScrn->bitsPerPixel, /* pitchInc */ - 128, /* minHeight */ - info->MaxLines, /* maxHeight */ - pScrn->display->virtualX, - pScrn->display->virtualY, - info->FbMapSize, - LOOKUP_BEST_REFRESH); - - if (modesFound < 1 && info->FBDev) { - fbdevHWUseBuildinMode(pScrn); - pScrn->displayWidth = fbdevHWGetLineLength(pScrn) - / info->CurrentLayout.pixel_bytes; - modesFound = 1; - } - - if (modesFound == -1) return FALSE; - - xf86PruneDriverModes(pScrn); - if (!modesFound || !pScrn->modes) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n"); - return FALSE; - } - - } else { - /* First, free any allocated modes during configuration, since - * we don't need them - */ - while (pScrn->modes) - xf86DeleteMode(&pScrn->modes, pScrn->modes); - while (pScrn->modePool) - xf86DeleteMode(&pScrn->modePool, pScrn->modePool); - - /* Next try to add DDC modes */ - modesFound = RADEONValidateDDCModes(pScrn, pScrn->display->modes, - info->DisplayType, 0); - - /* If that fails and we're connect to a flat panel, then try to - * add the flat panel modes - */ - if (info->DisplayType != MT_CRT) { - - /* some panels have DDC, but don't have internal scaler. - * in this case, we need to validate additional modes - * by using on-chip RMX. - */ - int user_modes_asked = 0, user_modes_found = 0, i; - DisplayModePtr tmp_mode = pScrn->modes; - while (pScrn->display->modes[user_modes_asked]) user_modes_asked++; - if (tmp_mode) { - for (i = 0; i < modesFound; i++) { - if (tmp_mode->type & M_T_USERDEF) user_modes_found++; - tmp_mode = tmp_mode->next; - } - } - - if ((modesFound <= 1) || (user_modes_found < user_modes_asked)) { - /* when panel size is not valid, try to validate - * mode using xf86ValidateModes routine - * This can happen when DDC is disabled. - */ - if (info->PanelXRes < 320 || info->PanelYRes < 200) - modesFound = - xf86ValidateModes(pScrn, - pScrn->monitor->Modes, - pScrn->display->modes, - clockRanges, - NULL, /* linePitches */ - 8 * 64, /* minPitch */ - 8 * 1024, /* maxPitch */ - info->allowColorTiling ? 2048 : - 64 * pScrn->bitsPerPixel, /* pitchInc */ - 128, /* minHeight */ - info->MaxLines, /* maxHeight */ - pScrn->display->virtualX, - pScrn->display->virtualY, - info->FbMapSize, - LOOKUP_BEST_REFRESH); - else if (!info->IsSecondary) - modesFound = RADEONValidateFPModes(pScrn, pScrn->display->modes); - } - } - - /* Setup the screen's clockRanges for the VidMode extension */ - if (!pScrn->clockRanges) { - pScrn->clockRanges = xnfcalloc(sizeof(*(pScrn->clockRanges)), 1); - memcpy(pScrn->clockRanges, clockRanges, sizeof(*clockRanges)); - pScrn->clockRanges->strategy = LOOKUP_BEST_REFRESH; - } - - /* Fail if we still don't have any valid modes */ - if (modesFound < 1) { - if (info->DisplayType == MT_CRT) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "No valid DDC modes found for this CRT\n"); - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Try turning off the \"DDCMode\" option\n"); - } else { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "No valid mode found for this DFP/LCD\n"); - } - return FALSE; - } - } - - xf86SetCrtcForModes(pScrn, 0); - - if (pRADEONEnt->HasCRTC2) { - if (pRADEONEnt->Controller[1]->binding == 1) { - - /* If we have 2 screens from the config file, we don't need - * to do clone thing, let each screen handles one head. - */ - if (!pRADEONEnt->HasSecondary) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Validating CRTC2 modes for MergedFB ------------ \n"); - - modesFound = RADEONValidateMergeModes(pScrn); - if (modesFound < 1) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "No valid mode found for CRTC2, disabling MergedFB\n"); - info->MergedFB = FALSE; - } - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Total of %d CRTC2 modes found for MergedFB------------ \n", - modesFound); - } - } - } - - pScrn->currentMode = pScrn->modes; - if(info->MergedFB) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Modes for CRT1: ********************\n"); - } - xf86PrintModes(pScrn); - - - if (pRADEONEnt->HasCRTC2) { - if(pRADEONEnt->Controller[1]->binding == 1) { - - xf86SetCrtcForModes(info->CRT2pScrn, INTERLACE_HALVE_V); - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Modes for CRT2: ********************\n"); - - xf86PrintModes(info->CRT2pScrn); - - info->CRT1Modes = pScrn->modes; - info->CRT1CurrentMode = pScrn->currentMode; - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Generating MergedFB mode list\n"); - - if (info->NoVirtual) { - pScrn->display->virtualX = 0; - pScrn->display->virtualY = 0; - } - pScrn->modes = RADEONGenerateModeList(pScrn, info->MetaModes, - info->CRT1Modes, info->CRT2pScrn->modes, - info->CRT2Position); - - if(!pScrn->modes) { - - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to parse MetaModes or no modes found. MergeFB mode disabled.\n"); - if(info->CRT2pScrn) { - if(info->CRT2pScrn->modes) { - while(info->CRT2pScrn->modes) - xf86DeleteMode(&info->CRT2pScrn->modes, info->CRT2pScrn->modes); - } - if(info->CRT2pScrn->monitor) { - if(info->CRT2pScrn->monitor->Modes) { - while(info->CRT2pScrn->monitor->Modes) - xf86DeleteMode(&info->CRT2pScrn->monitor->Modes, info->CRT2pScrn->monitor->Modes); - } - if(info->CRT2pScrn->monitor->DDC) xfree(info->CRT2pScrn->monitor->DDC); - xfree(info->CRT2pScrn->monitor); - } - xfree(info->CRT2pScrn); - info->CRT2pScrn = NULL; - } - pScrn->modes = info->CRT1Modes; - info->CRT1Modes = NULL; - info->MergedFB = FALSE; - - } - } - } - - if (info->MergedFB) { - /* If no virtual dimension was given by the user, - * calculate a sane one now. Adapts pScrn->virtualX, - * pScrn->virtualY and pScrn->displayWidth. - */ - RADEONRecalcDefaultVirtualSize(pScrn); - info->CRT2pScrn->virtualX = pScrn->virtualX; - info->CRT2pScrn->virtualY = pScrn->virtualY; - RADEONSetPitch(pScrn); - RADEONSetPitch(info->CRT2pScrn); - - pScrn->modes = pScrn->modes->next; /* We get the last from GenerateModeList() */ - pScrn->currentMode = pScrn->modes; - - /* Update CurrentLayout */ - info->CurrentLayout.mode = pScrn->currentMode; - info->CurrentLayout.displayWidth = pScrn->displayWidth; - } - - /* Set DPI */ - /* xf86SetDpi(pScrn, 0, 0); */ - - if (info->MergedFB) { - RADEONMergedFBSetDpi(pScrn, info->CRT2pScrn, info->CRT2Position); - } else { - xf86SetDpi(pScrn, 0, 0); - info->RADEONDPIVX = pScrn->virtualX; - info->RADEONDPIVY = pScrn->virtualY; - } - - /* Get ScreenInit function */ - if (!xf86LoadSubModule(pScrn, "fb")) return FALSE; - - xf86LoaderReqSymLists(fbSymbols, NULL); - - info->CurrentLayout.displayWidth = pScrn->displayWidth; - info->CurrentLayout.mode = pScrn->currentMode; - - return TRUE; -} - /* This is called by RADEONPreInit to initialize the hardware cursor */ static Bool RADEONPreInitCursor(ScrnInfoPtr pScrn) { @@ -2503,7 +2075,7 @@ static Bool RADEONPreInitDRI(ScrnInfoPtr pScrn) "Direct Rendering Disabled -- " "Dual-head configuration is not working with " "DRI at present.\n" - "Please use the radeon MergedFB option if you " + "Please use the radeon randr 1.2 support option if you " "want Dual-head with DRI.\n"); return FALSE; } @@ -2919,25 +2491,43 @@ static Bool RADEONPreInitXv(ScrnInfoPtr pScrn) static Bool RADEONPreInitControllers(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10) { RADEONInfoPtr info = RADEONPTR(pScrn); + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + int i; if (!info->IsSecondary) { - if (!RADEONAllocateConnectors(pScrn)) + + if (!RADEONAllocatePortInfo(pScrn)) return FALSE; if (!RADEONAllocateControllers(pScrn)) return FALSE; - } RADEONGetBIOSInfo(pScrn, pInt10); RADEONSetupConnectors(pScrn); + + if (!info->IsSecondary) { + if (!RADEONAllocateConnectors(pScrn)) + return FALSE; + } + + if (!info->IsSecondary) { + RADEONQueryConnectedDisplays(pScrn); + } + RADEONMapControllers(pScrn); RADEONGetClockInfo(pScrn); RADEONGetPanelInfo(pScrn); RADEONGetTVDacAdjInfo(pScrn); - + + for (i = 0; i < config->num_output; i++) + { + xf86OutputPtr output = config->output[i]; + + output->status = (*output->funcs->detect) (output); + } return TRUE; } @@ -2954,6 +2544,7 @@ RADEONProbeDDC(ScrnInfoPtr pScrn, int indx) _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags) { + xf86CrtcConfigPtr xf86_config; RADEONInfoPtr info; xf86Int10InfoPtr pInt10 = NULL; void *int10_save = NULL; @@ -2968,7 +2559,6 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags) info = RADEONPTR(pScrn); info->IsSecondary = FALSE; info->IsPrimary = FALSE; - info->MergedFB = FALSE; info->IsSwitching = FALSE; info->MMIO = NULL; @@ -3060,6 +2650,11 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags) pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_VIEWPORT | RAC_CURSOR; pScrn->monitor = pScrn->confScreen->monitor; + /* Allocate an xf86CrtcConfig */ + xf86CrtcConfigInit (pScrn); + xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + + if (!RADEONPreInitVisual(pScrn)) goto fail; @@ -3170,27 +2765,37 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags) */ info->directRenderingEnabled = RADEONPreInitDRI(pScrn); #endif - if (!RADEONPreInitVRAM(pScrn)) goto fail; RADEONPreInitColorTiling(pScrn); + xf86CrtcSetSizeRange (pScrn, 320, 200, 2708, 1152);//nfo->MaxSurfaceWidth, info->MaxLines); + + RADEONPreInitDDC(pScrn); if (!RADEONPreInitControllers(pScrn, pInt10)) goto fail; - /* collect MergedFB options */ - /* only parse mergedfb options on the primary head. - Mergedfb is already disabled in xinerama/screen based - multihead */ - if (!info->IsSecondary) - RADEONGetMergedFBOptions(pScrn); - if (!RADEONPreInitGamma(pScrn)) goto fail; + if (!xf86InitialConfiguration (pScrn)) + { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n"); + goto fail; + } + + pScrn->displayWidth = (pScrn->virtualX + 63) & ~63; + + /* Set display resolution */ + xf86SetDpi(pScrn, 0, 0); - if (!RADEONPreInitModes(pScrn, pInt10)) goto fail; + /* Get ScreenInit function */ + if (!xf86LoadSubModule(pScrn, "fb")) return FALSE; + + xf86LoaderReqSymLists(fbSymbols, NULL); + + if (!RADEONPreInitGamma(pScrn)) goto fail; if (!RADEONPreInitCursor(pScrn)) goto fail; @@ -3198,6 +2803,19 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags) if (!RADEONPreInitXv(pScrn)) goto fail; + info->CurrentLayout.displayWidth = pScrn->displayWidth; + + if (!xf86RandR12PreInit (pScrn)) + { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "RandR initialization failure\n"); + goto fail; + } + + if (pScrn->modes == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n"); + goto fail; + } + /* Free the video bios (if applicable) */ if (info->VBIOS) { xfree(info->VBIOS); @@ -3254,9 +2872,12 @@ static void RADEONLoadPalette(ScrnInfoPtr pScrn, int numColors, { RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); int i; - int idx, j; + int index, j; unsigned char r, g, b; + CARD16 lut_r[256], lut_g[256], lut_b[256]; + int c; #ifdef XF86DRI if (info->CPStarted && pScrn->pScreen) DRILock(pScrn->pScreen, 0); @@ -3268,109 +2889,59 @@ static void RADEONLoadPalette(ScrnInfoPtr pScrn, int numColors, if (info->FBDev) { fbdevHWLoadPalette(pScrn, numColors, indices, colors, pVisual); } else { - /* If the second monitor is connected, we also need to deal with - * the secondary palette - */ - if (info->IsSecondary) j = 1; - else j = 0; - - PAL_SELECT(j); - - if (info->CurrentLayout.depth == 15) { - /* 15bpp mode. This sends 32 values. */ - for (i = 0; i < numColors; i++) { - idx = indices[i]; - r = colors[idx].red; - g = colors[idx].green; - b = colors[idx].blue; - OUTPAL(idx * 8, r, g, b); - } - } else if (info->CurrentLayout.depth == 16) { - /* 16bpp mode. This sends 64 values. - * - * There are twice as many green values as there are values - * for red and blue. So, we take each red and blue pair, - * and combine it with each of the two green values. - */ - for (i = 0; i < numColors; i++) { - idx = indices[i]; - r = colors[idx / 2].red; - g = colors[idx].green; - b = colors[idx / 2].blue; - RADEONWaitForFifo(pScrn, 32); /* delay */ - OUTPAL(idx * 4, r, g, b); - - /* AH - Added to write extra green data - How come this isn't - * needed on R128? We didn't load the extra green data in the - * other routine - */ - if (idx <= 31) { - r = colors[idx].red; - g = colors[(idx * 2) + 1].green; - b = colors[idx].blue; - RADEONWaitForFifo(pScrn, 32); /* delay */ - OUTPAL(idx * 8, r, g, b); - } - } - } else { - /* 8bpp mode. This sends 256 values. */ - for (i = 0; i < numColors; i++) { - idx = indices[i]; - r = colors[idx].red; - b = colors[idx].blue; - g = colors[idx].green; - RADEONWaitForFifo(pScrn, 32); /* delay */ - OUTPAL(idx, r, g, b); - } - } - if (info->MergedFB) { - PAL_SELECT(1); - if (info->CurrentLayout.depth == 15) { - /* 15bpp mode. This sends 32 values. */ - for (i = 0; i < numColors; i++) { - idx = indices[i]; - r = colors[idx].red; - g = colors[idx].green; - b = colors[idx].blue; - OUTPAL(idx * 8, r, g, b); - } - } else if (info->CurrentLayout.depth == 16) { - /* 16bpp mode. This sends 64 values. - * - * There are twice as many green values as there are values - * for red and blue. So, we take each red and blue pair, - * and combine it with each of the two green values. - */ - for (i = 0; i < numColors; i++) { - idx = indices[i]; - r = colors[idx / 2].red; - g = colors[idx].green; - b = colors[idx / 2].blue; - OUTPAL(idx * 4, r, g, b); - - /* AH - Added to write extra green data - How come - * this isn't needed on R128? We didn't load the - * extra green data in the other routine. - */ - if (idx <= 31) { - r = colors[idx].red; - g = colors[(idx * 2) + 1].green; - b = colors[idx].blue; - OUTPAL(idx * 8, r, g, b); - } - } - } else { - /* 8bpp mode. This sends 256 values. */ - for (i = 0; i < numColors; i++) { - idx = indices[i]; - r = colors[idx].red; - b = colors[idx].blue; - g = colors[idx].green; - OUTPAL(idx, r, g, b); - } - } - } + for (c = 0; c < xf86_config->num_crtc; c++) { + xf86CrtcPtr crtc = xf86_config->crtc[c]; + RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private; + + for (i = 0 ; i < 256; i++) { + lut_r[i] = radeon_crtc->lut_r[i] << 8; + lut_g[i] = radeon_crtc->lut_g[i] << 8; + lut_b[i] = radeon_crtc->lut_b[i] << 8; + } + + switch (info->CurrentLayout.depth) { + case 15: + for (i = 0; i < numColors; i++) { + index = indices[i]; + for (j = 0; j < 8; j++) { + lut_r[index * 8 + j] = colors[index].red << 8; + lut_g[index * 8 + j] = colors[index].green << 8; + lut_b[index * 8 + j] = colors[index].blue << 8; + } + } + case 16: + for (i = 0; i < numColors; i++) { + index = indices[i]; + + if (i <= 31) { + for (j = 0; j < 8; j++) { + lut_r[index * 8 + j] = colors[index].red << 8; + lut_b[index * 8 + j] = colors[index].blue << 8; + } + } + + for (j = 0; j < 4; j++) { + lut_g[index * 4 + j] = colors[index].green << 8; + } + } + default: + for (i = 0; i < numColors; i++) { + index = indices[i]; + lut_r[index] = colors[index].red << 8; + lut_g[index] = colors[index].green << 8; + lut_b[index] = colors[index].blue << 8; + } + break; + } + + /* Make the change through RandR */ +#ifdef RANDR_12_INTERFACE + RRCrtcGammaSet(crtc->randr_crtc, lut_r, lut_g, lut_b); +#else + crtc->funcs->gamma_set(crtc, lut_r, lut_g, lut_b, 256); +#endif + } } #ifdef XF86DRI @@ -3749,6 +3320,7 @@ _X_EXPORT Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; RADEONInfoPtr info = RADEONPTR(pScrn); + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); int hasDRI = 0; #ifdef RENDER int subPixelOrder = SubPixelUnknown; @@ -3793,17 +3365,7 @@ _X_EXPORT Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, info->allowColorTiling = FALSE; } if (info->allowColorTiling) { - if (info->MergedFB) { - if ((((RADEONMergedDisplayModePtr)pScrn->currentMode->Private)->CRT1->Flags & - (V_DBLSCAN | V_INTERLACE)) || - (((RADEONMergedDisplayModePtr)pScrn->currentMode->Private)->CRT2->Flags & - (V_DBLSCAN | V_INTERLACE))) - info->tilingEnabled = FALSE; - else info->tilingEnabled = TRUE; - } - else { - info->tilingEnabled = (pScrn->currentMode->Flags & (V_DBLSCAN | V_INTERLACE)) ? FALSE : TRUE; - } + info->tilingEnabled = (pScrn->currentMode->Flags & (V_DBLSCAN | V_INTERLACE)) ? FALSE : TRUE; } /* Visual setup */ @@ -4025,18 +3587,9 @@ _X_EXPORT Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, else if (strcmp(s, "NONE") == 0) subPixelOrder = SubPixelNone; PictureSetSubpixelOrder (pScreen, subPixelOrder); } - - if (PictureGetSubpixelOrder (pScreen) == SubPixelUnknown) { - switch (info->DisplayType) { - case MT_NONE: subPixelOrder = SubPixelUnknown; break; - case MT_LCD: subPixelOrder = SubPixelHorizontalRGB; break; - case MT_DFP: subPixelOrder = SubPixelHorizontalRGB; break; - default: subPixelOrder = SubPixelNone; break; - } - PictureSetSubpixelOrder (pScreen, subPixelOrder); - } #endif + pScrn->vtSema = TRUE; if (info->FBDev) { unsigned char *RADEONMMIO = info->MMIO; @@ -4048,7 +3601,24 @@ _X_EXPORT Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, info->ModeReg.surface_cntl = INREG(RADEON_SURFACE_CNTL); info->ModeReg.surface_cntl &= ~RADEON_SURF_TRANSLATION_DIS; } else { - if (!RADEONModeInit(pScrn, pScrn->currentMode)) return FALSE; + int i; + for (i = 0; i < xf86_config->num_crtc; i++) + { + xf86CrtcPtr crtc = xf86_config->crtc[i]; + + /* Mark that we'll need to re-set the mode for sure */ + memset(&crtc->mode, 0, sizeof(crtc->mode)); + if (!crtc->desiredMode.CrtcHDisplay) { + crtc->desiredMode = *RADEONCrtcFindClosestMode (crtc, pScrn->currentMode); + crtc->desiredRotation = RR_Rotate_0; + crtc->desiredX = 0; + crtc->desiredY = 0; + } + + if (!xf86CrtcSetMode (crtc, &crtc->desiredMode, crtc->desiredRotation, crtc->desiredX, crtc->desiredY)) + return FALSE; + + } } RADEONSaveScreen(pScreen, SCREEN_SAVER_ON); @@ -4115,10 +3685,6 @@ _X_EXPORT Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, RADEONChangeSurfaces(pScrn); } - if(info->MergedFB) - /* need this here to fix up sarea values */ - RADEONAdjustFrameMerged(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); - /* Enable aceleration */ if (!xf86ReturnOptValBool(info->Options, OPTION_NOACCEL, FALSE)) { RADEONTRACE(("Initializing Acceleration\n")); @@ -4138,7 +3704,7 @@ _X_EXPORT Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, /* Init DPMS */ RADEONTRACE(("Initializing DPMS\n")); - xf86DPMSInit(pScreen, RADEONDisplayPowerManagementSet, 0); + xf86DPMSInit(pScreen, xf86DPMSSet, 0); RADEONTRACE(("Initializing Cursor\n")); @@ -4177,42 +3743,16 @@ _X_EXPORT Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, xf86DrvMsg(scrnIndex, X_INFO, "Using software cursor\n"); } - /* Colormap setup */ - RADEONTRACE(("Initializing color map\n")); - if (!miCreateDefColormap(pScreen)) return FALSE; - if (!xf86HandleColormaps(pScreen, 256, info->dac6bits ? 6 : 8, - RADEONLoadPalette, NULL, - CMAP_PALETTED_TRUECOLOR -#if 0 /* This option messes up text mode! (eich@suse.de) */ - | CMAP_LOAD_EVEN_IF_OFFSCREEN -#endif - | CMAP_RELOAD_ON_MODE_SWITCH)) return FALSE; + /* DGA setup */ RADEONTRACE(("Initializing DGA\n")); RADEONDGAInit(pScreen); - /* Wrap some funcs for MergedFB */ - if(info->MergedFB) { - info->PointerMoved = pScrn->PointerMoved; - pScrn->PointerMoved = RADEONMergePointerMoved; - /* Psuedo xinerama */ - if(info->UseRADEONXinerama) { - RADEONnoPanoramiXExtension = FALSE; - RADEONXineramaExtensionInit(pScrn); - } else { - info->MouseRestrictions = FALSE; - } - } - /* Init Xv */ RADEONTRACE(("Initializing Xv\n")); RADEONInitVideo(pScreen); - if(info->MergedFB) - /* need this here to fix up sarea values */ - RADEONAdjustFrameMerged(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); - /* Provide SaveScreen & wrap BlockHandler and CloseScreen */ /* Wrap CloseScreen */ info->CloseScreen = pScreen->CloseScreen; @@ -4221,6 +3761,27 @@ _X_EXPORT Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, info->BlockHandler = pScreen->BlockHandler; pScreen->BlockHandler = RADEONBlockHandler; + /* Rotation */ + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "RandR enabled, ignore the following RandR disabled message.\n"); + xf86DisableRandR(); /* Disable built-in RandR extension */ + + xf86RandR12Init (pScreen); + xf86RandR12SetRotations (pScreen, RR_Rotate_0); + + info->CreateScreenResources = pScreen->CreateScreenResources; + pScreen->CreateScreenResources = RADEONCreateScreenResources; + + /* Colormap setup */ + RADEONTRACE(("Initializing color map\n")); + if (!miCreateDefColormap(pScreen)) return FALSE; + if (!xf86HandleColormaps(pScreen, 256, info->dac6bits ? 6 : 8, + RADEONLoadPalette, NULL, + CMAP_PALETTED_TRUECOLOR +#if 0 /* This option messes up text mode! (eich@suse.de) */ + | CMAP_LOAD_EVEN_IF_OFFSCREEN +#endif + | CMAP_RELOAD_ON_MODE_SWITCH)) return FALSE; + /* Note unused options */ if (serverGeneration == 1) xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); @@ -4468,11 +4029,9 @@ static void RADEONRestoreCommonRegisters(ScrnInfoPtr pScrn, CARD32 tmp; RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); - if (pRADEONEnt->HasSecondary || info->MergedFB) { - tmp = INREG(RADEON_DAC_CNTL2); - OUTREG(RADEON_DAC_CNTL2, tmp & ~RADEON_DAC2_DAC_CLK_SEL); - usleep(100000); - } + tmp = INREG(RADEON_DAC_CNTL2); + OUTREG(RADEON_DAC_CNTL2, tmp & ~RADEON_DAC2_DAC_CLK_SEL); + usleep(100000); } } @@ -5028,40 +4587,14 @@ void RADEONChangeSurfaces(ScrnInfoPtr pScrn) RADEONSaveSurfaces(pScrn, &info->ModeReg); } -#if 0 -/* Write palette data */ -static void RADEONRestorePalette(ScrnInfoPtr pScrn, RADEONSavePtr restore) -{ - RADEONInfoPtr info = RADEONPTR(pScrn); - unsigned char *RADEONMMIO = info->MMIO; - int i; - - if (!restore->palette_valid) return; - - PAL_SELECT(1); - OUTPAL_START(0); - for (i = 0; i < 256; i++) { - RADEONWaitForFifo(pScrn, 32); /* delay */ - OUTPAL_NEXT_CARD32(restore->palette2[i]); - } - - PAL_SELECT(0); - OUTPAL_START(0); - for (i = 0; i < 256; i++) { - RADEONWaitForFifo(pScrn, 32); /* delay */ - OUTPAL_NEXT_CARD32(restore->palette[i]); - } -} -#endif - /* Write out state to define a new video mode */ -static void RADEONRestoreMode(ScrnInfoPtr pScrn, RADEONSavePtr restore) +void RADEONRestoreMode(ScrnInfoPtr pScrn, RADEONSavePtr restore) { RADEONInfoPtr info = RADEONPTR(pScrn); RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); - RADEONController* pCRTC1 = pRADEONEnt->Controller[0]; - RADEONController* pCRTC2 = pRADEONEnt->Controller[1]; - RADEONConnector *pPort; + RADEONCrtcPrivatePtr pCRTC1 = pRADEONEnt->Controller[0]; + RADEONCrtcPrivatePtr pCRTC2 = pRADEONEnt->Controller[1]; + xf86OutputPtr output; RADEONTRACE(("RADEONRestoreMode(%p)\n", restore)); /* For Non-dual head card, we don't have private field in the Entity */ @@ -5099,10 +4632,9 @@ static void RADEONRestoreMode(ScrnInfoPtr pScrn, RADEONSavePtr restore) RADEONRestoreCrtc2Registers(pScrn, restore); RADEONRestorePLL2Registers(pScrn, restore); RADEONRestoreFPRegisters(pScrn, restore); - pPort = RADEONGetCrtcConnector(pScrn, 2); - if (pPort) { - RADEONEnableDisplay(pScrn, pPort, TRUE); - pCRTC2->IsActive = TRUE; + output = RADEONGetCrtcConnector(pScrn, 2); + if (output) { + RADEONEnableDisplay(pScrn, output, TRUE); } } else { RADEONRestoreMemMapRegisters(pScrn, restore); @@ -5115,16 +4647,14 @@ static void RADEONRestoreMode(ScrnInfoPtr pScrn, RADEONSavePtr restore) RADEONRestoreCrtcRegisters(pScrn, restore); RADEONRestorePLLRegisters(pScrn, restore); RADEONRestoreFPRegisters(pScrn, restore); - pPort = RADEONGetCrtcConnector(pScrn, 1); - if (pPort) { - RADEONEnableDisplay(pScrn, pPort, TRUE); - pCRTC1->IsActive = TRUE; + output = RADEONGetCrtcConnector(pScrn, 1); + if (output) { + RADEONEnableDisplay(pScrn, output, TRUE); } if (pCRTC2->binding == 1) { - pPort = RADEONGetCrtcConnector(pScrn, 2); - if (pPort) { - RADEONEnableDisplay(pScrn, pPort, TRUE); - pCRTC2->IsActive = TRUE; + output = RADEONGetCrtcConnector(pScrn, 2); + if (output) { + RADEONEnableDisplay(pScrn, output, TRUE); } } } @@ -5139,16 +4669,14 @@ static void RADEONRestoreMode(ScrnInfoPtr pScrn, RADEONSavePtr restore) RADEONRestoreCrtcRegisters(pScrn, restore); RADEONRestorePLLRegisters(pScrn, restore); RADEONRestoreFPRegisters(pScrn, restore); - pPort = RADEONGetCrtcConnector(pScrn, 1); - if (pPort) { - RADEONEnableDisplay(pScrn, pPort, TRUE); - pCRTC1->IsActive = TRUE; + output = RADEONGetCrtcConnector(pScrn, 1); + if (output) { + RADEONEnableDisplay(pScrn, output, TRUE); } if ((pCRTC2->binding == 1) || pRADEONEnt->HasSecondary) { - pPort = RADEONGetCrtcConnector(pScrn, 2); - if (pPort) { - RADEONEnableDisplay(pScrn, pPort, TRUE); - pCRTC2->IsActive = TRUE; + output = RADEONGetCrtcConnector(pScrn, 2); + if (output) { + RADEONEnableDisplay(pScrn, output, TRUE); } } } @@ -5428,7 +4956,7 @@ static void RADEONSave(ScrnInfoPtr pScrn) } /* Restore the original (text) mode */ -static void RADEONRestore(ScrnInfoPtr pScrn) +void RADEONRestore(ScrnInfoPtr pScrn) { RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; @@ -5467,7 +4995,7 @@ static void RADEONRestore(ScrnInfoPtr pScrn) if (!info->IsSecondary) RADEONRestoreSurfaces(pScrn, restore); -#if 0 +#if 1 /* Temp fix to "solve" VT switch problems. When switching VTs on * some systems, the console can either hang or the fonts can be * corrupted. This hack solves the problem 99% of the time. A @@ -5509,8 +5037,19 @@ static void RADEONRestore(ScrnInfoPtr pScrn) } } #endif +#if 0 + { + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + int i; + for (i = 0; i <= xf86_config->num_crtc; i++) { + if (i == 0) + xf86_config->crtc[i]->enabled = 1; + else + xf86_config->crtc[i]->enabled = 0; + } + } RADEONUnblank(pScrn); - +#endif #if 0 RADEONWaitForVerticalSync(pScrn); #endif @@ -5817,24 +5356,24 @@ static void RADEONInitDAC2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save, } } -static void RADEONInitOutputRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, DisplayModePtr mode, RADEONConnector *pPort, int crtc_num) +static void RADEONInitOutputRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, DisplayModePtr mode, xf86OutputPtr output, int crtc_num) { Bool IsPrimary = crtc_num == 1 ? TRUE : FALSE; - - if (pPort->MonType == MT_CRT) { - if (pPort->DACType == DAC_PRIMARY) { + RADEONOutputPrivatePtr radeon_output = output->driver_private; + if (radeon_output->MonType == MT_CRT) { + if (radeon_output->DACType == DAC_PRIMARY) { RADEONInitDACRegisters(pScrn, save, mode, IsPrimary); } else { RADEONInitDAC2Registers(pScrn, save, mode, IsPrimary); } - } else if (pPort->MonType == MT_LCD) { + } else if (radeon_output->MonType == MT_LCD) { if (crtc_num == 1) RADEONInitRMXRegisters(pScrn, save, mode); RADEONInitLVDSRegisters(pScrn, save, mode, IsPrimary); - } else if (pPort->MonType == MT_DFP) { + } else if (radeon_output->MonType == MT_DFP) { if (crtc_num == 1) RADEONInitRMXRegisters(pScrn, save, mode); - if (pPort->TMDSType == TMDS_INT) { + if (radeon_output->TMDSType == TMDS_INT) { RADEONInitFPRegisters(pScrn, save, mode, IsPrimary); } else { RADEONInitFP2Registers(pScrn, save, mode, IsPrimary); @@ -5851,10 +5390,7 @@ static Bool RADEONInitCrtcRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, int hsync_wid; int vsync_wid; RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); - - pRADEONEnt->Controller[0]->IsUsed = TRUE; - pRADEONEnt->Controller[0]->IsActive = TRUE; - pRADEONEnt->Controller[0]->pCurMode = mode; + xf86OutputPtr connector; switch (info->CurrentLayout.pixel_code) { case 4: format = 1; break; @@ -6003,9 +5539,9 @@ static Bool RADEONInitCrtcRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, /* get the output connected to this CRTC */ if (pRADEONEnt->PortInfo[0]->crtc_num == 1) { - RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->PortInfo[0], 1); + RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->pOutput[0], 1); } else if (pRADEONEnt->PortInfo[1]->crtc_num == 1) { - RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->PortInfo[1], 1); + RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->pOutput[1], 1); } if (info->IsDellServer) { @@ -6042,10 +5578,6 @@ static Bool RADEONInitCrtc2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save, if (info->IsSecondary) info0 = RADEONPTR(pRADEONEnt->pPrimaryScrn); - pRADEONEnt->Controller[1]->IsUsed = TRUE; - pRADEONEnt->Controller[1]->IsActive = TRUE; - pRADEONEnt->Controller[1]->pCurMode = mode; - switch (info->CurrentLayout.pixel_code) { case 4: format = 1; break; case 8: format = 2; break; @@ -6110,7 +5642,7 @@ static Bool RADEONInitCrtc2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save, save->crtc2_offset_cntl &= ~RADEON_CRTC_TILE_EN; } - save->crtc2_pitch = ((pScrn->displayWidth * pScrn->bitsPerPixel) + + save->crtc2_pitch = ((info->CurrentLayout.displayWidth * pScrn->bitsPerPixel) + ((pScrn->bitsPerPixel * 8) -1)) / (pScrn->bitsPerPixel * 8); save->crtc2_pitch |= save->crtc2_pitch << 16; @@ -6138,9 +5670,9 @@ static Bool RADEONInitCrtc2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save, /* get the output connected to this CRTC */ if (pRADEONEnt->PortInfo[0]->crtc_num == 2) { - RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->PortInfo[0], 2); + RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->pOutput[0], 2); } else if (pRADEONEnt->PortInfo[1]->crtc_num == 2) { - RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->PortInfo[1], 2); + RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->pOutput[1], 2); } /* We must set SURFACE_CNTL properly on the second screen too */ @@ -6316,66 +5848,20 @@ static void RADEONInitPalette(RADEONSavePtr save) #endif /* Define registers for a requested video mode */ -static Bool RADEONInit2(ScrnInfoPtr pScrn, DisplayModePtr crtc1, - DisplayModePtr crtc2, int crtc_mask, - RADEONSavePtr save) +Bool RADEONInit2(ScrnInfoPtr pScrn, DisplayModePtr crtc1, + DisplayModePtr crtc2, int crtc_mask, + RADEONSavePtr save, RADEONMonitorType montype) { RADEONInfoPtr info = RADEONPTR(pScrn); RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); - double dot_clock = crtc1->Clock/1000.0; + double dot_clock = 0; RADEONInfoPtr info0 = NULL; ScrnInfoPtr pScrn0 = NULL; -#if RADEON_DEBUG - ErrorF("%-12.12s %7.2f %4d %4d %4d %4d %4d %4d %4d %4d (%d,%d)", - crtc1->name, - dot_clock, - - crtc1->HDisplay, - crtc1->HSyncStart, - crtc1->HSyncEnd, - crtc1->HTotal, - - crtc1->VDisplay, - crtc1->VSyncStart, - crtc1->VSyncEnd, - crtc1->VTotal, - pScrn->depth, - pScrn->bitsPerPixel); - if (crtc1->Flags & V_DBLSCAN) ErrorF(" D"); - if (crtc1->Flags & V_CSYNC) ErrorF(" C"); - if (crtc1->Flags & V_INTERLACE) ErrorF(" I"); - if (crtc1->Flags & V_PHSYNC) ErrorF(" +H"); - if (crtc1->Flags & V_NHSYNC) ErrorF(" -H"); - if (crtc1->Flags & V_PVSYNC) ErrorF(" +V"); - if (crtc1->Flags & V_NVSYNC) ErrorF(" -V"); - ErrorF("\n"); - ErrorF("%-12.12s %7.2f %4d %4d %4d %4d %4d %4d %4d %4d (%d,%d)", - crtc1->name, - dot_clock, - - crtc1->CrtcHDisplay, - crtc1->CrtcHSyncStart, - crtc1->CrtcHSyncEnd, - crtc1->CrtcHTotal, - - crtc1->CrtcVDisplay, - crtc1->CrtcVSyncStart, - crtc1->CrtcVSyncEnd, - crtc1->CrtcVTotal, - pScrn->depth, - pScrn->bitsPerPixel); - if (crtc1->Flags & V_DBLSCAN) ErrorF(" D"); - if (crtc1->Flags & V_CSYNC) ErrorF(" C"); - if (crtc1->Flags & V_INTERLACE) ErrorF(" I"); - if (crtc1->Flags & V_PHSYNC) ErrorF(" +H"); - if (crtc1->Flags & V_NHSYNC) ErrorF(" -H"); - if (crtc1->Flags & V_PVSYNC) ErrorF(" +V"); - if (crtc1->Flags & V_NVSYNC) ErrorF(" -V"); - ErrorF("\n"); -#endif - - info->Flags = crtc1->Flags; + if (crtc_mask & 1) + xf86PrintModeline(pScrn, crtc1); + if (crtc_mask & 2) + xf86PrintModeline(pScrn, crtc2); RADEONInitMemMapRegisters(pScrn, save, info); RADEONInitCommonRegisters(save, info); @@ -6403,14 +5889,20 @@ static Bool RADEONInit2(ScrnInfoPtr pScrn, DisplayModePtr crtc1, /* if (!info->PaletteSavedOnVT) RADEONInitPalette(save); */ break; case 2: - pScrn0 = pRADEONEnt->pPrimaryScrn; - info0 = RADEONPTR(pScrn0); + if (pRADEONEnt->HasSecondary) { + pScrn0 = pRADEONEnt->pPrimaryScrn; + info0 = RADEONPTR(pScrn0); + } else { + pScrn0 = pScrn; + info0 = info; + } dot_clock = crtc2->Clock/1000.0; if (!RADEONInitCrtc2Registers(pScrn, save, crtc2, info)) return FALSE; - RADEONInitPLL2Registers(pScrn, save, &info->pll, dot_clock, info->DisplayType != MT_CRT); + RADEONInitPLL2Registers(pScrn, save, &info->pll, dot_clock, montype != MT_CRT); /* Make sure primary has the same copy */ - memcpy(&info0->ModeReg, save, sizeof(RADEONSaveRec)); + if (pRADEONEnt->HasSecondary) + memcpy(&info0->ModeReg, save, sizeof(RADEONSaveRec)); break; case 3: if (!RADEONInitCrtcRegisters(pScrn, save, @@ -6426,13 +5918,13 @@ static Bool RADEONInit2(ScrnInfoPtr pScrn, DisplayModePtr crtc1, } RADEONInitCrtc2Registers(pScrn, save, crtc2, info); dot_clock = crtc2->Clock / 1000.0; - RADEONInitPLL2Registers(pScrn, save, &info->pll, dot_clock, info->MergeType != MT_CRT); + RADEONInitPLL2Registers(pScrn, save, &info->pll, dot_clock, montype != MT_CRT); break; default: return FALSE; } - RADEONTRACE(("RADEONInit returns %p\n", save)); + RADEONTRACE(("RADEONInit2 %d returns %p\n", crtc_mask, save)); return TRUE; } @@ -6442,12 +5934,9 @@ static Bool RADEONInit(ScrnInfoPtr pScrn, DisplayModePtr mode, RADEONInfoPtr info = RADEONPTR(pScrn); if (info->IsSecondary) { - return RADEONInit2(pScrn, NULL, mode, 2, save); - } else if (info->MergedFB) { - return RADEONInit2(pScrn, ((RADEONMergedDisplayModePtr)mode->Private)->CRT1, - ((RADEONMergedDisplayModePtr)mode->Private)->CRT2, 3, save); + return RADEONInit2(pScrn, NULL, mode, 2, save, 0); } else { - return RADEONInit2(pScrn, mode, NULL, 1, save); + return RADEONInit2(pScrn, mode, NULL, 1, save, 0); } } @@ -6528,17 +6017,7 @@ _X_EXPORT Bool RADEONSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) RADEONTRACE(("RADEONSwitchMode() !n")); if (info->allowColorTiling) { - if (info->MergedFB) { - if ((((RADEONMergedDisplayModePtr)mode->Private)->CRT1->Flags & - (V_DBLSCAN | V_INTERLACE)) || - (((RADEONMergedDisplayModePtr)mode->Private)->CRT2->Flags & - (V_DBLSCAN | V_INTERLACE))) - info->tilingEnabled = FALSE; - else info->tilingEnabled = TRUE; - } - else { - info->tilingEnabled = (mode->Flags & (V_DBLSCAN | V_INTERLACE)) ? FALSE : TRUE; - } + info->tilingEnabled = (mode->Flags & (V_DBLSCAN | V_INTERLACE)) ? FALSE : TRUE; #ifdef XF86DRI if (info->directRenderingEnabled && (info->tilingEnabled != tilingOld)) { RADEONSAREAPrivPtr pSAREAPriv; @@ -6596,10 +6075,7 @@ _X_EXPORT Bool RADEONSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) /* Since RandR (indirectly) uses SwitchMode(), we need to * update our Xinerama info here, too, in case of resizing */ - if (info->MergedFB) { - RADEONMergedFBResetDpi(pScrn, FALSE); - RADEONUpdateXineramaScreenInfo(pScrn); - } else if(info->constantDPI) { + if(info->constantDPI) { RADEONResetDPI(pScrn, FALSE); } @@ -6765,9 +6241,7 @@ _X_EXPORT void RADEONAdjustFrame(int scrnIndex, int x, int y, int flags) if (info->accelOn) RADEON_SYNC(info, pScrn); - if(info->MergedFB) { - RADEONAdjustFrameMerged(scrnIndex, x, y, flags); - } else if (info->FBDev) { + if (info->FBDev) { fbdevHWAdjustFrame(scrnIndex, x, y, flags); } else { RADEONDoAdjustFrame(pScrn, x, y, FALSE); @@ -6786,6 +6260,7 @@ _X_EXPORT Bool RADEONEnterVT(int scrnIndex, int flags) ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); RADEONTRACE(("RADEONEnterVT\n")); @@ -6811,8 +6286,33 @@ _X_EXPORT Bool RADEONEnterVT(int scrnIndex, int flags) info->ModeReg.surface_cntl = INREG(RADEON_SURFACE_CNTL); RADEONRestoreFBDevRegisters(pScrn, &info->ModeReg); - } else - if (!RADEONModeInit(pScrn, pScrn->currentMode)) return FALSE; + } else { + int i; + + pScrn->vtSema = TRUE; + for (i = 0; i < xf86_config->num_crtc; i++) + { + xf86CrtcPtr crtc = xf86_config->crtc[i]; + RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private; + radeon_crtc->binding = info->IsSecondary ? 2 : 1; + /* Mark that we'll need to re-set the mode for sure */ + memset(&crtc->mode, 0, sizeof(crtc->mode)); + if (!crtc->desiredMode.CrtcHDisplay) { + crtc->desiredMode = *RADEONCrtcFindClosestMode (crtc, pScrn->currentMode); + crtc->desiredRotation = RR_Rotate_0; + crtc->desiredX = 0; + crtc->desiredY = 0; + } + + if (!xf86CrtcSetMode (crtc, &crtc->desiredMode, crtc->desiredRotation, + crtc->desiredX, crtc->desiredY)) + return FALSE; + + } + } +#if 0 + if (!RADEONModeInit(pScrn, pScrn->currentMode)) return FALSE; +#endif if (!info->IsSecondary) RADEONRestoreSurfaces(pScrn, &info->ModeReg); @@ -6882,7 +6382,6 @@ _X_EXPORT void RADEONLeaveVT(int scrnIndex, int flags) } RADEONRestore(pScrn); - RADEONTRACE(("Ok, leaving now...\n")); } @@ -6924,7 +6423,6 @@ static Bool RADEONCloseScreen(int scrnIndex, ScreenPtr pScreen) #endif /* USE_XAA */ if (pScrn->vtSema) { - RADEONDisplayPowerManagementSet(pScrn, DPMSModeOn, 0); RADEONRestore(pScrn); } @@ -6977,40 +6475,6 @@ _X_EXPORT void RADEONFreeScreen(int scrnIndex, int flags) /* when server quits at PreInit, we don't need do this anymore*/ if (!info) return; - if(info->MergedFB) { - if(pScrn->modes) { - pScrn->currentMode = pScrn->modes; - do { - DisplayModePtr p = pScrn->currentMode->next; - if(pScrn->currentMode->Private) - xfree(pScrn->currentMode->Private); - xfree(pScrn->currentMode); - pScrn->currentMode = p; - } while(pScrn->currentMode != pScrn->modes); - } - pScrn->currentMode = info->CRT1CurrentMode; - pScrn->modes = info->CRT1Modes; - info->CRT1CurrentMode = NULL; - info->CRT1Modes = NULL; - - if(info->CRT2pScrn) { - if(info->CRT2pScrn->modes) { - while(info->CRT2pScrn->modes) - xf86DeleteMode(&info->CRT2pScrn->modes, info->CRT2pScrn->modes); - } - if(info->CRT2pScrn->monitor) { - if(info->CRT2pScrn->monitor->Modes) { - while(info->CRT2pScrn->monitor->Modes) - xf86DeleteMode(&info->CRT2pScrn->monitor->Modes, info->CRT2pScrn->monitor->Modes); - } - if(info->CRT2pScrn->monitor->DDC) xfree(info->CRT2pScrn->monitor->DDC); - xfree(info->CRT2pScrn->monitor); - } - xfree(info->CRT2pScrn); - info->CRT2pScrn = NULL; - } - } - #ifdef WITH_VGAHW if (info->VGAAccess && xf86LoaderCheckSymbol("vgaHWFreeHWRec")) vgaHWFreeHWRec(pScrn); @@ -7018,235 +6482,6 @@ _X_EXPORT void RADEONFreeScreen(int scrnIndex, int flags) RADEONFreeRec(pScrn); } -static void -RADEONGetMergedFBOptions(ScrnInfoPtr pScrn) -{ - RADEONInfoPtr info = RADEONPTR(pScrn); - RADEONConnector *connector; - char *strptr; - char *default_hsync = "28-33"; - char *default_vrefresh = "43-72"; - Bool val; - Bool default_range = FALSE; - static const char *mybadparm = "\"%s\" is is not a valid parameter for option \"%s\"\n"; - - if (info->FBDev == TRUE) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "MergedFB does not work with Option UseFBDev, MergedFB mode is disabled\n"); - info->MergedFB = FALSE; - return; - } - - /* collect MergedFB options */ - info->MergedFB = TRUE; - info->UseRADEONXinerama = TRUE; - info->CRT2IsScrn0 = FALSE; - info->CRT2Position = radeonClone; - info->MergedFBXDPI = info->MergedFBYDPI = 0; - info->CRT1XOffs = info->CRT1YOffs = info->CRT2XOffs = info->CRT2YOffs = 0; - info->NonRect = info->HaveNonRect = info->HaveOffsRegions = FALSE; - info->MBXNR1XMAX = info->MBXNR1YMAX = info->MBXNR2XMAX = info->MBXNR2YMAX = 65536; - info->MouseRestrictions = TRUE; - - if (info->MergeType == MT_NONE) { - info->MergedFB = FALSE; - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Failed to detect secondary monitor, MergedFB/Clone mode disabled\n"); - } else if ((connector = RADEONGetCrtcConnector(pScrn, 2))) { - if (!connector->MonInfo) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Failed to detect secondary monitor DDC, default HSync and VRefresh used\n"); - default_range = TRUE; - } - } - - if (xf86GetOptValBool(info->Options, OPTION_MERGEDFB, &val)) { - if (val) { - info->MergedFB = TRUE; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "MergedFB mode forced on.\n"); - } else { - info->MergedFB = FALSE; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "MergedFB mode forced off.\n"); - } - } - - /* Do some MergedFB mode initialisation */ - if(info->MergedFB) { - info->CRT2pScrn = xalloc(sizeof(ScrnInfoRec)); - if(!info->CRT2pScrn) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate memory for merged pScrn, MergedFB mode is disabled\n"); - info->MergedFB = FALSE; - } else { - memcpy(info->CRT2pScrn, pScrn, sizeof(ScrnInfoRec)); - } - } - if(info->MergedFB) { - int result, ival; - Bool valid = FALSE; - char *tempstr; - strptr = (char *)xf86GetOptValString(info->Options, OPTION_CRT2POS); - if (strptr) { - tempstr = xalloc(strlen(strptr) + 1); - result = sscanf(strptr, "%s %d", tempstr, &ival); - } else { /* Not specified - default is "Clone" */ - tempstr = NULL; - result = 0; - info->CRT2Position = radeonClone; - valid = TRUE; - } - if(result >= 1) { - if(!xf86NameCmp(tempstr,"LeftOf")) { - info->CRT2Position = radeonLeftOf; - valid = TRUE; - if(result == 2) { - if(ival < 0) info->CRT1YOffs = -ival; - else info->CRT2YOffs = ival; - } - info->CRT2IsScrn0 = TRUE; - } else if(!xf86NameCmp(tempstr,"RightOf")) { - info->CRT2Position = radeonRightOf; - valid = TRUE; - if(result == 2) { - if(ival < 0) info->CRT1YOffs = -ival; - else info->CRT2YOffs = ival; - } - info->CRT2IsScrn0 = FALSE; - } else if(!xf86NameCmp(tempstr,"Above")) { - info->CRT2Position = radeonAbove; - valid = TRUE; - if(result == 2) { - if(ival < 0) info->CRT1XOffs = -ival; - else info->CRT2XOffs = ival; - } - info->CRT2IsScrn0 = FALSE; - } else if(!xf86NameCmp(tempstr,"Below")) { - info->CRT2Position = radeonBelow; - valid = TRUE; - if(result == 2) { - if(ival < 0) info->CRT1XOffs = -ival; - else info->CRT2XOffs = ival; - } - info->CRT2IsScrn0 = TRUE; - } else if(!xf86NameCmp(tempstr,"Clone")) { - info->CRT2Position = radeonClone; - if(result == 1) valid = TRUE; - /*info->CRT2IsScrn0 = TRUE;*/ - } - } - if(!valid) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "\"%s\" is not a valid parameter for Option \"CRT2Position\"\n", strptr); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Valid parameters are \"RightOf\", \"LeftOf\", \"Above\", \"Below\", or \"Clone\"\n"); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Except for \"Clone\", the parameter may be followed by an integer.\n"); - } - xfree(tempstr); - - strptr = (char *)xf86GetOptValString(info->Options, OPTION_METAMODES); - if(strptr) { - info->MetaModes = xalloc(strlen(strptr) + 1); - if(info->MetaModes) memcpy(info->MetaModes, strptr, strlen(strptr) + 1); - } - strptr = (char *)xf86GetOptValString(info->Options, OPTION_CRT2HSYNC); - if(strptr) { - info->CRT2HSync = xalloc(strlen(strptr) + 1); - if(info->CRT2HSync) memcpy(info->CRT2HSync, strptr, strlen(strptr) + 1); - } - strptr = (char *)xf86GetOptValString(info->Options, OPTION_CRT2VREFRESH); - if(strptr) { - info->CRT2VRefresh = xalloc(strlen(strptr) + 1); - if(info->CRT2VRefresh) memcpy(info->CRT2VRefresh, strptr, strlen(strptr) + 1); - } - - if(xf86GetOptValBool(info->Options, OPTION_RADEONXINERAMA, &val)) { - if (!val) - info->UseRADEONXinerama = FALSE; - } - if(info->UseRADEONXinerama) { - if(xf86GetOptValBool(info->Options, OPTION_CRT2ISSCRN0, &val)) { - if(val) info->CRT2IsScrn0 = TRUE; - else info->CRT2IsScrn0 = FALSE; - } - if(xf86GetOptValBool(info->Options, OPTION_MERGEDFBNONRECT, &val)) { - info->NonRect = val ? TRUE : FALSE; - } - if(xf86GetOptValBool(info->Options, OPTION_MERGEDFBMOUSER, &val)) { - info->MouseRestrictions = val ? TRUE : FALSE; - } - } - strptr = (char *)xf86GetOptValString(info->Options, OPTION_MERGEDDPI); - if(strptr) { - int val1 = 0, val2 = 0; - sscanf(strptr, "%d %d", &val1, &val2); - if(val1 && val2) { - info->MergedFBXDPI = val1; - info->MergedFBYDPI = val2; - } else { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, mybadparm, strptr, "MergedDPI"); - } - } - } - - if(info->MergedFB) { - /* fill in monitor */ - info->CRT2pScrn->monitor = xalloc(sizeof(MonRec)); - if(info->CRT2pScrn->monitor) { - DisplayModePtr tempm = NULL, currentm = NULL, newm = NULL; - memcpy(info->CRT2pScrn->monitor, pScrn->monitor, sizeof(MonRec)); - info->CRT2pScrn->monitor->DDC = NULL; - info->CRT2pScrn->monitor->Modes = NULL; - info->CRT2pScrn->monitor->id = "CRT2 Monitor"; - tempm = pScrn->monitor->Modes; - while(tempm) { - if(!(newm = xalloc(sizeof(DisplayModeRec)))) break; - memcpy(newm, tempm, sizeof(DisplayModeRec)); - if(!(newm->name = xalloc(strlen(tempm->name) + 1))) { - xfree(newm); - break; - } - strcpy(newm->name, tempm->name); - if(!info->CRT2pScrn->monitor->Modes) - info->CRT2pScrn->monitor->Modes = newm; - if(currentm) { - currentm->next = newm; - newm->prev = currentm; - } - currentm = newm; - tempm = tempm->next; - } - - /* xf86SetDDCproperties(info->CRT2pScrn, pRADEONEnt->MonInfo2); */ - - connector = RADEONGetCrtcConnector(pScrn, 2); - info->CRT2pScrn->monitor->DDC = connector ? connector->MonInfo : NULL; - - if (default_range) { - RADEONStrToRanges(info->CRT2pScrn->monitor->hsync, default_hsync, MAX_HSYNC); - RADEONStrToRanges(info->CRT2pScrn->monitor->vrefresh, default_vrefresh, MAX_VREFRESH); - } - if(info->CRT2HSync) { - info->CRT2pScrn->monitor->nHsync = - RADEONStrToRanges(info->CRT2pScrn->monitor->hsync, info->CRT2HSync, MAX_HSYNC); - } - if(info->CRT2VRefresh) { - info->CRT2pScrn->monitor->nVrefresh = - RADEONStrToRanges(info->CRT2pScrn->monitor->vrefresh, info->CRT2VRefresh, MAX_VREFRESH); - } - - } else { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate memory for CRT2 monitor, MergedFB mode disabled.\n"); - if(info->CRT2pScrn) xfree(info->CRT2pScrn); - info->CRT2pScrn = NULL; - info->MergedFB = FALSE; - } - } -} - static void RADEONForceSomeClocks(ScrnInfoPtr pScrn) { /* It appears from r300 and rv100 may need some clocks forced-on */ diff --git a/src/radeon_mergedfb.c b/src/radeon_mergedfb.c deleted file mode 100644 index 820ba4b..0000000 --- a/src/radeon_mergedfb.c +++ /dev/null @@ -1,2089 +0,0 @@ -/* - * Copyright 2003 Alex Deucher. - * - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation on the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NON-INFRINGEMENT. IN NO EVENT SHALL ALEX DEUCHER, OR ANY OTHER - * CONTRIBUTORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/* - * Authors: - * Alex Deucher <agd5f@yahoo.com> - * Based, in large part, on the sis driver by Thomas Winischhofer. - */ - -#include <string.h> -#include <stdio.h> - -#include "xf86.h" -#include "xf86Priv.h" -#include "xf86Resources.h" -#include "xf86_OSproc.h" -#include "extnsionst.h" /* required */ -#include <X11/extensions/panoramiXproto.h> /* required */ -#include "dixstruct.h" -#include "vbe.h" - - -#include "radeon.h" -#include "radeon_reg.h" -#include "radeon_macros.h" -#include "radeon_mergedfb.h" - -/* psuedo xinerama support */ -static unsigned char RADEONXineramaReqCode = 0; -int RADEONXineramaPixWidth = 0; -int RADEONXineramaPixHeight = 0; -int RADEONXineramaNumScreens = 0; -RADEONXineramaData *RADEONXineramadataPtr = NULL; -static int RADEONXineramaGeneration; -Bool RADEONnoPanoramiXExtension = TRUE; - -int RADEONProcXineramaQueryVersion(ClientPtr client); -int RADEONProcXineramaGetState(ClientPtr client); -int RADEONProcXineramaGetScreenCount(ClientPtr client); -int RADEONProcXineramaGetScreenSize(ClientPtr client); -int RADEONProcXineramaIsActive(ClientPtr client); -int RADEONProcXineramaQueryScreens(ClientPtr client); -int RADEONSProcXineramaDispatch(ClientPtr client); - -static void -RADEONChooseCursorCRTC(ScrnInfoPtr pScrn1, int x, int y); - -/* mergedfb functions */ -/* Helper function for CRT2 monitor vrefresh/hsync options - * (Taken from mga, sis drivers) - */ -int -RADEONStrToRanges(range *r, char *s, int max) -{ - float num = 0.0; - int rangenum = 0; - Bool gotdash = FALSE; - Bool nextdash = FALSE; - char* strnum = NULL; - do { - switch(*s) { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - case '.': - if(strnum == NULL) { - strnum = s; - gotdash = nextdash; - nextdash = FALSE; - } - break; - case '-': - case ' ': - case 0: - if(strnum == NULL) break; - sscanf(strnum, "%f", &num); - strnum = NULL; - if(gotdash) - r[rangenum - 1].hi = num; - else { - r[rangenum].lo = num; - r[rangenum].hi = num; - rangenum++; - } - if(*s == '-') nextdash = (rangenum != 0); - else if(rangenum >= max) return rangenum; - break; - default : - return 0; - } - } while(*(s++) != 0); - - return rangenum; -} - -/* Copy and link two modes (i, j) for merged-fb mode - * (Taken from mga, sis drivers) - * Copys mode i, merges j to copy of i, links the result to dest, and returns it. - * Links i and j in Private record. - * If dest is NULL, return value is copy of i linked to itself. - * For mergedfb auto-config, we only check the dimension - * against virtualX/Y, if they were user-provided. - */ -static DisplayModePtr -RADEONCopyModeNLink(ScrnInfoPtr pScrn, DisplayModePtr dest, - DisplayModePtr i, DisplayModePtr j, - RADEONScrn2Rel srel) -{ - DisplayModePtr mode; - int dx = 0,dy = 0; - RADEONInfoPtr info = RADEONPTR(pScrn); - - if(!((mode = xalloc(sizeof(DisplayModeRec))))) return dest; - memcpy(mode, i, sizeof(DisplayModeRec)); - if(!((mode->Private = xalloc(sizeof(RADEONMergedDisplayModeRec))))) { - xfree(mode); - return dest; - } - ((RADEONMergedDisplayModePtr)mode->Private)->CRT1 = i; - ((RADEONMergedDisplayModePtr)mode->Private)->CRT2 = j; - ((RADEONMergedDisplayModePtr)mode->Private)->CRT2Position = srel; - mode->PrivSize = 0; - - switch(srel) { - case radeonLeftOf: - case radeonRightOf: - if(!(pScrn->display->virtualX)) { - dx = i->HDisplay + j->HDisplay; - } else { - dx = min(pScrn->virtualX, i->HDisplay + j->HDisplay); - } - dx -= mode->HDisplay; - if(!(pScrn->display->virtualY)) { - dy = max(i->VDisplay, j->VDisplay); - } else { - dy = min(pScrn->virtualY, max(i->VDisplay, j->VDisplay)); - } - dy -= mode->VDisplay; - break; - case radeonAbove: - case radeonBelow: - if(!(pScrn->display->virtualY)) { - dy = i->VDisplay + j->VDisplay; - } else { - dy = min(pScrn->virtualY, i->VDisplay + j->VDisplay); - } - dy -= mode->VDisplay; - if(!(pScrn->display->virtualX)) { - dx = max(i->HDisplay, j->HDisplay); - } else { - dx = min(pScrn->virtualX, max(i->HDisplay, j->HDisplay)); - } - dx -= mode->HDisplay; - break; - case radeonClone: - if(!(pScrn->display->virtualX)) { - dx = max(i->HDisplay, j->HDisplay); - } else { - dx = min(pScrn->virtualX, max(i->HDisplay, j->HDisplay)); - } - dx -= mode->HDisplay; - if(!(pScrn->display->virtualY)) { - dy = max(i->VDisplay, j->VDisplay); - } else { - dy = min(pScrn->virtualY, max(i->VDisplay, j->VDisplay)); - } - dy -= mode->VDisplay; - break; - } - mode->HDisplay += dx; - mode->HSyncStart += dx; - mode->HSyncEnd += dx; - mode->HTotal += dx; - mode->VDisplay += dy; - mode->VSyncStart += dy; - mode->VSyncEnd += dy; - mode->VTotal += dy; - - /* Provide a fake VRefresh/DotClock in order to trick the vidmode - * extension to allow selecting among a number of modes whose merged result - * looks identical but consists of different modes for CRT1 and CRT2 - */ - mode->VRefresh = (float)((i->Clock * 1000.0 / i->HTotal / i->VTotal) * 100 + - (j->Clock * 1000.0 / j->HTotal / j->VTotal)); - - mode->Clock = (int)(mode->VRefresh * 0.001 * mode->HTotal * mode->VTotal); - - if( ((mode->HDisplay * ((pScrn->bitsPerPixel + 7) / 8) * mode->VDisplay) > - (pScrn->videoRam * 1024)) || - (mode->HDisplay > 8191) || - (mode->VDisplay > 8191) ) { - - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Skipped \"%s\" (%dx%d), not enough video RAM or beyond hardware specs\n", - mode->name, mode->HDisplay, mode->VDisplay); - xfree(mode->Private); - xfree(mode); - - return dest; - } - - if(srel != radeonClone) { - info->AtLeastOneNonClone = TRUE; - } - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Merged \"%s\" (%dx%d) and \"%s\" (%dx%d) to %dx%d%s\n", - i->name, i->HDisplay, i->VDisplay, j->name, j->HDisplay, j->VDisplay, - mode->HDisplay, mode->VDisplay, (srel == radeonClone) ? " (Clone)" : ""); - - mode->next = mode; - mode->prev = mode; - - if(dest) { - mode->next = dest->next; /* Insert node after "dest" */ - dest->next->prev = mode; - mode->prev = dest; - dest->next = mode; - } - - return mode; -} - -/* Helper function to find a mode from a given name - * (Taken from mga, sis drivers) - */ -static DisplayModePtr -RADEONGetModeFromName(char* str, DisplayModePtr i) -{ - DisplayModePtr c = i; - if(!i) return NULL; - do { - if(strcmp(str, c->name) == 0) return c; - c = c->next; - } while(c != i); - return NULL; -} - -static DisplayModePtr -RADEONFindWidestTallestMode(DisplayModePtr i, Bool tallest) -{ - DisplayModePtr c = i, d = NULL; - int max = 0; - if(!i) return NULL; - do { - if(tallest) { - if(c->VDisplay > max) { - max = c->VDisplay; - d = c; - } - } else { - if(c->HDisplay > max) { - max = c->HDisplay; - d = c; - } - } - c = c->next; - } while(c != i); - return d; -} - -static void -RADEONFindWidestTallestCommonMode(DisplayModePtr i, DisplayModePtr j, Bool tallest, - DisplayModePtr *a, DisplayModePtr *b) -{ - DisplayModePtr c = i, d; - int max = 0; - Bool foundone; - - (*a) = (*b) = NULL; - - if(!i || !j) return; - - do { - d = j; - foundone = FALSE; - do { - if( (c->HDisplay == d->HDisplay) && - (c->VDisplay == d->VDisplay) ) { - foundone = TRUE; - break; - } - d = d->next; - } while(d != j); - if(foundone) { - if(tallest) { - if(c->VDisplay > max) { - max = c->VDisplay; - (*a) = c; - (*b) = d; - } - } else { - if(c->HDisplay > max) { - max = c->HDisplay; - (*a) = c; - (*b) = d; - } - } - } - c = c->next; - } while(c != i); -} - -static DisplayModePtr -RADEONGenerateModeListFromLargestModes(ScrnInfoPtr pScrn, - DisplayModePtr i, DisplayModePtr j, - RADEONScrn2Rel srel) -{ - - RADEONInfoPtr info = RADEONPTR(pScrn); - DisplayModePtr mode1 = NULL; - DisplayModePtr mode2 = NULL; - DisplayModePtr mode3 = NULL; - DisplayModePtr mode4 = NULL; - DisplayModePtr result = NULL; - - info->AtLeastOneNonClone = FALSE; - - /* Now build a default list of MetaModes. - * - Non-clone: If the user enabled NonRectangular, we use the - * largest mode for each CRT1 and CRT2. If not, we use the largest - * common mode for CRT1 and CRT2 (if available). Additionally, and - * regardless if the above, we produce a clone mode consisting of - * the largest common mode (if available) in order to use DGA. - * - Clone: If the (global) CRT2Position is Clone, we use the - * largest common mode if available, otherwise the first two modes - * in each list. - */ - - switch(srel) { - case radeonLeftOf: - case radeonRightOf: - mode1 = RADEONFindWidestTallestMode(i, FALSE); - mode2 = RADEONFindWidestTallestMode(j, FALSE); - RADEONFindWidestTallestCommonMode(i, j, FALSE, &mode3, &mode4); - break; - case radeonAbove: - case radeonBelow: - mode1 = RADEONFindWidestTallestMode(i, TRUE); - mode2 = RADEONFindWidestTallestMode(j, TRUE); - RADEONFindWidestTallestCommonMode(i, j, TRUE, &mode3, &mode4); - break; - case radeonClone: - RADEONFindWidestTallestCommonMode(i, j, FALSE, &mode3, &mode4); - if(mode3 && mode4) { - mode1 = mode3; - mode2 = mode4; - } else { - mode1 = i; - mode2 = j; - } - } - - if(srel != radeonClone) { - if(mode3 && mode4 && !info->NonRect) { - mode1 = mode3; - mode2 = mode2; - } - } - - if(mode1 && mode2) { - result = RADEONCopyModeNLink(pScrn, result, mode1, mode2, srel); - } - - if(srel != radeonClone) { - if(mode3 && mode4) { - result = RADEONCopyModeNLink(pScrn, result, mode3, mode4, radeonClone); - } - } - return result; -} - -/* Generate the merged-fb mode modelist - * (Taken from mga, sis drivers) - */ -static DisplayModePtr -RADEONGenerateModeListFromMetaModes(ScrnInfoPtr pScrn, char* str, - DisplayModePtr i, DisplayModePtr j, - RADEONScrn2Rel srel) -{ - char* strmode = str; - char modename[256]; - Bool gotdash = FALSE; - char gotsep = 0; - RADEONScrn2Rel sr; - DisplayModePtr mode1 = NULL; - DisplayModePtr mode2 = NULL; - DisplayModePtr result = NULL; - int myslen; - RADEONInfoPtr info = RADEONPTR(pScrn); - - info->AtLeastOneNonClone = FALSE; - - do { - switch(*str) { - case 0: - case '-': - case '+': - case ' ': - case ',': - case ';': - if(strmode != str) { - - myslen = str - strmode; - if(myslen > 255) myslen = 255; - strncpy(modename, strmode, myslen); - modename[myslen] = 0; - - if(gotdash) { - if(mode1 == NULL) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Error parsing MetaModes parameter\n"); - return NULL; - } - mode2 = RADEONGetModeFromName(modename, j); - if(!mode2) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Mode \"%s\" is not a supported mode for CRT2\n", modename); - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "\t(Skipping metamode \"%s%c%s\")\n", mode1->name, gotsep, modename); - mode1 = NULL; - gotsep = 0; - } - } else { - mode1 = RADEONGetModeFromName(modename, i); - if(!mode1) { - char* tmps = str; - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Mode \"%s\" is not a supported mode for CRT1\n", modename); - while(*tmps == ' ' || *tmps == ';') tmps++; - /* skip the next mode */ - if(*tmps == '-' || *tmps == '+' || *tmps == ',') { - tmps++; - /* skip spaces */ - while(*tmps == ' ' || *tmps == ';') tmps++; - /* skip modename */ - while(*tmps && *tmps != ' ' && *tmps != ';' && *tmps != '-' && *tmps != '+' && *tmps != ',') tmps++; - myslen = tmps - strmode; - if(myslen > 255) myslen = 255; - strncpy(modename,strmode,myslen); - modename[myslen] = 0; - str = tmps-1; - } - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "\t(Skipping metamode \"%s\")\n", modename); - mode1 = NULL; - gotsep = 0; - } - } - gotdash = FALSE; - } - strmode = str + 1; - gotdash |= (*str == '-' || *str == '+' || *str == ','); - if (*str == '-' || *str == '+' || *str == ',') - gotsep = *str; - - if(*str != 0) break; - /* Fall through otherwise */ - - default: - if(!gotdash && mode1) { - sr = srel; - if(gotsep == '+') sr = radeonClone; - if(!mode2) { - mode2 = RADEONGetModeFromName(mode1->name, j); - sr = radeonClone; - } - if(!mode2) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Mode \"%s\" is not a supported mode for CRT2\n", mode1->name); - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "\t(Skipping metamode \"%s\")\n", modename); - mode1 = NULL; - } else { - result = RADEONCopyModeNLink(pScrn, result, mode1, mode2, sr); - mode1 = NULL; - mode2 = NULL; - } - gotsep = 0; - } - break; - - } - - } while(*(str++) != 0); - - return result; -} - -DisplayModePtr -RADEONGenerateModeList(ScrnInfoPtr pScrn, char* str, - DisplayModePtr i, DisplayModePtr j, - RADEONScrn2Rel srel) -{ - RADEONInfoPtr info = RADEONPTR(pScrn); - - if(str != NULL) { - return(RADEONGenerateModeListFromMetaModes(pScrn, str, i, j, srel)); - } else { - if (srel == radeonClone ) { - DisplayModePtr p, q, result = NULL; - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Clone mode, list all common modes\n"); - for (p = i; p->next != i; p = p->next) - for (q = j; q->next != j; q = q->next) - if ((p->HDisplay == q->HDisplay) && - (p->VDisplay == q->VDisplay)) - result = RADEONCopyModeNLink(pScrn, result, p, q, srel); - return result; - } else { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "No MetaModes given, linking %s modes by default\n", - (info->NonRect ? - (((srel == radeonLeftOf) || (srel == radeonRightOf)) ? "widest" : "tallest") - : - (((srel == radeonLeftOf) || (srel == radeonRightOf)) ? "widest common" : "tallest common")) ); - return(RADEONGenerateModeListFromLargestModes(pScrn, i, j, srel)); - } - } -} - -void -RADEONRecalcDefaultVirtualSize(ScrnInfoPtr pScrn) -{ - RADEONInfoPtr info = RADEONPTR(pScrn); - DisplayModePtr mode, bmode; - int maxh, maxv; - static const char *str = "MergedFB: Virtual %s %d\n"; - static const char *errstr = "Virtual %s to small for given CRT2Position offset\n"; - - mode = bmode = pScrn->modes; - maxh = maxv = 0; - do { - if(mode->HDisplay > maxh) maxh = mode->HDisplay; - if(mode->VDisplay > maxv) maxv = mode->VDisplay; - mode = mode->next; - } while(mode != bmode); - maxh += info->CRT1XOffs + info->CRT2XOffs; - maxv += info->CRT1YOffs + info->CRT2YOffs; - - if(!(pScrn->display->virtualX)) { - if(maxh > 8191) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Virtual width with CRT2Position offset beyond hardware specs\n"); - info->CRT1XOffs = info->CRT2XOffs = 0; - maxh -= (info->CRT1XOffs + info->CRT2XOffs); - } - pScrn->virtualX = maxh; - pScrn->displayWidth = maxh; - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, str, "width", maxh); - } else { - if(maxh < pScrn->display->virtualX) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, errstr, "width"); - info->CRT1XOffs = info->CRT2XOffs = 0; - } - } - - if(!(pScrn->display->virtualY)) { - pScrn->virtualY = maxv; - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, str, "height", maxv); - } else { - if(maxv < pScrn->display->virtualY) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, errstr, "height"); - info->CRT1YOffs = info->CRT2YOffs = 0; - } - } -} - -/* Pseudo-Xinerama extension for MergedFB mode */ -void -RADEONUpdateXineramaScreenInfo(ScrnInfoPtr pScrn1) -{ - RADEONInfoPtr info = RADEONPTR(pScrn1); - ScrnInfoPtr pScrn2 = NULL; - int crt1scrnnum = 0, crt2scrnnum = 1; - int x1=0, x2=0, y1=0, y2=0, h1=0, h2=0, w1=0, w2=0; - int realvirtX, realvirtY; - DisplayModePtr currentMode, firstMode; - Bool infochanged = FALSE; - Bool usenonrect = info->NonRect; - const char *rectxine = "\t... setting up rectangular Xinerama layout\n"; - - info->MBXNR1XMAX = info->MBXNR1YMAX = info->MBXNR2XMAX = info->MBXNR2YMAX = 65536; - info->HaveNonRect = info->HaveOffsRegions = FALSE; - - if(!info->MergedFB) return; - - if(RADEONnoPanoramiXExtension) return; - - if(!RADEONXineramadataPtr) return; - - if(info->CRT2IsScrn0) { - crt1scrnnum = 1; - crt2scrnnum = 0; - } - - pScrn2 = info->CRT2pScrn; - - /* Attention: Usage of RandR may lead into virtual X and Y values - * actually smaller than our MetaModes! To avoid this, we calculate - * the maxCRT fields here (and not somewhere else, like in CopyNLink) - */ - - /* "Real" virtual: Virtual without the Offset */ - realvirtX = pScrn1->virtualX - info->CRT1XOffs - info->CRT2XOffs; - realvirtY = pScrn1->virtualY - info->CRT1YOffs - info->CRT2YOffs; - - if((info->RADEONXineramaVX != pScrn1->virtualX) || (info->RADEONXineramaVY != pScrn1->virtualY)) { - - if(!(pScrn1->modes)) { - xf86DrvMsg(pScrn1->scrnIndex, X_ERROR, - "Internal error: RADEONUpdateXineramaScreenInfo(): pScrn->modes is NULL\n"); - return; - } - - info->maxCRT1_X1 = info->maxCRT1_X2 = 0; - info->maxCRT1_Y1 = info->maxCRT1_Y2 = 0; - info->maxCRT2_X1 = info->maxCRT2_X2 = 0; - info->maxCRT2_Y1 = info->maxCRT2_Y2 = 0; - info->maxClone_X1 = info->maxClone_X2 = 0; - info->maxClone_Y1 = info->maxClone_Y2 = 0; - - currentMode = firstMode = pScrn1->modes; - - do { - - DisplayModePtr p = currentMode->next; - DisplayModePtr i = ((RADEONMergedDisplayModePtr)currentMode->Private)->CRT1; - DisplayModePtr j = ((RADEONMergedDisplayModePtr)currentMode->Private)->CRT2; - RADEONScrn2Rel srel = ((RADEONMergedDisplayModePtr)currentMode->Private)->CRT2Position; - - if((currentMode->HDisplay <= realvirtX) && (currentMode->VDisplay <= realvirtY) && - (i->HDisplay <= realvirtX) && (j->HDisplay <= realvirtX) && - (i->VDisplay <= realvirtY) && (j->VDisplay <= realvirtY)) { - - if(srel != radeonClone) { - if(info->maxCRT1_X1 == i->HDisplay) { - if(info->maxCRT1_X2 < j->HDisplay) { - info->maxCRT1_X2 = j->HDisplay; /* Widest CRT2 mode displayed with widest CRT1 mode */ - } - } else if(info->maxCRT1_X1 < i->HDisplay) { - info->maxCRT1_X1 = i->HDisplay; /* Widest CRT1 mode */ - info->maxCRT1_X2 = j->HDisplay; - } - if(info->maxCRT2_X2 == j->HDisplay) { - if(info->maxCRT2_X1 < i->HDisplay) { - info->maxCRT2_X1 = i->HDisplay; /* Widest CRT1 mode displayed with widest CRT2 mode */ - } - } else if(info->maxCRT2_X2 < j->HDisplay) { - info->maxCRT2_X2 = j->HDisplay; /* Widest CRT2 mode */ - info->maxCRT2_X1 = i->HDisplay; - } - if(info->maxCRT1_Y1 == i->VDisplay) { /* Same as above, but tallest instead of widest */ - if(info->maxCRT1_Y2 < j->VDisplay) { - info->maxCRT1_Y2 = j->VDisplay; - } - } else if(info->maxCRT1_Y1 < i->VDisplay) { - info->maxCRT1_Y1 = i->VDisplay; - info->maxCRT1_Y2 = j->VDisplay; - } - if(info->maxCRT2_Y2 == j->VDisplay) { - if(info->maxCRT2_Y1 < i->VDisplay) { - info->maxCRT2_Y1 = i->VDisplay; - } - } else if(info->maxCRT2_Y2 < j->VDisplay) { - info->maxCRT2_Y2 = j->VDisplay; - info->maxCRT2_Y1 = i->VDisplay; - } - } else { - if(info->maxClone_X1 < i->HDisplay) { - info->maxClone_X1 = i->HDisplay; - } - if(info->maxClone_X2 < j->HDisplay) { - info->maxClone_X2 = j->HDisplay; - } - if(info->maxClone_Y1 < i->VDisplay) { - info->maxClone_Y1 = i->VDisplay; - } - if(info->maxClone_Y2 < j->VDisplay) { - info->maxClone_Y2 = j->VDisplay; - } - } - } - currentMode = p; - - } while((currentMode) && (currentMode != firstMode)); - - info->RADEONXineramaVX = pScrn1->virtualX; - info->RADEONXineramaVY = pScrn1->virtualY; - infochanged = TRUE; - - } - - if((usenonrect) && (info->CRT2Position != radeonClone) && info->maxCRT1_X1) { - switch(info->CRT2Position) { - case radeonLeftOf: - case radeonRightOf: - if((info->maxCRT1_Y1 != realvirtY) && (info->maxCRT2_Y2 != realvirtY)) { - usenonrect = FALSE; - } - break; - case radeonAbove: - case radeonBelow: - if((info->maxCRT1_X1 != realvirtX) && (info->maxCRT2_X2 != realvirtX)) { - usenonrect = FALSE; - } - break; - case radeonClone: - break; - } - - if(infochanged && !usenonrect) { - xf86DrvMsg(pScrn1->scrnIndex, X_INFO, - "Virtual screen size does not match maximum display modes...\n"); - xf86DrvMsg(pScrn1->scrnIndex, X_INFO, rectxine); - - } - } else if(infochanged && usenonrect) { - usenonrect = FALSE; - xf86DrvMsg(pScrn1->scrnIndex, X_INFO, - "Only clone modes available for this virtual screen size...\n"); - xf86DrvMsg(pScrn1->scrnIndex, X_INFO, rectxine); - } - - if(info->maxCRT1_X1) { /* Means we have at least one non-clone mode */ - switch(info->CRT2Position) { - case radeonLeftOf: - x1 = min(info->maxCRT1_X2, pScrn1->virtualX - info->maxCRT1_X1); - if(x1 < 0) x1 = 0; - y1 = info->CRT1YOffs; - w1 = pScrn1->virtualX - x1; - h1 = realvirtY; - if((usenonrect) && (info->maxCRT1_Y1 != realvirtY)) { - h1 = info->MBXNR1YMAX = info->maxCRT1_Y1; - info->NonRectDead.x0 = x1; - info->NonRectDead.x1 = x1 + w1 - 1; - info->NonRectDead.y0 = y1 + h1; - info->NonRectDead.y1 = pScrn1->virtualY - 1; - info->HaveNonRect = TRUE; - } - x2 = 0; - y2 = info->CRT2YOffs; - w2 = max(info->maxCRT2_X2, pScrn1->virtualX - info->maxCRT2_X1); - if(w2 > pScrn1->virtualX) w2 = pScrn1->virtualX; - h2 = realvirtY; - if((usenonrect) && (info->maxCRT2_Y2 != realvirtY)) { - h2 = info->MBXNR2YMAX = info->maxCRT2_Y2; - info->NonRectDead.x0 = x2; - info->NonRectDead.x1 = x2 + w2 - 1; - info->NonRectDead.y0 = y2 + h2; - info->NonRectDead.y1 = pScrn1->virtualY - 1; - info->HaveNonRect = TRUE; - } - break; - case radeonRightOf: - x1 = 0; - y1 = info->CRT1YOffs; - w1 = max(info->maxCRT1_X1, pScrn1->virtualX - info->maxCRT1_X2); - if(w1 > pScrn1->virtualX) w1 = pScrn1->virtualX; - h1 = realvirtY; - if((usenonrect) && (info->maxCRT1_Y1 != realvirtY)) { - h1 = info->MBXNR1YMAX = info->maxCRT1_Y1; - info->NonRectDead.x0 = x1; - info->NonRectDead.x1 = x1 + w1 - 1; - info->NonRectDead.y0 = y1 + h1; - info->NonRectDead.y1 = pScrn1->virtualY - 1; - info->HaveNonRect = TRUE; - } - x2 = min(info->maxCRT2_X1, pScrn1->virtualX - info->maxCRT2_X2); - if(x2 < 0) x2 = 0; - y2 = info->CRT2YOffs; - w2 = pScrn1->virtualX - x2; - h2 = realvirtY; - if((usenonrect) && (info->maxCRT2_Y2 != realvirtY)) { - h2 = info->MBXNR2YMAX = info->maxCRT2_Y2; - info->NonRectDead.x0 = x2; - info->NonRectDead.x1 = x2 + w2 - 1; - info->NonRectDead.y0 = y2 + h2; - info->NonRectDead.y1 = pScrn1->virtualY - 1; - info->HaveNonRect = TRUE; - } - break; - case radeonAbove: - x1 = info->CRT1XOffs; - y1 = min(info->maxCRT1_Y2, pScrn1->virtualY - info->maxCRT1_Y1); - if(y1 < 0) y1 = 0; - w1 = realvirtX; - h1 = pScrn1->virtualY - y1; - if((usenonrect) && (info->maxCRT1_X1 != realvirtX)) { - w1 = info->MBXNR1XMAX = info->maxCRT1_X1; - info->NonRectDead.x0 = x1 + w1; - info->NonRectDead.x1 = pScrn1->virtualX - 1; - info->NonRectDead.y0 = y1; - info->NonRectDead.y1 = y1 + h1 - 1; - info->HaveNonRect = TRUE; - } - x2 = info->CRT2XOffs; - y2 = 0; - w2 = realvirtX; - h2 = max(info->maxCRT2_Y2, pScrn1->virtualY - info->maxCRT2_Y1); - if(h2 > pScrn1->virtualY) h2 = pScrn1->virtualY; - if((usenonrect) && (info->maxCRT2_X2 != realvirtX)) { - w2 = info->MBXNR2XMAX = info->maxCRT2_X2; - info->NonRectDead.x0 = x2 + w2; - info->NonRectDead.x1 = pScrn1->virtualX - 1; - info->NonRectDead.y0 = y2; - info->NonRectDead.y1 = y2 + h2 - 1; - info->HaveNonRect = TRUE; - } - break; - case radeonBelow: - x1 = info->CRT1XOffs; - y1 = 0; - w1 = realvirtX; - h1 = max(info->maxCRT1_Y1, pScrn1->virtualY - info->maxCRT1_Y2); - if(h1 > pScrn1->virtualY) h1 = pScrn1->virtualY; - if((usenonrect) && (info->maxCRT1_X1 != realvirtX)) { - w1 = info->MBXNR1XMAX = info->maxCRT1_X1; - info->NonRectDead.x0 = x1 + w1; - info->NonRectDead.x1 = pScrn1->virtualX - 1; - info->NonRectDead.y0 = y1; - info->NonRectDead.y1 = y1 + h1 - 1; - info->HaveNonRect = TRUE; - } - x2 = info->CRT2XOffs; - y2 = min(info->maxCRT2_Y1, pScrn1->virtualY - info->maxCRT2_Y2); - if(y2 < 0) y2 = 0; - w2 = realvirtX; - h2 = pScrn1->virtualY - y2; - if((usenonrect) && (info->maxCRT2_X2 != realvirtX)) { - w2 = info->MBXNR2XMAX = info->maxCRT2_X2; - info->NonRectDead.x0 = x2 + w2; - info->NonRectDead.x1 = pScrn1->virtualX - 1; - info->NonRectDead.y0 = y2; - info->NonRectDead.y1 = y2 + h2 - 1; - info->HaveNonRect = TRUE; - } - default: - break; - } - - switch(info->CRT2Position) { - case radeonLeftOf: - case radeonRightOf: - if(info->CRT1YOffs) { - info->OffDead1.x0 = x1; - info->OffDead1.x1 = x1 + w1 - 1; - info->OffDead1.y0 = 0; - info->OffDead1.y1 = y1 - 1; - info->OffDead2.x0 = x2; - info->OffDead2.x1 = x2 + w2 - 1; - info->OffDead2.y0 = y2 + h2; - info->OffDead2.y1 = pScrn1->virtualY - 1; - info->HaveOffsRegions = TRUE; - } else if(info->CRT2YOffs) { - info->OffDead1.x0 = x2; - info->OffDead1.x1 = x2 + w2 - 1; - info->OffDead1.y0 = 0; - info->OffDead1.y1 = y2 - 1; - info->OffDead2.x0 = x1; - info->OffDead2.x1 = x1 + w1 - 1; - info->OffDead2.y0 = y1 + h1; - info->OffDead2.y1 = pScrn1->virtualY - 1; - info->HaveOffsRegions = TRUE; - } - break; - case radeonAbove: - case radeonBelow: - if(info->CRT1XOffs) { - info->OffDead1.x0 = x2 + w2; - info->OffDead1.x1 = pScrn1->virtualX - 1; - info->OffDead1.y0 = y2; - info->OffDead1.y1 = y2 + h2 - 1; - info->OffDead2.x0 = 0; - info->OffDead2.x1 = x1 - 1; - info->OffDead2.y0 = y1; - info->OffDead2.y1 = y1 + h1 - 1; - info->HaveOffsRegions = TRUE; - } else if(info->CRT2XOffs) { - info->OffDead1.x0 = x1 + w1; - info->OffDead1.x1 = pScrn1->virtualX - 1; - info->OffDead1.y0 = y1; - info->OffDead1.y1 = y1 + h1 - 1; - info->OffDead2.x0 = 0; - info->OffDead2.x1 = x2 - 1; - info->OffDead2.y0 = y2; - info->OffDead2.y1 = y2 + h2 - 1; - info->HaveOffsRegions = TRUE; - } - default: - break; - } - - } else { /* Only clone-modes left */ - - x1 = x2 = 0; - y1 = y2 = 0; - w1 = w2 = max(info->maxClone_X1, info->maxClone_X2); - h1 = h2 = max(info->maxClone_Y1, info->maxClone_Y2); - - } - - RADEONXineramadataPtr[crt1scrnnum].x = x1; - RADEONXineramadataPtr[crt1scrnnum].y = y1; - RADEONXineramadataPtr[crt1scrnnum].width = w1; - RADEONXineramadataPtr[crt1scrnnum].height = h1; - RADEONXineramadataPtr[crt2scrnnum].x = x2; - RADEONXineramadataPtr[crt2scrnnum].y = y2; - RADEONXineramadataPtr[crt2scrnnum].width = w2; - RADEONXineramadataPtr[crt2scrnnum].height = h2; - - if(infochanged) { - xf86DrvMsg(pScrn1->scrnIndex, X_INFO, - "Pseudo-Xinerama: CRT1 (Screen %d) (%d,%d)-(%d,%d)\n", - crt1scrnnum, x1, y1, w1+x1-1, h1+y1-1); - xf86DrvMsg(pScrn1->scrnIndex, X_INFO, - "Pseudo-Xinerama: CRT2 (Screen %d) (%d,%d)-(%d,%d)\n", - crt2scrnnum, x2, y2, w2+x2-1, h2+y2-1); - if(info->HaveNonRect) { - xf86DrvMsg(pScrn1->scrnIndex, X_INFO, - "Pseudo-Xinerama: Inaccessible area (%d,%d)-(%d,%d)\n", - info->NonRectDead.x0, info->NonRectDead.y0, - info->NonRectDead.x1, info->NonRectDead.y1); - } - if(info->HaveOffsRegions) { - xf86DrvMsg(pScrn1->scrnIndex, X_INFO, - "Pseudo-Xinerama: Inaccessible offset area (%d,%d)-(%d,%d)\n", - info->OffDead1.x0, info->OffDead1.y0, - info->OffDead1.x1, info->OffDead1.y1); - xf86DrvMsg(pScrn1->scrnIndex, X_INFO, - "Pseudo-Xinerama: Inaccessible offset area (%d,%d)-(%d,%d)\n", - info->OffDead2.x0, info->OffDead2.y0, - info->OffDead2.x1, info->OffDead2.y1); - } - if(info->HaveNonRect || info->HaveOffsRegions) { - xf86DrvMsg(pScrn1->scrnIndex, X_INFO, - "Mouse restriction for inaccessible areas is %s\n", - info->MouseRestrictions ? "enabled" : "disabled"); - } - } -} -/* Proc */ - -int -RADEONProcXineramaQueryVersion(ClientPtr client) -{ - xPanoramiXQueryVersionReply rep; - register int n; - - REQUEST_SIZE_MATCH(xPanoramiXQueryVersionReq); - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.majorVersion = RADEON_XINERAMA_MAJOR_VERSION; - rep.minorVersion = RADEON_XINERAMA_MINOR_VERSION; - if(client->swapped) { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swaps(&rep.majorVersion, n); - swaps(&rep.minorVersion, n); - } - WriteToClient(client, sizeof(xPanoramiXQueryVersionReply), (char *)&rep); - return (client->noClientException); -} - -int -RADEONProcXineramaGetState(ClientPtr client) -{ - REQUEST(xPanoramiXGetStateReq); - WindowPtr pWin; - xPanoramiXGetStateReply rep; - register int n; - - REQUEST_SIZE_MATCH(xPanoramiXGetStateReq); - pWin = LookupWindow(stuff->window, client); - if(!pWin) return BadWindow; - - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.state = !RADEONnoPanoramiXExtension; - if(client->swapped) { - swaps (&rep.sequenceNumber, n); - swapl (&rep.length, n); - swaps (&rep.state, n); - } - WriteToClient(client, sizeof(xPanoramiXGetStateReply), (char *)&rep); - return client->noClientException; -} - -int -RADEONProcXineramaGetScreenCount(ClientPtr client) -{ - REQUEST(xPanoramiXGetScreenCountReq); - WindowPtr pWin; - xPanoramiXGetScreenCountReply rep; - register int n; - - REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq); - pWin = LookupWindow(stuff->window, client); - if(!pWin) return BadWindow; - - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.ScreenCount = RADEONXineramaNumScreens; - if(client->swapped) { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swaps(&rep.ScreenCount, n); - } - WriteToClient(client, sizeof(xPanoramiXGetScreenCountReply), (char *)&rep); - return client->noClientException; -} - -int -RADEONProcXineramaGetScreenSize(ClientPtr client) -{ - REQUEST(xPanoramiXGetScreenSizeReq); - WindowPtr pWin; - xPanoramiXGetScreenSizeReply rep; - register int n; - - REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq); - pWin = LookupWindow (stuff->window, client); - if(!pWin) return BadWindow; - - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.width = RADEONXineramadataPtr[stuff->screen].width; - rep.height = RADEONXineramadataPtr[stuff->screen].height; - if(client->swapped) { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swaps(&rep.width, n); - swaps(&rep.height, n); - } - WriteToClient(client, sizeof(xPanoramiXGetScreenSizeReply), (char *)&rep); - return client->noClientException; -} - -int -RADEONProcXineramaIsActive(ClientPtr client) -{ - xXineramaIsActiveReply rep; - - REQUEST_SIZE_MATCH(xXineramaIsActiveReq); - - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.state = !RADEONnoPanoramiXExtension; - if(client->swapped) { - register int n; - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swapl(&rep.state, n); - } - WriteToClient(client, sizeof(xXineramaIsActiveReply), (char *) &rep); - return client->noClientException; -} - -int -RADEONProcXineramaQueryScreens(ClientPtr client) -{ - xXineramaQueryScreensReply rep; - - REQUEST_SIZE_MATCH(xXineramaQueryScreensReq); - - rep.type = X_Reply; - rep.sequenceNumber = client->sequence; - rep.number = (RADEONnoPanoramiXExtension) ? 0 : RADEONXineramaNumScreens; - rep.length = rep.number * sz_XineramaScreenInfo >> 2; - if(client->swapped) { - register int n; - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swapl(&rep.number, n); - } - WriteToClient(client, sizeof(xXineramaQueryScreensReply), (char *)&rep); - - if(!RADEONnoPanoramiXExtension) { - xXineramaScreenInfo scratch; - int i; - - for(i = 0; i < RADEONXineramaNumScreens; i++) { - scratch.x_org = RADEONXineramadataPtr[i].x; - scratch.y_org = RADEONXineramadataPtr[i].y; - scratch.width = RADEONXineramadataPtr[i].width; - scratch.height = RADEONXineramadataPtr[i].height; - if(client->swapped) { - register int n; - swaps(&scratch.x_org, n); - swaps(&scratch.y_org, n); - swaps(&scratch.width, n); - swaps(&scratch.height, n); - } - WriteToClient(client, sz_XineramaScreenInfo, (char *)&scratch); - } - } - - return client->noClientException; -} - -static int -RADEONProcXineramaDispatch(ClientPtr client) -{ - REQUEST(xReq); - switch (stuff->data) - { - case X_PanoramiXQueryVersion: - return RADEONProcXineramaQueryVersion(client); - case X_PanoramiXGetState: - return RADEONProcXineramaGetState(client); - case X_PanoramiXGetScreenCount: - return RADEONProcXineramaGetScreenCount(client); - case X_PanoramiXGetScreenSize: - return RADEONProcXineramaGetScreenSize(client); - case X_XineramaIsActive: - return RADEONProcXineramaIsActive(client); - case X_XineramaQueryScreens: - return RADEONProcXineramaQueryScreens(client); - } - return BadRequest; -} - -/* SProc */ - -static int -RADEONSProcXineramaQueryVersion (ClientPtr client) -{ - REQUEST(xPanoramiXQueryVersionReq); - register int n; - swaps(&stuff->length,n); - REQUEST_SIZE_MATCH (xPanoramiXQueryVersionReq); - return RADEONProcXineramaQueryVersion(client); -} - -static int -RADEONSProcXineramaGetState(ClientPtr client) -{ - REQUEST(xPanoramiXGetStateReq); - register int n; - swaps (&stuff->length, n); - REQUEST_SIZE_MATCH(xPanoramiXGetStateReq); - return RADEONProcXineramaGetState(client); -} - -static int -RADEONSProcXineramaGetScreenCount(ClientPtr client) -{ - REQUEST(xPanoramiXGetScreenCountReq); - register int n; - swaps (&stuff->length, n); - REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq); - return RADEONProcXineramaGetScreenCount(client); -} - -static int -RADEONSProcXineramaGetScreenSize(ClientPtr client) -{ - REQUEST(xPanoramiXGetScreenSizeReq); - register int n; - swaps (&stuff->length, n); - REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq); - return RADEONProcXineramaGetScreenSize(client); -} - -static int -RADEONSProcXineramaIsActive(ClientPtr client) -{ - REQUEST(xXineramaIsActiveReq); - register int n; - swaps (&stuff->length, n); - REQUEST_SIZE_MATCH(xXineramaIsActiveReq); - return RADEONProcXineramaIsActive(client); -} - -static int -RADEONSProcXineramaQueryScreens(ClientPtr client) -{ - REQUEST(xXineramaQueryScreensReq); - register int n; - swaps (&stuff->length, n); - REQUEST_SIZE_MATCH(xXineramaQueryScreensReq); - return RADEONProcXineramaQueryScreens(client); -} - -int -RADEONSProcXineramaDispatch(ClientPtr client) -{ - REQUEST(xReq); - switch (stuff->data) { - case X_PanoramiXQueryVersion: - return RADEONSProcXineramaQueryVersion(client); - case X_PanoramiXGetState: - return RADEONSProcXineramaGetState(client); - case X_PanoramiXGetScreenCount: - return RADEONSProcXineramaGetScreenCount(client); - case X_PanoramiXGetScreenSize: - return RADEONSProcXineramaGetScreenSize(client); - case X_XineramaIsActive: - return RADEONSProcXineramaIsActive(client); - case X_XineramaQueryScreens: - return RADEONSProcXineramaQueryScreens(client); - } - return BadRequest; -} - -static void -RADEONXineramaResetProc(ExtensionEntry* extEntry) -{ - if(RADEONXineramadataPtr) { - Xfree(RADEONXineramadataPtr); - RADEONXineramadataPtr = NULL; - } -} - -void -RADEONXineramaExtensionInit(ScrnInfoPtr pScrn) -{ - RADEONInfoPtr info = RADEONPTR(pScrn); - Bool success = FALSE; - - if(!(RADEONXineramadataPtr)) { - - if(!info->MergedFB) { - RADEONnoPanoramiXExtension = TRUE; - info->MouseRestrictions = FALSE; - return; - } - -#ifdef PANORAMIX - if(!noPanoramiXExtension) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Xinerama active, not initializing Radeon Pseudo-Xinerama\n"); - RADEONnoPanoramiXExtension = TRUE; - info->MouseRestrictions = FALSE; - return; - } -#endif - - if(RADEONnoPanoramiXExtension) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Radeon Pseudo-Xinerama disabled\n"); - info->MouseRestrictions = FALSE; - return; - } - - if(info->CRT2Position == radeonClone) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Running MergedFB in Clone mode, Radeon Pseudo-Xinerama disabled\n"); - RADEONnoPanoramiXExtension = TRUE; - info->MouseRestrictions = FALSE; - return; - } - - if(!(info->AtLeastOneNonClone)) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Only Clone modes defined, Radeon Pseudo-Xinerama disabled\n"); - RADEONnoPanoramiXExtension = TRUE; - info->MouseRestrictions = FALSE; - return; - } - - RADEONXineramaNumScreens = 2; - - while(RADEONXineramaGeneration != serverGeneration) { - - info->XineramaExtEntry = AddExtension(PANORAMIX_PROTOCOL_NAME, 0,0, - RADEONProcXineramaDispatch, - RADEONSProcXineramaDispatch, - RADEONXineramaResetProc, - StandardMinorOpcode); - - if(!info->XineramaExtEntry) break; - - RADEONXineramaReqCode = (unsigned char)info->XineramaExtEntry->base; - - if(!(RADEONXineramadataPtr = (RADEONXineramaData *) - xcalloc(RADEONXineramaNumScreens, sizeof(RADEONXineramaData)))) break; - - RADEONXineramaGeneration = serverGeneration; - success = TRUE; - } - - if(!success) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to initialize Radeon Pseudo-Xinerama extension\n"); - RADEONnoPanoramiXExtension = TRUE; - info->MouseRestrictions = FALSE; - return; - } - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Initialized Radeon Pseudo-Xinerama extension\n"); - - info->RADEONXineramaVX = 0; - info->RADEONXineramaVY = 0; - - } - - RADEONUpdateXineramaScreenInfo(pScrn); - -} -/* End of PseudoXinerama */ - -static Bool -InRegion(int x, int y, region r) -{ - return (r.x0 <= x) && (x <= r.x1) && (r.y0 <= y) && (y <= r.y1); -} - -void -RADEONMergePointerMoved(int scrnIndex, int x, int y) -{ - ScrnInfoPtr pScrn1 = xf86Screens[scrnIndex]; - RADEONInfoPtr info = RADEONPTR(pScrn1); - ScrnInfoPtr pScrn2 = info->CRT2pScrn; - region out, in1, in2, f2, f1; - int deltax, deltay; - int temp1, temp2; - int old1x0, old1y0, old2x0, old2y0; - int CRT1XOffs = 0, CRT1YOffs = 0, CRT2XOffs = 0, CRT2YOffs = 0; - int HVirt = pScrn1->virtualX; - int VVirt = pScrn1->virtualY; - int sigstate; - Bool doit = FALSE, HaveNonRect = FALSE, HaveOffsRegions = FALSE; - RADEONScrn2Rel srel = ((RADEONMergedDisplayModePtr)info->CurrentLayout.mode->Private)->CRT2Position; - - if(info->DGAactive) { - return; - /* DGA: There is no cursor and no panning while DGA is active. */ - /* If it were, we would need to do: */ - /* HVirt = info->CurrentLayout.displayWidth; - VVirt = info->CurrentLayout.displayHeight; - BOUND(x, info->CurrentLayout.DGAViewportX, HVirt); - BOUND(y, info->CurrentLayout.DGAViewportY, VVirt); */ - } else { - CRT1XOffs = info->CRT1XOffs; - CRT1YOffs = info->CRT1YOffs; - CRT2XOffs = info->CRT2XOffs; - CRT2YOffs = info->CRT2YOffs; - HaveNonRect = info->HaveNonRect; - HaveOffsRegions = info->HaveOffsRegions; - } - - /* Check if the pointer is inside our dead areas */ - if((info->MouseRestrictions) && (srel != radeonClone) && !RADEONnoPanoramiXExtension) { - if(HaveNonRect) { - if(InRegion(x, y, info->NonRectDead)) { - switch(srel) { - case radeonLeftOf: - case radeonRightOf: y = info->NonRectDead.y0 - 1; - doit = TRUE; - break; - case radeonAbove: - case radeonBelow: x = info->NonRectDead.x0 - 1; - doit = TRUE; - default: break; - } - } - } - if(HaveOffsRegions) { - if(InRegion(x, y, info->OffDead1)) { - switch(srel) { - case radeonLeftOf: - case radeonRightOf: y = info->OffDead1.y1; - doit = TRUE; - break; - case radeonAbove: - case radeonBelow: x = info->OffDead1.x1; - doit = TRUE; - default: break; - } - } else if(InRegion(x, y, info->OffDead2)) { - switch(srel) { - case radeonLeftOf: - case radeonRightOf: y = info->OffDead2.y0 - 1; - doit = TRUE; - break; - case radeonAbove: - case radeonBelow: x = info->OffDead2.x0 - 1; - doit = TRUE; - default: break; - } - } - } - if(doit) { - UpdateCurrentTime(); - sigstate = xf86BlockSIGIO(); - miPointerAbsoluteCursor(x, y, currentTime.milliseconds); - xf86UnblockSIGIO(sigstate); - return; - } - } - - f1.x0 = old1x0 = info->CRT1frameX0; - f1.x1 = info->CRT1frameX1; - f1.y0 = old1y0 = info->CRT1frameY0; - f1.y1 = info->CRT1frameY1; - f2.x0 = old2x0 = pScrn2->frameX0; - f2.x1 = pScrn2->frameX1; - f2.y0 = old2y0 = pScrn2->frameY0; - f2.y1 = pScrn2->frameY1; - - /* Define the outer region. Crossing this causes all frames to move */ - out.x0 = pScrn1->frameX0; - out.x1 = pScrn1->frameX1; - out.y0 = pScrn1->frameY0; - out.y1 = pScrn1->frameY1; - - /* - * Define the inner sliding window. Being outsize both frames but - * inside the outer clipping window will slide corresponding frame - */ - in1 = out; - in2 = out; - switch(srel) { - case radeonLeftOf: - in1.x0 = f1.x0; - in2.x1 = f2.x1; - break; - case radeonRightOf: - in1.x1 = f1.x1; - in2.x0 = f2.x0; - break; - case radeonBelow: - in1.y1 = f1.y1; - in2.y0 = f2.y0; - break; - case radeonAbove: - in1.y0 = f1.y0; - in2.y1 = f2.y1; - break; - case radeonClone: - break; - } - - deltay = 0; - deltax = 0; - - if(InRegion(x, y, out)) { /* inside outer region */ - - /* xf86DrvMsg(0, X_INFO, "1: %d %d | %d %d %d %d | %d %d %d %d\n", - x, y, in1.x0, in1.x1, in1.y0, in1.y1, f1.x0, f1.x1, f1.y0, f1.y1); */ - - if(InRegion(x, y, in1) && !InRegion(x, y, f1)) { - REBOUND(f1.x0, f1.x1, x); - REBOUND(f1.y0, f1.y1, y); - deltax = 1; - /* xf86DrvMsg(0, X_INFO, "2: %d %d | %d %d %d %d | %d %d %d %d\n", - x, y, in1.x0, in1.x1, in1.y0, in1.y1, f1.x0, f1.x1, f1.y0, f1.y1); */ - } - if(InRegion(x, y, in2) && !InRegion(x, y, f2)) { - REBOUND(f2.x0, f2.x1, x); - REBOUND(f2.y0, f2.y1, y); - deltax = 1; - } - - } else { /* outside outer region */ - - /* xf86DrvMsg(0, X_INFO, "3: %d %d | %d %d %d %d | %d %d %d %d\n", - x, y, in1.x0, in1.x1, in1.y0, in1.y1, f1.x0, f1.x1, f1.y0, f1.y1); - xf86DrvMsg(0, X_INFO, "3-out: %d %d %d %d\n", - out.x0, out.x1, out.y0, out.y1); */ - - if(out.x0 > x) { - deltax = x - out.x0; - } - if(out.x1 < x) { - deltax = x - out.x1; - } - if(deltax) { - pScrn1->frameX0 += deltax; - pScrn1->frameX1 += deltax; - f1.x0 += deltax; - f1.x1 += deltax; - f2.x0 += deltax; - f2.x1 += deltax; - } - - if(out.y0 > y) { - deltay = y - out.y0; - } - if(out.y1 < y) { - deltay = y - out.y1; - } - if(deltay) { - pScrn1->frameY0 += deltay; - pScrn1->frameY1 += deltay; - f1.y0 += deltay; - f1.y1 += deltay; - f2.y0 += deltay; - f2.y1 += deltay; - } - - switch(srel) { - case radeonLeftOf: - if(x >= f1.x0) { REBOUND(f1.y0, f1.y1, y); } - if(x <= f2.x1) { REBOUND(f2.y0, f2.y1, y); } - break; - case radeonRightOf: - if(x <= f1.x1) { REBOUND(f1.y0, f1.y1, y); } - if(x >= f2.x0) { REBOUND(f2.y0, f2.y1, y); } - break; - case radeonBelow: - if(y <= f1.y1) { REBOUND(f1.x0, f1.x1, x); } - if(y >= f2.y0) { REBOUND(f2.x0, f2.x1, x); } - break; - case radeonAbove: - if(y >= f1.y0) { REBOUND(f1.x0, f1.x1, x); } - if(y <= f2.y1) { REBOUND(f2.x0, f2.x1, x); } - break; - case radeonClone: - break; - } - - } - - if(deltax || deltay) { - info->CRT1frameX0 = f1.x0; - info->CRT1frameY0 = f1.y0; - pScrn2->frameX0 = f2.x0; - pScrn2->frameY0 = f2.y0; - - switch(((RADEONMergedDisplayModePtr)info->CurrentLayout.mode->Private)->CRT2Position) { - case radeonLeftOf: - case radeonRightOf: - if(info->CRT1YOffs || info->CRT2YOffs || HaveNonRect) { - if(info->CRT1frameY0 != old1y0) { - if(info->CRT1frameY0 < info->CRT1YOffs) - info->CRT1frameY0 = info->CRT1YOffs; - temp1 = info->CRT1frameY0 + CDMPTR->CRT1->VDisplay; - /*temp2 = pScrn1->virtualY - info->CRT2YOffs;*/ - temp2 = min((VVirt - CRT2YOffs), (CRT1YOffs + info->MBXNR1YMAX)); - if(temp1 > temp2) - info->CRT1frameY0 -= (temp1 - temp2); - } - if(pScrn2->frameY0 != old2y0) { - if(pScrn2->frameY0 < info->CRT2YOffs) - pScrn2->frameY0 = info->CRT2YOffs; - temp1 = pScrn2->frameY0 + CDMPTR->CRT2->VDisplay; - /*temp2 = pScrn1->virtualY - info->CRT1YOffs;*/ - temp2 = min((VVirt - CRT1YOffs), (CRT2YOffs + info->MBXNR2YMAX)); - if(temp1 > temp2) - pScrn2->frameY0 -= (temp1 - temp2); - } - } - break; - case radeonBelow: - case radeonAbove: - if(info->CRT1XOffs || info->CRT2XOffs || HaveNonRect) { - if(info->CRT1frameX0 != old1x0) { - if(info->CRT1frameX0 < info->CRT1XOffs) - info->CRT1frameX0 = info->CRT1XOffs; - temp1 = info->CRT1frameX0 + CDMPTR->CRT1->HDisplay; - /*temp2 = pScrn1->virtualX - info->CRT2XOffs;*/ - temp2 = min((HVirt - CRT2XOffs), (CRT1XOffs + info->MBXNR1XMAX)); - if(temp1 > temp2) - info->CRT1frameX0 -= (temp1 - temp2); - } - if(pScrn2->frameX0 != old2x0) { - if(pScrn2->frameX0 < info->CRT2XOffs) - pScrn2->frameX0 = info->CRT2XOffs; - temp1 = pScrn2->frameX0 + CDMPTR->CRT2->HDisplay; - /*temp2 = pScrn1->virtualX - info->CRT1XOffs;*/ - temp2 = min((HVirt - CRT1XOffs), (CRT2XOffs + info->MBXNR2XMAX)); - if(temp1 > temp2) - pScrn2->frameX0 -= (temp1 - temp2); - } - } - break; - case radeonClone: - break; - } - - info->CRT1frameX1 = info->CRT1frameX0 + CDMPTR->CRT1->HDisplay - 1; - info->CRT1frameY1 = info->CRT1frameY0 + CDMPTR->CRT1->VDisplay - 1; - pScrn2->frameX1 = pScrn2->frameX0 + CDMPTR->CRT2->HDisplay - 1; - pScrn2->frameY1 = pScrn2->frameY0 + CDMPTR->CRT2->VDisplay - 1; -#if 0 - pScrn1->frameX1 = pScrn1->frameX0 + info->CurrentLayout.mode->HDisplay - 1; - pScrn1->frameY1 = pScrn1->frameY0 + info->CurrentLayout.mode->VDisplay - 1; -#endif - - RADEONDoAdjustFrame(pScrn1, info->CRT1frameX0, info->CRT1frameY0, FALSE); - RADEONDoAdjustFrame(pScrn1, pScrn2->frameX0, pScrn2->frameY0, TRUE); - } -} - -static void -RADEONAdjustFrameMergedHelper(int scrnIndex, int x, int y, int flags) -{ - ScrnInfoPtr pScrn1 = xf86Screens[scrnIndex]; - RADEONInfoPtr info = RADEONPTR(pScrn1); - ScrnInfoPtr pScrn2 = info->CRT2pScrn; - int VTotal = info->CurrentLayout.mode->VDisplay; - int HTotal = info->CurrentLayout.mode->HDisplay; - int VMax = VTotal; - int HMax = HTotal; - int HVirt = pScrn1->virtualX; - int VVirt = pScrn1->virtualY; - int x1 = x, x2 = x; - int y1 = y, y2 = y; - int CRT1XOffs = 0, CRT1YOffs = 0, CRT2XOffs = 0, CRT2YOffs = 0; - int MBXNR1XMAX = 65536, MBXNR1YMAX = 65536, MBXNR2XMAX = 65536, MBXNR2YMAX = 65536; - - if(info->DGAactive) { - HVirt = info->CurrentLayout.displayWidth; - VVirt = info->CurrentLayout.displayHeight; - } else { - CRT1XOffs = info->CRT1XOffs; - CRT1YOffs = info->CRT1YOffs; - CRT2XOffs = info->CRT2XOffs; - CRT2YOffs = info->CRT2YOffs; - MBXNR1XMAX = info->MBXNR1XMAX; - MBXNR1YMAX = info->MBXNR1YMAX; - MBXNR2XMAX = info->MBXNR2XMAX; - MBXNR2YMAX = info->MBXNR2YMAX; - } - - - BOUND(x, 0, pScrn1->virtualX - HTotal); - BOUND(y, 0, pScrn1->virtualY - VTotal); - if(SDMPTR(pScrn1)->CRT2Position != radeonClone) { -#if 0 - BOUND(x1, info->CRT1XOffs, pScrn1->virtualX - HTotal - info->CRT2XOffs); - BOUND(y1, info->CRT1YOffs, pScrn1->virtualY - VTotal - info->CRT2YOffs); - BOUND(x2, info->CRT2XOffs, pScrn1->virtualX - HTotal - info->CRT1XOffs); - BOUND(y2, info->CRT2YOffs, pScrn1->virtualY - VTotal - info->CRT1YOffs); -#endif - BOUND(x1, CRT1XOffs, min(HVirt, MBXNR1XMAX + CRT1XOffs) - min(HTotal, MBXNR1XMAX) - CRT2XOffs); - BOUND(y1, CRT1YOffs, min(VVirt, MBXNR1YMAX + CRT1YOffs) - min(VTotal, MBXNR1YMAX) - CRT2YOffs); - BOUND(x2, CRT2XOffs, min(HVirt, MBXNR2XMAX + CRT2XOffs) - min(HTotal, MBXNR2XMAX) - CRT1XOffs); - BOUND(y2, CRT2YOffs, min(VVirt, MBXNR2YMAX + CRT2YOffs) - min(VTotal, MBXNR2YMAX) - CRT1YOffs); - } - - switch(SDMPTR(pScrn1)->CRT2Position) { - case radeonLeftOf: - pScrn2->frameX0 = x2; - /*BOUND(pScrn2->frameY0, y2, y2 + VMax - CDMPTR->CRT2->VDisplay);*/ - BOUND(pScrn2->frameY0, y2, y2 + min(VMax, MBXNR2YMAX) - CDMPTR->CRT2->VDisplay); - info->CRT1frameX0 = x1 + CDMPTR->CRT2->HDisplay; - /*BOUND(info->CRT1frameY0, y1, y1 + VMax - CDMPTR->CRT1->VDisplay);*/ - BOUND(info->CRT1frameY0, y1, y1 + min(VMax, MBXNR1YMAX) - CDMPTR->CRT1->VDisplay); - break; - case radeonRightOf: - info->CRT1frameX0 = x1; - /*BOUND(info->CRT1frameY0, y1, y1 + VMax - CDMPTR->CRT1->VDisplay);*/ - BOUND(info->CRT1frameY0, y1, y1 + min(VMax, MBXNR1YMAX) - CDMPTR->CRT1->VDisplay); - pScrn2->frameX0 = x2 + CDMPTR->CRT1->HDisplay; - /*BOUND(pScrn2->frameY0, y2, y2 + VMax - CDMPTR->CRT2->VDisplay);*/ - BOUND(pScrn2->frameY0, y2, y2 + min(VMax, MBXNR2YMAX) - CDMPTR->CRT2->VDisplay); - break; - case radeonAbove: - /*BOUND(pScrn2->frameX0, x2, x2 + HMax - CDMPTR->CRT2->HDisplay);*/ - BOUND(pScrn2->frameX0, x2, x2 + min(HMax, MBXNR2XMAX) - CDMPTR->CRT2->HDisplay); - pScrn2->frameY0 = y2; - /*BOUND(info->CRT1frameX0, x1, x1 + HMax - CDMPTR->CRT1->HDisplay);*/ - BOUND(info->CRT1frameX0, x1, x1 + min(HMax, MBXNR1XMAX) - CDMPTR->CRT1->HDisplay); - info->CRT1frameY0 = y1 + CDMPTR->CRT2->VDisplay; - break; - case radeonBelow: - /*BOUND(info->CRT1frameX0, x1, x1 + HMax - CDMPTR->CRT1->HDisplay);*/ - BOUND(info->CRT1frameX0, x1, x1 + min(HMax, MBXNR1XMAX) - CDMPTR->CRT1->HDisplay); - info->CRT1frameY0 = y1; - /*BOUND(pScrn2->frameX0, x2, x2 + HMax - CDMPTR->CRT2->HDisplay);*/ - BOUND(pScrn2->frameX0, x2, x2 + min(HMax, MBXNR2XMAX) - CDMPTR->CRT2->HDisplay); - pScrn2->frameY0 = y2 + CDMPTR->CRT1->VDisplay; - break; - case radeonClone: - BOUND(info->CRT1frameX0, x, x + HMax - CDMPTR->CRT1->HDisplay); - BOUND(info->CRT1frameY0, y, y + VMax - CDMPTR->CRT1->VDisplay); - BOUND(pScrn2->frameX0, x, x + HMax - CDMPTR->CRT2->HDisplay); - BOUND(pScrn2->frameY0, y, y + VMax - CDMPTR->CRT2->VDisplay); - break; - } - - BOUND(info->CRT1frameX0, 0, pScrn1->virtualX - CDMPTR->CRT1->HDisplay); - BOUND(info->CRT1frameY0, 0, pScrn1->virtualY - CDMPTR->CRT1->VDisplay); - BOUND(pScrn2->frameX0, 0, pScrn1->virtualX - CDMPTR->CRT2->HDisplay); - BOUND(pScrn2->frameY0, 0, pScrn1->virtualY - CDMPTR->CRT2->VDisplay); - - pScrn1->frameX0 = x; - pScrn1->frameY0 = y; - - info->CRT1frameX1 = info->CRT1frameX0 + CDMPTR->CRT1->HDisplay - 1; - info->CRT1frameY1 = info->CRT1frameY0 + CDMPTR->CRT1->VDisplay - 1; - pScrn2->frameX1 = pScrn2->frameX0 + CDMPTR->CRT2->HDisplay - 1; - pScrn2->frameY1 = pScrn2->frameY0 + CDMPTR->CRT2->VDisplay - 1; - pScrn1->frameX1 = pScrn1->frameX0 + info->CurrentLayout.mode->HDisplay - 1; - pScrn1->frameY1 = pScrn1->frameY0 + info->CurrentLayout.mode->VDisplay - 1; - - if(SDMPTR(pScrn1)->CRT2Position != radeonClone) { - pScrn1->frameX1 += CRT1XOffs + CRT2XOffs; - pScrn1->frameY1 += CRT1YOffs + CRT2YOffs; - } - -/* - RADEONDoAdjustFrame(pScrn1, info->CRT1frameX0, info->CRT1frameY0, FALSE); - RADEONDoAdjustFrame(pScrn1, pScrn2->frameX0, pScrn2->frameY0, TRUE); -*/ -} - -void -RADEONAdjustFrameMerged(int scrnIndex, int x, int y, int flags) -{ - ScrnInfoPtr pScrn1 = xf86Screens[scrnIndex]; - RADEONInfoPtr info = RADEONPTR(pScrn1); - ScrnInfoPtr pScrn2 = info->CRT2pScrn; - - RADEONAdjustFrameMergedHelper(scrnIndex, x, y, flags); - RADEONDoAdjustFrame(pScrn1, info->CRT1frameX0, info->CRT1frameY0, FALSE); - RADEONDoAdjustFrame(pScrn1, pScrn2->frameX0, pScrn2->frameY0, TRUE); -} - -static void -RADEONMergedFBCalcDPI(ScrnInfoPtr pScrn1, ScrnInfoPtr pScrn2, RADEONScrn2Rel srel, Bool quiet) -{ - RADEONInfoPtr info = RADEONPTR(pScrn1); - MessageType from = X_DEFAULT; - xf86MonPtr DDC1 = (xf86MonPtr)(pScrn1->monitor->DDC); - xf86MonPtr DDC2 = (xf86MonPtr)(pScrn2->monitor->DDC); - int ddcWidthmm = 0, ddcHeightmm = 0; - const char *dsstr = "MergedFB: Display dimensions: %dx%d mm\n"; - - /* This sets the DPI for MergedFB mode. The problem is that - * this can never be exact, because the output devices may - * have different dimensions. This function tries to compromise - * through a few assumptions, and it just calculates an average - * DPI value for both monitors. - */ - - /* Copy user-given DisplaySize (which should regard BOTH monitors!) */ - pScrn1->widthmm = pScrn1->monitor->widthmm; - pScrn1->heightmm = pScrn1->monitor->heightmm; - - if(monitorResolution > 0) { - - /* Set command line given values (overrules given options) */ - pScrn1->xDpi = monitorResolution; - pScrn1->yDpi = monitorResolution; - from = X_CMDLINE; - - } else if(info->MergedFBXDPI) { - - /* Set option-wise given values (overrules DisplaySize config option) */ - pScrn1->xDpi = info->MergedFBXDPI; - pScrn1->yDpi = info->MergedFBYDPI; - from = X_CONFIG; - - } else if(pScrn1->widthmm > 0 || pScrn1->heightmm > 0) { - - /* Set values calculated from given DisplaySize */ - from = X_CONFIG; - if(pScrn1->widthmm > 0) { - pScrn1->xDpi = (int)((double)pScrn1->virtualX * 25.4 / pScrn1->widthmm); - } - if(pScrn1->heightmm > 0) { - pScrn1->yDpi = (int)((double)pScrn1->virtualY * 25.4 / pScrn1->heightmm); - } - if(!quiet) { - xf86DrvMsg(pScrn1->scrnIndex, from, dsstr, pScrn1->widthmm, pScrn1->heightmm); - } - - } else if(ddcWidthmm && ddcHeightmm) { - - /* Set values from DDC-provided display size */ - - /* Get DDC display size; if only either CRT1 or CRT2 provided these, - * assume equal dimensions for both, otherwise add dimensions - */ - if( (DDC1 && (DDC1->features.hsize > 0 && DDC1->features.vsize > 0)) && - (DDC2 && (DDC2->features.hsize > 0 && DDC2->features.vsize > 0)) ) { - ddcWidthmm = max(DDC1->features.hsize, DDC2->features.hsize) * 10; - ddcHeightmm = max(DDC1->features.vsize, DDC2->features.vsize) * 10; - switch(srel) { - case radeonLeftOf: - case radeonRightOf: - ddcWidthmm = (DDC1->features.hsize + DDC2->features.hsize) * 10; - break; - case radeonAbove: - case radeonBelow: - ddcHeightmm = (DDC1->features.vsize + DDC2->features.vsize) * 10; - default: - break; - } - } else if(DDC1 && (DDC1->features.hsize > 0 && DDC1->features.vsize > 0)) { - ddcWidthmm = DDC1->features.hsize * 10; - ddcHeightmm = DDC1->features.vsize * 10; - switch(srel) { - case radeonLeftOf: - case radeonRightOf: - ddcWidthmm *= 2; - break; - case radeonAbove: - case radeonBelow: - ddcHeightmm *= 2; - default: - break; - } - } else if(DDC2 && (DDC2->features.hsize > 0 && DDC2->features.vsize > 0) ) { - ddcWidthmm = DDC2->features.hsize * 10; - ddcHeightmm = DDC2->features.vsize * 10; - switch(srel) { - case radeonLeftOf: - case radeonRightOf: - ddcWidthmm *= 2; - break; - case radeonAbove: - case radeonBelow: - ddcHeightmm *= 2; - default: - break; - } - } - - from = X_PROBED; - - if(!quiet) { - xf86DrvMsg(pScrn1->scrnIndex, from, dsstr, ddcWidthmm, ddcHeightmm); - } - - pScrn1->widthmm = ddcWidthmm; - pScrn1->heightmm = ddcHeightmm; - if(pScrn1->widthmm > 0) { - pScrn1->xDpi = (int)((double)pScrn1->virtualX * 25.4 / pScrn1->widthmm); - } - if(pScrn1->heightmm > 0) { - pScrn1->yDpi = (int)((double)pScrn1->virtualY * 25.4 / pScrn1->heightmm); - } - - } else { - - pScrn1->xDpi = pScrn1->yDpi = DEFAULT_DPI; - - } - - /* Sanity check */ - if(pScrn1->xDpi > 0 && pScrn1->yDpi <= 0) - pScrn1->yDpi = pScrn1->xDpi; - if(pScrn1->yDpi > 0 && pScrn1->xDpi <= 0) - pScrn1->xDpi = pScrn1->yDpi; - - pScrn2->xDpi = pScrn1->xDpi; - pScrn2->yDpi = pScrn1->yDpi; - - if(!quiet) { - xf86DrvMsg(pScrn1->scrnIndex, from, "MergedFB: DPI set to (%d, %d)\n", - pScrn1->xDpi, pScrn1->yDpi); - } -} - - -void -RADEONMergedFBSetDpi(ScrnInfoPtr pScrn1, ScrnInfoPtr pScrn2, RADEONScrn2Rel srel) -{ - RADEONInfoPtr info = RADEONPTR(pScrn1); - - RADEONMergedFBCalcDPI(pScrn1, pScrn2, srel, FALSE); - - info->MergedDPISRel = srel; - info->RADEONMergedDPIVX = pScrn1->virtualX; - info->RADEONMergedDPIVY = pScrn1->virtualY; - -} - -void -RADEONMergedFBResetDpi(ScrnInfoPtr pScrn, Bool force) -{ - RADEONInfoPtr info = RADEONPTR(pScrn); - ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; - RADEONScrn2Rel srel = ((RADEONMergedDisplayModePtr)info->CurrentLayout.mode->Private)->CRT2Position; - - /* This does the same calculation for the DPI as - * the initial run. This means that an eventually - * given -dpi command line switch will lead to - * constant dpi values, regardless of the virtual - * screen size. - * I consider this consequent. If this is undesired, - * one should use the DisplaySize parameter in the - * config file instead of the command line switch. - * The DPI will be calculated then. - */ - - if(force || - (info->MergedDPISRel != srel) || - (info->RADEONMergedDPIVX != pScrn->virtualX) || - (info->RADEONMergedDPIVY != pScrn->virtualY) - ) { - - RADEONMergedFBCalcDPI(pScrn, info->CRT2pScrn, srel, TRUE); - - pScreen->mmWidth = (pScrn->virtualX * 254 + pScrn->xDpi * 5) / (pScrn->xDpi * 10); - pScreen->mmHeight = (pScrn->virtualY * 254 + pScrn->yDpi * 5) / (pScrn->yDpi * 10); - - info->MergedDPISRel = srel; - info->RADEONMergedDPIVX = pScrn->virtualX; - info->RADEONMergedDPIVY = pScrn->virtualY; - - } -} - -/* radeon cursor helpers */ -static void -RADEONChooseCursorCRTC(ScrnInfoPtr pScrn1, int x, int y) -{ - RADEONInfoPtr info = RADEONPTR(pScrn1); - unsigned char *RADEONMMIO = info->MMIO; - RADEONScrn2Rel srel = - ((RADEONMergedDisplayModePtr)info->CurrentLayout.mode->Private)->CRT2Position; - ScrnInfoPtr pScrn2 = info->CRT2pScrn; - - if (srel == radeonClone) { - /* show cursor 2 */ - OUTREGP(RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_CUR_EN, - ~RADEON_CRTC2_CUR_EN); - /* show cursor 1 */ - OUTREGP(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_CUR_EN, - ~RADEON_CRTC_CUR_EN); - } - else { - if (((x >= pScrn1->frameX0) && (x <= pScrn1->frameX1)) && - ((y >= pScrn1->frameY0) && (y <= pScrn1->frameY1))) { - /* hide cursor 2 */ - OUTREGP(RADEON_CRTC2_GEN_CNTL, 0, ~RADEON_CRTC2_CUR_EN); - /* show cursor 1 */ - OUTREGP(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_CUR_EN, - ~RADEON_CRTC_CUR_EN); - } - if (((x >= pScrn2->frameX0) && (x <= pScrn2->frameX1)) && - ((y >= pScrn2->frameY0) && (y <= pScrn2->frameY1))) { - /* hide cursor 1 */ - OUTREGP(RADEON_CRTC_GEN_CNTL, 0, ~RADEON_CRTC_CUR_EN); - /* show cursor 2 */ - OUTREGP(RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_CUR_EN, - ~RADEON_CRTC2_CUR_EN); - } - } -} - -void -RADEONSetCursorPositionMerged(ScrnInfoPtr pScrn, int x, int y) -{ - RADEONInfoPtr info = RADEONPTR(pScrn); - unsigned char *RADEONMMIO = info->MMIO; - xf86CursorInfoPtr cursor = info->cursor; - int xorigin = 0; - int yorigin = 0; - int stride = 256; - ScrnInfoPtr pScrn2 = info->CRT2pScrn; - DisplayModePtr mode1 = CDMPTR->CRT1; - DisplayModePtr mode2 = CDMPTR->CRT2; - int x1, y1, x2, y2; - int total_y1 = pScrn->frameY1 - pScrn->frameY0; - int total_y2 = pScrn2->frameY1 - pScrn2->frameY0; - - if (x < 0) xorigin = -x+1; - if (y < 0) yorigin = -y+1; - /* if (y > total_y) y = total_y; */ - if (xorigin >= cursor->MaxWidth) xorigin = cursor->MaxWidth - 1; - if (yorigin >= cursor->MaxHeight) yorigin = cursor->MaxHeight - 1; - - x += pScrn->frameX0; - y += pScrn->frameY0; - - x1 = x - info->CRT1frameX0; - y1 = y - info->CRT1frameY0; - - x2 = x - pScrn2->frameX0; - y2 = y - pScrn2->frameY0; - - if (y1 > total_y1) - y1 = total_y1; - if (y2 > total_y2) - y2 = total_y2; - - if(mode1->Flags & V_INTERLACE) - y1 /= 2; - else if(mode1->Flags & V_DBLSCAN) - y1 *= 2; - - if(mode2->Flags & V_INTERLACE) - y2 /= 2; - else if(mode2->Flags & V_DBLSCAN) - y2 *= 2; - - if (x < 0) - x = 0; - if (y < 0) - y = 0; - - RADEONChooseCursorCRTC(pScrn, x, y); - - /* cursor1 */ - OUTREG(RADEON_CUR_HORZ_VERT_OFF, (RADEON_CUR_LOCK - | (xorigin << 16) - | yorigin)); - OUTREG(RADEON_CUR_HORZ_VERT_POSN, (RADEON_CUR_LOCK - | ((xorigin ? 0 : x1) << 16) - | (yorigin ? 0 : y1))); - OUTREG(RADEON_CUR_OFFSET, info->cursor_offset + yorigin * stride); - /* cursor2 */ - OUTREG(RADEON_CUR2_HORZ_VERT_OFF, (RADEON_CUR2_LOCK - | (xorigin << 16) - | yorigin)); - OUTREG(RADEON_CUR2_HORZ_VERT_POSN, (RADEON_CUR2_LOCK - | ((xorigin ? 0 : x2) << 16) - | (yorigin ? 0 : y2))); - OUTREG(RADEON_CUR2_OFFSET, info->cursor_offset + yorigin * stride); -} - -/* radeon Xv helpers */ - -/* choose the crtc for the overlay for mergedfb based on the location - of the output window and the orientation of the crtcs */ - -void -RADEONChooseOverlayCRTC( - ScrnInfoPtr pScrn, - BoxPtr dstBox -) { - RADEONInfoPtr info = RADEONPTR(pScrn); - RADEONScrn2Rel srel = - ((RADEONMergedDisplayModePtr)info->CurrentLayout.mode->Private)->CRT2Position; - - if (srel == radeonLeftOf) { - if (dstBox->x1 >= info->CRT2pScrn->frameX1) - info->OverlayOnCRTC2 = FALSE; - else - info->OverlayOnCRTC2 = TRUE; - } - if (srel == radeonRightOf) { - if (dstBox->x2 <= info->CRT2pScrn->frameX0) - info->OverlayOnCRTC2 = FALSE; - else - info->OverlayOnCRTC2 = TRUE; - } - if (srel == radeonAbove) { - if (dstBox->y1 >= info->CRT2pScrn->frameY1) - info->OverlayOnCRTC2 = FALSE; - else - info->OverlayOnCRTC2 = TRUE; - } - if (srel == radeonBelow) { - if (dstBox->y2 <= info->CRT2pScrn->frameY0) - info->OverlayOnCRTC2 = FALSE; - else - info->OverlayOnCRTC2 = TRUE; - } -} diff --git a/src/radeon_mergedfb.h b/src/radeon_mergedfb.h deleted file mode 100644 index d9bcc03..0000000 --- a/src/radeon_mergedfb.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright 2003 Alex Deucher. - * - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation on the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NON-INFRINGEMENT. IN NO EVENT SHALL ALEX DEUCHER, OR ANY OTHER - * CONTRIBUTORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -/* - * Authors: - * Alex Deucher <agd5f@yahoo.com> - * - */ - -#ifndef _RADEON_MERGEDFB_H_ -#define _RADEON_MERGEDFB_H_ - -#include "xf86.h" - -#include "radeon.h" - -#if 0 - /* Psuedo Xinerama support */ -#define NEED_REPLIES /* ? */ -#define EXTENSION_PROC_ARGS void * -#include "extnsionst.h" /* required */ -#include <X11/extensions/panoramiXproto.h> /* required */ -#define RADEON_XINERAMA_MAJOR_VERSION 1 -#define RADEON_XINERAMA_MINOR_VERSION 1 - -/* needed for pseudo-xinerama by radeon_driver.c */ -Bool RADEONnoPanoramiXExtension = TRUE; - -/* Relative merge position */ -typedef enum { - radeonLeftOf, - radeonRightOf, - radeonAbove, - radeonBelow, - radeonClone -} RADEONScrn2Rel; -#endif - -#define SDMPTR(x) ((RADEONMergedDisplayModePtr)(x->currentMode->Private)) -#define CDMPTR ((RADEONMergedDisplayModePtr)(info->CurrentLayout.mode->Private)) - -#define BOUND(test,low,hi) { \ - if(test < low) test = low; \ - if(test > hi) test = hi; } - -#define REBOUND(low,hi,test) { \ - if(test < low) { \ - hi += test-low; \ - low = test; } \ - if(test > hi) { \ - low += test-hi; \ - hi = test; } } - -typedef struct _MergedDisplayModeRec { - DisplayModePtr CRT1; - DisplayModePtr CRT2; - RADEONScrn2Rel CRT2Position; -} RADEONMergedDisplayModeRec, *RADEONMergedDisplayModePtr; - -typedef struct _RADEONXineramaData { - int x; - int y; - int width; - int height; -} RADEONXineramaData; - -/* needed by radeon_driver.c */ -extern void -RADEONAdjustFrameMerged(int scrnIndex, int x, int y, int flags); -extern void -RADEONMergePointerMoved(int scrnIndex, int x, int y); -extern DisplayModePtr -RADEONGenerateModeList(ScrnInfoPtr pScrn, char* str, - DisplayModePtr i, DisplayModePtr j, - RADEONScrn2Rel srel); -extern int -RADEONStrToRanges(range *r, char *s, int max); -extern void -RADEONXineramaExtensionInit(ScrnInfoPtr pScrn); -extern void -RADEONUpdateXineramaScreenInfo(ScrnInfoPtr pScrn1); -extern void -RADEONMergedFBSetDpi(ScrnInfoPtr pScrn1, ScrnInfoPtr pScrn2, RADEONScrn2Rel srel); -extern void -RADEONMergedFBResetDpi(ScrnInfoPtr pScrn, Bool force); -extern void -RADEONRecalcDefaultVirtualSize(ScrnInfoPtr pScrn); - -/* needed by radeon_cursor.c */ -extern void -RADEONSetCursorPositionMerged(ScrnInfoPtr pScrn, int x, int y); - -/* needed by radeon_video.c */ -extern void -RADEONChooseOverlayCRTC(ScrnInfoPtr, BoxPtr); - -#endif /* _RADEON_MERGEDFB_H_ */ diff --git a/src/radeon_modes.c b/src/radeon_modes.c index 70bf184..064b1ae 100644 --- a/src/radeon_modes.c +++ b/src/radeon_modes.c @@ -42,80 +42,18 @@ #include "xf86.h" /* Driver data structures */ +#include "randrstr.h" +#include "radeon_probe.h" #include "radeon.h" #include "radeon_reg.h" #include "radeon_macros.h" -#include "radeon_probe.h" + #include "radeon_version.h" +#include "xf86Modes.h" /* DDC support */ #include "xf86DDC.h" - -/* Established timings from EDID standard */ -static struct -{ - int hsize; - int vsize; - int refresh; -} est_timings[] = { - {1280, 1024, 75}, - {1024, 768, 75}, - {1024, 768, 70}, - {1024, 768, 60}, - {1024, 768, 87}, - {832, 624, 75}, - {800, 600, 75}, - {800, 600, 72}, - {800, 600, 60}, - {800, 600, 56}, - {640, 480, 75}, - {640, 480, 72}, - {640, 480, 67}, - {640, 480, 60}, - {720, 400, 88}, - {720, 400, 70}, -}; - -/* This function will sort all modes according to their resolution. - * Highest resolution first. - */ -static void RADEONSortModes(DisplayModePtr *new, DisplayModePtr *first, - DisplayModePtr *last) -{ - DisplayModePtr p; - - p = *last; - while (p) { - if ((((*new)->HDisplay < p->HDisplay) && - ((*new)->VDisplay < p->VDisplay)) || - (((*new)->HDisplay == p->HDisplay) && - ((*new)->VDisplay == p->VDisplay) && - ((*new)->Clock < p->Clock))) { - - if (p->next) p->next->prev = *new; - (*new)->prev = p; - (*new)->next = p->next; - p->next = *new; - if (!((*new)->next)) *last = *new; - break; - } - if (!p->prev) { - (*new)->prev = NULL; - (*new)->next = p; - p->prev = *new; - *first = *new; - break; - } - p = p->prev; - } - - if (!*first) { - *first = *new; - (*new)->prev = NULL; - (*new)->next = NULL; - *last = *new; - } -} +#include <randrstr.h> void RADEONSetPitch (ScrnInfoPtr pScrn) { @@ -138,304 +76,6 @@ void RADEONSetPitch (ScrnInfoPtr pScrn) pScrn->displayWidth = dummy; } -/* When no mode provided in config file, this will add all modes supported in - * DDC date the pScrn->modes list - */ -static DisplayModePtr RADEONDDCModes(ScrnInfoPtr pScrn, xf86MonPtr ddc) -{ - DisplayModePtr p; - DisplayModePtr last = NULL; - DisplayModePtr new = NULL; - DisplayModePtr first = NULL; - int count = 0; - int j, tmp; - char stmp[32]; - - /* Go thru detailed timing table first */ - for (j = 0; j < 4; j++) { - if (ddc->det_mon[j].type == 0) { - struct detailed_timings *d_timings = - &ddc->det_mon[j].section.d_timings; - - if (d_timings->h_active == 0 || d_timings->v_active == 0) break; - - new = xnfcalloc(1, sizeof (DisplayModeRec)); - memset(new, 0, sizeof (DisplayModeRec)); - - new->HDisplay = d_timings->h_active; - new->VDisplay = d_timings->v_active; - - sprintf(stmp, "%dx%d", new->HDisplay, new->VDisplay); - new->name = xnfalloc(strlen(stmp) + 1); - strcpy(new->name, stmp); - - new->HTotal = new->HDisplay + d_timings->h_blanking; - new->HSyncStart = new->HDisplay + d_timings->h_sync_off; - new->HSyncEnd = new->HSyncStart + d_timings->h_sync_width; - new->VTotal = new->VDisplay + d_timings->v_blanking; - new->VSyncStart = new->VDisplay + d_timings->v_sync_off; - new->VSyncEnd = new->VSyncStart + d_timings->v_sync_width; - new->Clock = d_timings->clock / 1000; - new->Flags = (d_timings->interlaced ? V_INTERLACE : 0); - new->status = MODE_OK; -#ifdef M_T_PREFERRED - if (PREFERRED_TIMING_MODE(ddc->features.msc)) - new->type = M_T_PREFERRED; - else -#endif - new->type = M_T_DEFAULT; - - if (d_timings->sync == 3) { - switch (d_timings->misc) { - case 0: new->Flags |= V_NHSYNC | V_NVSYNC; break; - case 1: new->Flags |= V_PHSYNC | V_NVSYNC; break; - case 2: new->Flags |= V_NHSYNC | V_PVSYNC; break; - case 3: new->Flags |= V_PHSYNC | V_PVSYNC; break; - } - } - count++; - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Valid Mode from Detailed timing table: %s\n", - new->name); - - RADEONSortModes(&new, &first, &last); - } - } - - /* Search thru standard VESA modes from EDID */ - for (j = 0; j < 8; j++) { - if (ddc->timings2[j].hsize == 0 || ddc->timings2[j].vsize == 0) - continue; - for (p = pScrn->monitor->Modes; p && p->next; p = p->next->next) { - /* Ignore all double scan modes */ - if ((ddc->timings2[j].hsize == p->HDisplay) && - (ddc->timings2[j].vsize == p->VDisplay)) { - float refresh = - (float)p->Clock * 1000.0 / p->HTotal / p->VTotal; - - if (abs((float)ddc->timings2[j].refresh - refresh) < 1.0) { - /* Is this good enough? */ - new = xnfcalloc(1, sizeof (DisplayModeRec)); - memcpy(new, p, sizeof(DisplayModeRec)); - new->name = xnfalloc(strlen(p->name) + 1); - strcpy(new->name, p->name); - new->status = MODE_OK; - new->type = M_T_DEFAULT; - - count++; - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Valid Mode from standard timing table: %s\n", - new->name); - - RADEONSortModes(&new, &first, &last); - break; - } - } - } - } - - /* Search thru established modes from EDID */ - tmp = (ddc->timings1.t1 << 8) | ddc->timings1.t2; - for (j = 0; j < 16; j++) { - if (tmp & (1 << j)) { - for (p = pScrn->monitor->Modes; p && p->next; p = p->next->next) { - if ((est_timings[j].hsize == p->HDisplay) && - (est_timings[j].vsize == p->VDisplay)) { - float refresh = - (float)p->Clock * 1000.0 / p->HTotal / p->VTotal; - - if (abs((float)est_timings[j].refresh - refresh) < 1.0) { - /* Is this good enough? */ - new = xnfcalloc(1, sizeof (DisplayModeRec)); - memcpy(new, p, sizeof(DisplayModeRec)); - new->name = xnfalloc(strlen(p->name) + 1); - strcpy(new->name, p->name); - new->status = MODE_OK; - new->type = M_T_DEFAULT; - - count++; - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Valid Mode from established timing " - "table: %s\n", new->name); - - RADEONSortModes(&new, &first, &last); - break; - } - } - } - } - } - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Total of %d mode(s) found.\n", count); - - return first; -} - -/* XFree86's xf86ValidateModes routine doesn't work well with DDC modes, - * so here is our own validation routine. - */ -int RADEONValidateDDCModes(ScrnInfoPtr pScrn1, char **ppModeName, - RADEONMonitorType DisplayType, int crtc2) -{ - RADEONInfoPtr info = RADEONPTR(pScrn1); - DisplayModePtr p; - DisplayModePtr last = NULL; - DisplayModePtr first = NULL; - DisplayModePtr ddcModes = NULL; - int count = 0; - int i, width, height; - ScrnInfoPtr pScrn = pScrn1; - - if (crtc2) - pScrn = info->CRT2pScrn; - - pScrn->virtualX = pScrn1->display->virtualX; - pScrn->virtualY = pScrn1->display->virtualY; - - if (pScrn->monitor->DDC) { - int maxVirtX = pScrn->virtualX; - int maxVirtY = pScrn->virtualY; - - /* Collect all of the DDC modes */ - first = last = ddcModes = RADEONDDCModes(pScrn, pScrn->monitor->DDC); - - for (p = ddcModes; p; p = p->next) { - - /* If primary head is a flat panel, use RMX by default */ - if ((!info->IsSecondary && DisplayType != MT_CRT) && - (!info->ddc_mode) && (!crtc2)) { - /* These values are effective values after expansion. - * They are not really used to set CRTC registers. - */ - p->HTotal = info->PanelXRes + info->HBlank; - p->HSyncStart = info->PanelXRes + info->HOverPlus; - p->HSyncEnd = p->HSyncStart + info->HSyncWidth; - p->VTotal = info->PanelYRes + info->VBlank; - p->VSyncStart = info->PanelYRes + info->VOverPlus; - p->VSyncEnd = p->VSyncStart + info->VSyncWidth; - p->Clock = info->DotClock; - - p->Flags |= RADEON_USE_RMX; - } - - maxVirtX = MAX(maxVirtX, p->HDisplay); - maxVirtY = MAX(maxVirtY, p->VDisplay); - count++; - - last = p; - } - - /* Match up modes that are specified in the XF86Config file */ - if (ppModeName[0]) { - DisplayModePtr next; - - /* Reset the max virtual dimensions */ - maxVirtX = pScrn->virtualX; - maxVirtY = pScrn->virtualY; - - /* Reset list */ - first = last = NULL; - - for (i = 0; ppModeName[i]; i++) { - /* FIXME: Use HDisplay and VDisplay instead of mode string */ - if (sscanf(ppModeName[i], "%dx%d", &width, &height) == 2) { - for (p = ddcModes; p; p = next) { - next = p->next; - - if (p->HDisplay == width && p->VDisplay == height) { - /* We found a DDC mode that matches the one - requested in the XF86Config file */ - p->type |= M_T_USERDEF; - - /* Update the max virtual setttings */ - maxVirtX = MAX(maxVirtX, width); - maxVirtY = MAX(maxVirtY, height); - - /* Unhook from DDC modes */ - if (p->prev) p->prev->next = p->next; - if (p->next) p->next->prev = p->prev; - if (p == ddcModes) ddcModes = p->next; - - /* Add to used modes */ - if (last) { - last->next = p; - p->prev = last; - } else { - first = p; - p->prev = NULL; - } - p->next = NULL; - last = p; - - break; - } - } - } - } - - /* - * Add remaining DDC modes if they're smaller than the user - * specified modes - */ - for (p = ddcModes; p; p = next) { - next = p->next; - if (p->HDisplay <= maxVirtX && p->VDisplay <= maxVirtY) { - /* Unhook from DDC modes */ - if (p->prev) p->prev->next = p->next; - if (p->next) p->next->prev = p->prev; - if (p == ddcModes) ddcModes = p->next; - - /* Add to used modes */ - if (last) { - last->next = p; - p->prev = last; - } else { - first = p; - p->prev = NULL; - } - p->next = NULL; - last = p; - } - } - - /* Delete unused modes */ - while (ddcModes) - xf86DeleteMode(&ddcModes, ddcModes); - } else { - /* - * No modes were configured, so we make the DDC modes - * available for the user to cycle through. - */ - for (p = ddcModes; p; p = p->next) - p->type |= M_T_USERDEF; - } - - if (crtc2) { - pScrn->virtualX = maxVirtX; - pScrn->virtualY = maxVirtY; - } else { - pScrn->virtualX = pScrn->display->virtualX = maxVirtX; - pScrn->virtualY = pScrn->display->virtualY = maxVirtY; - } - } - - /* Close the doubly-linked mode list, if we found any usable modes */ - if (last) { - last->next = first; - first->prev = last; - pScrn->modes = first; - RADEONSetPitch(pScrn); - } - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Total number of valid DDC mode(s) found: %d\n", count); - - return count; -} /* This is used only when no mode is specified for FP and no ddc is * available. We force it to native mode, if possible. @@ -486,7 +126,7 @@ static DisplayModePtr RADEONFPNativeMode(ScrnInfoPtr pScrn) /* FP mode initialization routine for using on-chip RMX to scale */ -int RADEONValidateFPModes(ScrnInfoPtr pScrn, char **ppModeName) +int RADEONValidateFPModes(ScrnInfoPtr pScrn, char **ppModeName, DisplayModePtr *modeList) { RADEONInfoPtr info = RADEONPTR(pScrn); DisplayModePtr last = NULL; @@ -569,7 +209,7 @@ int RADEONValidateFPModes(ScrnInfoPtr pScrn, char **ppModeName) } /* add in all default vesa modes smaller than panel size, used for randr*/ - for (p = pScrn->monitor->Modes; p && p->next; p = p->next->next) { + for (p = *modeList; p && p->next; p = p->next->next) { if ((p->HDisplay <= info->PanelXRes) && (p->VDisplay <= info->PanelYRes)) { tmp = first; while (tmp) { @@ -609,10 +249,10 @@ int RADEONValidateFPModes(ScrnInfoPtr pScrn, char **ppModeName) /* Close the doubly-linked mode list, if we found any usable modes */ if (last) { - last->next = first; - first->prev = last; - pScrn->modes = first; - RADEONSetPitch(pScrn); + last->next = NULL; //first; + first->prev = NULL; //last; + *modeList = first; + //RADEONSetPitch(pScrn); } xf86DrvMsg(pScrn->scrnIndex, X_INFO, @@ -621,164 +261,65 @@ int RADEONValidateFPModes(ScrnInfoPtr pScrn, char **ppModeName) return count; } - -int RADEONValidateMergeModes(ScrnInfoPtr pScrn1) +DisplayModePtr +RADEONProbeOutputModes(xf86OutputPtr output) { - RADEONInfoPtr info = RADEONPTR(pScrn1); - ClockRangePtr clockRanges; - int modesFound; - ScrnInfoPtr pScrn = info->CRT2pScrn; - - /* fill in pScrn2 */ - pScrn->videoRam = pScrn1->videoRam; - pScrn->depth = pScrn1->depth; - pScrn->numClocks = pScrn1->numClocks; - pScrn->progClock = pScrn1->progClock; - pScrn->fbFormat = pScrn1->fbFormat; - pScrn->videoRam = pScrn1->videoRam; - pScrn->maxHValue = pScrn1->maxHValue; - pScrn->maxVValue = pScrn1->maxVValue; - pScrn->xInc = pScrn1->xInc; - - if (info->NoVirtual) { - pScrn1->display->virtualX = 0; - pScrn1->display->virtualY = 0; - } - - if (pScrn->monitor->DDC) { - /* If we still don't know sync range yet, let's try EDID. - * - * Note that, since we can have dual heads, Xconfigurator - * may not be able to probe both monitors correctly through - * vbe probe function (RADEONProbeDDC). Here we provide an - * additional way to auto-detect sync ranges if they haven't - * been added to XF86Config manually. - */ - if (pScrn->monitor->nHsync <= 0) - RADEONSetSyncRangeFromEdid(pScrn, 1); - if (pScrn->monitor->nVrefresh <= 0) - RADEONSetSyncRangeFromEdid(pScrn, 0); + ScrnInfoPtr pScrn = output->scrn; + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR (pScrn); + RADEONInfoPtr info = RADEONPTR(pScrn); + RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); + RADEONOutputPrivatePtr radeon_output = output->driver_private; + DisplayModePtr mode; + DisplayModePtr test; + xf86MonPtr edid_mon; + DisplayModePtr modes = NULL; + + /* force reprobe */ + radeon_output->MonType = MT_UNKNOWN; + + RADEONConnectorFindMonitor(pScrn, output); + + if (radeon_output->type == OUTPUT_DVI || radeon_output->type == OUTPUT_VGA) { + edid_mon = xf86OutputGetEDID (output, radeon_output->pI2CBus); + xf86OutputSetEDID (output, edid_mon); + + modes = xf86OutputGetEDIDModes (output); + return modes; } - - /* Get mode information */ - pScrn->progClock = TRUE; - clockRanges = xnfcalloc(sizeof(*clockRanges), 1); - clockRanges->next = NULL; - clockRanges->minClock = info->pll.min_pll_freq; - clockRanges->maxClock = info->pll.max_pll_freq * 10; - clockRanges->clockIndex = -1; - clockRanges->interlaceAllowed = (info->MergeType == MT_CRT); - clockRanges->doubleScanAllowed = (info->MergeType == MT_CRT); - - /* We'll use our own mode validation routine for DFP/LCD, since - * xf86ValidateModes does not work correctly with the DFP/LCD modes - * 'stretched' from their native mode. - */ - if (info->MergeType == MT_CRT && !info->ddc_mode) { - - modesFound = - xf86ValidateModes(pScrn, - pScrn->monitor->Modes, - pScrn1->display->modes, - clockRanges, - NULL, /* linePitches */ - 8 * 64, /* minPitch */ - 8 * 1024, /* maxPitch */ - info->allowColorTiling ? 2048 : - 64 * pScrn1->bitsPerPixel, /* pitchInc */ - 128, /* minHeight */ - info->MaxLines, /* maxHeight */ - pScrn1->display->virtualX ? pScrn1->virtualX : 0, - pScrn1->display->virtualY ? pScrn1->virtualY : 0, - info->FbMapSize, - LOOKUP_BEST_REFRESH); - - if (modesFound == -1) return 0; - - xf86PruneDriverModes(pScrn); - if (!modesFound || !pScrn->modes) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n"); - return 0; - } - - } else { - /* First, free any allocated modes during configuration, since - * we don't need them - */ - while (pScrn->modes) - xf86DeleteMode(&pScrn->modes, pScrn->modes); - while (pScrn->modePool) - xf86DeleteMode(&pScrn->modePool, pScrn->modePool); - - /* Next try to add DDC modes */ - modesFound = RADEONValidateDDCModes(pScrn, pScrn1->display->modes, - info->MergeType, 1); - - /* If that fails and we're connect to a flat panel, then try to - * add the flat panel modes - */ - if (info->MergeType != MT_CRT) { - - /* some panels have DDC, but don't have internal scaler. - * in this case, we need to validate additional modes - * by using on-chip RMX. - */ - int user_modes_asked = 0, user_modes_found = 0, i; - DisplayModePtr tmp_mode = pScrn->modes; - while (pScrn1->display->modes[user_modes_asked]) user_modes_asked++; - if (tmp_mode) { - for (i = 0; i < modesFound; i++) { - if (tmp_mode->type & M_T_USERDEF) user_modes_found++; - tmp_mode = tmp_mode->next; - } - } - - if ((modesFound <= 1) || (user_modes_found < user_modes_asked)) { - /* when panel size is not valid, try to validate - * mode using xf86ValidateModes routine - * This can happen when DDC is disabled. - */ - /* if (info->PanelXRes < 320 || info->PanelYRes < 200) */ - modesFound = - xf86ValidateModes(pScrn, - pScrn->monitor->Modes, - pScrn1->display->modes, - clockRanges, - NULL, /* linePitches */ - 8 * 64, /* minPitch */ - 8 * 1024, /* maxPitch */ - info->allowColorTiling ? 2048 : - 64 * pScrn1->bitsPerPixel, /* pitchInc */ - 128, /* minHeight */ - info->MaxLines, /* maxHeight */ - pScrn1->display->virtualX, - pScrn1->display->virtualY, - info->FbMapSize, - LOOKUP_BEST_REFRESH); - - } - } - - /* Setup the screen's clockRanges for the VidMode extension */ - if (!pScrn->clockRanges) { - pScrn->clockRanges = xnfcalloc(sizeof(*(pScrn->clockRanges)), 1); - memcpy(pScrn->clockRanges, clockRanges, sizeof(*clockRanges)); - pScrn->clockRanges->strategy = LOOKUP_BEST_REFRESH; - } - - /* Fail if we still don't have any valid modes */ - if (modesFound < 1) { - if (info->MergeType == MT_CRT) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "No valid DDC modes found for this CRT\n"); - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Try turning off the \"DDCMode\" option\n"); - } else { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "No valid mode found for this DFP/LCD\n"); - } - return 0; + if (radeon_output->type == OUTPUT_LVDS) { + /* okay we got DDC info */ + if (output->MonInfo) { + /* Debug info for now, at least */ + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID for output %d\n", radeon_output->num); + xf86PrintEDID(output->MonInfo); + + modes = xf86DDCGetModes(pScrn->scrnIndex, output->MonInfo); + + for (mode = modes; mode != NULL; mode = mode->next) { + if (mode->Flags & V_DBLSCAN) { + if ((mode->CrtcHDisplay >= 1024) || (mode->CrtcVDisplay >= 768)) + mode->status = MODE_CLOCK_RANGE; + } } + xf86PruneInvalidModes(pScrn, &modes, TRUE); + + /* do some physcial size stuff */ + } + + + if (modes == NULL) { + MonRec fixed_mon; + + RADEONValidateFPModes(pScrn, pScrn->display->modes, &modes); + } + } + + if (modes) { + xf86ValidateModesUserConfig(pScrn, modes); + xf86PruneInvalidModes(pScrn, &modes, + FALSE); } - return modesFound; + return modes; } + + diff --git a/src/radeon_probe.h b/src/radeon_probe.h index b651e7d..c783460 100644 --- a/src/radeon_probe.h +++ b/src/radeon_probe.h @@ -38,10 +38,13 @@ #include "xf86str.h" #include "xf86DDC.h" +#include "randrstr.h" #define _XF86MISC_SERVER_ #include <X11/extensions/xf86misc.h> +#include "xf86Crtc.h" + typedef enum { DDC_NONE_DETECTED, @@ -102,28 +105,36 @@ typedef enum TMDS_EXT = 1 } RADEONTmdsType; -typedef struct -{ - Bool IsUsed; - Bool IsActive; - int binding; // which instance of the driver "owns" this controller - DisplayModePtr pCurMode; -} RADEONController; - -typedef struct +typedef enum { + OUTPUT_NONE, + OUTPUT_VGA, + OUTPUT_DVI, + OUTPUT_LVDS, + OUTPUT_STV, + OUTPUT_CTV, +} RADEONOutputType; + +typedef struct _RADEONCrtcPrivateRec { + int crtc_id; + int binding; + /* Lookup table values to be set when the CRTC is enabled */ + CARD8 lut_r[256], lut_g[256], lut_b[256]; +} RADEONCrtcPrivateRec, *RADEONCrtcPrivatePtr; + +typedef struct _RADEONOutputPrivateRec { + int num; + RADEONOutputType type; + void *dev_priv; RADEONDDCType DDCType; RADEONDacType DACType; RADEONTmdsType TMDSType; RADEONConnectorType ConnectorType; RADEONMonitorType MonType; - xf86MonPtr MonInfo; - - /* one connector can be bound to one CRTC */ int crtc_num; -} RADEONConnector; - - + int DDCReg; + I2CBusPtr pI2CBus; +} RADEONOutputPrivateRec, *RADEONOutputPrivatePtr; #define RADEON_MAX_CONNECTOR 2 #define RADEON_MAX_CRTC 2 @@ -144,8 +155,12 @@ typedef struct Bool ReversedDAC; /* TVDAC used as primary dac */ Bool ReversedTMDS; /* DDC_DVI is used for external TMDS */ - RADEONConnector *PortInfo[RADEON_MAX_CONNECTOR]; - RADEONController *Controller[RADEON_MAX_CRTC]; /* pointer to a controller */ + xf86OutputPtr pOutput[RADEON_MAX_CONNECTOR]; + RADEONOutputPrivatePtr PortInfo[RADEON_MAX_CONNECTOR]; + + xf86CrtcPtr pCrtc[RADEON_MAX_CRTC]; + RADEONCrtcPrivatePtr Controller[RADEON_MAX_CRTC]; + } RADEONEntRec, *RADEONEntPtr; /* radeon_probe.c */ diff --git a/src/radeon_video.c b/src/radeon_video.c index 390df89..d080982 100644 --- a/src/radeon_video.c +++ b/src/radeon_video.c @@ -12,7 +12,6 @@ #include "radeon_reg.h" #include "radeon_macros.h" #include "radeon_probe.h" -#include "radeon_mergedfb.h" #include "radeon_video.h" #include "xf86.h" @@ -1334,7 +1333,7 @@ RADEONAllocAdaptor(ScrnInfoPtr pScrn) */ /* Figure out which head we are on */ - if ((info->MergedFB && info->OverlayOnCRTC2) || info->IsSecondary) + if ((info->OverlayOnCRTC2) || info->IsSecondary) dot_clock = info->ModeReg.dot_clock_freq_2; else dot_clock = info->ModeReg.dot_clock_freq; @@ -2455,7 +2454,7 @@ RADEONDisplayVideo( workarounds for chip erratas */ /* Figure out which head we are on for dot clock */ - if ((info->MergedFB && info->OverlayOnCRTC2) || info->IsSecondary) + if (info->OverlayOnCRTC2 || info->IsSecondary) dot_clock = info->ModeReg.dot_clock_freq_2; else dot_clock = info->ModeReg.dot_clock_freq; @@ -2480,11 +2479,8 @@ RADEONDisplayVideo( v_inc_shift = 20; y_mult = 1; - if (info->MergedFB) { - if (info->OverlayOnCRTC2) - overlay_mode = ((RADEONMergedDisplayModePtr)info->CurrentLayout.mode->Private)->CRT2; - else - overlay_mode = ((RADEONMergedDisplayModePtr)info->CurrentLayout.mode->Private)->CRT1; + /* TODO NO IDEA WHAT THIS IS ABOUT */ + if (0) {//info->MergedFB) { if (overlay_mode->Flags & V_INTERLACE) v_inc_shift++; if (overlay_mode->Flags & V_DBLSCAN) { @@ -2651,19 +2647,6 @@ RADEONDisplayVideo( x_off = 0; /* needed to make the overlay work on crtc1 in leftof and above modes */ - if (info->MergedFB) { - RADEONScrn2Rel srel = - ((RADEONMergedDisplayModePtr)info->CurrentLayout.mode->Private)->CRT2Position; - overlay_mode = ((RADEONMergedDisplayModePtr)info->CurrentLayout.mode->Private)->CRT2; - if (srel == radeonLeftOf) { - x_off -= overlay_mode->CrtcHDisplay; - /* y_off -= pScrn->frameY0; */ - } - if (srel == radeonAbove) { - y_off -= overlay_mode->CrtcVDisplay; - /* x_off -= pScrn->frameX0; */ - } - } /* Put the hardware overlay on CRTC2: * @@ -2672,7 +2655,7 @@ RADEONDisplayVideo( * rendering for the second head. */ - if ((info->MergedFB && info->OverlayOnCRTC2) || info->IsSecondary) { + if (info->OverlayOnCRTC2 || info->IsSecondary) { x_off = 0; OUTREG(RADEON_OV1_Y_X_START, ((dstBox->x1 + x_off) | ((dstBox->y1*y_mult) << 16))); @@ -2780,6 +2763,7 @@ RADEONPutImage( DrawablePtr pDraw ){ RADEONInfoPtr info = RADEONPTR(pScrn); + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data; INT32 xa, xb, ya, yb; unsigned char *dst_start; @@ -2789,6 +2773,7 @@ RADEONPutImage( int top, left, npixels, nlines, bpp; BoxRec dstBox; CARD32 tmp; + xf86CrtcPtr crtc; /* * s2offset, s3offset - byte offsets into U and V plane of the @@ -2821,24 +2806,21 @@ RADEONPutImage( dstBox.y1 = drw_y; dstBox.y2 = drw_y + drw_h; - if (info->MergedFB) - RADEONChooseOverlayCRTC(pScrn, &dstBox); + RADEONChooseOverlayCRTC(pScrn, &dstBox); if(!xf86XVClipVideoHelper(&dstBox, &xa, &xb, &ya, &yb, clipBoxes, width, height)) return Success; - if (info->MergedFB && info->OverlayOnCRTC2) { - dstBox.x1 -= info->CRT2pScrn->frameX0; - dstBox.x2 -= info->CRT2pScrn->frameX0; - dstBox.y1 -= info->CRT2pScrn->frameY0; - dstBox.y2 -= info->CRT2pScrn->frameY0; - } else { - dstBox.x1 -= pScrn->frameX0; - dstBox.x2 -= pScrn->frameX0; - dstBox.y1 -= pScrn->frameY0; - dstBox.y2 -= pScrn->frameY0; - } + if (info->OverlayOnCRTC2) + crtc = xf86_config->crtc[1]; + else + crtc = xf86_config->crtc[0]; + + dstBox.x1 -= crtc->x; + dstBox.x2 -= crtc->x; + dstBox.y1 -= crtc->y; + dstBox.y2 -= crtc->y; bpp = pScrn->bitsPerPixel >> 3; @@ -3180,12 +3162,13 @@ RADEONDisplaySurface( ){ OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr; ScrnInfoPtr pScrn = surface->pScrn; - + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); RADEONInfoPtr info = RADEONPTR(pScrn); RADEONPortPrivPtr portPriv = info->adaptor->pPortPrivates[0].ptr; INT32 xa, ya, xb, yb; BoxRec dstBox; + xf86CrtcPtr crtc; if (src_w > (drw_w << 4)) drw_w = src_w >> 4; @@ -3202,24 +3185,21 @@ RADEONDisplaySurface( dstBox.y1 = drw_y; dstBox.y2 = drw_y + drw_h; - if (info->MergedFB) - RADEONChooseOverlayCRTC(pScrn, &dstBox); + RADEONChooseOverlayCRTC(pScrn, &dstBox); if (!xf86XVClipVideoHelper(&dstBox, &xa, &xb, &ya, &yb, clipBoxes, surface->width, surface->height)) return Success; - if (info->MergedFB && info->OverlayOnCRTC2) { - dstBox.x1 -= info->CRT2pScrn->frameX0; - dstBox.x2 -= info->CRT2pScrn->frameX0; - dstBox.y1 -= info->CRT2pScrn->frameY0; - dstBox.y2 -= info->CRT2pScrn->frameY0; - } else { - dstBox.x1 -= pScrn->frameX0; - dstBox.x2 -= pScrn->frameX0; - dstBox.y1 -= pScrn->frameY0; - dstBox.y2 -= pScrn->frameY0; - } + if (info->OverlayOnCRTC2) + crtc = xf86_config->crtc[1]; + else + crtc = xf86_config->crtc[0]; + + dstBox.x1 -= crtc->x; + dstBox.x2 -= crtc->x; + dstBox.y1 -= crtc->y; + dstBox.y2 -= crtc->y; #if 0 /* this isn't needed */ @@ -3291,6 +3271,7 @@ RADEONPutVideo( ){ RADEONInfoPtr info = RADEONPTR(pScrn); RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; INT32 xa, xb, ya, yb, top; unsigned int pitch, new_size, alloc_size; @@ -3303,6 +3284,7 @@ RADEONPutVideo( int width, height; int mult; int vbi_line_width, vbi_start, vbi_end; + xf86CrtcPtr crtc; RADEON_SYNC(info, pScrn); /* @@ -3344,23 +3326,20 @@ RADEONPutVideo( else vbi_line_width = 2000; /* might need adjustment */ - if (info->MergedFB) - RADEONChooseOverlayCRTC(pScrn, &dstBox); + RADEONChooseOverlayCRTC(pScrn, &dstBox); if(!xf86XVClipVideoHelper(&dstBox, &xa, &xb, &ya, &yb, clipBoxes, width, height)) return Success; - if (info->MergedFB && info->OverlayOnCRTC2) { - dstBox.x1 -= info->CRT2pScrn->frameX0; - dstBox.x2 -= info->CRT2pScrn->frameX0; - dstBox.y1 -= info->CRT2pScrn->frameY0; - dstBox.y2 -= info->CRT2pScrn->frameY0; - } else { - dstBox.x1 -= pScrn->frameX0; - dstBox.x2 -= pScrn->frameX0; - dstBox.y1 -= pScrn->frameY0; - dstBox.y2 -= pScrn->frameY0; - } + if (info->OverlayOnCRTC2) + crtc = xf86_config->crtc[1]; + else + crtc = xf86_config->crtc[0]; + + dstBox.x1 -= crtc->x; + dstBox.x2 -= crtc->x; + dstBox.y1 -= crtc->y; + dstBox.y2 -= crtc->y; bpp = pScrn->bitsPerPixel >> 3; pitch = bpp * pScrn->displayWidth; |