summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/atichip.c56
-rw-r--r--src/atichip.h18
-rw-r--r--src/radeon.h66
-rw-r--r--src/radeon_accel.c14
-rw-r--r--src/radeon_accelfuncs.c2
-rw-r--r--src/radeon_bios.c514
-rw-r--r--src/radeon_driver.c1453
-rw-r--r--src/radeon_macros.h10
-rw-r--r--src/radeon_probe.c59
-rw-r--r--src/radeon_probe.h71
-rw-r--r--src/radeon_reg.h17
-rw-r--r--src/radeon_video.c4
12 files changed, 1507 insertions, 777 deletions
diff --git a/src/atichip.c b/src/atichip.c
index 3c2b094..3c369bf 100644
--- a/src/atichip.c
+++ b/src/atichip.c
@@ -1,6 +1,6 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atichip.c,v 1.37 2003/10/07 22:47:11 martin Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atichip.c,v 1.38tsi Exp $ */
/*
- * Copyright 1997 through 2003 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org
+ * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
@@ -95,13 +95,19 @@ const char *ATIChipNames[] =
"ATI Radeon 8500/9100",
"ATI Radeon 9000",
"ATI Radeon Mobility M9",
- "ATI Radeon 9000 IGP",
+ "ATI Radeon 9100 IGP",
+ "ATI Radeon 9200 IGP",
"ATI Radeon 9200",
"ATI Radeon Mobility M9+",
"ATI Radeon 9700/9500",
"ATI Radeon 9600",
"ATI Radeon 9800",
"ATI Radeon 9800XT",
+ "ATI Radeon X300/M22",
+ "ATI Radeon X600/M24",
+ "ATI Radeon X800/M18",
+ "ATI Radeon X800 PCIE",
+ "ATI unknown Radeon",
"ATI Rage HDTV"
};
@@ -687,6 +693,10 @@ ATIChipID
case NewChipID('X', '5'):
return ATI_CHIP_RS300;
+ case NewChipID('x', '4'):
+ case NewChipID('x', '5'):
+ return ATI_CHIP_RS350;
+
case NewChipID('Y', '\''):
case NewChipID('Y', 'a'):
case NewChipID('Y', 'b'):
@@ -733,14 +743,48 @@ ATIChipID
case NewChipID('N', 'J'):
return ATI_CHIP_R360;
+ case NewChipID('[', '\''):
+ case NewChipID('[', 'b'):
+ case NewChipID('[', 'd'):
+ case NewChipID('[', 'e'):
+ case NewChipID('T', '\''):
+ case NewChipID('T', 'd'):
+ return ATI_CHIP_RV370;
+
+ case NewChipID('>', 'P'):
+ case NewChipID('>', 'T'):
+ case NewChipID('1', 'P'):
+ case NewChipID('1', 'T'):
+ return ATI_CHIP_RV380;
+
+ case NewChipID('J', 'H'):
+ case NewChipID('J', 'I'):
+ case NewChipID('J', 'J'):
+ case NewChipID('J', 'K'):
+ case NewChipID('J', 'L'):
+ case NewChipID('J', 'M'):
+ case NewChipID('J', 'N'):
+ case NewChipID('J', 'P'):
+ return ATI_CHIP_R420;
+
+ case NewChipID('U', 'H'):
+ case NewChipID('U', 'I'):
+ case NewChipID('U', 'J'):
+ case NewChipID('U', 'K'):
+ case NewChipID('U', 'Q'):
+ case NewChipID('U', 'R'):
+ case NewChipID('U', 'T'):
+ case NewChipID(']', 'W'):
+ return ATI_CHIP_R423;
+
case NewChipID('H', 'D'):
return ATI_CHIP_HDTV;
default:
/*
- * I'd say it's a Rage128 or a Radeon here, except that I don't
- * support them.
+ * Treat anything else as an unknown Radeon. Please keep the above
+ * up-to-date however, as it serves as a central chip list.
*/
- return ATI_CHIP_Mach64;
+ return ATI_CHIP_Radeon;
}
}
diff --git a/src/atichip.h b/src/atichip.h
index 4cc30a0..40841e1 100644
--- a/src/atichip.h
+++ b/src/atichip.h
@@ -1,6 +1,6 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atichip.h,v 1.25 2003/10/07 22:47:11 martin Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atichip.h,v 1.26tsi Exp $ */
/*
- * Copyright 1997 through 2003 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org
+ * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
@@ -77,7 +77,7 @@ typedef enum
ATI_CHIP_264LTPRO, /* Mach64 */
ATI_CHIP_264XL, /* Mach64 */
ATI_CHIP_MOBILITY, /* Mach64 */
- ATI_CHIP_Mach64, /* Mach64 */
+ ATI_CHIP_Mach64, /* Last among Mach64's */
ATI_CHIP_RAGE128GL, /* Rage128 */
ATI_CHIP_RAGE128VR, /* Rage128 */
ATI_CHIP_RAGE128PROGL, /* Rage128 */
@@ -85,7 +85,7 @@ typedef enum
ATI_CHIP_RAGE128PROULTRA, /* Rage128 */
ATI_CHIP_RAGE128MOBILITY3, /* Rage128 */
ATI_CHIP_RAGE128MOBILITY4, /* Rage128 */
- ATI_CHIP_Rage128, /* Rage128 */
+ ATI_CHIP_Rage128, /* Last among Rage128's */
ATI_CHIP_RADEON, /* Radeon */
ATI_CHIP_RADEONVE, /* Radeon VE */
ATI_CHIP_RADEONMOBILITY6, /* Radeon M6 */
@@ -97,13 +97,19 @@ typedef enum
ATI_CHIP_R200, /* R200 */
ATI_CHIP_RV250, /* RV250 */
ATI_CHIP_RADEONMOBILITY9, /* Radeon M9 */
- ATI_CHIP_RS300, /* Radoen 9000 IGP */
+ ATI_CHIP_RS300, /* Radoen 9100 IGP */
+ ATI_CHIP_RS350, /* Radoen 9200 IGP */
ATI_CHIP_RV280, /* RV250 */
ATI_CHIP_RADEONMOBILITY9PLUS, /* Radeon M9+ */
ATI_CHIP_R300, /* R300 */
- ATI_CHIP_RV350, /* RV350 */
+ ATI_CHIP_RV350, /* RV350/M10/M11 */
ATI_CHIP_R350, /* R350 */
ATI_CHIP_R360, /* R360 */
+ ATI_CHIP_RV370, /* RV370/M22 */
+ ATI_CHIP_RV380, /* RV380/M24 */
+ ATI_CHIP_R420, /* R420/M18 */
+ ATI_CHIP_R423, /* R423 */
+ ATI_CHIP_Radeon, /* Last among Radeon's */
ATI_CHIP_HDTV /* HDTV */
} ATIChipType;
diff --git a/src/radeon.h b/src/radeon.h
index 6c2c628..1918d89 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -45,6 +45,7 @@
/* XAA and Cursor Support */
#include "xaa.h"
+#include "vbe.h"
#include "xf86Cursor.h"
/* DDC support */
@@ -53,6 +54,7 @@
/* Xv support */
#include "xf86xv.h"
+#include "radeon_probe.h"
/* DRI support */
#ifdef XF86DRI
#define _XF86DRI_SERVER_
@@ -133,6 +135,7 @@ typedef struct {
CARD32 bios_4_scratch;
CARD32 bios_5_scratch;
CARD32 bios_6_scratch;
+
/* Other registers to save for VT switches */
CARD32 dp_datatype;
CARD32 rbbm_soft_reset;
@@ -213,6 +216,9 @@ typedef struct {
Bool palette_valid;
CARD32 palette[256];
CARD32 palette2[256];
+
+ CARD32 tv_dac_cntl;
+
} RADEONSaveRec, *RADEONSavePtr;
typedef struct {
@@ -233,31 +239,6 @@ typedef struct {
} RADEONFBLayout;
typedef enum {
- MT_NONE,
- MT_CRT,
- MT_LCD,
- MT_DFP,
- MT_CTV,
- MT_STV
-} RADEONMonitorType;
-
-typedef enum {
- DDC_NONE_DETECTED,
- DDC_MONID,
- DDC_DVI,
- DDC_VGA,
- DDC_CRT2
-} RADEONDDCType;
-
-typedef enum {
- CONNECTOR_NONE,
- CONNECTOR_PROPRIETARY,
- CONNECTOR_CRT,
- CONNECTOR_DVI_I,
- CONNECTOR_DVI_D
-} RADEONConnectorType;
-
-typedef enum {
CHIP_FAMILY_UNKNOW,
CHIP_FAMILY_LEGACY,
CHIP_FAMILY_RADEON,
@@ -267,14 +248,32 @@ typedef enum {
CHIP_FAMILY_RS200, /* U2 (IGP330M/340M/350M) or A4 (IGP330/340/345/350), RS250 (IGP 7000) */
CHIP_FAMILY_R200,
CHIP_FAMILY_RV250,
- CHIP_FAMILY_RS300, /* Radeon 9000 IGP */
+ CHIP_FAMILY_RS300, /* RS300/RS350 */
CHIP_FAMILY_RV280,
CHIP_FAMILY_R300,
CHIP_FAMILY_R350,
CHIP_FAMILY_RV350,
+ CHIP_FAMILY_RV380, /* RV370/RV380/M22/M24 */
+ CHIP_FAMILY_R420, /* R420/R423/M18 */
CHIP_FAMILY_LAST
} RADEONChipFamily;
+#define IS_RV100_VARIANT ((info->ChipFamily == CHIP_FAMILY_RV100) || \
+ (info->ChipFamily == CHIP_FAMILY_RV200) || \
+ (info->ChipFamily == CHIP_FAMILY_RS100) || \
+ (info->ChipFamily == CHIP_FAMILY_RS200) || \
+ (info->ChipFamily == CHIP_FAMILY_RV250) || \
+ (info->ChipFamily == CHIP_FAMILY_RV280) || \
+ (info->ChipFamily == CHIP_FAMILY_RS300))
+
+
+#define IS_R300_VARIANT ((info->ChipFamily == CHIP_FAMILY_R300) || \
+ (info->ChipFamily == CHIP_FAMILY_RV350) || \
+ (info->ChipFamily == CHIP_FAMILY_R350) || \
+ (info->ChipFamily == CHIP_FAMILY_RV380) || \
+ (info->ChipFamily == CHIP_FAMILY_R420))
+
+
typedef struct {
CARD32 freq;
CARD32 value;
@@ -298,6 +297,10 @@ typedef struct {
unsigned char *FB; /* Map of frame buffer */
CARD8 *VBIOS; /* Video BIOS pointer */
+ Bool IsAtomBios; /* New BIOS used in R420 etc. */
+ int ROMHeaderStart; /* Start of the ROM Info Table */
+ int MasterDataStart; /* Offset for Master Data Table for ATOM BIOS */
+
CARD32 MemCntl;
CARD32 BusCntl;
unsigned long FbMapSize; /* Size of frame buffer, in bytes */
@@ -310,11 +313,11 @@ typedef struct {
Bool HasCRTC2; /* All cards except original Radeon */
Bool IsMobility; /* Mobile chips for laptops */
Bool IsIGP; /* IGP chips */
+ Bool HasSingleDAC; /* only TVDAC on chip */
Bool IsSecondary; /* Second Screen */
Bool IsSwitching; /* Flag for switching mode */
Bool OverlayOnCRTC2;
Bool PanelOff; /* Force panel (LCD/DFP) off */
- int FPBIOSstart; /* Start of the flat panel info */
Bool ddc_mode; /* Validate mode by matching exactly
* the modes supported in DDC data
*/
@@ -589,6 +592,8 @@ typedef struct {
int MergedFBXDPI, MergedFBYDPI;
Bool NoVirtual;
+ /* special handlings for DELL triple-head server */
+ Bool IsDellServer;
} RADEONInfoRec, *RADEONInfoPtr;
@@ -599,6 +604,7 @@ do { \
info->fifo_slots -= entries; \
} while (0)
+extern RADEONEntPtr RADEONEntPriv(ScrnInfoPtr pScrn);
extern void RADEONWaitForFifoFunction(ScrnInfoPtr pScrn, int entries);
extern void RADEONWaitForIdleMMIO(ScrnInfoPtr pScrn);
#ifdef XF86DRI
@@ -643,6 +649,12 @@ extern void RADEONCPFlushIndirect(ScrnInfoPtr pScrn, int discard);
extern void RADEONCPReleaseIndirect(ScrnInfoPtr pScrn);
extern int RADEONCPStop(ScrnInfoPtr pScrn, RADEONInfoPtr info);
+extern Bool RADEONGetBIOSInfo(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10);
+extern Bool RADEONGetConnectorInfoFromBIOS (ScrnInfoPtr pScrn);
+extern Bool RADEONGetClockInfoFromBIOS (ScrnInfoPtr pScrn);
+extern Bool RADEONGetLVDSInfoFromBIOS (ScrnInfoPtr pScrn);
+extern Bool RADEONGetTMDSInfoFromBIOS (ScrnInfoPtr pScrn);
+extern Bool RADEONGetHardCodedEDIDFromBIOS (ScrnInfoPtr pScrn);
#define RADEONCP_START(pScrn, info) \
do { \
diff --git a/src/radeon_accel.c b/src/radeon_accel.c
index b111530..43f7d46 100644
--- a/src/radeon_accel.c
+++ b/src/radeon_accel.c
@@ -211,9 +211,7 @@ void RADEONEngineReset(ScrnInfoPtr pScrn)
host_path_cntl = INREG(RADEON_HOST_PATH_CNTL);
rbbm_soft_reset = INREG(RADEON_RBBM_SOFT_RESET);
- if ((info->ChipFamily == CHIP_FAMILY_R300) ||
- (info->ChipFamily == CHIP_FAMILY_R350) ||
- (info->ChipFamily == CHIP_FAMILY_RV350)) {
+ if (IS_R300_VARIANT) {
CARD32 tmp;
OUTREG(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset |
@@ -227,7 +225,6 @@ void RADEONEngineReset(ScrnInfoPtr pScrn)
} else {
OUTREG(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset |
RADEON_SOFT_RESET_CP |
- RADEON_SOFT_RESET_HI |
RADEON_SOFT_RESET_SE |
RADEON_SOFT_RESET_RE |
RADEON_SOFT_RESET_PP |
@@ -236,7 +233,6 @@ void RADEONEngineReset(ScrnInfoPtr pScrn)
INREG(RADEON_RBBM_SOFT_RESET);
OUTREG(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset & (CARD32)
~(RADEON_SOFT_RESET_CP |
- RADEON_SOFT_RESET_HI |
RADEON_SOFT_RESET_SE |
RADEON_SOFT_RESET_RE |
RADEON_SOFT_RESET_PP |
@@ -249,9 +245,7 @@ void RADEONEngineReset(ScrnInfoPtr pScrn)
INREG(RADEON_HOST_PATH_CNTL);
OUTREG(RADEON_HOST_PATH_CNTL, host_path_cntl);
- if ((info->ChipFamily != CHIP_FAMILY_R300) &&
- (info->ChipFamily != CHIP_FAMILY_R350) &&
- (info->ChipFamily != CHIP_FAMILY_RV350))
+ if (IS_R300_VARIANT)
OUTREG(RADEON_RBBM_SOFT_RESET, rbbm_soft_reset);
OUTREG(RADEON_CLOCK_CNTL_INDEX, clock_cntl_index);
@@ -279,9 +273,7 @@ void RADEONEngineRestore(ScrnInfoPtr pScrn)
*/
/* Turn of all automatic flushing - we'll do it all */
- if ((info->ChipFamily != CHIP_FAMILY_R300) &&
- (info->ChipFamily != CHIP_FAMILY_R350) &&
- (info->ChipFamily != CHIP_FAMILY_RV350))
+ if (!IS_R300_VARIANT)
OUTREG(RADEON_RB2D_DSTCACHE_MODE, 0);
pitch64 = ((pScrn->displayWidth * (pScrn->bitsPerPixel / 8) + 0x3f)) >> 6;
diff --git a/src/radeon_accelfuncs.c b/src/radeon_accelfuncs.c
index ec9d04f..d9185a0 100644
--- a/src/radeon_accelfuncs.c
+++ b/src/radeon_accelfuncs.c
@@ -1367,7 +1367,7 @@ FUNC_NAME(RADEONAccelInit)(ScreenPtr pScreen, XAAInfoRecPtr a)
a->CPUToScreenTextureFlags = XAA_RENDER_POWER_OF_2_TILE_ONLY;
a->CPUToScreenTextureFormats = RADEONTextureFormats;
- if (info->ChipFamily >= CHIP_FAMILY_R300) {
+ if (IS_R300_VARIANT) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Render acceleration "
"unsupported on Radeon 9500/9700 and newer.\n");
return;
diff --git a/src/radeon_bios.c b/src/radeon_bios.c
new file mode 100644
index 0000000..d54c9b9
--- /dev/null
+++ b/src/radeon_bios.c
@@ -0,0 +1,514 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_bios.c,v 1.0 Exp $ */
+/*
+ * Copyright 2004 ATI Technologies Inc., Markham, Ontario
+ *
+ * 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 ATI, VA LINUX SYSTEMS AND/OR
+ * THEIR SUPPLIERS 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.
+ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+
+#include "radeon.h"
+#include "radeon_macros.h"
+#include "radeon_probe.h"
+#include "radeon_reg.h"
+#include "vbe.h"
+
+/* Read the Video BIOS block and the FP registers (if applicable). */
+Bool RADEONGetBIOSInfo(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ int tmp;
+
+ if (!(info->VBIOS = xalloc(RADEON_VBIOS_SIZE))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Cannot allocate space for hold Video BIOS!\n");
+ return FALSE;
+ } else {
+ if (pInt10) {
+ info->BIOSAddr = pInt10->BIOSseg << 4;
+ (void)memcpy(info->VBIOS, xf86int10Addr(pInt10, info->BIOSAddr),
+ RADEON_VBIOS_SIZE);
+ } else {
+ xf86ReadPciBIOS(0, info->PciTag, 0, info->VBIOS, RADEON_VBIOS_SIZE);
+ if (info->VBIOS[0] != 0x55 || info->VBIOS[1] != 0xaa) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Video BIOS not detected in PCI space!\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Attempting to read Video BIOS from "
+ "legacy ISA space!\n");
+ info->BIOSAddr = 0x000c0000;
+ xf86ReadDomainMemory(info->PciTag, info->BIOSAddr,
+ RADEON_VBIOS_SIZE, info->VBIOS);
+ }
+ }
+ }
+
+ if (info->VBIOS[0] != 0x55 || info->VBIOS[1] != 0xaa) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Unrecognized BIOS signature, BIOS data will not be used\n");
+ xfree (info->VBIOS);
+ info->VBIOS = NULL;
+ return FALSE;
+ }
+
+ if (info->VBIOS) info->ROMHeaderStart = RADEON_BIOS16(0x48);
+
+ if(!info->ROMHeaderStart) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Invalid ROM pointer, BIOS data will not be used\n");
+ xfree (info->VBIOS);
+ info->VBIOS = NULL;
+ return FALSE;
+ }
+
+ tmp = info->ROMHeaderStart + 4;
+ if ((RADEON_BIOS8(tmp) == 'A' &&
+ RADEON_BIOS8(tmp+1) == 'T' &&
+ RADEON_BIOS8(tmp+2) == 'O' &&
+ RADEON_BIOS8(tmp+3) == 'M') ||
+ (RADEON_BIOS8(tmp) == 'M' &&
+ RADEON_BIOS8(tmp+1) == 'O' &&
+ RADEON_BIOS8(tmp+2) == 'T' &&
+ RADEON_BIOS8(tmp+3) == 'A'))
+ info->IsAtomBios = TRUE;
+ else
+ info->IsAtomBios = FALSE;
+
+ if (info->IsAtomBios)
+ info->MasterDataStart = RADEON_BIOS16 (info->ROMHeaderStart + 32);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%s BIOS detected\n",
+ info->IsAtomBios ? "ATOM":"Legacy");
+
+ return TRUE;
+}
+
+Bool RADEONGetConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
+{
+ RADEONInfoPtr info = RADEONPTR (pScrn);
+ RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
+ int i = 0, j, tmp, tmp0=0, tmp1=0;
+
+ if(!info->VBIOS) return FALSE;
+
+ if (info->IsAtomBios) {
+ if((tmp = RADEON_BIOS16 (info->MasterDataStart + 22))) {
+ int crtc = 0, id[2];
+ tmp1 = RADEON_BIOS16 (tmp + 4);
+ for (i=0; i<8; i++) {
+ if(tmp1 & (1<<i)) {
+ CARD16 portinfo = RADEON_BIOS16(tmp+6+i*2);
+ if (crtc < 2) {
+ if ((i==2) || (i==6)) continue; /* ignore TV here */
+
+ if (crtc == 1) {
+ /* sharing same port with id[0] */
+ if (((portinfo>>8) & 0xf) == id[0]) {
+ if (i == 3)
+ pRADEONEnt->PortInfo[0].TMDSType = TMDS_INT;
+ else if (i == 7)
+ pRADEONEnt->PortInfo[0].TMDSType = TMDS_EXT;
+
+ if (pRADEONEnt->PortInfo[0].DACType == DAC_UNKNOWN)
+ pRADEONEnt->PortInfo[0].DACType = (portinfo & 0xf) - 1;
+ continue;
+ }
+ }
+
+ id[crtc] = (portinfo>>8) & 0xf;
+ pRADEONEnt->PortInfo[crtc].DACType = (portinfo & 0xf) - 1;
+ pRADEONEnt->PortInfo[crtc].ConnectorType = (portinfo>>4) & 0xf;
+ if (i == 3)
+ pRADEONEnt->PortInfo[crtc].TMDSType = TMDS_INT;
+ else if (i == 7)
+ pRADEONEnt->PortInfo[crtc].TMDSType = TMDS_EXT;
+
+ if((tmp0 = RADEON_BIOS16 (info->MasterDataStart + 24)) && id[crtc]) {
+ switch (RADEON_BIOS16 (tmp0 + 4 + 27 * id[crtc]) * 4)
+ {
+ case RADEON_GPIO_MONID:
+ pRADEONEnt->PortInfo[crtc].DDCType = DDC_MONID;
+ break;
+ case RADEON_GPIO_DVI_DDC:
+ pRADEONEnt->PortInfo[crtc].DDCType = DDC_DVI;
+ break;
+ case RADEON_GPIO_VGA_DDC:
+ pRADEONEnt->PortInfo[crtc].DDCType = DDC_VGA;
+ break;
+ case RADEON_GPIO_CRT2_DDC:
+ pRADEONEnt->PortInfo[crtc].DDCType = DDC_CRT2;
+ break;
+ default:
+ pRADEONEnt->PortInfo[crtc].DDCType = DDC_NONE;
+ break;
+ }
+
+ } else {
+ pRADEONEnt->PortInfo[crtc].DDCType = DDC_NONE;
+ }
+ crtc++;
+ } else {
+ /* we have already had two CRTCs assigned. the rest may share the same
+ * port with the existing connector, fill in them accordingly.
+ */
+ for (j=0; j<2; j++) {
+ if (((portinfo>>8) & 0xf) == id[j]) {
+ if (i == 3)
+ pRADEONEnt->PortInfo[j].TMDSType = TMDS_INT;
+ else if (i == 7)
+ pRADEONEnt->PortInfo[j].TMDSType = TMDS_EXT;
+
+ if (pRADEONEnt->PortInfo[j].DACType == DAC_UNKNOWN)
+ pRADEONEnt->PortInfo[j].DACType = (portinfo & 0xf) - 1;
+ }
+ }
+ }
+ }
+ }
+
+ for (i=0; i<2; i++) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Port%d: DDCType-%d, DACType-%d, TMDSType-%d, ConnectorType-%d\n",
+ i, pRADEONEnt->PortInfo[i].DDCType, pRADEONEnt->PortInfo[i].DACType,
+ pRADEONEnt->PortInfo[i].TMDSType, pRADEONEnt->PortInfo[i].ConnectorType);
+ }
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "No Device Info Table found!\n");
+ return FALSE;
+ }
+ } else {
+ if ((tmp = RADEON_BIOS16(info->ROMHeaderStart + 0x50))) {
+ for (i = 1; i < 4; i++) {
+
+ if (!RADEON_BIOS8(tmp + i*2) && i > 1) break; /* end of table */
+
+ tmp0 = RADEON_BIOS16(tmp + i*2);
+ if (((tmp0 >> 12) & 0x1f) == 0) continue; /* no connector */
+
+ /* internal DDC_DVI port will get assigned to PortInfo[0], or if there is no DDC_DVI (like in some IGPs). */
+ tmp1 = ((((tmp0 >> 8) & 0xf) == DDC_DVI) || (tmp1 == 1)) ? 0 : 1; /* determine port info index */
+
+ pRADEONEnt->PortInfo[tmp1].DDCType = (tmp0 >> 8) & 0x0f;
+ if (pRADEONEnt->PortInfo[tmp1].DDCType > DDC_CRT2) pRADEONEnt->PortInfo[tmp1].DDCType = DDC_NONE_DETECTED;
+ pRADEONEnt->PortInfo[tmp1].DACType = (tmp0 & 0x01) ? DAC_TVDAC : DAC_PRIMARY;
+ pRADEONEnt->PortInfo[tmp1].ConnectorType = (tmp0 >> 12) & 0x0f;
+ if (pRADEONEnt->PortInfo[tmp1].ConnectorType > CONNECTOR_UNSUPPORTED) pRADEONEnt->PortInfo[tmp1].ConnectorType = CONNECTOR_UNSUPPORTED;
+ pRADEONEnt->PortInfo[tmp1].TMDSType = ((tmp0 >> 4) & 0x01) ? TMDS_EXT : TMDS_INT;
+
+ /* some sanity checks */
+ if (((pRADEONEnt->PortInfo[tmp1].ConnectorType != CONNECTOR_DVI_D) &&
+ (pRADEONEnt->PortInfo[tmp1].ConnectorType != CONNECTOR_DVI_I)) &&
+ pRADEONEnt->PortInfo[tmp1].TMDSType == TMDS_INT)
+ pRADEONEnt->PortInfo[tmp1].TMDSType = TMDS_UNKNOWN;
+
+ xf86DrvMsg(0, X_INFO, "Connector%d: DDCType-%d, DACType-%d, TMDSType-%d, ConnectorType-%d\n",
+ tmp1, pRADEONEnt->PortInfo[tmp1].DDCType, pRADEONEnt->PortInfo[tmp1].DACType,
+ pRADEONEnt->PortInfo[tmp1].TMDSType, pRADEONEnt->PortInfo[tmp1].ConnectorType);
+ }
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "No Connector Info Table found!\n");
+ return FALSE;
+ }
+
+ if (info->IsMobility) {
+ if ((tmp = RADEON_BIOS16(info->ROMHeaderStart + 0x42))) {
+ if ((tmp0 = RADEON_BIOS16(tmp + 0x15))) {
+ if ((tmp1 = RADEON_BIOS8(tmp0+2) & 0x07)) {
+ pRADEONEnt->PortInfo[0].DDCType = tmp1;
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "LCD DDC Info Table found!\n");
+ }
+ }
+ }
+ }
+
+#if 0
+/* External TMDS Table, not used now */
+ if ((tmp0 = RADEON_BIOS16(info->ROMHeaderStart + 0x58))) {
+
+ //pRADEONEnt->PortInfo[1].DDCType = (RADEON_BIOS8(tmp0 + 7) & 0x07);
+ //pRADEONEnt->PortInfo[1].ConnectorType = CONNECTOR_DVI_I;
+ //pRADEONEnt->PortInfo[1].TMDSType = TMDS_EXT;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "External TMDS found.\n");
+
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NO External TMDS Info found\n");
+
+ }
+#endif
+
+ }
+ return TRUE;
+}
+
+/* Read PLL parameters from BIOS block. Default to typical values if there
+ is no BIOS. */
+Bool RADEONGetClockInfoFromBIOS (ScrnInfoPtr pScrn)
+{
+ RADEONInfoPtr info = RADEONPTR (pScrn);
+ RADEONPLLPtr pll = &info->pll;
+ CARD16 pll_info_block;
+
+ if (!info->VBIOS) {
+ return FALSE;
+ } else {
+ if (info->IsAtomBios) {
+ pll_info_block = RADEON_BIOS16 (info->MasterDataStart + 12);
+
+ pll->reference_freq = RADEON_BIOS16 (pll_info_block + 82);
+ pll->reference_div = 0; /* Need to derive from existing setting
+ or use a new algorithm to calculate
+ from min_input and max_input
+ */
+ pll->min_pll_freq = RADEON_BIOS16 (pll_info_block + 78);
+ pll->max_pll_freq = RADEON_BIOS32 (pll_info_block + 32);
+ pll->xclk = RADEON_BIOS16 (pll_info_block + 72);
+
+ info->sclk = RADEON_BIOS32(pll_info_block + 8) / 100.0;
+ info->mclk = RADEON_BIOS32(pll_info_block + 12) / 100.0;
+ if (info->sclk == 0) info->sclk = 200;
+ if (info->mclk == 0) info->mclk = 200;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ref_freq: %d, min_pll: %ld, max_pll: %ld, xclk: %d, sclk: %f, mclk: %f\n",
+ pll->reference_freq, pll->min_pll_freq, pll->max_pll_freq, pll->xclk, info->sclk, info->mclk);
+
+ } else {
+ pll_info_block = RADEON_BIOS16 (info->ROMHeaderStart + 0x30);
+
+ pll->reference_freq = RADEON_BIOS16 (pll_info_block + 0x0e);
+ pll->reference_div = RADEON_BIOS16 (pll_info_block + 0x10);
+ pll->min_pll_freq = RADEON_BIOS32 (pll_info_block + 0x12);
+ pll->max_pll_freq = RADEON_BIOS32 (pll_info_block + 0x16);
+ pll->xclk = RADEON_BIOS16 (pll_info_block + 0x08);
+
+ info->sclk = RADEON_BIOS16(pll_info_block + 8) / 100.0;
+ info->mclk = RADEON_BIOS16(pll_info_block + 10) / 100.0;
+ }
+ }
+
+ return TRUE;
+}
+
+Bool RADEONGetLVDSInfoFromBIOS (ScrnInfoPtr pScrn)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned long tmp, i;
+
+ if (!info->VBIOS) return FALSE;
+
+ if (info->IsAtomBios) {
+ if((tmp = RADEON_BIOS16 (info->MasterDataStart + 16))) {
+
+ info->PanelXRes = RADEON_BIOS16(tmp+6);
+ info->PanelYRes = RADEON_BIOS16(tmp+10);
+ info->DotClock = RADEON_BIOS16(tmp+4)*10;
+ info->HBlank = RADEON_BIOS16(tmp+8);
+ info->HOverPlus = RADEON_BIOS16(tmp+14);
+ info->HSyncWidth = RADEON_BIOS16(tmp+16);
+ info->VBlank = RADEON_BIOS16(tmp+12);
+ info->VOverPlus = RADEON_BIOS16(tmp+18);
+ info->VSyncWidth = RADEON_BIOS16(tmp+20);
+ info->PanelPwrDly = RADEON_BIOS16(tmp+40);
+
+ info->Flags = 0;
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "LVDS Info:\n"
+ "XRes: %d, YRes: %d, DotClock: %d\n"
+ "HBlank: %d, HOverPlus: %d, HSyncWidth: %d\n"
+ "VBlank: %d, VOverPlus: %d, VSyncWidth: %d\n",
+ info->PanelXRes, info->PanelYRes, info->DotClock,
+ info->HBlank,info->HOverPlus, info->HSyncWidth,
+ info->VBlank, info->VOverPlus, info->VSyncWidth);
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "No LVDS Info Table found in BIOS!\n");
+ return FALSE;
+ }
+ } else {
+
+ tmp = RADEON_BIOS16(info->ROMHeaderStart + 0x40);
+
+ if (!tmp) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "No Panel Info Table found in BIOS!\n");
+ return FALSE;
+ } else {
+ char stmp[30];
+ int tmp0;
+
+ for (i = 0; i < 24; i++)
+ stmp[i] = RADEON_BIOS8(tmp+i+1);
+ stmp[24] = 0;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Panel ID string: %s\n", stmp);
+
+ info->PanelXRes = RADEON_BIOS16(tmp+25);
+ info->PanelYRes = RADEON_BIOS16(tmp+27);
+ xf86DrvMsg(0, X_INFO, "Panel Size from BIOS: %dx%d\n",
+ info->PanelXRes, info->PanelYRes);
+
+ info->PanelPwrDly = RADEON_BIOS16(tmp+44);
+ if (info->PanelPwrDly > 2000 || info->PanelPwrDly < 0)
+ info->PanelPwrDly = 2000;
+
+ /* some panels only work well with certain divider combinations.
+ */
+ info->RefDivider = RADEON_BIOS16(tmp+46);
+ info->PostDivider = RADEON_BIOS8(tmp+48);
+ info->FeedbackDivider = RADEON_BIOS16(tmp+49);
+ if ((info->RefDivider != 0) &&
+ (info->FeedbackDivider > 3)) {
+ info->UseBiosDividers = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "BIOS provided dividers will be used.\n");
+ }
+
+ /* We don't use a while loop here just in case we have a corrupted BIOS image.
+ The max number of table entries is 23 at present, but may grow in future.
+ To ensure it works with future revisions we loop it to 32.
+ */
+ for (i = 0; i < 32; i++) {
+ tmp0 = RADEON_BIOS16(tmp+64+i*2);
+ if (tmp0 == 0) break;
+ if ((RADEON_BIOS16(tmp0) == info->PanelXRes) &&
+ (RADEON_BIOS16(tmp0+2) == info->PanelYRes)) {
+ info->HBlank = (RADEON_BIOS16(tmp0+17) -
+ RADEON_BIOS16(tmp0+19)) * 8;
+ info->HOverPlus = (RADEON_BIOS16(tmp0+21) -
+ RADEON_BIOS16(tmp0+19) - 1) * 8;
+ info->HSyncWidth = RADEON_BIOS8(tmp0+23) * 8;
+ info->VBlank = (RADEON_BIOS16(tmp0+24) -
+ RADEON_BIOS16(tmp0+26));
+ info->VOverPlus = ((RADEON_BIOS16(tmp0+28) & 0x7ff) -
+ RADEON_BIOS16(tmp0+26));
+ info->VSyncWidth = ((RADEON_BIOS16(tmp0+28) & 0xf800) >> 11);
+ info->DotClock = RADEON_BIOS16(tmp0+9) * 10;
+ info->Flags = 0;
+ }
+ }
+ }
+ }
+ return TRUE;
+}
+
+Bool RADEONGetHardCodedEDIDFromBIOS (ScrnInfoPtr pScrn)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned long tmp;
+ char EDID[256];
+
+ if (!info->VBIOS) return FALSE;
+
+ if (info->IsAtomBios) {
+ /* Not yet */
+ return FALSE;
+ } else {
+ if (!(tmp = RADEON_BIOS16(info->ROMHeaderStart + 0x4c))) {
+ return FALSE;
+ }
+
+ memcpy(EDID, (char*)(info->VBIOS + tmp), 256);
+
+ info->DotClock = (*(CARD16*)(EDID+54)) * 10;
+ info->PanelXRes = (*(CARD8*)(EDID+56)) + ((*(CARD8*)(EDID+58))>>4)*256;
+ info->HBlank = (*(CARD8*)(EDID+57)) + ((*(CARD8*)(EDID+58)) & 0xf)*256;
+ info->HOverPlus = (*(CARD8*)(EDID+62)) + ((*(CARD8*)(EDID+65)>>6)*256);
+ info->HSyncWidth = (*(CARD8*)(EDID+63)) + (((*(CARD8*)(EDID+65)>>4) & 3)*256);
+ info->PanelYRes = (*(CARD8*)(EDID+59)) + ((*(CARD8*)(EDID+61))>>4)*256;
+ info->VBlank = ((*(CARD8*)(EDID+60)) + ((*(CARD8*)(EDID+61)) & 0xf)*256);
+ info->VOverPlus = (((*(CARD8*)(EDID+64))>>4) + (((*(CARD8*)(EDID+65)>>2) & 3)*16));
+ info->VSyncWidth = (((*(CARD8*)(EDID+64)) & 0xf) + ((*(CARD8*)(EDID+65)) & 3)*256);
+ info->Flags = V_NHSYNC | V_NVSYNC; /**(CARD8*)(EDID+71);*/
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hardcoded EDID data will be used for TMDS panel\n");
+ }
+ return TRUE;
+}
+
+Bool RADEONGetTMDSInfoFromBIOS (ScrnInfoPtr pScrn)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ CARD32 tmp, maxfreq;
+ int i, n;
+
+ if (!info->VBIOS) return FALSE;
+
+ if (info->IsAtomBios) {
+ if((tmp = RADEON_BIOS16 (info->MasterDataStart + 18))) {
+
+ maxfreq = RADEON_BIOS16(tmp+4);
+
+ for (i=0; i<4; i++) {
+ info->tmds_pll[i].freq = RADEON_BIOS16(tmp+i*6+6);
+ /* This assumes each field in TMDS_PLL has 6 bit as in R300/R420 */
+ info->tmds_pll[i].value = ((RADEON_BIOS8(tmp+i*6+8) & 0x3f) |
+ ((RADEON_BIOS8(tmp+i*6+10) & 0x3f)<<6) |
+ ((RADEON_BIOS8(tmp+i*6+9) & 0xf)<<12) |
+ ((RADEON_BIOS8(tmp+i*6+11) & 0xf)<<16));
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "TMDS PLL from BIOS: %ld %lx\n",
+ info->tmds_pll[i].freq, info->tmds_pll[i].value);
+
+ if (maxfreq == info->tmds_pll[i].freq) {
+ info->tmds_pll[i].freq = 0xffffffff;
+ break;
+ }
+ }
+ return TRUE;
+ }
+ } else {
+
+ tmp = RADEON_BIOS16(info->ROMHeaderStart + 0x34);
+ if (tmp) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "DFP table revision: %d\n", RADEON_BIOS8(tmp));
+ if (RADEON_BIOS8(tmp) == 3) {
+ n = RADEON_BIOS8(tmp + 5) + 1;
+ if (n > 4) n = 4;
+ for (i=0; i<n; i++) {
+ info->tmds_pll[i].value = RADEON_BIOS32(tmp+i*10+0x08);
+ info->tmds_pll[i].freq = RADEON_BIOS16(tmp+i*10+0x10);
+ }
+ return TRUE;
+ }
+
+ /* revision 4 has some problem as it appears in RV280,
+ comment it off for now, use default instead */
+ /*
+ else if (RADEON_BIOS8(tmp) == 4) {
+ int stride = 0;
+ n = RADEON_BIOS8(tmp + 5) + 1;
+ if (n > 4) n = 4;
+ for (i=0; i<n; i++) {
+ info->tmds_pll[i].value = RADEON_BIOS32(tmp+stride+0x08);
+ info->tmds_pll[i].freq = RADEON_BIOS16(tmp+stride+0x10);
+ if (i == 0) stride += 10;
+ else stride += 6;
+ }
+ return TRUE;
+ }
+ */
+ }
+ }
+ return FALSE;
+}
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 11c05d0..742d4aa 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -423,7 +423,7 @@ static struct
{720, 400, 70},
};
-static const RADEONTMDSPll default_tmds_pll[CHIP_FAMILY_LAST][4] =
+static const RADEONTMDSPll default_tmds_pll[CHIP_FAMILY_LAST][4] =
{
{{0, 0}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_UNKNOW*/
{{0, 0}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_LEGACY*/
@@ -439,6 +439,8 @@ static const RADEONTMDSPll default_tmds_pll[CHIP_FAMILY_LAST][4] =
{{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_R300*/
{{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_R350*/
{{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RV350*/
+ {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RV380*/
+ {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_R420*/
};
extern int getRADEONEntityIndex(void);
@@ -452,7 +454,7 @@ struct RADEONInt10Save {
static Bool RADEONMapMMIO(ScrnInfoPtr pScrn);
static Bool RADEONUnmapMMIO(ScrnInfoPtr pScrn);
-static RADEONEntPtr RADEONEntPriv(ScrnInfoPtr pScrn)
+RADEONEntPtr RADEONEntPriv(ScrnInfoPtr pScrn)
{
DevUnion *pPriv;
RADEONInfoPtr info = RADEONPTR(pScrn);
@@ -844,12 +846,13 @@ static int RADEONDiv(int n, int d)
return (n + (d / 2)) / d;
}
-static RADEONMonitorType RADEONDisplayDDCConnected(ScrnInfoPtr pScrn, RADEONDDCType DDCType, xf86MonPtr* MonInfo)
+static RADEONMonitorType RADEONDisplayDDCConnected(ScrnInfoPtr pScrn, RADEONDDCType DDCType, RADEONConnector* port)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
unsigned char *RADEONMMIO = info->MMIO;
unsigned long DDCReg;
RADEONMonitorType MonType = MT_NONE;
+ xf86MonPtr* MonInfo = &port->MonInfo;
int i, j;
DDCReg = info->DDCReg;
@@ -941,10 +944,13 @@ 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 ((INREG(RADEON_FP_GEN_CNTL) & (1<<7)) || !info->IsMobility)
- MonType = MT_DFP;
- else
- MonType = MT_LCD;
+ if (port->TMDSType == TMDS_EXT) MonType = MT_DFP;
+ else {
+ if ((INREG(RADEON_FP_GEN_CNTL) & (1<<7)) || !info->IsMobility)
+ MonType = MT_DFP;
+ else
+ MonType = MT_LCD;
+ }
} else MonType = MT_CRT;
} else MonType = MT_NONE;
@@ -1010,7 +1016,7 @@ RADEONCrtIsPhysicallyConnected(ScrnInfoPtr pScrn, int IsCrtDac)
ulData |= 0x2;
OUTREG(RADEON_DAC_CNTL, ulData);
- usleep(1000);
+ usleep(10000);
ulData = INREG(RADEON_DAC_CNTL);
bConnected = (RADEON_DAC_CMP_OUTPUT & ulData)?1:0;
@@ -1034,7 +1040,6 @@ RADEONCrtIsPhysicallyConnected(ScrnInfoPtr pScrn, int IsCrtDac)
#if 0
if (info->ChipFamily == CHIP_FAMILY_R200) {
-
unsigned long ulOrigGPIO_MONID;
unsigned long ulOrigFP2_GEN_CNTL;
unsigned long ulOrigDISP_OUTPUT_CNTL;
@@ -1150,15 +1155,13 @@ RADEONCrtIsPhysicallyConnected(ScrnInfoPtr pScrn, int IsCrtDac)
| RADEON_RED_MX_FORCE_DAC_DATA
| RADEON_GRN_MX_FORCE_DAC_DATA
| RADEON_BLU_MX_FORCE_DAC_DATA);
- if ((info->ChipFamily == CHIP_FAMILY_R300) ||
- (info->ChipFamily == CHIP_FAMILY_R350) ||
- (info->ChipFamily == CHIP_FAMILY_RV350))
+ if (IS_R300_VARIANT)
ulData |= 0x180 << RADEON_TV_FORCE_DAC_DATA_SHIFT;
else
ulData |= 0x1f5 << RADEON_TV_FORCE_DAC_DATA_SHIFT;
OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, ulData);
- usleep(1000);
+ usleep(10000);
ulData = INREG(RADEON_TV_DAC_CNTL);
bConnected = (ulData & RADEON_TV_DAC_CMPOUT)?1:0;
@@ -1178,513 +1181,7 @@ RADEONCrtIsPhysicallyConnected(ScrnInfoPtr pScrn, int IsCrtDac)
return(bConnected ? MT_CRT : MT_NONE);
}
-static void RADEONQueryConnectedDisplays(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
- const char *s;
- Bool ignore_edid = FALSE, ddc_crt2_used = FALSE;
-
-#define RADEON_BIOS8(v) (info->VBIOS[v])
-#define RADEON_BIOS16(v) (info->VBIOS[v] | \
- (info->VBIOS[(v) + 1] << 8))
-#define RADEON_BIOS32(v) (info->VBIOS[v] | \
- (info->VBIOS[(v) + 1] << 8) | \
- (info->VBIOS[(v) + 2] << 16) | \
- (info->VBIOS[(v) + 3] << 24))
-
- pRADEONEnt->MonType1 = MT_NONE;
- pRADEONEnt->MonType2 = MT_NONE;
- pRADEONEnt->MonInfo1 = NULL;
- pRADEONEnt->MonInfo2 = NULL;
- pRADEONEnt->ReversedDAC = FALSE;
- pRADEONEnt->ReversedTMDS = FALSE;
-
- /* IgnoreEDID option is different from NoDDC 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.
- */
- 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"
- * primary and secondary port displays can have one of following:
- * NONE, CRT, LVDS, TMDS
- * With this option, driver will bring up monitors as specified,
- * not using auto-detection routines to probe monitors.
- */
-
- /* current monitor mapping scheme:
- * Two displays connected:
- * Primary Port:
- * CRTC1 -> FP/TMDS -> DVI port -> TMDS panel --> Primary or
- * CRTC1 -> FP/LVDS -> Int. LCD -> LVDS panel --> Primary or
- * CRTC1 -> TV DAC -> DVI port -> CRT monitor --> Primary
- *
- * Secondary Port
- * CRTC2 -> CRT DAC -> VGA port -> CRT monitor --> Secondary or
- * CRTC2 -> FP2/Ext. -> DVI port -> TMDS panel --> Secondary
- *
- * Only DVI (or Int. LDC) conneced:
- * CRTC1 -> FP/TMDS -> DVI port -> TMDS panel --> Primary or
- * CRTC1 -> FP/LVDS -> Int. LCD -> LVDS panel --> Primary or
- * CRTC1 -> TV DAC -> DVI port -> CRT monitor --> Primary
- *
- * Only VGA (can be DVI on some dual-DVI boards) connected:
- * CRTC1 -> CRT DAC -> VGA port -> CRT monitor --> Primary or
- * CRTC1 -> FP2/Ext. -> DVI port -> TMDS panel --> Primary (not supported)
- *
- * Note, this is different from Windows scheme where
- * if a digital panel is connected to DVI port, DVI will be the 1st port
- * otherwise, VGA port will be treated as 1st port
- *
- * Here we always treat DVI port as primary if both ports are connected.
- * When only one port is connected, it will be treated as
- * primary regardless which port or what type of display is involved.
- */
-
- if ((s = xf86GetOptValString(info->Options, OPTION_MONITOR_LAYOUT))) {
- char s1[5], s2[5];
- int i = 0, second = 0;
-
- /* When using user specified monitor types, we will not do DDC detection
- *
- */
- do {
- switch(*s)
- {
- case ',':
- s1[i] = '\0';
- i = 0;
- second = 1;
- break;
- case ' ':
- case '\t':
- case '\n':
- case '\r':
- break;
- default:
- if (second)
- s2[i] = *s;
- else
- s1[i] = *s;
- i++;
- if (i == 4) break;
- }
- } while(*s++);
- s2[i] = '\0';
-
- if (strcmp(s1, "NONE") == 0)
- pRADEONEnt->MonType1 = MT_NONE;
- else if (strcmp(s1, "CRT") == 0)
- pRADEONEnt->MonType1 = MT_CRT;
- else if (strcmp(s1, "TMDS") == 0)
- pRADEONEnt->MonType1 = MT_DFP;
- else if (strcmp(s1, "LVDS") == 0)
- pRADEONEnt->MonType1 = MT_LCD;
- else
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Invalid Monitor type specified for 1st port \n");
- if (strcmp(s2, "NONE") == 0)
- pRADEONEnt->MonType2 = MT_NONE;
- else if (strcmp(s2, "CRT") == 0)
- pRADEONEnt->MonType2 = MT_CRT;
- else if (strcmp(s2, "TMDS") == 0)
- pRADEONEnt->MonType2 = MT_DFP;
- else if (strcmp(s2, "LVDS") == 0)
- pRADEONEnt->MonType2 = MT_LCD;
- else
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Invalid Monitor type specified for 2nd port \n");
-
- if (!ignore_edid) {
- if (pRADEONEnt->MonType1) /* assuming the first port using DDC_DVI */
- if(!RADEONDisplayDDCConnected(pScrn, DDC_DVI, &pRADEONEnt->MonInfo1)) {
- RADEONDisplayDDCConnected(pScrn, DDC_CRT2, &pRADEONEnt->MonInfo1);
- ddc_crt2_used = TRUE;
- }
- if (pRADEONEnt->MonType2) { /* assuming the second port using DDC_VGA/DDC_CRT2 */
- if(!RADEONDisplayDDCConnected(pScrn, DDC_VGA, &pRADEONEnt->MonInfo2))
- if (!ddc_crt2_used)
- RADEONDisplayDDCConnected(pScrn, DDC_CRT2, &pRADEONEnt->MonInfo2);
- }
- }
-
- if (!pRADEONEnt->MonType1) {
- if (pRADEONEnt->MonType2) {
- pRADEONEnt->MonType1 = pRADEONEnt->MonType2;
- pRADEONEnt->MonInfo1 = pRADEONEnt->MonInfo2;
- } else {
- pRADEONEnt->MonType1 = MT_CRT;
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "No valid monitor specified, force to CRT on 1st port\n");
- }
- pRADEONEnt->MonType2 = MT_NONE;
- pRADEONEnt->MonInfo2 = NULL;
- }
- } else {
- /* Auto detection */
- int i;
- CARD32 tmp;
-
- /* Old single head radeon cards */
- if(!info->HasCRTC2) {
- if((pRADEONEnt->MonType1 = RADEONDisplayDDCConnected(pScrn, DDC_DVI, &pRADEONEnt->MonInfo1)));
- else if((pRADEONEnt->MonType1 = RADEONDisplayDDCConnected(pScrn, DDC_VGA, &pRADEONEnt->MonInfo1)));
- else if((pRADEONEnt->MonType1 = RADEONDisplayDDCConnected(pScrn, DDC_CRT2, &pRADEONEnt->MonInfo1)));
- else if (pInt10) {
- if (xf86LoadSubModule(pScrn, "vbe")) {
- vbeInfoPtr pVbe;
- pVbe = VBEInit(pInt10, info->pEnt->index);
- if (pVbe) {
- for (i = 0; i < 5; i++) {
- pRADEONEnt->MonInfo1 = vbeDoEDID(pVbe, NULL);
- }
- if (pRADEONEnt->MonInfo1->rawData[0x14] & 0x80)
- pRADEONEnt->MonType1 = MT_DFP;
- else pRADEONEnt->MonType1 = MT_CRT;
- }
- }
- } else
- pRADEONEnt->MonType1 = MT_CRT;
-
- pRADEONEnt->HasSecondary = FALSE;
- if (!ignore_edid) {
- if (pRADEONEnt->MonInfo1) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Monitor1 EDID data ---------------------------\n");
- xf86PrintEDID( pRADEONEnt->MonInfo1 );
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "End of Monitor1 EDID data --------------------\n");
- }
- }
- return;
- }
-
- /* Normally the port uses DDC_DVI connected with TVDAC,
- * But this is not true for OEM cards which have TVDAC and CRT DAC reversed.
- * If that's the case, we need also reverse the port arrangement.
- * BIOS settings are supposed report this correctly, work fine for all cards tested.
- * But there may be some exceptions, in that case, user can reverse their monitor
- * definition in config file to correct the problem.
- */
- if (info->VBIOS && (tmp = RADEON_BIOS16(info->FPBIOSstart + 0x50))) {
- for (i = 1; i < 4; i++) {
- unsigned int tmp0;
- if (!RADEON_BIOS8(tmp + i*2) && i > 1) break;
- tmp0 = RADEON_BIOS16(tmp + i*2);
- if ((!(tmp0 & 0x01)) && (((tmp0 >> 8) & 0xf) == DDC_DVI)) {
- pRADEONEnt->ReversedDAC = TRUE;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Reversed DACs detected\n");
- }
- if ((((tmp0 >> 8) & 0x0f) == DDC_DVI ) && ((tmp0 >> 4) & 0x1)) {
- pRADEONEnt->ReversedTMDS = TRUE;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Reversed TMDS detected\n");
- }
- }
- }
-
- /* Primary Head (DVI or Laptop Int. panel)*/
- /* A ddc capable display connected on DVI port */
- if((pRADEONEnt->MonType1 = RADEONDisplayDDCConnected(pScrn, DDC_DVI, &pRADEONEnt->MonInfo1)));
- else if((pRADEONEnt->MonType1 =
- RADEONDisplayDDCConnected(pScrn, DDC_CRT2, &pRADEONEnt->MonInfo1))) {
- ddc_crt2_used = TRUE;
- } else if ((info->IsMobility) &&
- (info->VBIOS && (INREG(RADEON_BIOS_4_SCRATCH) & 4))) {
- /* non-DDC laptop panel connected on primary */
- pRADEONEnt->MonType1 = MT_LCD;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Non-DDC laptop panel detected\n");
- } else {
- /* CRT on DVI, TODO: not reliable, make it always return false for now*/
- pRADEONEnt->MonType1 = RADEONCrtIsPhysicallyConnected(pScrn, pRADEONEnt->ReversedDAC);
- }
-
- /* Secondary Head (mostly VGA, can be DVI on some OEM boards)*/
- if((pRADEONEnt->MonType2 =
- RADEONDisplayDDCConnected(pScrn, DDC_VGA, &pRADEONEnt->MonInfo2)));
- else if(!ddc_crt2_used)
- pRADEONEnt->MonType2 =
- RADEONDisplayDDCConnected(pScrn, DDC_CRT2, &pRADEONEnt->MonInfo2);
- if (!pRADEONEnt->MonType2)
- pRADEONEnt->MonType2 = RADEONCrtIsPhysicallyConnected(pScrn, !pRADEONEnt->ReversedDAC);
-
- if(pRADEONEnt->ReversedTMDS) {
- /* always keep internal TMDS as primary head */
- if (pRADEONEnt->MonType1 == MT_DFP ||
- pRADEONEnt->MonType2 == MT_DFP) {
- int tmp1 = pRADEONEnt->MonType1;
- xf86MonPtr MonInfo = pRADEONEnt->MonInfo1;
- pRADEONEnt->MonInfo1 = pRADEONEnt->MonInfo2;
- pRADEONEnt->MonInfo2 = MonInfo;
- pRADEONEnt->MonType1 = pRADEONEnt->MonType2;
- pRADEONEnt->MonType2 = tmp1;
- if ((pRADEONEnt->MonType1 == MT_CRT) ||
- (pRADEONEnt->MonType2 == MT_CRT)) {
- pRADEONEnt->ReversedDAC ^= 1;
- }
- }
- }
-
- /* no display detected on DVI port*/
- if (pRADEONEnt->MonType1 == MT_NONE) {
- if (pRADEONEnt->MonType2 != MT_NONE) {
- /* Only one detected on VGA, let it to be primary */
- pRADEONEnt->MonType1 = pRADEONEnt->MonType2;
- pRADEONEnt->MonInfo1 = pRADEONEnt->MonInfo2;
- pRADEONEnt->MonType2 = MT_NONE;
- pRADEONEnt->MonInfo2 = NULL;
- } else {
- /* Non detected, Default to a CRT connected */
- pRADEONEnt->MonType1 = MT_CRT;
- }
- }
- }
-
- if(s) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Displays Configured by MonitorLayout: \n\tMonitor1--Type %d, Monitor2--Type %d\n\n",
- pRADEONEnt->MonType1, pRADEONEnt->MonType2);
- } else {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Displays Detected: Monitor1--Type %d, Monitor2--Type %d\n\n",
- pRADEONEnt->MonType1, pRADEONEnt->MonType2);
- }
-
- if(ignore_edid) {
- pRADEONEnt->MonInfo1 = NULL;
- pRADEONEnt->MonInfo2 = NULL;
- }
-
- if (!ignore_edid) {
- if (pRADEONEnt->MonInfo1) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Monitor1 EDID data ---------------------------\n");
- xf86PrintEDID( pRADEONEnt->MonInfo1 );
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "End of Monitor1 EDID data --------------------\n");
- }
- if (pRADEONEnt->MonInfo2) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Monitor2 EDID data ---------------------------\n");
- xf86PrintEDID( pRADEONEnt->MonInfo2 );
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "End of Monitor2 EDID data --------------------\n");
- }
- }
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "\n");
-
- info->OverlayOnCRTC2 = FALSE;
-
- if (pRADEONEnt->MonType2 == MT_NONE)
- pRADEONEnt->HasSecondary = FALSE;
-}
-
-
-/* Read the Video BIOS block and the FP registers (if applicable). */
-static Bool RADEONGetBIOSParameters(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned long tmp, i;
-
- if (!(info->VBIOS = xalloc(RADEON_VBIOS_SIZE))) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Cannot allocate space for hold Video BIOS!\n");
- return FALSE;
- }
-
- if (pInt10) {
- info->BIOSAddr = pInt10->BIOSseg << 4;
- (void)memcpy(info->VBIOS, xf86int10Addr(pInt10, info->BIOSAddr),
- RADEON_VBIOS_SIZE);
- } else {
- xf86ReadPciBIOS(0, info->PciTag, 0, info->VBIOS, RADEON_VBIOS_SIZE);
- if (info->VBIOS[0] != 0x55 || info->VBIOS[1] != 0xaa) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Video BIOS not detected in PCI space!\n");
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Attempting to read Video BIOS from "
- "legacy ISA space!\n");
- info->BIOSAddr = 0x000c0000;
- xf86ReadDomainMemory(info->PciTag, info->BIOSAddr,
- RADEON_VBIOS_SIZE, info->VBIOS);
- }
- }
-
- if (info->VBIOS[0] != 0x55 || info->VBIOS[1] != 0xaa) {
- xfree(info->VBIOS);
- info->FPBIOSstart = 0;
- info->VBIOS = NULL;
- info->BIOSAddr = 0x00000000;
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Video BIOS not found!\n");
- } else
- info->FPBIOSstart = RADEON_BIOS16(0x48);
- info->OverlayOnCRTC2 = FALSE;
-
- if (!info->IsSecondary)
- RADEONQueryConnectedDisplays(pScrn, pInt10);
-
- {
- RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
-
- /* info->MergedFB = FALSE; */
- info->MergeType = MT_NONE;
-
- if(info->HasCRTC2) {
- if(info->IsSecondary) {
- info->DisplayType = (RADEONMonitorType)pRADEONEnt->MonType2;
- if(info->DisplayType == MT_NONE) return FALSE;
- } else {
- info->DisplayType = (RADEONMonitorType)pRADEONEnt->MonType1;
-
- if(!pRADEONEnt->HasSecondary) {
- if ((info->MergeType = pRADEONEnt->MonType2)) {
- /* info->MergedFB = TRUE; */
- }
- }
- }
- } else {
- info->DisplayType = (RADEONMonitorType)pRADEONEnt->MonType1;
- }
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%s Display == Type %d\n",
- (info->IsSecondary ? "Secondary" : "Primary"),
- info->DisplayType);
-
- if (info->MergedFB)
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Secondary Display == Type %d\n",
- info->MergeType);
-
- info->HBlank = 0;
- info->HOverPlus = 0;
- info->HSyncWidth = 0;
- info->VBlank = 0;
- info->VOverPlus = 0;
- info->VSyncWidth = 0;
- info->DotClock = 0;
- info->UseBiosDividers = FALSE;
-
- if (info->DisplayType == MT_LCD && info->VBIOS &&
- !(xf86GetOptValString(info->Options, OPTION_PANEL_SIZE))) {
- tmp = RADEON_BIOS16(info->FPBIOSstart + 0x40);
- if (!tmp) {
- info->PanelPwrDly = 200;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "No Panel Info Table found in BIOS!\n");
- } else {
- char stmp[30];
- int tmp0;
-
- for (i = 0; i < 24; i++)
- stmp[i] = RADEON_BIOS8(tmp+i+1);
- stmp[24] = 0;
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Panel ID string: %s\n", stmp);
-
- info->PanelXRes = RADEON_BIOS16(tmp+25);
- info->PanelYRes = RADEON_BIOS16(tmp+27);
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel Size from BIOS: %dx%d\n",
- info->PanelXRes, info->PanelYRes);
-
- info->PanelPwrDly = RADEON_BIOS16(tmp+44);
- if (info->PanelPwrDly > 2000 || info->PanelPwrDly < 0)
- info->PanelPwrDly = 2000;
-
- /* some panels only work well with certain divider combinations.
- */
- info->RefDivider = RADEON_BIOS16(tmp+46);
- info->PostDivider = RADEON_BIOS8(tmp+48);
- info->FeedbackDivider = RADEON_BIOS16(tmp+49);
- if ((info->RefDivider != 0) &&
- (info->FeedbackDivider > 3)) {
- info->UseBiosDividers = TRUE;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "BIOS provided dividers will be used.\n");
- }
-
- /* We don't use a while loop here just in case we have a corrupted BIOS image.
- The max number of table entries is 23 at present, but may grow in future.
- To ensure it works with future revisions we loop it to 32.
- */
- for (i = 0; i < 32; i++) {
- tmp0 = RADEON_BIOS16(tmp+64+i*2);
- if (tmp0 == 0) break;
- if ((RADEON_BIOS16(tmp0) == info->PanelXRes) &&
- (RADEON_BIOS16(tmp0+2) == info->PanelYRes)) {
- info->HBlank = (RADEON_BIOS16(tmp0+17) -
- RADEON_BIOS16(tmp0+19)) * 8;
- info->HOverPlus = (RADEON_BIOS16(tmp0+21) -
- RADEON_BIOS16(tmp0+19) - 1) * 8;
- info->HSyncWidth = RADEON_BIOS8(tmp0+23) * 8;
- info->VBlank = (RADEON_BIOS16(tmp0+24) -
- RADEON_BIOS16(tmp0+26));
- info->VOverPlus = ((RADEON_BIOS16(tmp0+28) & 0x7ff) -
- RADEON_BIOS16(tmp0+26));
- info->VSyncWidth = ((RADEON_BIOS16(tmp0+28) & 0xf800) >> 11);
- info->DotClock = RADEON_BIOS16(tmp0+9) * 10;
- info->Flags = 0;
- }
- }
-
- if (info->DotClock == 0) {
- DisplayModePtr tmp_mode = NULL;
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "No valid timing info from BIOS.\n");
- /* No timing information for the native mode,
- 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.
- */
- tmp_mode = pScrn->monitor->Modes;
- while(tmp_mode) {
- if ((tmp_mode->HDisplay == info->PanelXRes) &&
- (tmp_mode->VDisplay == info->PanelYRes)) {
-
- 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) && !pRADEONEnt->MonInfo1) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Panel size is not correctly detected.\n"
- "Please try to use PanelSize option for correct settings.\n");
- return FALSE;
- }
- }
- }
- }
- }
-
- if (info->VBIOS) {
- tmp = RADEON_BIOS16(info->FPBIOSstart + 0x30);
- info->sclk = RADEON_BIOS16(tmp + 8) / 100.0;
- info->mclk = RADEON_BIOS16(tmp + 10) / 100.0;
- } else {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "No valid info for SCLK/MCLK for display bandwidth calculation.\n");
- info->sclk = 200.00;
- info->mclk = 200.00;
- }
-
- return TRUE;
-}
-
+#if defined(__powerpc__)
static Bool RADEONProbePLLParameters(ScrnInfoPtr pScrn)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
@@ -1796,121 +1293,181 @@ static Bool RADEONProbePLLParameters(ScrnInfoPtr pScrn)
return TRUE;
}
+#endif
-static void RADEONGetTMDSInfo(ScrnInfoPtr pScrn)
+static void RADEONGetPanelInfoFromReg (ScrnInfoPtr pScrn)
{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- CARD32 tmp;
- int i, n;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ CARD32 fp_vert_stretch = INREG(RADEON_FP_VERT_STRETCH);
+ CARD32 fp_horz_stretch = INREG(RADEON_FP_HORZ_STRETCH);
- for (i=0; i<4; i++) {
- info->tmds_pll[i].value = 0;
- info->tmds_pll[i].freq = 0;
+ info->PanelPwrDly = 200;
+ if (fp_vert_stretch & RADEON_VERT_STRETCH_ENABLE) {
+ info->PanelYRes = (fp_vert_stretch>>12) + 1;
+ } else {
+ info->PanelYRes = (INREG(RADEON_CRTC_V_TOTAL_DISP)>>16) + 1;
}
+ if (fp_horz_stretch & RADEON_HORZ_STRETCH_ENABLE) {
+ info->PanelXRes = ((fp_vert_stretch>>16) + 1) * 8;
+ } else {
+ info->PanelXRes = ((INREG(RADEON_CRTC_H_TOTAL_DISP)>>16) + 1) * 8;
+ }
+
+ if ((info->PanelXRes < 640) || (info->PanelYRes < 480)) {
+ info->PanelXRes = 640;
+ info->PanelYRes = 480;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Panel size %dx%d is derived, this may not be correct.\n"
+ "If not, use PanelSize option to overwrite this setting\n",
+ info->PanelXRes, info->PanelYRes);
+}
- if (info->VBIOS) {
- tmp = RADEON_BIOS16(info->FPBIOSstart + 0x34);
- if (tmp) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "DFP table revision: %d\n", RADEON_BIOS8(tmp));
- if (RADEON_BIOS8(tmp) == 3) {
- n = RADEON_BIOS8(tmp + 5) + 1;
- if (n > 4) n = 4;
- for (i=0; i<n; i++) {
- info->tmds_pll[i].value = RADEON_BIOS32(tmp+i*10+0x08);
- info->tmds_pll[i].freq = RADEON_BIOS16(tmp+i*10+0x10);
- }
- return;
- }
+static Bool RADEONGetLVDSInfo (ScrnInfoPtr pScrn)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
- /* revision 4 has some problem as it appears in RV280,
- comment it off for new, use default instead */
- /*
- else if (RADEON_BIOS8(tmp) == 4) {
- int stride = 0;
- n = RADEON_BIOS8(tmp + 5) + 1;
- if (n > 4) n = 4;
- for (i=0; i<n; i++) {
- info->tmds_pll[i].value = RADEON_BIOS32(tmp+stride+0x08);
- info->tmds_pll[i].freq = RADEON_BIOS16(tmp+stride+0x10);
- if (i == 0) stride += 10;
- else stride += 6;
- }
- return;
- }
- */
- }
- }
+ if (!RADEONGetLVDSInfoFromBIOS(pScrn))
+ RADEONGetPanelInfoFromReg(pScrn);
- for (i=0; i<4; i++) {
- info->tmds_pll[i].value = default_tmds_pll[info->ChipFamily][i].value;
- info->tmds_pll[i].freq = default_tmds_pll[info->ChipFamily][i].freq;
+ if (info->DotClock == 0) {
+ RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
+ DisplayModePtr tmp_mode = NULL;
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "No valid timing info from BIOS.\n");
+ /* No timing information for the native mode,
+ 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.
+ */
+ tmp_mode = pScrn->monitor->Modes;
+ while(tmp_mode) {
+ if ((tmp_mode->HDisplay == info->PanelXRes) &&
+ (tmp_mode->VDisplay == info->PanelYRes)) {
+
+ 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) && !pRADEONEnt->PortInfo[0].MonInfo) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Panel size is not correctly detected.\n"
+ "Please try to use PanelSize option for correct settings.\n");
+ return FALSE;
+ }
}
+
+ return TRUE;
}
-/* Read PLL parameters from BIOS block. Default to typical values if
- * there is no BIOS.
- */
-static Bool RADEONGetPLLParameters(ScrnInfoPtr pScrn)
+static void RADEONGetTMDSInfo(ScrnInfoPtr pScrn)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONPLLPtr pll = &info->pll;
- CARD16 bios_header;
- CARD16 pll_info_block;
- double min_dotclock;
+ int i;
- if (!info->VBIOS) {
+ for (i=0; i<4; i++) {
+ info->tmds_pll[i].value = 0;
+ info->tmds_pll[i].freq = 0;
+ }
- pll->min_pll_freq = 12500;
- pll->max_pll_freq = 35000;
+ if (RADEONGetTMDSInfoFromBIOS(pScrn)) return;
+ for (i=0; i<4; i++) {
+ info->tmds_pll[i].value = default_tmds_pll[info->ChipFamily][i].value;
+ info->tmds_pll[i].freq = default_tmds_pll[info->ChipFamily][i].freq;
+ }
+}
- if (!RADEONProbePLLParameters(pScrn)) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Video BIOS not detected, using default PLL parameters!\n");
-
- switch (info->Chipset) {
- case PCI_CHIP_R200_QL:
- case PCI_CHIP_R200_QN:
- case PCI_CHIP_R200_QO:
- case PCI_CHIP_R200_BB:
- pll->reference_freq = 2700;
- pll->reference_div = 12;
- pll->xclk = 27500;
- break;
- case PCI_CHIP_RV250_Id:
- case PCI_CHIP_RV250_Ie:
- case PCI_CHIP_RV250_If:
- case PCI_CHIP_RV250_Ig:
- pll->reference_freq = 2700;
- pll->reference_div = 12;
- pll->xclk = 24975;
- break;
- case PCI_CHIP_RV200_QW:
- pll->reference_freq = 2700;
- pll->reference_div = 12;
- pll->xclk = 23000;
- break;
- default:
- pll->reference_freq = 2700;
- pll->reference_div = 67;
- pll->xclk = 16615;
- break;
- }
+static void RADEONGetPanelInfo (ScrnInfoPtr pScrn)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ char* s;
+
+ if((s = xf86GetOptValString(info->Options, OPTION_PANEL_SIZE))) {
+ info->PanelPwrDly = 200;
+ if (sscanf (s, "%dx%d", &info->PanelXRes, &info->PanelYRes) != 2) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Invalid PanelSize option: %s\n", s);
+ RADEONGetPanelInfoFromReg(pScrn);
}
} else {
- bios_header = RADEON_BIOS16(0x48);
- pll_info_block = RADEON_BIOS16(bios_header + 0x30);
- RADEONTRACE(("Header at 0x%04x; PLL Information at 0x%04x\n",
- bios_header, pll_info_block));
- pll->reference_freq = RADEON_BIOS16(pll_info_block + 0x0e);
- pll->reference_div = RADEON_BIOS16(pll_info_block + 0x10);
- pll->min_pll_freq = RADEON_BIOS32(pll_info_block + 0x12);
- pll->max_pll_freq = RADEON_BIOS32(pll_info_block + 0x16);
- pll->xclk = RADEON_BIOS16(pll_info_block + 0x08);
+ if(info->DisplayType == MT_LCD) {
+ RADEONGetLVDSInfo(pScrn);
+ } else if ((info->DisplayType == MT_DFP) || (info->MergeType == MT_DFP)) {
+ RADEONGetTMDSInfo(pScrn);
+ if (!pScrn->monitor->DDC)
+ RADEONGetHardCodedEDIDFromBIOS(pScrn);
+ }
+ }
+}
+
+static void RADEONGetClockInfo(ScrnInfoPtr pScrn)
+{
+ RADEONInfoPtr info = RADEONPTR (pScrn);
+ RADEONPLLPtr pll = &info->pll;
+ double min_dotclock;
+
+ if (RADEONGetClockInfoFromBIOS(pScrn)) {
+ if (pll->reference_div < 2) {
+ /* retrive it from register setting for fitting into current PLL algorithm.
+ We'll probably need a new routine to calculate the best ref_div from BIOS
+ provided min_input_pll and max_input_pll
+ */
+ CARD32 tmp;
+ tmp = INPLL(pScrn, RADEON_PPLL_REF_DIV);
+ if (IS_R300_VARIANT ||
+ (info->ChipFamily == CHIP_FAMILY_RS300)) {
+ pll->reference_div = (tmp & R300_PPLL_REF_DIV_ACC_MASK) >> R300_PPLL_REF_DIV_ACC_SHIFT;
+ } else {
+ pll->reference_div = tmp & RADEON_PPLL_REF_DIV_MASK;
+ }
+
+ if (pll->reference_div < 2) pll->reference_div = 12;
+ }
+
+ } else {
+ xf86DrvMsg (pScrn->scrnIndex, X_WARNING,
+ "Video BIOS not detected, using default clock settings!\n");
+
+#if defined(__powerpc__)
+ if (RADEONProbePLLParameters(pScrn)) return;
+#endif
+ if (info->IsIGP)
+ pll->reference_freq = 1432;
+ else
+ pll->reference_freq = 2700;
+
+ pll->reference_div = 12;
+ pll->min_pll_freq = 12500;
+ pll->max_pll_freq = 35000;
+ pll->xclk = 10300;
+
+ info->sclk = 200.00;
+ info->mclk = 200.00;
}
+ xf86DrvMsg (pScrn->scrnIndex, X_INFO,
+ "PLL parameters: rf=%d rd=%d min=%ld max=%ld; xclk=%d\n",
+ pll->reference_freq,
+ pll->reference_div,
+ pll->min_pll_freq, pll->max_pll_freq, pll->xclk);
+
/* (Some?) Radeon BIOSes seem too lie about their minimum dot
* clocks. Allow users to override the detected minimum dot clock
* value (e.g., and allow it to be suitable for TV sets).
@@ -1930,10 +1487,392 @@ static Bool RADEONGetPLLParameters(ScrnInfoPtr pScrn)
pll->min_pll_freq = min_dotclock * 1000;
}
}
+}
+
+static BOOL RADEONQueryConnectedMonitors(ScrnInfoPtr pScrn)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ const char *s;
+ Bool ignore_edid = FALSE;
+ int i = 0, second = 0, max_mt;
+
+ const char *MonTypeName[7] =
+ {
+ "AUTO",
+ "NONE",
+ "CRT",
+ "LVDS",
+ "TMDS",
+ "CTV",
+ "STV"
+ };
+
+ const RADEONMonitorType MonTypeID[7] =
+ {
+ MT_UNKNOWN, /* this is just a dummy value for AUTO DETECTION */
+ MT_NONE, /* NONE -> NONE */
+ MT_CRT, /* CRT -> CRT */
+ MT_LCD, /* Laptop LCDs are driven via LVDS port */
+ MT_DFP, /* DFPs are driven via TMDS */
+ MT_CTV, /* CTV -> CTV */
+ MT_STV, /* STV -> STV */
+ };
+
+ const char *TMDSTypeName[3] =
+ {
+ "NONE",
+ "Internal",
+ "External"
+ };
+
+ const char *DDCTypeName[5] =
+ {
+ "NONE",
+ "MONID",
+ "DVI_DDC",
+ "VGA_DDC",
+ "CRT2_DDC"
+ };
+
+ const char *DACTypeName[3] =
+ {
+ "Unknown",
+ "Primary",
+ "TVDAC/ExtDAC",
+ };
+
+ const char *ConnectorTypeName[8] =
+ {
+ "None",
+ "Proprietary",
+ "VGA",
+ "DVI-I",
+ "DVI-D",
+ "CTV",
+ "STV",
+ "Unsupported"
+ };
+
+ const char *ConnectorTypeNameATOM[10] =
+ {
+ "None",
+ "VGA",
+ "DVI-I",
+ "DVI-D",
+ "DVI-A",
+ "STV",
+ "CTV",
+ "LVDS",
+ "Digital",
+ "Unsupported"
+ };
+
+ max_mt = 5;
+
+ if(info->IsSecondary) {
+ info->DisplayType = (RADEONMonitorType)pRADEONEnt->MonType2;
+ if(info->DisplayType == MT_NONE) return FALSE;
+ return TRUE;
+ }
+
+
+ /* We first get the information about all connectors from BIOS.
+ * This is how the card is phyiscally wired up.
+ * The information should be correct even on a OEM card.
+ * If not, we may have problem -- need to use MonitorLayout option.
+ */
+ 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;
+ }
+
+ if (!RADEONGetConnectorInfoFromBIOS(pScrn)) {
+ /* 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_D;
+
+ 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;
+ pRADEONEnt->PortInfo[1].ConnectorType = CONNECTOR_CRT;
+ }
+
+ /* 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;
+ } else if ((pRADEONEnt->PortInfo[0].TMDSType != TMDS_INT &&
+ pRADEONEnt->PortInfo[1].TMDSType != TMDS_INT)) {
+ /* no TMDS_INT port, make primary DAC port first */
+ if (pRADEONEnt->PortInfo[1].DACType == DAC_PRIMARY) {
+ RADEONConnector connector;
+ connector = pRADEONEnt->PortInfo[0];
+ pRADEONEnt->PortInfo[0] = pRADEONEnt->PortInfo[1];
+ pRADEONEnt->PortInfo[1] = connector;
+ }
+ }
+
+ if (info->HasSingleDAC) {
+ /* For RS300/RS350/RS400 chips, there is no primary DAC. Force VGA port to use TVDAC*/
+ if (pRADEONEnt->PortInfo[0].ConnectorType == CONNECTOR_CRT) {
+ pRADEONEnt->PortInfo[0].DACType = DAC_TVDAC;
+ pRADEONEnt->PortInfo[1].DACType = DAC_PRIMARY;
+ } else {
+ pRADEONEnt->PortInfo[1].DACType = DAC_TVDAC;
+ pRADEONEnt->PortInfo[0].DACType = DAC_PRIMARY;
+ }
+ } else if (!info->HasCRTC2) {
+ 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"
+ * primary and secondary port displays can have one of following:
+ * NONE, CRT, LVDS, TMDS
+ * With this option, driver will bring up monitors as specified,
+ * not using auto-detection routines to probe monitors.
+ *
+ * This option can be used when the false monitor detection occurs.
+ *
+ * This option can also be used to disable one connected display.
+ * For example, if you have a laptop connected to an external CRT
+ * and you want to disable the internal LCD panel, you can specify
+ * Option "MonitorLayout" "NONE, CRT"
+ *
+ * This option can also used to disable Clone mode. One there is only
+ * one monitor is specified, clone mode will be turned off automatically
+ * even you have two monitors connected.
+ *
+ * Another usage of this option is you want to config the server
+ * to start up with a certain monitor arrangement even one monitor
+ * is not plugged in when server starts.
+ */
+ if ((s = xf86GetOptValString(info->Options, OPTION_MONITOR_LAYOUT))) {
+ char s1[5], s2[5];
+ i = 0;
+ /* When using user specified monitor types, we will not do DDC detection
+ *
+ */
+ do {
+ switch(*s) {
+ case ',':
+ s1[i] = '\0';
+ i = 0;
+ second = 1;
+ break;
+ case ' ':
+ case '\t':
+ case '\n':
+ case '\r':
+ break;
+ default:
+ if (second)
+ s2[i] = *s;
+ else
+ s1[i] = *s;
+ i++;
+ break;
+ }
+ if (i > 4) i = 4;
+ } while(*s++);
+ s2[i] = '\0';
+
+ for (i = 0; i < max_mt; i++) {
+ if (strcmp(s1, MonTypeName[i]) == 0) {
+ pRADEONEnt->PortInfo[0].MonType = MonTypeID[i];
+ break;
+ }
+ }
+ if (i == max_mt)
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Invalid Monitor type specified for 2nd port \n");
+
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "MonitorLayout Option: \n\tMonitor1--Type %s, Monitor2--Type %s\n\n", s1, s2);
+
+ if (pRADEONEnt->PortInfo[1].MonType == MT_CRT) {
+ pRADEONEnt->PortInfo[1].DACType = DAC_PRIMARY;
+ pRADEONEnt->PortInfo[1].TMDSType = TMDS_UNKNOWN;
+ pRADEONEnt->PortInfo[1].DDCType = DDC_VGA;
+ pRADEONEnt->PortInfo[1].ConnectorType = CONNECTOR_CRT;
+ pRADEONEnt->PortInfo[0].DACType = DAC_TVDAC;
+ pRADEONEnt->PortInfo[0].TMDSType = TMDS_UNKNOWN;
+ pRADEONEnt->PortInfo[0].DDCType = DDC_NONE_DETECTED;
+ pRADEONEnt->PortInfo[0].ConnectorType = pRADEONEnt->PortInfo[0].MonType+1;
+ pRADEONEnt->PortInfo[0].MonInfo = NULL;
+ }
+
+ if (!ignore_edid) {
+ if ((pRADEONEnt->PortInfo[0].MonType > MT_NONE) &&
+ (pRADEONEnt->PortInfo[0].MonType < MT_STV))
+ RADEONDisplayDDCConnected(pScrn, pRADEONEnt->PortInfo[0].DDCType,
+ &pRADEONEnt->PortInfo[0]);
+ if ((pRADEONEnt->PortInfo[1].MonType > MT_NONE) &&
+ (pRADEONEnt->PortInfo[1].MonType < MT_STV))
+ RADEONDisplayDDCConnected(pScrn, pRADEONEnt->PortInfo[1].DDCType,
+ &pRADEONEnt->PortInfo[1]);
+ }
+
+ }
+
+ if (pRADEONEnt->PortInfo[0].MonType == MT_UNKNOWN || pRADEONEnt->PortInfo[1].MonType == MT_UNKNOWN) {
+
+ if(((!info->HasCRTC2) || info->IsDellServer) &&
+ (pRADEONEnt->PortInfo[0].MonType == MT_UNKNOWN)) {
+ if((pRADEONEnt->PortInfo[0].MonType = RADEONDisplayDDCConnected(pScrn, DDC_DVI, &pRADEONEnt->PortInfo[0])));
+ else if((pRADEONEnt->PortInfo[0].MonType = RADEONDisplayDDCConnected(pScrn, DDC_VGA, &pRADEONEnt->PortInfo[0])));
+ else if((pRADEONEnt->PortInfo[0].MonType = RADEONDisplayDDCConnected(pScrn, DDC_CRT2, &pRADEONEnt->PortInfo[0])));
+ else
+ pRADEONEnt->PortInfo[0].MonType = MT_CRT;
+
+ if (!ignore_edid) {
+ if (pRADEONEnt->PortInfo[0].MonInfo) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Monitor1 EDID data ---------------------------\n");
+ xf86PrintEDID(pRADEONEnt->PortInfo[0].MonInfo );
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "End of Monitor1 EDID data --------------------\n");
+ }
+ }
+
+ pRADEONEnt->MonType1 = pRADEONEnt->PortInfo[0].MonType;
+ pRADEONEnt->MonInfo1 = pRADEONEnt->PortInfo[0].MonInfo;
+ pRADEONEnt->MonType2 = MT_NONE;
+ pRADEONEnt->MonInfo2 = NULL;
+ info->MergeType = MT_NONE;
+ return TRUE;
+ }
+
+ /* Primary Head (DVI or Laptop Int. panel)*/
+ /* A ddc capable display connected on DVI port */
+ if (pRADEONEnt->PortInfo[0].MonType == MT_UNKNOWN) {
+ if((pRADEONEnt->PortInfo[0].MonType = RADEONDisplayDDCConnected(pScrn, pRADEONEnt->PortInfo[0].DDCType, &pRADEONEnt->PortInfo[0])));
+ else if (info->IsMobility &&
+ (INREG(RADEON_BIOS_4_SCRATCH) & 4)) {
+ /* non-DDC laptop panel connected on primary */
+ pRADEONEnt->PortInfo[0].MonType = MT_LCD;
+ } else {
+ /* CRT on DVI, TODO: not reliable, make it always return false for now*/
+ pRADEONEnt->PortInfo[0].MonType = RADEONCrtIsPhysicallyConnected(pScrn, !(pRADEONEnt->PortInfo[0].DACType));
+ }
+ }
+
+ /* Secondary Head (mostly VGA, can be DVI on some OEM boards)*/
+ if (pRADEONEnt->PortInfo[1].MonType == MT_UNKNOWN) {
+ if((pRADEONEnt->PortInfo[1].MonType =
+ RADEONDisplayDDCConnected(pScrn, pRADEONEnt->PortInfo[1].DDCType, &pRADEONEnt->PortInfo[1])));
+ else if (info->IsMobility &&
+ (INREG(RADEON_FP2_GEN_CNTL) & RADEON_FP2_ON)) {
+ /* non-DDC TMDS panel connected through DVO */
+ pRADEONEnt->PortInfo[1].MonType = MT_DFP;
+ } else
+ pRADEONEnt->PortInfo[1].MonType = RADEONCrtIsPhysicallyConnected(pScrn, !(pRADEONEnt->PortInfo[1].DACType));
+ }
+ }
+
+ if(ignore_edid) {
+ pRADEONEnt->PortInfo[0].MonInfo = NULL;
+ pRADEONEnt->PortInfo[1].MonInfo = NULL;
+ } else {
+ if (pRADEONEnt->PortInfo[0].MonInfo) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID data from the display on port 1 ----------------------\n");
+ xf86PrintEDID(pRADEONEnt->PortInfo[0].MonInfo );
+ }
+
+ if (pRADEONEnt->PortInfo[1].MonInfo) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID data from the display on port 2-----------------------\n");
+ xf86PrintEDID(pRADEONEnt->PortInfo[1].MonInfo );
+ }
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "\n");
+
+ pRADEONEnt->MonType1 = pRADEONEnt->PortInfo[0].MonType;
+ pRADEONEnt->MonInfo1 = pRADEONEnt->PortInfo[0].MonInfo;
+ pRADEONEnt->MonType2 = pRADEONEnt->PortInfo[1].MonType;
+ pRADEONEnt->MonInfo2 = pRADEONEnt->PortInfo[1].MonInfo;
+ if (pRADEONEnt->PortInfo[0].MonType == MT_NONE) {
+ if (pRADEONEnt->PortInfo[1].MonType == MT_NONE) {
+ pRADEONEnt->MonType1 = MT_CRT;
+ pRADEONEnt->MonInfo1 = NULL;
+ } else {
+ RADEONConnector tmp;
+ pRADEONEnt->MonType1 = pRADEONEnt->PortInfo[1].MonType;
+ pRADEONEnt->MonInfo1 = pRADEONEnt->PortInfo[1].MonInfo;
+ tmp = pRADEONEnt->PortInfo[0];
+ pRADEONEnt->PortInfo[0] = pRADEONEnt->PortInfo[1];
+ pRADEONEnt->PortInfo[1] = tmp;
+ }
+ pRADEONEnt->MonType2 = MT_NONE;
+ pRADEONEnt->MonInfo2 = NULL;
+ }
+
+ info->DisplayType = pRADEONEnt->MonType1;
+ pRADEONEnt->ReversedDAC = FALSE;
+ info->OverlayOnCRTC2 = FALSE;
+ info->MergeType = MT_NONE;
+ if (pRADEONEnt->MonType2 != MT_NONE) {
+ if(!pRADEONEnt->HasSecondary) {
+ info->MergeType = pRADEONEnt->MonType2;
+ }
+
+ if (pRADEONEnt->PortInfo[1].DACType == DAC_TVDAC) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Reversed DAC decteced\n");
+ pRADEONEnt->ReversedDAC = TRUE;
+ }
+ } else {
+ pRADEONEnt->HasSecondary = FALSE;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Primary:\n Monitor -- %s\n Connector -- %s\n DAC Type -- %s\n TMDS Type -- %s\n DDC Type -- %s\n",
+ MonTypeName[pRADEONEnt->PortInfo[0].MonType+1],
+ info->IsAtomBios ?
+ ConnectorTypeNameATOM[pRADEONEnt->PortInfo[0].ConnectorType]:
+ ConnectorTypeName[pRADEONEnt->PortInfo[0].ConnectorType],
+ DACTypeName[pRADEONEnt->PortInfo[0].DACType+1],
+ TMDSTypeName[pRADEONEnt->PortInfo[0].TMDSType+1],
+ DDCTypeName[pRADEONEnt->PortInfo[0].DDCType]);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Secondary:\n Monitor -- %s\n Connector -- %s\n DAC Type -- %s\n TMDS Type -- %s\n DDC Type -- %s\n",
+ MonTypeName[pRADEONEnt->PortInfo[1].MonType+1],
+ info->IsAtomBios ?
+ ConnectorTypeNameATOM[pRADEONEnt->PortInfo[1].ConnectorType]:
+ ConnectorTypeName[pRADEONEnt->PortInfo[1].ConnectorType],
+ DACTypeName[pRADEONEnt->PortInfo[1].DACType+1],
+ TMDSTypeName[pRADEONEnt->PortInfo[1].TMDSType+1],
+ DDCTypeName[pRADEONEnt->PortInfo[1].DDCType]);
return TRUE;
}
+
/* This is called by RADEONPreInit to set up the default visual */
static Bool RADEONPreInitVisual(ScrnInfoPtr pScrn)
{
@@ -2032,20 +1971,34 @@ RADEONSetFBLocation(ScrnInfoPtr pScrn)
CARD32 mc_fb_location;
CARD32 mc_agp_location = INREG(RADEON_MC_AGP_LOCATION);
+
+ /* This function has many problems with newer cards.
+ * Even with older cards, all registers changed here are not
+ * restored properly when X quits, this will also cause
+ * various problems, especially with radeonfb.
+ * Since we don't have DRI support for R300 and above cards,
+ * we just hardcode these values for now.
+ * Need to revisit this whole function!!!
+ */
+ if (IS_R300_VARIANT) {
+ info->fbLocation = 0;
+
+ if (!info->IsSecondary) {
+ RADEONWaitForIdleMMIO(pScrn);
+ OUTREG (RADEON_MC_FB_LOCATION, (INREG(RADEON_CONFIG_MEMSIZE) - 1) & 0xffff0000);
+ OUTREG(RADEON_DISPLAY_BASE_ADDR, info->fbLocation);
+ OUTREG(RADEON_DISPLAY2_BASE_ADDR, info->fbLocation);
+ OUTREG(RADEON_OV0_BASE_ADDR, info->fbLocation);
+ }
+ return;
+ }
+
if (info->IsIGP) {
mc_fb_location = INREG(RADEON_NB_TOM);
OUTREG(RADEON_GRPH2_BUFFER_CNTL,
INREG(RADEON_GRPH2_BUFFER_CNTL) & ~0x7f0000);
- if ((info->ChipFamily == CHIP_FAMILY_RS100) ||
- (info->ChipFamily == CHIP_FAMILY_RS200)) {
- /* This is to workaround the asic bug for RMX, some versions
- of BIOS don't have this register initialized correctly.
- */
- OUTREGP(RADEON_CRTC_MORE_CNTL, RADEON_CRTC_H_CUTOFF_ACTIVE_EN,
- ~RADEON_CRTC_H_CUTOFF_ACTIVE_EN);
- }
} else
#ifdef XF86DRI
if ( info->directRenderingEnabled && info->drmMinor < 10 ) {
@@ -2091,9 +2044,7 @@ static void RADEONGetVRamType(ScrnInfoPtr pScrn)
info->IsDDR = FALSE;
tmp = INREG(RADEON_MEM_CNTL);
- if ((info->ChipFamily == CHIP_FAMILY_R300) ||
- (info->ChipFamily == CHIP_FAMILY_R350) ||
- (info->ChipFamily == CHIP_FAMILY_RV350)) {
+ if (IS_R300_VARIANT) {
tmp &= R300_MEM_NUM_CHANNELS_MASK;
switch (tmp) {
case 0: info->RamWidth = 64; break;
@@ -2163,6 +2114,8 @@ static Bool RADEONPreInitConfig(ScrnInfoPtr pScrn)
info->HasCRTC2 = TRUE;
info->IsMobility = FALSE;
info->IsIGP = FALSE;
+ info->IsDellServer = FALSE;
+ info->HasSingleDAC = FALSE;
switch (info->Chipset) {
case PCI_CHIP_RADEON_LY:
case PCI_CHIP_RADEON_LZ:
@@ -2173,6 +2126,23 @@ static Bool RADEONPreInitConfig(ScrnInfoPtr pScrn)
case PCI_CHIP_RV100_QY:
case PCI_CHIP_RV100_QZ:
info->ChipFamily = CHIP_FAMILY_RV100;
+
+ /* DELL triple-head configuration. */
+ if ((info->PciInfo->subsysVendor == PCI_VENDOR_DELL) &&
+ ((info->PciInfo->subsysCard == 0x016c) ||
+ (info->PciInfo->subsysCard == 0x016d) ||
+ (info->PciInfo->subsysCard == 0x016e) ||
+ (info->PciInfo->subsysCard == 0x016f) ||
+ (info->PciInfo->subsysCard == 0x0170) ||
+ (info->PciInfo->subsysCard == 0x017d) ||
+ (info->PciInfo->subsysCard == 0x017e) ||
+ (info->PciInfo->subsysCard == 0x0183) ||
+ (info->PciInfo->subsysCard == 0x018a) ||
+ (info->PciInfo->subsysCard == 0x019a))) {
+ info->IsDellServer = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "DELL server detected, force to special setup\n");
+ }
+
break;
case PCI_CHIP_RS100_4336:
@@ -2222,10 +2192,13 @@ static Bool RADEONPreInitConfig(ScrnInfoPtr pScrn)
break;
case PCI_CHIP_RS300_5835:
+ case PCI_CHIP_RS350_7835:
info->IsMobility = TRUE;
case PCI_CHIP_RS300_5834:
+ case PCI_CHIP_RS350_7834:
info->ChipFamily = CHIP_FAMILY_RS300;
info->IsIGP = TRUE;
+ info->HasSingleDAC = TRUE;
break;
case PCI_CHIP_RV280_5C61:
@@ -2276,6 +2249,46 @@ static Bool RADEONPreInitConfig(ScrnInfoPtr pScrn)
info->ChipFamily = CHIP_FAMILY_R350;
break;
+ case PCI_CHIP_RV380_3150:
+ case PCI_CHIP_RV380_3154:
+ info->IsMobility = TRUE;
+ case PCI_CHIP_RV380_3E50:
+ case PCI_CHIP_RV380_3E54:
+ info->ChipFamily = CHIP_FAMILY_RV380;
+ break;
+
+ case PCI_CHIP_RV370_5460:
+ case PCI_CHIP_RV370_5464:
+ info->IsMobility = TRUE;
+ case PCI_CHIP_RV370_5B60:
+ case PCI_CHIP_RV370_5B64:
+ case PCI_CHIP_RV370_5B65:
+ info->ChipFamily = CHIP_FAMILY_RV380;
+ break;
+
+ case PCI_CHIP_R420_JN:
+ info->IsMobility = TRUE;
+ case PCI_CHIP_R420_JH:
+ case PCI_CHIP_R420_JI:
+ case PCI_CHIP_R420_JJ:
+ case PCI_CHIP_R420_JK:
+ case PCI_CHIP_R420_JL:
+ case PCI_CHIP_R420_JM:
+ case PCI_CHIP_R420_JP:
+ info->ChipFamily = CHIP_FAMILY_R420;
+ break;
+
+ case PCI_CHIP_R423_UH:
+ case PCI_CHIP_R423_UI:
+ case PCI_CHIP_R423_UJ:
+ case PCI_CHIP_R423_UK:
+ case PCI_CHIP_R423_UQ:
+ case PCI_CHIP_R423_UR:
+ case PCI_CHIP_R423_UT:
+ case PCI_CHIP_R423_5D57:
+ info->ChipFamily = CHIP_FAMILY_R420;
+ break;
+
default:
/* Original Radeon/7200 */
info->ChipFamily = CHIP_FAMILY_RADEON;
@@ -2332,7 +2345,18 @@ static Bool RADEONPreInitConfig(ScrnInfoPtr pScrn)
OUTREG(RADEON_CONFIG_MEMSIZE, pScrn->videoRam * 1024);
} else {
- pScrn->videoRam = INREG(RADEON_CONFIG_MEMSIZE) / 1024;
+ /* There are different HDP mapping schemes depending on single/multi funciton setting,
+ * chip family, HDP mode, and the generation of HDP mapping scheme.
+ * To make things simple, we only allow maximum 128M addressable FB. Anything more than
+ * 128M is configured as invisible FB to CPU that can only be accessed from chip side.
+ */
+ pScrn->videoRam = INREG(RADEON_CONFIG_MEMSIZE) / 1024;
+ if (pScrn->videoRam > 128*1024) pScrn->videoRam = 128*1024;
+ if ((info->ChipFamily == CHIP_FAMILY_RV350) ||
+ (info->ChipFamily == CHIP_FAMILY_RV380) ||
+ (info->ChipFamily == CHIP_FAMILY_R420)) {
+ OUTREGP (RADEON_HOST_PATH_CNTL, (1<<23), ~(1<<23));
+ }
}
/* Some production boards of m6 will return 0 if it's 8 MB */
@@ -2421,7 +2445,7 @@ static Bool RADEONPreInitConfig(ScrnInfoPtr pScrn)
if (pciReadLong(info->PciTag, PCI_CMD_STAT_REG) & RADEON_CAP_LIST) {
CARD32 cap_ptr, cap_id;
-
+
cap_ptr = pciReadLong(info->PciTag,
RADEON_CAPABILITIES_PTR_PCI_CONFIG)
& RADEON_CAP_PTR_MASK;
@@ -3301,7 +3325,7 @@ static int RADEONValidateMergeModes(ScrnInfoPtr pScrn1)
* 'stretched' from their native mode.
*/
if (info->MergeType == MT_CRT && !info->ddc_mode) {
-
+
modesFound =
xf86ValidateModes(pScrn,
pScrn->monitor->Modes,
@@ -4179,11 +4203,10 @@ Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags)
RADEONPreInitDDC(pScrn);
- if (!RADEONGetBIOSParameters(pScrn, pInt10))
- goto fail;
-
- if (info->DisplayType == MT_DFP)
- RADEONGetTMDSInfo(pScrn);
+ RADEONGetBIOSInfo(pScrn, pInt10);
+ if (!RADEONQueryConnectedMonitors(pScrn)) goto fail;
+ RADEONGetClockInfo(pScrn);
+ RADEONGetPanelInfo(pScrn);
/* collect MergedFB options */
/* only parse mergedfb options on the primary head.
@@ -4192,11 +4215,6 @@ Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags)
if (!info->IsSecondary)
RADEONGetMergedFBOptions(pScrn);
- if (info->DisplayType == MT_DFP)
- RADEONGetTMDSInfo(pScrn);
-
- if (!RADEONGetPLLParameters(pScrn)) goto fail;
-
if (!RADEONPreInitGamma(pScrn)) goto fail;
if (!RADEONPreInitModes(pScrn, pInt10)) goto fail;
@@ -4249,6 +4267,7 @@ fail:
fail2:
if(info->MMIO) RADEONUnmapMMIO(pScrn);
info->MMIO = NULL;
+
fail1:
RADEONFreeRec(pScrn);
@@ -4980,9 +4999,7 @@ static void RADEONRestoreCommonRegisters(ScrnInfoPtr pScrn,
if (info->HasCRTC2 &&
!info->IsSwitching &&
info->ChipFamily != CHIP_FAMILY_R200 &&
- info->ChipFamily != CHIP_FAMILY_R300 &&
- info->ChipFamily != CHIP_FAMILY_R350 &&
- info->ChipFamily != CHIP_FAMILY_RV350) {
+ !IS_R300_VARIANT) {
CARD32 tmp;
RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
@@ -5048,6 +5065,13 @@ static void RADEONRestoreCrtcRegisters(ScrnInfoPtr pScrn,
OUTREG(RADEON_CRTC_PITCH, restore->crtc_pitch);
OUTREG(RADEON_DISP_MERGE_CNTL, restore->disp_merge_cntl);
OUTREG(RADEON_CRTC_MORE_CNTL, restore->crtc_more_cntl);
+
+ if (info->IsDellServer) {
+ OUTREG(RADEON_TV_DAC_CNTL, restore->tv_dac_cntl);
+ OUTREG(RADEON_DISP_HW_DEBUG, restore->disp_hw_debug);
+ OUTREG(RADEON_DAC_CNTL2, restore->dac2_cntl);
+ OUTREG(RADEON_CRTC2_GEN_CNTL, restore->crtc2_gen_cntl);
+ }
}
/* Write CRTC2 registers */
@@ -5067,9 +5091,7 @@ static void RADEONRestoreCrtc2Registers(ScrnInfoPtr pScrn,
OUTREG(RADEON_TV_DAC_CNTL, 0x00280203);
if ((info->ChipFamily == CHIP_FAMILY_R200) ||
- (info->ChipFamily == CHIP_FAMILY_R300) ||
- (info->ChipFamily == CHIP_FAMILY_R350) ||
- (info->ChipFamily == CHIP_FAMILY_RV350)) {
+ IS_R300_VARIANT) {
OUTREG(RADEON_DISP_OUTPUT_CNTL, restore->disp_output_cntl);
} else {
OUTREG(RADEON_DISP_HW_DEBUG, restore->disp_hw_debug);
@@ -5128,7 +5150,6 @@ static void RADEONRestoreFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
if (info->DisplayType != MT_DFP) {
unsigned long tmpPixclksCntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
- OUTREG(RADEON_BIOS_5_SCRATCH, restore->bios_5_scratch);
if (info->IsMobility || info->IsIGP) {
/* Asic bug, when turning off LVDS_ON, we have to make sure
@@ -5251,10 +5272,8 @@ static void RADEONRestorePLLRegisters(ScrnInfoPtr pScrn,
RADEON_PLL_DIV_SEL,
~(RADEON_PLL_DIV_SEL));
- if ((info->ChipFamily == CHIP_FAMILY_R300) ||
- (info->ChipFamily == CHIP_FAMILY_RS300) ||
- (info->ChipFamily == CHIP_FAMILY_R350) ||
- (info->ChipFamily == CHIP_FAMILY_RV350)) {
+ if (IS_R300_VARIANT ||
+ (info->ChipFamily == CHIP_FAMILY_RS300)) {
if (restore->ppll_ref_div & R300_PPLL_REF_DIV_ACC_MASK) {
/* When restoring console mode, use saved PPLL_REF_DIV
* setting.
@@ -5533,6 +5552,13 @@ static void RADEONSaveCrtcRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
save->crtc_pitch = INREG(RADEON_CRTC_PITCH);
save->disp_merge_cntl = INREG(RADEON_DISP_MERGE_CNTL);
save->crtc_more_cntl = INREG(RADEON_CRTC_MORE_CNTL);
+
+ if (info->IsDellServer) {
+ save->tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
+ save->dac2_cntl = INREG(RADEON_DAC_CNTL2);
+ save->disp_hw_debug = INREG (RADEON_DISP_HW_DEBUG);
+ save->crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL);
+ }
}
/* Read flat panel registers */
@@ -5839,6 +5865,9 @@ static void RADEONInitDispBandwidth(ScrnInfoPtr pScrn)
int stop_req, max_stop_req;
float read_return_rate, time_disp1_drop_priority;
+ /* R420 family not supported yet */
+ if (info->ChipFamily == CHIP_FAMILY_R420) return;
+
if (pRADEONEnt->pSecondaryScrn) {
if (info->IsSecondary) return;
info2 = RADEONPTR(pRADEONEnt->pSecondaryScrn);
@@ -5882,13 +5911,7 @@ static void RADEONInitDispBandwidth(ScrnInfoPtr pScrn)
stop_req = mode1->HDisplay * info->CurrentLayout.pixel_bytes / 16;
/* setup Max GRPH_STOP_REQ default value */
- if ((info->ChipFamily == CHIP_FAMILY_RV100) ||
- (info->ChipFamily == CHIP_FAMILY_RV200) ||
- (info->ChipFamily == CHIP_FAMILY_RV250) ||
- (info->ChipFamily == CHIP_FAMILY_RV280) ||
- (info->ChipFamily == CHIP_FAMILY_RS100) ||
- (info->ChipFamily == CHIP_FAMILY_RS200) ||
- (info->ChipFamily == CHIP_FAMILY_RS300))
+ if (IS_RV100_VARIANT)
max_stop_req = 0x5c;
else
max_stop_req = 0x7c;
@@ -5916,9 +5939,7 @@ static void RADEONInitDispBandwidth(ScrnInfoPtr pScrn)
mem_tcas = MemTcas2 [data];
}
- if ((info->ChipFamily == CHIP_FAMILY_R300) ||
- (info->ChipFamily == CHIP_FAMILY_R350) ||
- (info->ChipFamily == CHIP_FAMILY_RV350)) {
+ if (IS_R300_VARIANT) {
/* on the R300, Tcas is included in Trbs.
*/
@@ -5959,9 +5980,7 @@ static void RADEONInitDispBandwidth(ScrnInfoPtr pScrn)
/* Find the memory controller latency for the display client.
*/
- if ((info->ChipFamily == CHIP_FAMILY_R300) ||
- (info->ChipFamily == CHIP_FAMILY_R350) ||
- (info->ChipFamily == CHIP_FAMILY_RV350)) {
+ if (IS_R300_VARIANT) {
/*not enough for R350 ???*/
/*
if (!mode2) sclk_delay = 150;
@@ -6238,25 +6257,14 @@ static Bool RADEONInitCrtcRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save,
(pScrn->bitsPerPixel * 8));
save->crtc_pitch |= save->crtc_pitch << 16;
- /* Some versions of BIOS setup CRTC_MORE_CNTL for a DFP, if we
- have a CRT here, it should be cleared to avoild a blank screen.
- */
- if (info->DisplayType == MT_CRT)
- save->crtc_more_cntl = (info->SavedReg.crtc_more_cntl &
- ~(RADEON_CRTC_H_CUTOFF_ACTIVE_EN |
- RADEON_CRTC_V_CUTOFF_ACTIVE_EN));
- else
- save->crtc_more_cntl = info->SavedReg.crtc_more_cntl;
-
- /* Some versions of BIOS setup CRTC_MORE_CNTL for a DFP, if we
- have a CRT here, it should be cleared to avoild a blank screen.
- */
- if (info->DisplayType == MT_CRT)
- save->crtc_more_cntl = (info->SavedReg.crtc_more_cntl &
- ~(RADEON_CRTC_H_CUTOFF_ACTIVE_EN |
- RADEON_CRTC_V_CUTOFF_ACTIVE_EN));
- else
- save->crtc_more_cntl = info->SavedReg.crtc_more_cntl;
+ save->crtc_more_cntl = 0;
+ if ((info->ChipFamily == CHIP_FAMILY_RS100) ||
+ (info->ChipFamily == CHIP_FAMILY_RS200)) {
+ /* This is to workaround the asic bug for RMX, some versions
+ of BIOS dosen't have this register initialized correctly.
+ */
+ save->crtc_more_cntl |= RADEON_CRTC_H_CUTOFF_ACTIVE_EN;
+ }
save->surface_cntl = 0;
save->disp_merge_cntl = info->SavedReg.disp_merge_cntl;
@@ -6277,6 +6285,23 @@ static Bool RADEONInitCrtcRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save,
}
#endif
+ if (info->IsDellServer) {
+ save->dac2_cntl = info->SavedReg.dac2_cntl;
+ save->tv_dac_cntl = info->SavedReg.tv_dac_cntl;
+ save->crtc2_gen_cntl = info->SavedReg.crtc2_gen_cntl;
+ save->disp_hw_debug = info->SavedReg.disp_hw_debug;
+
+ save->dac2_cntl &= ~RADEON_DAC2_DAC_CLK_SEL;
+ save->dac2_cntl |= RADEON_DAC2_DAC2_CLK_SEL;
+
+ /* For CRT on DAC2, don't turn it on if BIOS didn't
+ enable it, even it's detected.
+ */
+ save->disp_hw_debug |= RADEON_CRT2_DISP1_SEL;
+ save->tv_dac_cntl &= ~((1<<2) | (3<<8) | (7<<24) | (0xff<<16));
+ save->tv_dac_cntl |= (0x03 | (2<<8) | (0x58<<16));
+ }
+
RADEONTRACE(("Pitch = %d bytes (virtualX = %d, displayWidth = %d)\n",
save->crtc_pitch, pScrn->virtualX,
info->CurrentLayout.displayWidth));
@@ -6329,9 +6354,7 @@ static Bool RADEONInitCrtc2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save,
save->dac2_cntl |= RADEON_DAC2_DAC2_CLK_SEL;
save->disp_output_cntl = info->SavedReg.disp_output_cntl;
if (info->ChipFamily == CHIP_FAMILY_R200 ||
- info->ChipFamily == CHIP_FAMILY_R300 ||
- info->ChipFamily == CHIP_FAMILY_R350 ||
- info->ChipFamily == CHIP_FAMILY_RV350) {
+ IS_R300_VARIANT) {
save->disp_output_cntl &= ~(RADEON_DISP_DAC_SOURCE_MASK |
RADEON_DISP_DAC2_SOURCE_MASK);
if (pRADEONEnt->MonType1 != MT_CRT) {
@@ -6425,18 +6448,15 @@ static Bool RADEONInitCrtc2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save,
save->crtc2_gen_cntl = (RADEON_CRTC2_EN | (format << 8));
save->fp2_h_sync_strt_wid = save->crtc2_h_sync_strt_wid;
save->fp2_v_sync_strt_wid = save->crtc2_v_sync_strt_wid;
- save->fp2_gen_cntl = (RADEON_FP2_PANEL_FORMAT |
- RADEON_FP2_ON);
- if (info->ChipFamily >= CHIP_FAMILY_R200) {
- save->fp2_gen_cntl |= RADEON_FP2_DV0_EN;
- }
+ save->fp2_gen_cntl = info->SavedReg.fp2_gen_cntl | RADEON_FP2_ON;
if (info->ChipFamily == CHIP_FAMILY_R200 ||
- info->ChipFamily == CHIP_FAMILY_R300 ||
- info->ChipFamily == CHIP_FAMILY_R350 ||
- info->ChipFamily == CHIP_FAMILY_RV350) {
- save->fp2_gen_cntl &= ~RADEON_FP2_SOURCE_SEL_MASK;
- save->fp2_gen_cntl |= RADEON_FP2_SOURCE_SEL_CRTC2;
+ IS_R300_VARIANT) {
+ save->fp2_gen_cntl &= ~(R200_FP2_SOURCE_SEL_MASK |
+ RADEON_FP2_DVO_RATE_SEL_SDR);
+
+ save->fp2_gen_cntl |= (R200_FP2_SOURCE_SEL_CRTC2 |
+ RADEON_FP2_DVO_EN);
} else {
save->fp2_gen_cntl &= ~RADEON_FP2_SRC_SEL_MASK;
save->fp2_gen_cntl |= RADEON_FP2_SRC_SEL_CRTC2;
@@ -6447,16 +6467,6 @@ static Bool RADEONInitCrtc2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save,
else
save->fp2_gen_cntl &= ~RADEON_FP2_PANEL_FORMAT;/* 18 bit format */
- /* FIXME: When there are two DFPs, the 2nd DFP is driven by the
- * external TMDS transmitter. It may have a problem at
- * high dot clock for certain panels.
- */
-
- /* If BIOS has not turned it on, we'll keep it on so that we'll
- * have a valid VGA screen even after X quits or VT is switched
- * to the console mode.
- */
- info->SavedReg.fp2_gen_cntl = RADEON_FP2_ON;
}
RADEONTRACE(("Pitch = %d bytes (virtualX = %d, displayWidth = %d)\n",
@@ -6574,6 +6584,16 @@ static void RADEONInitFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr orig,
else
save->fp_gen_cntl &= ~RADEON_FP_PANEL_FORMAT;/* 18 bit format */
+ if (IS_R300_VARIANT ||
+ (info->ChipFamily == CHIP_FAMILY_R200)) {
+ save->fp_gen_cntl &= ~R200_FP_SOURCE_SEL_MASK;
+ if (mode->Flags & RADEON_USE_RMX)
+ save->fp_gen_cntl |= R200_FP_SOURCE_SEL_RMX;
+ else
+ save->fp_gen_cntl |= R200_FP_SOURCE_SEL_CRTC1;
+ } else
+ save->fp_gen_cntl |= RADEON_FP_SEL_CRTC1;
+
save->lvds_gen_cntl = orig->lvds_gen_cntl;
save->lvds_pll_cntl = orig->lvds_pll_cntl;
@@ -6614,9 +6634,7 @@ static void RADEONInitFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr orig,
break;
}
}
- if ((info->ChipFamily == CHIP_FAMILY_R300) ||
- (info->ChipFamily == CHIP_FAMILY_R350) ||
- (info->ChipFamily == CHIP_FAMILY_RV350) ||
+ if (IS_R300_VARIANT ||
(info->ChipFamily == CHIP_FAMILY_RV280)) {
if (tmp & 0xfff00000)
save->tmds_pll_cntl = tmp;
@@ -6629,9 +6647,7 @@ static void RADEONInitFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr orig,
save->tmds_pll_cntl));
save->tmds_transmitter_cntl &= ~(RADEON_TMDS_TRANSMITTER_PLLRST);
- if ((info->ChipFamily == CHIP_FAMILY_R300) ||
- (info->ChipFamily == CHIP_FAMILY_R350) ||
- (info->ChipFamily == CHIP_FAMILY_RV350) ||
+ if (IS_R300_VARIANT ||
(info->ChipFamily == CHIP_FAMILY_R200) || !info->HasCRTC2)
save->tmds_transmitter_cntl &= ~(RADEON_TMDS_TRANSMITTER_PLLEN);
else /* weird, RV chips got this bit reversed? */
@@ -7244,9 +7260,12 @@ void RADEONFreeScreen(int scrnIndex, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
RADEONInfoPtr info = RADEONPTR(pScrn);
-
+
RADEONTRACE(("RADEONFreeScreen\n"));
+ /* 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;
@@ -7343,9 +7362,9 @@ static void RADEONDacPowerSet(ScrnInfoPtr pScrn, Bool IsOn, Bool IsPrimaryDAC)
} else {
CARD32 fp2_gen_cntl = INREG(RADEON_FP2_GEN_CNTL);
if (IsOn) {
- fp2_gen_cntl |= RADEON_FP2_DV0_EN;
+ fp2_gen_cntl |= RADEON_FP2_DVO_EN;
} else {
- fp2_gen_cntl &= ~RADEON_FP2_DV0_EN;
+ fp2_gen_cntl &= ~RADEON_FP2_DVO_EN;
}
OUTREG(RADEON_FP2_GEN_CNTL, fp2_gen_cntl);
}
@@ -7441,7 +7460,7 @@ static void RADEONDisplayPowerManagementSet(ScrnInfoPtr pScrn,
OUTREGP (RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_BLANK_EN);
OUTREGP (RADEON_FP2_GEN_CNTL, RADEON_FP2_ON, ~RADEON_FP2_ON);
if (info->ChipFamily >= CHIP_FAMILY_R200) {
- OUTREGP (RADEON_FP2_GEN_CNTL, RADEON_FP2_DV0_EN, ~RADEON_FP2_DV0_EN);
+ OUTREGP (RADEON_FP2_GEN_CNTL, RADEON_FP2_DVO_EN, ~RADEON_FP2_DVO_EN);
}
} else if (info->DisplayType == MT_CRT) {
RADEONDacPowerSet(pScrn, TRUE, !pRADEONEnt->ReversedDAC);
@@ -7451,7 +7470,7 @@ static void RADEONDisplayPowerManagementSet(ScrnInfoPtr pScrn,
OUTREGP (RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_BLANK_EN);
OUTREGP (RADEON_FP2_GEN_CNTL, RADEON_FP2_ON, ~RADEON_FP2_ON);
if (info->ChipFamily >= CHIP_FAMILY_R200) {
- OUTREGP (RADEON_FP2_GEN_CNTL, RADEON_FP2_DV0_EN, ~RADEON_FP2_DV0_EN);
+ OUTREGP (RADEON_FP2_GEN_CNTL, RADEON_FP2_DVO_EN, ~RADEON_FP2_DVO_EN);
}
}
if (info->DisplayType == MT_DFP) {
@@ -7480,7 +7499,7 @@ static void RADEONDisplayPowerManagementSet(ScrnInfoPtr pScrn,
OUTREGP (RADEON_FP2_GEN_CNTL, RADEON_FP2_BLANK_EN, ~RADEON_FP2_BLANK_EN);
OUTREGP (RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_ON);
if (info->ChipFamily >= CHIP_FAMILY_R200) {
- OUTREGP (RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_DV0_EN);
+ OUTREGP (RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_DVO_EN);
}
} else if (info->DisplayType == MT_CRT) {
RADEONDacPowerSet(pScrn, FALSE, !pRADEONEnt->ReversedDAC);
@@ -7490,7 +7509,7 @@ static void RADEONDisplayPowerManagementSet(ScrnInfoPtr pScrn,
OUTREGP (RADEON_FP2_GEN_CNTL, RADEON_FP2_BLANK_EN, ~RADEON_FP2_BLANK_EN);
OUTREGP (RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_ON);
if (info->ChipFamily >= CHIP_FAMILY_R200) {
- OUTREGP (RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_DV0_EN);
+ OUTREGP (RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_DVO_EN);
}
}
if (info->DisplayType == MT_DFP) {
diff --git a/src/radeon_macros.h b/src/radeon_macros.h
index 5beaee8..71b9083 100644
--- a/src/radeon_macros.h
+++ b/src/radeon_macros.h
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_macros.h,v 1.3 2003/07/08 16:55:35 tsi Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_macros.h,v 1.2 2003/07/08 15:39:48 tsi Exp $ */
/*
* Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
* VA Linux Systems Inc., Fremont, California.
@@ -55,6 +55,14 @@
#endif
#include "compiler.h"
+#define RADEON_BIOS8(v) (info->VBIOS[v])
+#define RADEON_BIOS16(v) (info->VBIOS[v] | \
+ (info->VBIOS[(v) + 1] << 8))
+#define RADEON_BIOS32(v) (info->VBIOS[v] | \
+ (info->VBIOS[(v) + 1] << 8) | \
+ (info->VBIOS[(v) + 2] << 16) | \
+ (info->VBIOS[(v) + 3] << 24))
+
/* Memory mapped register access macros */
#define INREG8(addr) MMIO_IN8(RADEONMMIO, addr)
#define INREG16(addr) MMIO_IN16(RADEONMMIO, addr)
diff --git a/src/radeon_probe.c b/src/radeon_probe.c
index e139650..721c41b 100644
--- a/src/radeon_probe.c
+++ b/src/radeon_probe.c
@@ -80,6 +80,8 @@ SymTabRec RADEONChipsets[] = {
{ PCI_CHIP_RV250_Lg, "ATI Radeon Mobility 9000 (M9) Lg (AGP)" },
{ PCI_CHIP_RS300_5834, "ATI Radeon 9100 IGP (A5) 5834" },
{ PCI_CHIP_RS300_5835, "ATI Radeon Mobility 9100 IGP (U3) 5835" },
+ { PCI_CHIP_RS350_7834, "ATI Radeon 9100 PRO IGP 7834" },
+ { PCI_CHIP_RS350_7835, "ATI Radeon Mobility 9200 IGP 7835" },
{ PCI_CHIP_RV280_5960, "ATI Radeon 9200PRO 5960 (AGP)" },
{ PCI_CHIP_RV280_5961, "ATI Radeon 9200 5961 (AGP)" },
{ PCI_CHIP_RV280_5962, "ATI Radeon 9200 5962 (AGP)" },
@@ -114,6 +116,33 @@ SymTabRec RADEONChipsets[] = {
{ PCI_CHIP_R350_NI, "ATI Radeon 9800 NI (AGP)" },
{ PCI_CHIP_R350_NK, "ATI FireGL X2 NK (AGP)" },
{ PCI_CHIP_R360_NJ, "ATI Radeon 9800XT NJ (AGP)" },
+ { PCI_CHIP_RV380_3E50, "ATI Radeon X600 (RV380) 3E50 (PCIE)" },
+ { PCI_CHIP_RV380_3E54, "ATI FireGL V3200 (RV380) 3E54 (PCIE)" },
+ { PCI_CHIP_RV380_3150, "ATI Radeon Mobility X600 (M24) 3150 (PCIE)" },
+ { PCI_CHIP_RV380_3154, "ATI FireGL M24 GL 3154 (PCIE)" },
+ { PCI_CHIP_RV370_5B60, "ATI Radeon X300 (RV370) 5B60 (PCIE)" },
+ { PCI_CHIP_RV370_5B62, "ATI Radeon X600 (RV370) 5B62 (PCIE)" },
+ { PCI_CHIP_RV370_5B64, "ATI FireGL V3100 (RV370) 5B64 (PCIE)" },
+ { PCI_CHIP_RV370_5B65, "ATI FireGL D1100 (RV370) 5B65 (PCIE)" },
+ { PCI_CHIP_RV370_5460, "ATI Radeon Mobility M300 (M22) 5460 (PCIE)" },
+ { PCI_CHIP_RV370_5464, "ATI FireGL M22 GL 5464 (PCIE)" },
+ { PCI_CHIP_R420_JH, "ATI Radeon X800 (R420) JH (AGP)" },
+ { PCI_CHIP_R420_JI, "ATI Radeon X800PRO (R420) JI (AGP)" },
+ { PCI_CHIP_R420_JJ, "ATI Radeon X800SE (R420) JJ (AGP)" },
+ { PCI_CHIP_R420_JK, "ATI Radeon X800 (R420) JK (AGP)" },
+ { PCI_CHIP_R420_JL, "ATI Radeon X800 (R420) JL (AGP)" },
+ { PCI_CHIP_R420_JM, "ATI FireGL X3 (R420) JM (AGP)" },
+ { PCI_CHIP_R420_JN, "ATI Radeon Mobility 9800 (M18) JN (AGP)" },
+ { PCI_CHIP_R420_JP, "ATI Radeon X800XT (R420) JP (AGP)" },
+ { PCI_CHIP_R423_UH, "ATI Radeon X800 (R423) UH (PCIE)" },
+ { PCI_CHIP_R423_UI, "ATI Radeon X800PRO (R423) UI (PCIE)" },
+ { PCI_CHIP_R423_UJ, "ATI Radeon X800LE (R423) UJ (PCIE)" },
+ { PCI_CHIP_R423_UK, "ATI Radeon X800SE (R423) UK (PCIE)" },
+ { PCI_CHIP_R423_UQ, "ATI FireGL V7200 (R423) UQ (PCIE)" },
+ { PCI_CHIP_R423_UR, "ATI FireGL V5100 (R423) UR (PCIE)" },
+ { PCI_CHIP_R423_UT, "ATI FireGL V7100 (R423) UT (PCIE)" },
+ { PCI_CHIP_R423_5D57, "ATI Radeon X800XT (R423) 5D57 (PCIE)" },
+
{ -1, NULL }
};
@@ -148,6 +177,8 @@ PciChipsets RADEONPciChipsets[] = {
{ PCI_CHIP_RV250_Lg, PCI_CHIP_RV250_Lg, RES_SHARED_VGA },
{ PCI_CHIP_RS300_5834, PCI_CHIP_RS300_5834, RES_SHARED_VGA },
{ PCI_CHIP_RS300_5835, PCI_CHIP_RS300_5835, RES_SHARED_VGA },
+ { PCI_CHIP_RS350_7834, PCI_CHIP_RS350_7834, RES_SHARED_VGA },
+ { PCI_CHIP_RS350_7835, PCI_CHIP_RS350_7835, RES_SHARED_VGA },
{ PCI_CHIP_RV280_5960, PCI_CHIP_RV280_5960, RES_SHARED_VGA },
{ PCI_CHIP_RV280_5961, PCI_CHIP_RV280_5961, RES_SHARED_VGA },
{ PCI_CHIP_RV280_5962, PCI_CHIP_RV280_5962, RES_SHARED_VGA },
@@ -182,6 +213,33 @@ PciChipsets RADEONPciChipsets[] = {
{ PCI_CHIP_R350_NI, PCI_CHIP_R350_NI, RES_SHARED_VGA },
{ PCI_CHIP_R350_NK, PCI_CHIP_R350_NK, RES_SHARED_VGA },
{ PCI_CHIP_R360_NJ, PCI_CHIP_R360_NJ, RES_SHARED_VGA },
+ { PCI_CHIP_RV380_3E50, PCI_CHIP_RV380_3E50, RES_SHARED_VGA },
+ { PCI_CHIP_RV380_3E54, PCI_CHIP_RV380_3E54, RES_SHARED_VGA },
+ { PCI_CHIP_RV380_3150, PCI_CHIP_RV380_3150, RES_SHARED_VGA },
+ { PCI_CHIP_RV380_3154, PCI_CHIP_RV380_3154, RES_SHARED_VGA },
+ { PCI_CHIP_RV370_5B60, PCI_CHIP_RV370_5B60, RES_SHARED_VGA },
+ { PCI_CHIP_RV370_5B62, PCI_CHIP_RV370_5B62, RES_SHARED_VGA },
+ { PCI_CHIP_RV370_5B64, PCI_CHIP_RV370_5B64, RES_SHARED_VGA },
+ { PCI_CHIP_RV370_5B65, PCI_CHIP_RV370_5B65, RES_SHARED_VGA },
+ { PCI_CHIP_RV370_5460, PCI_CHIP_RV370_5460, RES_SHARED_VGA },
+ { PCI_CHIP_RV370_5464, PCI_CHIP_RV370_5464, RES_SHARED_VGA },
+ { PCI_CHIP_R420_JH, PCI_CHIP_R420_JH, RES_SHARED_VGA },
+ { PCI_CHIP_R420_JI, PCI_CHIP_R420_JI, RES_SHARED_VGA },
+ { PCI_CHIP_R420_JJ, PCI_CHIP_R420_JJ, RES_SHARED_VGA },
+ { PCI_CHIP_R420_JK, PCI_CHIP_R420_JK, RES_SHARED_VGA },
+ { PCI_CHIP_R420_JL, PCI_CHIP_R420_JL, RES_SHARED_VGA },
+ { PCI_CHIP_R420_JM, PCI_CHIP_R420_JM, RES_SHARED_VGA },
+ { PCI_CHIP_R420_JN, PCI_CHIP_R420_JN, RES_SHARED_VGA },
+ { PCI_CHIP_R420_JP, PCI_CHIP_R420_JP, RES_SHARED_VGA },
+ { PCI_CHIP_R423_UH, PCI_CHIP_R423_UH, RES_SHARED_VGA },
+ { PCI_CHIP_R423_UI, PCI_CHIP_R423_UI, RES_SHARED_VGA },
+ { PCI_CHIP_R423_UJ, PCI_CHIP_R423_UJ, RES_SHARED_VGA },
+ { PCI_CHIP_R423_UK, PCI_CHIP_R423_UK, RES_SHARED_VGA },
+ { PCI_CHIP_R423_UQ, PCI_CHIP_R423_UQ, RES_SHARED_VGA },
+ { PCI_CHIP_R423_UR, PCI_CHIP_R423_UR, RES_SHARED_VGA },
+ { PCI_CHIP_R423_UT, PCI_CHIP_R423_UT, RES_SHARED_VGA },
+ { PCI_CHIP_R423_5D57, PCI_CHIP_R423_5D57, RES_SHARED_VGA },
+
{ -1, -1, RES_UNDEFINED }
};
@@ -319,7 +377,6 @@ RADEONProbe(DriverPtr drv, int flags)
pPriv->ptr = xnfcalloc(sizeof(RADEONEntRec), 1);
pRADEONEnt = pPriv->ptr;
pRADEONEnt->HasSecondary = FALSE;
- pRADEONEnt->IsSecondaryRestored = FALSE;
} else {
pRADEONEnt = pPriv->ptr;
pRADEONEnt->HasSecondary = TRUE;
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index b3666eb..1cb38d1 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -45,6 +45,76 @@
#define _XF86MISC_SERVER_
#include "xf86misc.h"
+typedef enum
+{
+ DDC_NONE_DETECTED,
+ DDC_MONID,
+ DDC_DVI,
+ DDC_VGA,
+ DDC_CRT2
+} RADEONDDCType;
+
+typedef enum
+{
+ MT_UNKNOWN = -1,
+ MT_NONE = 0,
+ MT_CRT = 1,
+ MT_LCD = 2,
+ MT_DFP = 3,
+ MT_CTV = 4,
+ MT_STV = 5
+} RADEONMonitorType;
+
+typedef enum
+{
+ CONNECTOR_NONE,
+ CONNECTOR_PROPRIETARY,
+ CONNECTOR_CRT,
+ CONNECTOR_DVI_I,
+ CONNECTOR_DVI_D,
+ CONNECTOR_CTV,
+ CONNECTOR_STV,
+ CONNECTOR_UNSUPPORTED
+} RADEONConnectorType;
+
+typedef enum
+{
+ CONNECTOR_NONE_ATOM,
+ CONNECTOR_VGA_ATOM,
+ CONNECTOR_DVI_I_ATOM,
+ CONNECTOR_DVI_D_ATOM,
+ CONNECTOR_DVI_A_ATOM,
+ CONNECTOR_STV_ATOM,
+ CONNECTOR_CTV_ATOM,
+ CONNECTOR_LVDS_ATOM,
+ CONNECTOR_DIGITAL_ATOM,
+ CONNECTOR_UNSUPPORTED_ATOM
+} RADEONConnectorTypeATOM;
+
+typedef enum
+{
+ DAC_UNKNOWN = -1,
+ DAC_PRIMARY = 0,
+ DAC_TVDAC = 1
+} RADEONDacType;
+
+typedef enum
+{
+ TMDS_UNKNOWN = -1,
+ TMDS_INT = 0,
+ TMDS_EXT = 1
+} RADEONTmdsType;
+
+typedef struct
+{
+ RADEONDDCType DDCType;
+ RADEONDacType DACType;
+ RADEONTmdsType TMDSType;
+ RADEONConnectorType ConnectorType;
+ RADEONMonitorType MonType;
+ xf86MonPtr MonInfo;
+} RADEONConnector;
+
typedef struct
{
Bool HasSecondary;
@@ -65,6 +135,7 @@ typedef struct
xf86MonPtr MonInfo2;
Bool ReversedDAC; /* TVDAC used as primary dac */
Bool ReversedTMDS; /* DDC_DVI is used for external TMDS */
+ RADEONConnector PortInfo[2];
} RADEONEntRec, *RADEONEntPtr;
/* radeon_probe.c */
diff --git a/src/radeon_reg.h b/src/radeon_reg.h
index 92ae561..f2c4d6d 100644
--- a/src/radeon_reg.h
+++ b/src/radeon_reg.h
@@ -638,10 +638,17 @@
# define RADEON_FP_V_SYNC_WID_SHIFT 0x00000010
#define RADEON_FP_GEN_CNTL 0x0284
# define RADEON_FP_FPON (1 << 0)
+# define RADEON_FP_BLANK_EN (1 << 1)
# define RADEON_FP_TMDS_EN (1 << 2)
# define RADEON_FP_PANEL_FORMAT (1 << 3)
# define RADEON_FP_EN_TMDS (1 << 7)
# define RADEON_FP_DETECT_SENSE (1 << 8)
+# define R200_FP_SOURCE_SEL_MASK (3 << 10)
+# define R200_FP_SOURCE_SEL_CRTC1 (0 << 10)
+# define R200_FP_SOURCE_SEL_CRTC2 (1 << 10)
+# define R200_FP_SOURCE_SEL_RMX (2 << 10)
+# define R200_FP_SOURCE_SEL_TRANS (3 << 10)
+# define RADEON_FP_SEL_CRTC1 (0 << 13)
# define RADEON_FP_SEL_CRTC2 (1 << 13)
# define RADEON_FP_CRTC_DONT_SHADOW_HPAR (1 << 15)
# define RADEON_FP_CRTC_DONT_SHADOW_VPAR (1 << 16)
@@ -657,8 +664,10 @@
# define RADEON_FP2_BLANK_EN (1 << 1)
# define RADEON_FP2_ON (1 << 2)
# define RADEON_FP2_PANEL_FORMAT (1 << 3)
-# define RADEON_FP2_SOURCE_SEL_MASK (3 << 10)
-# define RADEON_FP2_SOURCE_SEL_CRTC2 (1 << 10)
+# define R200_FP2_SOURCE_SEL_MASK (3 << 10)
+# define R200_FP2_SOURCE_SEL_CRTC1 (0 << 10)
+# define R200_FP2_SOURCE_SEL_CRTC2 (1 << 10)
+# define R200_FP2_SOURCE_SEL_RMX (2 << 10)
# define RADEON_FP2_SRC_SEL_MASK (3 << 13)
# define RADEON_FP2_SRC_SEL_CRTC2 (1 << 13)
# define RADEON_FP2_FP_POL (1 << 16)
@@ -668,8 +677,8 @@
# define RADEON_FP2_PAD_FLOP_EN (1 << 22)
# define RADEON_FP2_CRC_EN (1 << 23)
# define RADEON_FP2_CRC_READ_EN (1 << 24)
-# define RADEON_FP2_DV0_EN (1 << 25)
-# define RADEON_FP2_DV0_RATE_SEL_SDR (1 << 26)
+# define RADEON_FP2_DVO_EN (1 << 25)
+# define RADEON_FP2_DVO_RATE_SEL_SDR (1 << 26)
#define RADEON_FP_H_SYNC_STRT_WID 0x02c4
#define RADEON_FP_H2_SYNC_STRT_WID 0x03c4
#define RADEON_FP_HORZ_STRETCH 0x028c
diff --git a/src/radeon_video.c b/src/radeon_video.c
index 2e75489..761fd5b 100644
--- a/src/radeon_video.c
+++ b/src/radeon_video.c
@@ -1393,9 +1393,7 @@ RADEONDisplayVideo(
x_off = 8;
y_off = 0;
- if ((info->ChipFamily == CHIP_FAMILY_R300) ||
- (info->ChipFamily == CHIP_FAMILY_R350) ||
- (info->ChipFamily == CHIP_FAMILY_RV350) ||
+ if (IS_R300_VARIANT ||
(info->ChipFamily == CHIP_FAMILY_R200))
x_off = 0;