summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGeorge Sapountzis <gsap7@yahoo.gr>2007-08-28 16:01:12 +0300
committerGeorge Sapountzis <gsap7@yahoo.gr>2007-08-28 16:01:12 +0300
commit7b38d9a1209f87255e5bb0aefe46a363ce4fb6ef (patch)
tree981bce7b10ffe6dc3940cada74d558213208b51b /src
parent2e3d43af1e5077cc61dd8668551a6291368d9ed2 (diff)
parent673f799729824f4439dd5f681f75dd5aab50947f (diff)
Merge branch 'master' into pci-rework
Conflicts: src/ati.c
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am22
-rw-r--r--src/ati.c601
-rw-r--r--src/ati.h72
-rw-r--r--src/atiadjust.c2
-rw-r--r--src/atichip.c508
-rw-r--r--src/atichip.h71
-rw-r--r--src/aticonfig.c2
-rw-r--r--src/aticonsole.c8
-rw-r--r--src/atidri.c11
-rw-r--r--src/atifillin.c47
-rw-r--r--src/atifillin.h41
-rw-r--r--src/atimach64probe.c80
-rw-r--r--src/atimach64probe.h3
-rw-r--r--src/atimach64xv.c3
-rw-r--r--src/atimodule.c40
-rw-r--r--src/atipreinit.c6
-rw-r--r--src/atiprobe.c1
-rw-r--r--src/atiscreen.c2
-rw-r--r--src/ativalid.c2
-rw-r--r--src/local_xf86Rename.h23
-rw-r--r--src/r128_dri.c4
-rw-r--r--src/r128_driver.c36
-rw-r--r--src/r128_probe.c33
-rw-r--r--src/r128_probe.h2
-rw-r--r--src/radeon.h339
-rw-r--r--src/radeon_accel.c38
-rw-r--r--src/radeon_accelfuncs.c10
-rw-r--r--src/radeon_bios.c1032
-rw-r--r--src/radeon_common.h7
-rw-r--r--src/radeon_commonfuncs.c14
-rw-r--r--src/radeon_crtc.c1317
-rw-r--r--src/radeon_cursor.c346
-rw-r--r--src/radeon_display.c1869
-rw-r--r--src/radeon_dri.c204
-rw-r--r--src/radeon_driver.c3872
-rw-r--r--src/radeon_exa.c17
-rw-r--r--src/radeon_exa_funcs.c23
-rw-r--r--src/radeon_mergedfb.c2089
-rw-r--r--src/radeon_mergedfb.h121
-rw-r--r--src/radeon_modes.c679
-rw-r--r--src/radeon_output.c2756
-rw-r--r--src/radeon_probe.c33
-rw-r--r--src/radeon_probe.h134
-rw-r--r--src/radeon_reg.h180
-rw-r--r--src/radeon_tv.c759
-rw-r--r--src/radeon_tv.h56
-rw-r--r--src/radeon_version.h2
-rw-r--r--src/radeon_video.c401
-rw-r--r--src/radeon_video.h6
-rw-r--r--src/theatre.c15
-rw-r--r--src/theatre200.c19
-rw-r--r--src/theatre_detect.c15
52 files changed, 9166 insertions, 8807 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 2528d2a7..dd7007e4 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -51,36 +51,37 @@ ati_drv_la_LTLIBRARIES = ati_drv.la
ati_drv_la_LDFLAGS = -module -avoid-version
ati_drv_ladir = @moduledir@/drivers
ati_drv_la_SOURCES = \
- ati.c atichip.c atimodule.c atimach64probe.c \
- radeon_probe.c r128_probe.c
+ ati.c atimodule.c
atimisc_drv_la_LTLIBRARIES = atimisc_drv.la
atimisc_drv_la_LDFLAGS = -module -avoid-version
atimisc_drv_ladir = @moduledir@/drivers
atimisc_drv_la_SOURCES = \
- atibus.c atiprobe.c atividmem.c \
+ atibus.c atichip.c atiprobe.c atividmem.c \
atiadjust.c atiaudio.c aticlock.c aticonfig.c aticonsole.c \
- atidac.c atidecoder.c atidsp.c atifillin.c atii2c.c \
+ atidac.c atidecoder.c atidsp.c atii2c.c \
atilock.c atimach64.c atimach64accel.c atimach64cursor.c \
atimach64i2c.c atimach64io.c atimach64xv.c atimode.c atipreinit.c \
atiprint.c atirgb514.c atiscreen.c atituner.c atiutil.c ativalid.c \
- atiload.c atimisc.c $(ATIMISC_DRI_SRCS) $(ATIMISC_DGA_SOURCES) \
- $(ATIMISC_CPIO_SOURCES) $(ATIMISC_EXA_SOURCES)
+ atiload.c atimisc.c atimach64probe.c $(ATIMISC_CPIO_SOURCES) \
+ $(ATIMISC_DGA_SOURCES) $(ATIMISC_DRI_SRCS) $(ATIMISC_EXA_SOURCES)
r128_drv_la_LTLIBRARIES = r128_drv.la
r128_drv_la_LDFLAGS = -module -avoid-version
r128_drv_ladir = @moduledir@/drivers
r128_drv_la_SOURCES = \
r128_accel.c r128_cursor.c r128_dga.c r128_driver.c \
- r128_video.c r128_misc.c $(R128_DRI_SRCS)
+ r128_video.c r128_misc.c r128_probe.c $(R128_DRI_SRCS)
radeon_drv_la_LTLIBRARIES = radeon_drv.la
radeon_drv_la_LDFLAGS = -module -avoid-version
radeon_drv_ladir = @moduledir@/drivers
radeon_drv_la_SOURCES = \
- radeon_accel.c radeon_mergedfb.c radeon_cursor.c radeon_dga.c \
+ radeon_accel.c radeon_cursor.c radeon_dga.c \
radeon_driver.c radeon_video.c radeon_bios.c radeon_mm_i2c.c \
- radeon_vip.c radeon_misc.c radeon_display.c radeon_modes.c $(RADEON_DRI_SRCS) $(RADEON_EXA_SOURCES)
+ radeon_vip.c radeon_misc.c radeon_probe.c radeon_display.c \
+ radeon_crtc.c radeon_output.c radeon_modes.c radeon_tv.c \
+ $(RADEON_DRI_SRCS) $(RADEON_EXA_SOURCES)
theatre_detect_drv_la_LTLIBRARIES = theatre_detect_drv.la
theatre_detect_drv_la_LDFLAGS = -module -avoid-version
@@ -123,7 +124,6 @@ EXTRA_DIST = \
atidri.h \
atidripriv.h \
atidsp.h \
- atifillin.h \
ati.h \
atii2c.h \
atiload.h \
@@ -176,12 +176,12 @@ EXTRA_DIST = \
radeon_exa_funcs.c \
radeon.h \
radeon_macros.h \
- radeon_mergedfb.h \
radeon_probe.h \
radeon_reg.h \
radeon_sarea.h \
radeon_version.h \
radeon_video.h \
+ radeon_tv.h \
theatre200.h \
theatre_detect.h \
theatre.h \
diff --git a/src/ati.c b/src/ati.c
index 803ac0bf..3f6cc0c2 100644
--- a/src/ati.c
+++ b/src/ati.c
@@ -60,14 +60,12 @@
#include "atipcirename.h"
#include "ati.h"
-#include "atichip.h"
+#include "atimodule.h"
#include "ativersion.h"
#include "atimach64probe.h"
#include "radeon_probe.h"
-#include "radeon_version.h"
#include "r128_probe.h"
-#include "r128_version.h"
/*
* ATIIdentify --
@@ -80,10 +78,13 @@ ATIIdentify
int flags
)
{
+ /*
+ * Only print chip families here, chip lists are printed when a subdriver
+ * is loaded.
+ */
xf86Msg(X_INFO, "%s: %s\n", ATI_NAME,
- "ATI driver (version " ATI_VERSION_NAME ") for chipset: mach64");
- R128Identify(flags);
- RADEONIdentify(flags);
+ "ATI driver wrapper (version " ATI_VERSION_NAME ") for chipsets: "
+ "mach64, rage128, radeon");
}
/*
@@ -99,61 +100,100 @@ ATIProbe
int flags
)
{
- pciVideoPtr pVideo, *xf86PciVideoInfo = xf86GetPciVideoInfo();
- Bool ProbeSuccess = FALSE;
+ pciVideoPtr pVideo;
+ pciVideoPtr *xf86PciVideoInfo;
Bool DoMach64 = FALSE;
Bool DoRage128 = FALSE, DoRadeon = FALSE;
- int i;
ATIChipType Chip;
- if (!(flags & PROBE_DETECT))
+ xf86PciVideoInfo = xf86GetPciVideoInfo();
+
+ if (xf86PciVideoInfo == NULL)
+ return FALSE;
+
+ while ((pVideo = *xf86PciVideoInfo++) != NULL)
{
- if (xf86MatchDevice(ATI_NAME, NULL) > 0)
+ if ((PCI_DEV_VENDOR_ID(pVideo) != PCI_VENDOR_ATI) ||
+ (PCI_DEV_DEVICE_ID(pVideo) == PCI_CHIP_MACH32))
+ continue;
+
+ /* Check for Rage128's, Radeon's and later adapters */
+ Chip = ATIChipID(PCI_DEV_DEVICE_ID(pVideo), PCI_DEV_REVISION(pVideo));
+ if (Chip <= ATI_CHIP_Mach64)
DoMach64 = TRUE;
- if (xf86MatchDevice(R128_NAME, NULL) > 0)
+ else if (Chip <= ATI_CHIP_Rage128)
DoRage128 = TRUE;
- if (xf86MatchDevice(RADEON_NAME, NULL) > 0)
+ else if (Chip <= ATI_CHIP_Radeon)
DoRadeon = TRUE;
}
- if (xf86PciVideoInfo)
+ /* Call Radeon driver probe */
+ if (DoRadeon)
{
- for (i = 0; (pVideo = xf86PciVideoInfo[i++]); )
+ pointer radeon = xf86LoadDrvSubModule(pDriver, "radeon");
+
+ if (!radeon)
{
- if ((PCI_DEV_VENDOR_ID(pVideo) != PCI_VENDOR_ATI) ||
- (PCI_DEV_DEVICE_ID(pVideo) == PCI_CHIP_MACH32))
- continue;
+ xf86Msg(X_ERROR,
+ ATI_NAME ": Failed to load \"radeon\" module.\n");
+ return FALSE;
+ }
- /* Check for Rage128's, Radeon's and later adapters */
- Chip = ATIChipID(PCI_DEV_DEVICE_ID(pVideo), PCI_DEV_REVISION(pVideo));
+ xf86LoaderReqSymLists(RADEONSymbols, NULL);
- if (Chip > ATI_CHIP_Mach64)
- {
- if (Chip <= ATI_CHIP_Rage128)
- DoRage128 = TRUE;
- else if (Chip <= ATI_CHIP_Radeon)
- DoRadeon = TRUE;
+ RADEONIdentify(flags);
- continue;
- }
+ if (RADEONProbe(pDriver, flags))
+ return TRUE;
- DoMach64 = TRUE;
+ xf86UnloadSubModule(radeon);
+ }
+
+ /* Call Rage 128 driver probe */
+ if (DoRage128)
+ {
+ pointer r128 = xf86LoadDrvSubModule(pDriver, "r128");
+
+ if (!r128)
+ {
+ xf86Msg(X_ERROR,
+ ATI_NAME ": Failed to load \"r128\" module.\n");
+ return FALSE;
}
+
+ xf86LoaderReqSymLists(R128Symbols, NULL);
+
+ R128Identify(flags);
+
+ if (R128Probe(pDriver, flags))
+ return TRUE;
+
+ xf86UnloadSubModule(r128);
}
/* Call Mach64 driver probe */
- if (DoMach64 && Mach64Probe(pDriver, flags))
- ProbeSuccess = TRUE;
+ if (DoMach64)
+ {
+ pointer atimisc = xf86LoadDrvSubModule(pDriver, "atimisc");
- /* Call Rage 128 driver probe */
- if (DoRage128 && R128Probe(pDriver, flags))
- ProbeSuccess = TRUE;
+ if (!atimisc)
+ {
+ xf86Msg(X_ERROR,
+ ATI_NAME ": Failed to load \"atimisc\" module.\n");
+ return FALSE;
+ }
- /* Call Radeon driver probe */
- if (DoRadeon && RADEONProbe(pDriver, flags))
- ProbeSuccess = TRUE;
+ xf86LoaderReqSymLists(ATISymbols, NULL);
+
+ Mach64Identify(flags);
+
+ if (Mach64Probe(pDriver, flags))
+ return TRUE;
- return ProbeSuccess;
+ xf86UnloadSubModule(atimisc);
+ }
+
+ return FALSE;
}
/*
@@ -161,22 +201,27 @@ ATIProbe
*
* Return recognised options that are intended for public consumption.
*/
-const OptionInfoRec *
+static const OptionInfoRec *
ATIAvailableOptions
(
int ChipId,
int BusId
)
{
- const OptionInfoRec *pOptions;
+ CARD16 ChipType = ChipId & 0xffff;
+ ATIChipType Chip;
- if ((pOptions = R128AvailableOptions(ChipId, BusId)))
- return pOptions;
+ /* Probe should have loaded the appropriate subdriver by this point */
- if ((pOptions = RADEONAvailableOptions(ChipId, BusId)))
- return pOptions;
+ Chip = ATIChipID(ChipType, 0x0); /* chip revision is don't care */
+ if (Chip <= ATI_CHIP_Mach64)
+ return Mach64AvailableOptions(ChipId, BusId);
+ else if (Chip <= ATI_CHIP_Rage128)
+ return R128AvailableOptions(ChipId, BusId);
+ else if (Chip <= ATI_CHIP_Radeon)
+ return RADEONAvailableOptions(ChipId, BusId);
- return Mach64AvailableOptions(ChipId, BusId);
+ return NULL;
}
/* The root of all evil... */
@@ -190,3 +235,469 @@ _X_EXPORT DriverRec ATI =
NULL,
0
};
+
+/*
+ * Chip-related definitions.
+ */
+const char *ATIChipNames[] =
+{
+ "Unknown",
+ "ATI 88800GX-C",
+ "ATI 88800GX-D",
+ "ATI 88800GX-E",
+ "ATI 88800GX-F",
+ "ATI 88800GX",
+ "ATI 88800CX",
+ "ATI 264CT",
+ "ATI 264ET",
+ "ATI 264VT",
+ "ATI 3D Rage",
+ "ATI 264VT-B",
+ "ATI 3D Rage II",
+ "ATI 264VT3",
+ "ATI 3D Rage II+DVD",
+ "ATI 3D Rage LT",
+ "ATI 264VT4",
+ "ATI 3D Rage IIc",
+ "ATI 3D Rage Pro",
+ "ATI 3D Rage LT Pro",
+ "ATI 3D Rage XL or XC",
+ "ATI 3D Rage Mobility",
+ "ATI unknown Mach64",
+ "ATI Rage 128 GL",
+ "ATI Rage 128 VR",
+ "ATI Rage 128 Pro GL",
+ "ATI Rage 128 Pro VR",
+ "ATI Rage 128 Pro ULTRA",
+ "ATI Rage 128 Mobility M3",
+ "ATI Rage 128 Mobility M4",
+ "ATI unknown Rage 128"
+ "ATI Radeon 7200",
+ "ATI Radeon 7000 (VE)",
+ "ATI Radeon Mobility M6",
+ "ATI Radeon IGP320",
+ "ATI Radeon IGP330/340/350",
+ "ATI Radeon 7000 IGP",
+ "ATI Radeon 7500",
+ "ATI Radeon Mobility M7",
+ "ATI Radeon 8500/9100",
+ "ATI Radeon 9000",
+ "ATI Radeon Mobility M9",
+ "ATI Radeon 9100 IGP",
+ "ATI Radeon 9200 IGP",
+ "ATI Radeon 9200",
+ "ATI Radeon Mobility M9+",
+ "ATI Radeon 9700/9500",
+ "ATI Radeon 9600/9550",
+ "ATI Radeon 9800",
+ "ATI Radeon 9800XT",
+ "ATI Radeon X300/X550/M22",
+ "ATI Radeon X600/X550/M24",
+ "ATI Radeon X800/M18 AGP",
+ "ATI Radeon X800/M28 PCIE",
+ "ATI Radeon X800XL PCIE",
+ "ATI Radeon X850 PCIE",
+ "ATI Radeon X850 AGP",
+ "ATI Radeon X700",
+ "ATI Xpress 200"
+ "ATI unknown Radeon",
+ "ATI Rage HDTV"
+};
+
+#include "atichip.h"
+
+/*
+ * ATIChipID --
+ *
+ * This returns the ATI_CHIP_* value (generally) associated with a particular
+ * ChipID/ChipRev combination.
+ */
+ATIChipType
+ATIChipID
+(
+ const CARD16 ChipID,
+ const CARD8 ChipRev
+)
+{
+ switch (ChipID)
+ {
+ case OldChipID('G', 'X'): case NewChipID('G', 'X'):
+ switch (ChipRev)
+ {
+ case 0x00U:
+ return ATI_CHIP_88800GXC;
+
+ case 0x01U:
+ return ATI_CHIP_88800GXD;
+
+ case 0x02U:
+ return ATI_CHIP_88800GXE;
+
+ case 0x03U:
+ return ATI_CHIP_88800GXF;
+
+ default:
+ return ATI_CHIP_88800GX;
+ }
+
+ case OldChipID('C', 'X'): case NewChipID('C', 'X'):
+ return ATI_CHIP_88800CX;
+
+ case OldChipID('C', 'T'): case NewChipID('C', 'T'):
+ return ATI_CHIP_264CT;
+
+ case OldChipID('E', 'T'): case NewChipID('E', 'T'):
+ return ATI_CHIP_264ET;
+
+ case OldChipID('V', 'T'): case NewChipID('V', 'T'):
+ /* For simplicity, ignore ChipID discrepancy that can occur here */
+ if (!(ChipRev & GetBits(CFG_CHIP_VERSION, CFG_CHIP_REV)))
+ return ATI_CHIP_264VT;
+ return ATI_CHIP_264VTB;
+
+ case OldChipID('G', 'T'): case NewChipID('G', 'T'):
+ if (!(ChipRev & GetBits(CFG_CHIP_VERSION, CFG_CHIP_REV)))
+ return ATI_CHIP_264GT;
+ return ATI_CHIP_264GTB;
+
+ case OldChipID('V', 'U'): case NewChipID('V', 'U'):
+ return ATI_CHIP_264VT3;
+
+ case OldChipID('G', 'U'): case NewChipID('G', 'U'):
+ return ATI_CHIP_264GTDVD;
+
+ case OldChipID('L', 'G'): case NewChipID('L', 'G'):
+ return ATI_CHIP_264LT;
+
+ case OldChipID('V', 'V'): case NewChipID('V', 'V'):
+ return ATI_CHIP_264VT4;
+
+ case OldChipID('G', 'V'): case NewChipID('G', 'V'):
+ case OldChipID('G', 'W'): case NewChipID('G', 'W'):
+ case OldChipID('G', 'Y'): case NewChipID('G', 'Y'):
+ case OldChipID('G', 'Z'): case NewChipID('G', 'Z'):
+ return ATI_CHIP_264GT2C;
+
+ case OldChipID('G', 'B'): case NewChipID('G', 'B'):
+ case OldChipID('G', 'D'): case NewChipID('G', 'D'):
+ case OldChipID('G', 'I'): case NewChipID('G', 'I'):
+ case OldChipID('G', 'P'): case NewChipID('G', 'P'):
+ case OldChipID('G', 'Q'): case NewChipID('G', 'Q'):
+ return ATI_CHIP_264GTPRO;
+
+ case OldChipID('L', 'B'): case NewChipID('L', 'B'):
+ case OldChipID('L', 'D'): case NewChipID('L', 'D'):
+ case OldChipID('L', 'I'): case NewChipID('L', 'I'):
+ case OldChipID('L', 'P'): case NewChipID('L', 'P'):
+ case OldChipID('L', 'Q'): case NewChipID('L', 'Q'):
+ return ATI_CHIP_264LTPRO;
+
+ case OldChipID('G', 'L'): case NewChipID('G', 'L'):
+ case OldChipID('G', 'M'): case NewChipID('G', 'M'):
+ case OldChipID('G', 'N'): case NewChipID('G', 'N'):
+ case OldChipID('G', 'O'): case NewChipID('G', 'O'):
+ case OldChipID('G', 'R'): case NewChipID('G', 'R'):
+ case OldChipID('G', 'S'): case NewChipID('G', 'S'):
+ return ATI_CHIP_264XL;
+
+ case OldChipID('L', 'M'): case NewChipID('L', 'M'):
+ case OldChipID('L', 'N'): case NewChipID('L', 'N'):
+ case OldChipID('L', 'R'): case NewChipID('L', 'R'):
+ case OldChipID('L', 'S'): case NewChipID('L', 'S'):
+ return ATI_CHIP_MOBILITY;
+
+ case NewChipID('R', 'E'):
+ case NewChipID('R', 'F'):
+ case NewChipID('R', 'G'):
+ case NewChipID('S', 'K'):
+ case NewChipID('S', 'L'):
+ case NewChipID('S', 'M'):
+ /* "SN" is listed as ATI_CHIP_RAGE128_4X in ATI docs */
+ case NewChipID('S', 'N'):
+ return ATI_CHIP_RAGE128GL;
+
+ case NewChipID('R', 'K'):
+ case NewChipID('R', 'L'):
+ /*
+ * ATI documentation lists SE/SF/SG under both ATI_CHIP_RAGE128VR
+ * and ATI_CHIP_RAGE128_4X, and lists SH/SK/SL under Rage 128 4X only.
+ * I'm stuffing them here for now until this can be clarified as ATI
+ * documentation doesn't mention their details. <mharris@redhat.com>
+ */
+ case NewChipID('S', 'E'):
+ case NewChipID('S', 'F'):
+ case NewChipID('S', 'G'):
+ case NewChipID('S', 'H'):
+ return ATI_CHIP_RAGE128VR;
+
+ /* case NewChipID('S', 'H'): */
+ /* case NewChipID('S', 'K'): */
+ /* case NewChipID('S', 'L'): */
+ /* case NewChipID('S', 'N'): */
+ /* return ATI_CHIP_RAGE128_4X; */
+
+ case NewChipID('P', 'A'):
+ case NewChipID('P', 'B'):
+ case NewChipID('P', 'C'):
+ case NewChipID('P', 'D'):
+ case NewChipID('P', 'E'):
+ case NewChipID('P', 'F'):
+ return ATI_CHIP_RAGE128PROGL;
+
+ case NewChipID('P', 'G'):
+ case NewChipID('P', 'H'):
+ case NewChipID('P', 'I'):
+ case NewChipID('P', 'J'):
+ case NewChipID('P', 'K'):
+ case NewChipID('P', 'L'):
+ case NewChipID('P', 'M'):
+ case NewChipID('P', 'N'):
+ case NewChipID('P', 'O'):
+ case NewChipID('P', 'P'):
+ case NewChipID('P', 'Q'):
+ case NewChipID('P', 'R'):
+ case NewChipID('P', 'S'):
+ case NewChipID('P', 'T'):
+ case NewChipID('P', 'U'):
+ case NewChipID('P', 'V'):
+ case NewChipID('P', 'W'):
+ case NewChipID('P', 'X'):
+ return ATI_CHIP_RAGE128PROVR;
+
+ case NewChipID('T', 'F'):
+ case NewChipID('T', 'L'):
+ case NewChipID('T', 'R'):
+ case NewChipID('T', 'S'):
+ case NewChipID('T', 'T'):
+ case NewChipID('T', 'U'):
+ return ATI_CHIP_RAGE128PROULTRA;
+
+ case NewChipID('L', 'E'):
+ case NewChipID('L', 'F'):
+ /*
+ * "LK" and "LL" are not in any ATI documentation I can find
+ * - mharris
+ */
+ case NewChipID('L', 'K'):
+ case NewChipID('L', 'L'):
+ return ATI_CHIP_RAGE128MOBILITY3;
+
+ case NewChipID('M', 'F'):
+ case NewChipID('M', 'L'):
+ return ATI_CHIP_RAGE128MOBILITY4;
+
+ case NewChipID('Q', 'D'):
+ case NewChipID('Q', 'E'):
+ case NewChipID('Q', 'F'):
+ case NewChipID('Q', 'G'):
+ return ATI_CHIP_RADEON;
+
+ case NewChipID('Q', 'Y'):
+ case NewChipID('Q', 'Z'):
+ case NewChipID('Q', '^'):
+ return ATI_CHIP_RADEONVE;
+
+ case NewChipID('L', 'Y'):
+ case NewChipID('L', 'Z'):
+ return ATI_CHIP_RADEONMOBILITY6;
+
+ case NewChipID('A', '6'):
+ case NewChipID('C', '6'):
+ return ATI_CHIP_RS100;
+
+ case NewChipID('A', '7'):
+ case NewChipID('C', '7'):
+ return ATI_CHIP_RS200;
+
+ case NewChipID('D', '7'):
+ case NewChipID('B', '7'):
+ return ATI_CHIP_RS250;
+
+ case NewChipID('L', 'W'):
+ case NewChipID('L', 'X'):
+ return ATI_CHIP_RADEONMOBILITY7;
+
+ case NewChipID('Q', 'H'):
+ case NewChipID('Q', 'I'):
+ case NewChipID('Q', 'J'):
+ case NewChipID('Q', 'K'):
+ case NewChipID('Q', 'L'):
+ case NewChipID('Q', 'M'):
+ case NewChipID('Q', 'N'):
+ case NewChipID('Q', 'O'):
+ case NewChipID('Q', 'h'):
+ case NewChipID('Q', 'i'):
+ case NewChipID('Q', 'j'):
+ case NewChipID('Q', 'k'):
+ case NewChipID('Q', 'l'):
+ case NewChipID('B', 'B'):
+ return ATI_CHIP_R200;
+
+ case NewChipID('Q', 'W'):
+ case NewChipID('Q', 'X'):
+ return ATI_CHIP_RV200;
+
+ case NewChipID('I', 'f'):
+ case NewChipID('I', 'g'):
+ return ATI_CHIP_RV250;
+
+ case NewChipID('L', 'd'):
+ case NewChipID('L', 'f'):
+ case NewChipID('L', 'g'):
+ return ATI_CHIP_RADEONMOBILITY9;
+
+ case NewChipID('X', '4'):
+ 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'):
+ case NewChipID('Y', 'd'):
+ case NewChipID('Y', 'e'):
+ return ATI_CHIP_RV280;
+
+ case NewChipID('\\', 'a'):
+ case NewChipID('\\', 'c'):
+ return ATI_CHIP_RADEONMOBILITY9PLUS;
+
+ case NewChipID('A', 'D'):
+ case NewChipID('A', 'E'):
+ case NewChipID('A', 'F'):
+ case NewChipID('A', 'G'):
+ case NewChipID('N', 'D'):
+ case NewChipID('N', 'E'):
+ case NewChipID('N', 'F'):
+ case NewChipID('N', 'G'):
+ return ATI_CHIP_R300;
+
+ case NewChipID('A', 'H'):
+ case NewChipID('A', 'I'):
+ case NewChipID('A', 'J'):
+ case NewChipID('A', 'K'):
+ case NewChipID('N', 'H'):
+ case NewChipID('N', 'I'):
+ case NewChipID('N', 'K'):
+ return ATI_CHIP_R350;
+
+ case NewChipID('A', 'P'):
+ case NewChipID('A', 'Q'):
+ case NewChipID('A', 'R'):
+ case NewChipID('A', 'S'):
+ case NewChipID('A', 'T'):
+ case NewChipID('A', 'U'):
+ case NewChipID('A', 'V'):
+ case NewChipID('N', 'P'):
+ case NewChipID('N', 'Q'):
+ case NewChipID('N', 'R'):
+ case NewChipID('N', 'S'):
+ case NewChipID('N', 'T'):
+ case NewChipID('N', 'V'):
+ return ATI_CHIP_RV350;
+
+ case NewChipID('N', 'J'):
+ return ATI_CHIP_R360;
+
+ case NewChipID('[', '\''):
+ case NewChipID('[', 'b'):
+ case NewChipID('[', 'c'):
+ case NewChipID('[', 'd'):
+ case NewChipID('[', 'e'):
+ case NewChipID('T', '\''):
+ case NewChipID('T', 'b'):
+ case NewChipID('T', 'd'):
+ return ATI_CHIP_RV370;
+
+ case NewChipID('>', 'P'):
+ case NewChipID('>', 'T'):
+ case NewChipID('1', 'P'):
+ case NewChipID('1', 'R'):
+ 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', 'O'):
+ case NewChipID('J', 'P'):
+ case NewChipID('J', 'T'):
+ return ATI_CHIP_R420;
+
+ case NewChipID('U', 'H'):
+ case NewChipID('U', 'I'):
+ case NewChipID('U', 'J'):
+ case NewChipID('U', 'K'):
+ case NewChipID('U', 'P'):
+ case NewChipID('U', 'Q'):
+ case NewChipID('U', 'R'):
+ case NewChipID('U', 'T'):
+ case NewChipID(']', 'W'):
+ /* those are m28, not 100% certain they are r423 could
+ be r480 but not r430 as their pci id names indicate... */
+ case NewChipID(']', 'H'):
+ case NewChipID(']', 'I'):
+ case NewChipID(']', 'J'):
+ return ATI_CHIP_R423;
+
+ case NewChipID('U', 'L'):
+ case NewChipID('U', 'M'):
+ case NewChipID('U', 'N'):
+ case NewChipID('U', 'O'):
+ return ATI_CHIP_R430;
+
+ case NewChipID(']', 'L'):
+ case NewChipID(']', 'M'):
+ case NewChipID(']', 'N'):
+ case NewChipID(']', 'O'):
+ case NewChipID(']', 'P'):
+ case NewChipID(']', 'R'):
+ return ATI_CHIP_R480;
+
+ case NewChipID('K', 'I'):
+ case NewChipID('K', 'J'):
+ case NewChipID('K', 'K'):
+ case NewChipID('K', 'L'):
+ return ATI_CHIP_R481;
+
+ case NewChipID('^', 'H'):
+ case NewChipID('^', 'J'):
+ case NewChipID('^', 'K'):
+ case NewChipID('^', 'L'):
+ case NewChipID('^', 'M'):
+ case NewChipID('^', 'O'):
+ case NewChipID('V', 'J'):
+ case NewChipID('V', 'K'):
+ case NewChipID('V', 'O'):
+ case NewChipID('V', 'R'):
+ case NewChipID('V', 'S'):
+ return ATI_CHIP_RV410;
+
+ case NewChipID('Z', 'A'):
+ case NewChipID('Z', 'B'):
+ case NewChipID('Z', 'a'):
+ case NewChipID('Z', 'b'):
+ case NewChipID('Y', 'T'):
+ case NewChipID('Y', 'U'):
+ case NewChipID('Y', 't'):
+ case NewChipID('Y', 'u'):
+ return ATI_CHIP_RS400;
+
+ case NewChipID('H', 'D'):
+ return ATI_CHIP_HDTV;
+
+ default:
+ /*
+ * 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_Radeon;
+ }
+}
diff --git a/src/ati.h b/src/ati.h
index fbb85213..48ab1cd3 100644
--- a/src/ati.h
+++ b/src/ati.h
@@ -33,4 +33,76 @@
extern DriverRec ATI;
+/*
+ * Chip-related definitions.
+ */
+typedef enum
+{
+ ATI_CHIP_NONE = 0,
+ ATI_CHIP_88800GXC, /* Mach64 */
+ ATI_CHIP_88800GXD, /* Mach64 */
+ ATI_CHIP_88800GXE, /* Mach64 */
+ ATI_CHIP_88800GXF, /* Mach64 */
+ ATI_CHIP_88800GX, /* Mach64 */
+ ATI_CHIP_88800CX, /* Mach64 */
+ ATI_CHIP_264CT, /* Mach64 */
+ ATI_CHIP_264ET, /* Mach64 */
+ ATI_CHIP_264VT, /* Mach64 */
+ ATI_CHIP_264GT, /* Mach64 */
+ ATI_CHIP_264VTB, /* Mach64 */
+ ATI_CHIP_264GTB, /* Mach64 */
+ ATI_CHIP_264VT3, /* Mach64 */
+ ATI_CHIP_264GTDVD, /* Mach64 */
+ ATI_CHIP_264LT, /* Mach64 */
+ ATI_CHIP_264VT4, /* Mach64 */
+ ATI_CHIP_264GT2C, /* Mach64 */
+ ATI_CHIP_264GTPRO, /* Mach64 */
+ ATI_CHIP_264LTPRO, /* Mach64 */
+ ATI_CHIP_264XL, /* Mach64 */
+ ATI_CHIP_MOBILITY, /* Mach64 */
+ ATI_CHIP_Mach64, /* Last among Mach64's */
+ ATI_CHIP_RAGE128GL, /* Rage128 */
+ ATI_CHIP_RAGE128VR, /* Rage128 */
+ ATI_CHIP_RAGE128PROGL, /* Rage128 */
+ ATI_CHIP_RAGE128PROVR, /* Rage128 */
+ ATI_CHIP_RAGE128PROULTRA, /* Rage128 */
+ ATI_CHIP_RAGE128MOBILITY3, /* Rage128 */
+ ATI_CHIP_RAGE128MOBILITY4, /* Rage128 */
+ ATI_CHIP_Rage128, /* Last among Rage128's */
+ ATI_CHIP_RADEON, /* Radeon */
+ ATI_CHIP_RADEONVE, /* Radeon VE */
+ ATI_CHIP_RADEONMOBILITY6, /* Radeon M6 */
+ ATI_CHIP_RS100, /* IGP320 */
+ ATI_CHIP_RS200, /* IGP340 */
+ ATI_CHIP_RS250, /* Radoen 7000 IGP */
+ ATI_CHIP_RV200, /* RV200 */
+ ATI_CHIP_RADEONMOBILITY7, /* Radeon M7 */
+ ATI_CHIP_R200, /* R200 */
+ ATI_CHIP_RV250, /* RV250 */
+ ATI_CHIP_RADEONMOBILITY9, /* Radeon M9 */
+ 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/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/M28? */
+ ATI_CHIP_R430, /* R430 */
+ ATI_CHIP_R480, /* R480/M28? */
+ ATI_CHIP_R481, /* R481 */
+ ATI_CHIP_RV410, /* RV410, M26 */
+ ATI_CHIP_RS400, /* RS400, RS410, RS480, RS482, ... */
+ ATI_CHIP_Radeon, /* Last among Radeon's */
+ ATI_CHIP_HDTV /* HDTV */
+} ATIChipType;
+
+extern const char *ATIChipNames[];
+
+extern ATIChipType ATIChipID(const CARD16, const CARD8);
+
#endif /* ___ATI_H___ */
diff --git a/src/atiadjust.c b/src/atiadjust.c
index f01fee69..267186f4 100644
--- a/src/atiadjust.c
+++ b/src/atiadjust.c
@@ -82,7 +82,7 @@ ATIAdjustPreInit
* displayed location in video memory. This is used to implement the virtual
* window.
*/
-_X_EXPORT void
+void
ATIAdjustFrame
(
int scrnIndex,
diff --git a/src/atichip.c b/src/atichip.c
index ddc7e0a7..5f8a2216 100644
--- a/src/atichip.c
+++ b/src/atichip.c
@@ -30,74 +30,6 @@
#include "atimach64io.h"
#include "ativersion.h"
-/*
- * Chip-related definitions.
- */
-const char *ATIChipNames[] =
-{
- "Unknown",
- "ATI 88800GX-C",
- "ATI 88800GX-D",
- "ATI 88800GX-E",
- "ATI 88800GX-F",
- "ATI 88800GX",
- "ATI 88800CX",
- "ATI 264CT",
- "ATI 264ET",
- "ATI 264VT",
- "ATI 3D Rage",
- "ATI 264VT-B",
- "ATI 3D Rage II",
- "ATI 264VT3",
- "ATI 3D Rage II+DVD",
- "ATI 3D Rage LT",
- "ATI 264VT4",
- "ATI 3D Rage IIc",
- "ATI 3D Rage Pro",
- "ATI 3D Rage LT Pro",
- "ATI 3D Rage XL or XC",
- "ATI 3D Rage Mobility",
- "ATI unknown Mach64",
- "ATI Rage 128 GL",
- "ATI Rage 128 VR",
- "ATI Rage 128 Pro GL",
- "ATI Rage 128 Pro VR",
- "ATI Rage 128 Pro ULTRA",
- "ATI Rage 128 Mobility M3",
- "ATI Rage 128 Mobility M4",
- "ATI unknown Rage 128"
- "ATI Radeon 7200",
- "ATI Radeon 7000 (VE)",
- "ATI Radeon Mobility M6",
- "ATI Radeon IGP320",
- "ATI Radeon IGP330/340/350",
- "ATI Radeon 7000 IGP",
- "ATI Radeon 7500",
- "ATI Radeon Mobility M7",
- "ATI Radeon 8500/9100",
- "ATI Radeon 9000",
- "ATI Radeon Mobility M9",
- "ATI Radeon 9100 IGP",
- "ATI Radeon 9200 IGP",
- "ATI Radeon 9200",
- "ATI Radeon Mobility M9+",
- "ATI Radeon 9700/9500",
- "ATI Radeon 9600/9550",
- "ATI Radeon 9800",
- "ATI Radeon 9800XT",
- "ATI Radeon X300/X550/M22",
- "ATI Radeon X600/X550/M24",
- "ATI Radeon X800/M18 AGP",
- "ATI Radeon X800/M28 PCIE",
- "ATI Radeon X800XL PCIE",
- "ATI Radeon X850 PCIE",
- "ATI Radeon X850 AGP",
- "ATI Radeon X700",
- "ATI Xpress 200"
- "ATI unknown Radeon",
- "ATI Rage HDTV"
-};
-
const char *ATIFoundryNames[] =
{ "SGS", "NEC", "KCS", "UMC", "TSMC", "5", "6", "UMC" };
@@ -115,18 +47,18 @@ ATIMach64ChipID
)
{
pATI->config_chip_id = inr(CONFIG_CHIP_ID);
- pATI->ChipType = GetBits(pATI->config_chip_id, 0xFFFFU);
+ pATI->ChipType = GetBits(pATI->config_chip_id, CFG_CHIP_TYPE);
pATI->ChipClass = GetBits(pATI->config_chip_id, CFG_CHIP_CLASS);
- pATI->ChipRevision = GetBits(pATI->config_chip_id, CFG_CHIP_REV);
+ pATI->ChipRev = GetBits(pATI->config_chip_id, CFG_CHIP_REV);
pATI->ChipVersion = GetBits(pATI->config_chip_id, CFG_CHIP_VERSION);
pATI->ChipFoundry = GetBits(pATI->config_chip_id, CFG_CHIP_FOUNDRY);
- pATI->ChipRev = pATI->ChipRevision;
+ pATI->ChipRevision = GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
switch (pATI->ChipType)
{
case OldChipID('G', 'X'):
pATI->ChipType = OldToNewChipID(pATI->ChipType);
case NewChipID('G', 'X'):
- switch (pATI->ChipRevision)
+ switch (pATI->ChipRev)
{
case 0x00U:
pATI->Chip = ATI_CHIP_88800GXC;
@@ -159,8 +91,6 @@ ATIMach64ChipID
case OldChipID('C', 'T'):
pATI->ChipType = OldToNewChipID(pATI->ChipType);
case NewChipID('C', 'T'):
- pATI->ChipRevision =
- GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
pATI->Chip = ATI_CHIP_264CT;
pATI->BusType = ATI_BUS_PCI;
break;
@@ -168,8 +98,6 @@ ATIMach64ChipID
case OldChipID('E', 'T'):
pATI->ChipType = OldToNewChipID(pATI->ChipType);
case NewChipID('E', 'T'):
- pATI->ChipRevision =
- GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
pATI->Chip = ATI_CHIP_264ET;
pATI->BusType = ATI_BUS_PCI;
break;
@@ -177,8 +105,6 @@ ATIMach64ChipID
case OldChipID('V', 'T'):
pATI->ChipType = OldToNewChipID(pATI->ChipType);
case NewChipID('V', 'T'):
- pATI->ChipRevision =
- GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
pATI->Chip = ATI_CHIP_264VT;
pATI->BusType = ATI_BUS_PCI;
/* Some early GT's are detected as VT's */
@@ -199,8 +125,6 @@ ATIMach64ChipID
case OldChipID('G', 'T'):
pATI->ChipType = OldToNewChipID(pATI->ChipType);
case NewChipID('G', 'T'):
- pATI->ChipRevision =
- GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
pATI->BusType = ATI_BUS_PCI;
if (!pATI->ChipVersion)
pATI->Chip = ATI_CHIP_264GT;
@@ -211,8 +135,6 @@ ATIMach64ChipID
case OldChipID('V', 'U'):
pATI->ChipType = OldToNewChipID(pATI->ChipType);
case NewChipID('V', 'U'):
- pATI->ChipRevision =
- GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
pATI->Chip = ATI_CHIP_264VT3;
pATI->BusType = ATI_BUS_PCI;
break;
@@ -220,8 +142,6 @@ ATIMach64ChipID
case OldChipID('G', 'U'):
pATI->ChipType = OldToNewChipID(pATI->ChipType);
case NewChipID('G', 'U'):
- pATI->ChipRevision =
- GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
pATI->Chip = ATI_CHIP_264GTDVD;
pATI->BusType = ATI_BUS_PCI;
break;
@@ -229,8 +149,6 @@ ATIMach64ChipID
case OldChipID('L', 'G'):
pATI->ChipType = OldToNewChipID(pATI->ChipType);
case NewChipID('L', 'G'):
- pATI->ChipRevision =
- GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
pATI->Chip = ATI_CHIP_264LT;
pATI->BusType = ATI_BUS_PCI;
break;
@@ -238,8 +156,6 @@ ATIMach64ChipID
case OldChipID('V', 'V'):
pATI->ChipType = OldToNewChipID(pATI->ChipType);
case NewChipID('V', 'V'):
- pATI->ChipRevision =
- GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
pATI->Chip = ATI_CHIP_264VT4;
pATI->BusType = ATI_BUS_PCI;
break;
@@ -249,8 +165,6 @@ ATIMach64ChipID
pATI->ChipType = OldToNewChipID(pATI->ChipType);
case NewChipID('G', 'V'):
case NewChipID('G', 'Y'):
- pATI->ChipRevision =
- GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
pATI->Chip = ATI_CHIP_264GT2C;
pATI->BusType = ATI_BUS_PCI;
break;
@@ -260,8 +174,6 @@ ATIMach64ChipID
pATI->ChipType = OldToNewChipID(pATI->ChipType);
case NewChipID('G', 'W'):
case NewChipID('G', 'Z'):
- pATI->ChipRevision =
- GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
pATI->Chip = ATI_CHIP_264GT2C;
pATI->BusType = ATI_BUS_AGP;
break;
@@ -273,8 +185,6 @@ ATIMach64ChipID
case NewChipID('G', 'I'):
case NewChipID('G', 'P'):
case NewChipID('G', 'Q'):
- pATI->ChipRevision =
- GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
pATI->Chip = ATI_CHIP_264GTPRO;
pATI->BusType = ATI_BUS_PCI;
break;
@@ -284,8 +194,6 @@ ATIMach64ChipID
pATI->ChipType = OldToNewChipID(pATI->ChipType);
case NewChipID('G', 'B'):
case NewChipID('G', 'D'):
- pATI->ChipRevision =
- GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
pATI->Chip = ATI_CHIP_264GTPRO;
pATI->BusType = ATI_BUS_AGP;
break;
@@ -297,8 +205,6 @@ ATIMach64ChipID
case NewChipID('L', 'I'):
case NewChipID('L', 'P'):
case NewChipID('L', 'Q'):
- pATI->ChipRevision =
- GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
pATI->Chip = ATI_CHIP_264LTPRO;
pATI->BusType = ATI_BUS_PCI;
pATI->LCDVBlendFIFOSize = 800;
@@ -309,8 +215,6 @@ ATIMach64ChipID
pATI->ChipType = OldToNewChipID(pATI->ChipType);
case NewChipID('L', 'B'):
case NewChipID('L', 'D'):
- pATI->ChipRevision =
- GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
pATI->Chip = ATI_CHIP_264LTPRO;
pATI->BusType = ATI_BUS_AGP;
pATI->LCDVBlendFIFOSize = 800;
@@ -325,8 +229,6 @@ ATIMach64ChipID
case NewChipID('G', 'O'):
case NewChipID('G', 'R'):
case NewChipID('G', 'S'):
- pATI->ChipRevision =
- GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
pATI->Chip = ATI_CHIP_264XL;
pATI->BusType = ATI_BUS_PCI;
pATI->LCDVBlendFIFOSize = 1024;
@@ -337,8 +239,6 @@ ATIMach64ChipID
pATI->ChipType = OldToNewChipID(pATI->ChipType);
case NewChipID('G', 'M'):
case NewChipID('G', 'N'):
- pATI->ChipRevision =
- GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
pATI->Chip = ATI_CHIP_264XL;
pATI->BusType = ATI_BUS_AGP;
pATI->LCDVBlendFIFOSize = 1024;
@@ -349,8 +249,6 @@ ATIMach64ChipID
pATI->ChipType = OldToNewChipID(pATI->ChipType);
case NewChipID('L', 'R'):
case NewChipID('L', 'S'):
- pATI->ChipRevision =
- GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
pATI->Chip = ATI_CHIP_MOBILITY;
pATI->BusType = ATI_BUS_PCI;
pATI->LCDVBlendFIFOSize = 1024;
@@ -361,8 +259,6 @@ ATIMach64ChipID
pATI->ChipType = OldToNewChipID(pATI->ChipType);
case NewChipID('L', 'M'):
case NewChipID('L', 'N'):
- pATI->ChipRevision =
- GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
pATI->Chip = ATI_CHIP_MOBILITY;
pATI->BusType = ATI_BUS_AGP;
pATI->LCDVBlendFIFOSize = 1024;
@@ -373,399 +269,3 @@ ATIMach64ChipID
break;
}
}
-
-/*
- * ATIChipID --
- *
- * This returns the ATI_CHIP_* value (generally) associated with a particular
- * ChipID/ChipRev combination.
- */
-ATIChipType
-ATIChipID
-(
- const CARD16 ChipID,
- const CARD8 ChipRev
-)
-{
- switch (ChipID)
- {
- case OldChipID('G', 'X'): case NewChipID('G', 'X'):
- switch (ChipRev)
- {
- case 0x00U:
- return ATI_CHIP_88800GXC;
-
- case 0x01U:
- return ATI_CHIP_88800GXD;
-
- case 0x02U:
- return ATI_CHIP_88800GXE;
-
- case 0x03U:
- return ATI_CHIP_88800GXF;
-
- default:
- return ATI_CHIP_88800GX;
- }
-
- case OldChipID('C', 'X'): case NewChipID('C', 'X'):
- return ATI_CHIP_88800CX;
-
- case OldChipID('C', 'T'): case NewChipID('C', 'T'):
- return ATI_CHIP_264CT;
-
- case OldChipID('E', 'T'): case NewChipID('E', 'T'):
- return ATI_CHIP_264ET;
-
- case OldChipID('V', 'T'): case NewChipID('V', 'T'):
- /* For simplicity, ignore ChipID discrepancy that can occur here */
- if (!(ChipRev & GetBits(CFG_CHIP_VERSION, CFG_CHIP_REV)))
- return ATI_CHIP_264VT;
- return ATI_CHIP_264VTB;
-
- case OldChipID('G', 'T'): case NewChipID('G', 'T'):
- if (!(ChipRev & GetBits(CFG_CHIP_VERSION, CFG_CHIP_REV)))
- return ATI_CHIP_264GT;
- return ATI_CHIP_264GTB;
-
- case OldChipID('V', 'U'): case NewChipID('V', 'U'):
- return ATI_CHIP_264VT3;
-
- case OldChipID('G', 'U'): case NewChipID('G', 'U'):
- return ATI_CHIP_264GTDVD;
-
- case OldChipID('L', 'G'): case NewChipID('L', 'G'):
- return ATI_CHIP_264LT;
-
- case OldChipID('V', 'V'): case NewChipID('V', 'V'):
- return ATI_CHIP_264VT4;
-
- case OldChipID('G', 'V'): case NewChipID('G', 'V'):
- case OldChipID('G', 'W'): case NewChipID('G', 'W'):
- case OldChipID('G', 'Y'): case NewChipID('G', 'Y'):
- case OldChipID('G', 'Z'): case NewChipID('G', 'Z'):
- return ATI_CHIP_264GT2C;
-
- case OldChipID('G', 'B'): case NewChipID('G', 'B'):
- case OldChipID('G', 'D'): case NewChipID('G', 'D'):
- case OldChipID('G', 'I'): case NewChipID('G', 'I'):
- case OldChipID('G', 'P'): case NewChipID('G', 'P'):
- case OldChipID('G', 'Q'): case NewChipID('G', 'Q'):
- return ATI_CHIP_264GTPRO;
-
- case OldChipID('L', 'B'): case NewChipID('L', 'B'):
- case OldChipID('L', 'D'): case NewChipID('L', 'D'):
- case OldChipID('L', 'I'): case NewChipID('L', 'I'):
- case OldChipID('L', 'P'): case NewChipID('L', 'P'):
- case OldChipID('L', 'Q'): case NewChipID('L', 'Q'):
- return ATI_CHIP_264LTPRO;
-
- case OldChipID('G', 'L'): case NewChipID('G', 'L'):
- case OldChipID('G', 'M'): case NewChipID('G', 'M'):
- case OldChipID('G', 'N'): case NewChipID('G', 'N'):
- case OldChipID('G', 'O'): case NewChipID('G', 'O'):
- case OldChipID('G', 'R'): case NewChipID('G', 'R'):
- case OldChipID('G', 'S'): case NewChipID('G', 'S'):
- return ATI_CHIP_264XL;
-
- case OldChipID('L', 'M'): case NewChipID('L', 'M'):
- case OldChipID('L', 'N'): case NewChipID('L', 'N'):
- case OldChipID('L', 'R'): case NewChipID('L', 'R'):
- case OldChipID('L', 'S'): case NewChipID('L', 'S'):
- return ATI_CHIP_MOBILITY;
-
- case NewChipID('R', 'E'):
- case NewChipID('R', 'F'):
- case NewChipID('R', 'G'):
- case NewChipID('S', 'K'):
- case NewChipID('S', 'L'):
- case NewChipID('S', 'M'):
- /* "SN" is listed as ATI_CHIP_RAGE128_4X in ATI docs */
- case NewChipID('S', 'N'):
- return ATI_CHIP_RAGE128GL;
-
- case NewChipID('R', 'K'):
- case NewChipID('R', 'L'):
- /*
- * ATI documentation lists SE/SF/SG under both ATI_CHIP_RAGE128VR
- * and ATI_CHIP_RAGE128_4X, and lists SH/SK/SL under Rage 128 4X only.
- * I'm stuffing them here for now until this can be clarified as ATI
- * documentation doesn't mention their details. <mharris@redhat.com>
- */
- case NewChipID('S', 'E'):
- case NewChipID('S', 'F'):
- case NewChipID('S', 'G'):
- case NewChipID('S', 'H'):
- return ATI_CHIP_RAGE128VR;
-
- /* case NewChipID('S', 'H'): */
- /* case NewChipID('S', 'K'): */
- /* case NewChipID('S', 'L'): */
- /* case NewChipID('S', 'N'): */
- /* return ATI_CHIP_RAGE128_4X; */
-
- case NewChipID('P', 'A'):
- case NewChipID('P', 'B'):
- case NewChipID('P', 'C'):
- case NewChipID('P', 'D'):
- case NewChipID('P', 'E'):
- case NewChipID('P', 'F'):
- return ATI_CHIP_RAGE128PROGL;
-
- case NewChipID('P', 'G'):
- case NewChipID('P', 'H'):
- case NewChipID('P', 'I'):
- case NewChipID('P', 'J'):
- case NewChipID('P', 'K'):
- case NewChipID('P', 'L'):
- case NewChipID('P', 'M'):
- case NewChipID('P', 'N'):
- case NewChipID('P', 'O'):
- case NewChipID('P', 'P'):
- case NewChipID('P', 'Q'):
- case NewChipID('P', 'R'):
- case NewChipID('P', 'S'):
- case NewChipID('P', 'T'):
- case NewChipID('P', 'U'):
- case NewChipID('P', 'V'):
- case NewChipID('P', 'W'):
- case NewChipID('P', 'X'):
- return ATI_CHIP_RAGE128PROVR;
-
- case NewChipID('T', 'F'):
- case NewChipID('T', 'L'):
- case NewChipID('T', 'R'):
- case NewChipID('T', 'S'):
- case NewChipID('T', 'T'):
- case NewChipID('T', 'U'):
- return ATI_CHIP_RAGE128PROULTRA;
-
- case NewChipID('L', 'E'):
- case NewChipID('L', 'F'):
- /*
- * "LK" and "LL" are not in any ATI documentation I can find
- * - mharris
- */
- case NewChipID('L', 'K'):
- case NewChipID('L', 'L'):
- return ATI_CHIP_RAGE128MOBILITY3;
-
- case NewChipID('M', 'F'):
- case NewChipID('M', 'L'):
- return ATI_CHIP_RAGE128MOBILITY4;
-
- case NewChipID('Q', 'D'):
- case NewChipID('Q', 'E'):
- case NewChipID('Q', 'F'):
- case NewChipID('Q', 'G'):
- return ATI_CHIP_RADEON;
-
- case NewChipID('Q', 'Y'):
- case NewChipID('Q', 'Z'):
- case NewChipID('Q', '^'):
- return ATI_CHIP_RADEONVE;
-
- case NewChipID('L', 'Y'):
- case NewChipID('L', 'Z'):
- return ATI_CHIP_RADEONMOBILITY6;
-
- case NewChipID('A', '6'):
- case NewChipID('C', '6'):
- return ATI_CHIP_RS100;
-
- case NewChipID('A', '7'):
- case NewChipID('C', '7'):
- return ATI_CHIP_RS200;
-
- case NewChipID('D', '7'):
- case NewChipID('B', '7'):
- return ATI_CHIP_RS250;
-
- case NewChipID('L', 'W'):
- case NewChipID('L', 'X'):
- return ATI_CHIP_RADEONMOBILITY7;
-
- case NewChipID('Q', 'H'):
- case NewChipID('Q', 'I'):
- case NewChipID('Q', 'J'):
- case NewChipID('Q', 'K'):
- case NewChipID('Q', 'L'):
- case NewChipID('Q', 'M'):
- case NewChipID('Q', 'N'):
- case NewChipID('Q', 'O'):
- case NewChipID('Q', 'h'):
- case NewChipID('Q', 'i'):
- case NewChipID('Q', 'j'):
- case NewChipID('Q', 'k'):
- case NewChipID('Q', 'l'):
- case NewChipID('B', 'B'):
- return ATI_CHIP_R200;
-
- case NewChipID('Q', 'W'):
- case NewChipID('Q', 'X'):
- return ATI_CHIP_RV200;
-
- case NewChipID('I', 'f'):
- case NewChipID('I', 'g'):
- return ATI_CHIP_RV250;
-
- case NewChipID('L', 'd'):
- case NewChipID('L', 'f'):
- case NewChipID('L', 'g'):
- return ATI_CHIP_RADEONMOBILITY9;
-
- case NewChipID('X', '4'):
- 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'):
- case NewChipID('Y', 'd'):
- case NewChipID('Y', 'e'):
- return ATI_CHIP_RV280;
-
- case NewChipID('\\', 'a'):
- case NewChipID('\\', 'c'):
- return ATI_CHIP_RADEONMOBILITY9PLUS;
-
- case NewChipID('A', 'D'):
- case NewChipID('A', 'E'):
- case NewChipID('A', 'F'):
- case NewChipID('A', 'G'):
- case NewChipID('N', 'D'):
- case NewChipID('N', 'E'):
- case NewChipID('N', 'F'):
- case NewChipID('N', 'G'):
- return ATI_CHIP_R300;
-
- case NewChipID('A', 'H'):
- case NewChipID('A', 'I'):
- case NewChipID('A', 'J'):
- case NewChipID('A', 'K'):
- case NewChipID('N', 'H'):
- case NewChipID('N', 'I'):
- case NewChipID('N', 'K'):
- return ATI_CHIP_R350;
-
- case NewChipID('A', 'P'):
- case NewChipID('A', 'Q'):
- case NewChipID('A', 'R'):
- case NewChipID('A', 'S'):
- case NewChipID('A', 'T'):
- case NewChipID('A', 'U'):
- case NewChipID('A', 'V'):
- case NewChipID('N', 'P'):
- case NewChipID('N', 'Q'):
- case NewChipID('N', 'R'):
- case NewChipID('N', 'S'):
- case NewChipID('N', 'T'):
- case NewChipID('N', 'V'):
- return ATI_CHIP_RV350;
-
- case NewChipID('N', 'J'):
- return ATI_CHIP_R360;
-
- case NewChipID('[', '\''):
- case NewChipID('[', 'b'):
- case NewChipID('[', 'c'):
- case NewChipID('[', 'd'):
- case NewChipID('[', 'e'):
- case NewChipID('T', '\''):
- case NewChipID('T', 'b'):
- case NewChipID('T', 'd'):
- return ATI_CHIP_RV370;
-
- case NewChipID('>', 'P'):
- case NewChipID('>', 'T'):
- case NewChipID('1', 'P'):
- case NewChipID('1', 'R'):
- 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', 'O'):
- case NewChipID('J', 'P'):
- case NewChipID('J', 'T'):
- return ATI_CHIP_R420;
-
- case NewChipID('U', 'H'):
- case NewChipID('U', 'I'):
- case NewChipID('U', 'J'):
- case NewChipID('U', 'K'):
- case NewChipID('U', 'P'):
- case NewChipID('U', 'Q'):
- case NewChipID('U', 'R'):
- case NewChipID('U', 'T'):
- case NewChipID(']', 'W'):
- /* those are m28, not 100% certain they are r423 could
- be r480 but not r430 as their pci id names indicate... */
- case NewChipID(']', 'H'):
- case NewChipID(']', 'I'):
- case NewChipID(']', 'J'):
- return ATI_CHIP_R423;
-
- case NewChipID('U', 'L'):
- case NewChipID('U', 'M'):
- case NewChipID('U', 'N'):
- case NewChipID('U', 'O'):
- return ATI_CHIP_R430;
-
- case NewChipID(']', 'L'):
- case NewChipID(']', 'M'):
- case NewChipID(']', 'N'):
- case NewChipID(']', 'O'):
- case NewChipID(']', 'P'):
- case NewChipID(']', 'R'):
- return ATI_CHIP_R480;
-
- case NewChipID('K', 'I'):
- case NewChipID('K', 'J'):
- case NewChipID('K', 'K'):
- case NewChipID('K', 'L'):
- return ATI_CHIP_R481;
-
- case NewChipID('^', 'H'):
- case NewChipID('^', 'J'):
- case NewChipID('^', 'K'):
- case NewChipID('^', 'L'):
- case NewChipID('^', 'M'):
- case NewChipID('^', 'O'):
- case NewChipID('V', 'J'):
- case NewChipID('V', 'K'):
- case NewChipID('V', 'O'):
- case NewChipID('V', 'R'):
- case NewChipID('V', 'S'):
- return ATI_CHIP_RV410;
-
- case NewChipID('Z', 'A'):
- case NewChipID('Z', 'B'):
- case NewChipID('Z', 'a'):
- case NewChipID('Z', 'b'):
- case NewChipID('Y', 'T'):
- case NewChipID('Y', 'U'):
- case NewChipID('Y', 't'):
- case NewChipID('Y', 'u'):
- return ATI_CHIP_RS400;
-
- case NewChipID('H', 'D'):
- return ATI_CHIP_HDTV;
-
- default:
- /*
- * 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_Radeon;
- }
-}
diff --git a/src/atichip.h b/src/atichip.h
index 733c7b1f..44cd1888 100644
--- a/src/atichip.h
+++ b/src/atichip.h
@@ -29,76 +29,6 @@
#include <X11/Xmd.h>
/*
- * Chip-related definitions.
- */
-typedef enum
-{
- ATI_CHIP_NONE = 0,
- ATI_CHIP_88800GXC, /* Mach64 */
- ATI_CHIP_88800GXD, /* Mach64 */
- ATI_CHIP_88800GXE, /* Mach64 */
- ATI_CHIP_88800GXF, /* Mach64 */
- ATI_CHIP_88800GX, /* Mach64 */
- ATI_CHIP_88800CX, /* Mach64 */
- ATI_CHIP_264CT, /* Mach64 */
- ATI_CHIP_264ET, /* Mach64 */
- ATI_CHIP_264VT, /* Mach64 */
- ATI_CHIP_264GT, /* Mach64 */
- ATI_CHIP_264VTB, /* Mach64 */
- ATI_CHIP_264GTB, /* Mach64 */
- ATI_CHIP_264VT3, /* Mach64 */
- ATI_CHIP_264GTDVD, /* Mach64 */
- ATI_CHIP_264LT, /* Mach64 */
- ATI_CHIP_264VT4, /* Mach64 */
- ATI_CHIP_264GT2C, /* Mach64 */
- ATI_CHIP_264GTPRO, /* Mach64 */
- ATI_CHIP_264LTPRO, /* Mach64 */
- ATI_CHIP_264XL, /* Mach64 */
- ATI_CHIP_MOBILITY, /* Mach64 */
- ATI_CHIP_Mach64, /* Last among Mach64's */
- ATI_CHIP_RAGE128GL, /* Rage128 */
- ATI_CHIP_RAGE128VR, /* Rage128 */
- ATI_CHIP_RAGE128PROGL, /* Rage128 */
- ATI_CHIP_RAGE128PROVR, /* Rage128 */
- ATI_CHIP_RAGE128PROULTRA, /* Rage128 */
- ATI_CHIP_RAGE128MOBILITY3, /* Rage128 */
- ATI_CHIP_RAGE128MOBILITY4, /* Rage128 */
- ATI_CHIP_Rage128, /* Last among Rage128's */
- ATI_CHIP_RADEON, /* Radeon */
- ATI_CHIP_RADEONVE, /* Radeon VE */
- ATI_CHIP_RADEONMOBILITY6, /* Radeon M6 */
- ATI_CHIP_RS100, /* IGP320 */
- ATI_CHIP_RS200, /* IGP340 */
- ATI_CHIP_RS250, /* Radoen 7000 IGP */
- ATI_CHIP_RV200, /* RV200 */
- ATI_CHIP_RADEONMOBILITY7, /* Radeon M7 */
- ATI_CHIP_R200, /* R200 */
- ATI_CHIP_RV250, /* RV250 */
- ATI_CHIP_RADEONMOBILITY9, /* Radeon M9 */
- 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/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/M28? */
- ATI_CHIP_R430, /* R430 */
- ATI_CHIP_R480, /* R480/M28? */
- ATI_CHIP_R481, /* R481 */
- ATI_CHIP_RV410, /* RV410, M26 */
- ATI_CHIP_RS400, /* RS400, RS410, RS480, RS482, ... */
- ATI_CHIP_Radeon, /* Last among Radeon's */
- ATI_CHIP_HDTV /* HDTV */
-} ATIChipType;
-
-extern const char *ATIChipNames[];
-
-/*
* Foundry codes for 264xT's.
*/
typedef enum
@@ -116,7 +46,6 @@ typedef enum
extern const char *ATIFoundryNames[];
extern void ATIMach64ChipID(ATIPtr, const CARD16);
-extern ATIChipType ATIChipID(const CARD16, const CARD8);
#define OldChipID(_1, _0) \
(SetBits(_0 - 'A', CHIP_CODE_0) | SetBits(_1 - 'A', CHIP_CODE_1))
diff --git a/src/aticonfig.c b/src/aticonfig.c
index a4ceddfc..1e119e00 100644
--- a/src/aticonfig.c
+++ b/src/aticonfig.c
@@ -234,7 +234,7 @@ static const OptionInfoRec ATIPublicOptions[] =
static const unsigned long ATIPublicOptionSize = SizeOf(ATIPublicOptions);
-_X_EXPORT const OptionInfoRec *
+const OptionInfoRec *
ATIOptionsWeak(void) { return ATIPublicOptions; }
/*
diff --git a/src/aticonsole.c b/src/aticonsole.c
index 6d0c662a..bd5ec9c5 100644
--- a/src/aticonsole.c
+++ b/src/aticonsole.c
@@ -628,7 +628,7 @@ ATILeaveGraphics
*
* This function switches to another graphics video state.
*/
-_X_EXPORT Bool
+Bool
ATISwitchMode
(
int iScreen,
@@ -681,7 +681,7 @@ ATISwitchMode
*
* This function sets the server's virtual console to a graphics video state.
*/
-_X_EXPORT Bool
+Bool
ATIEnterVT
(
int iScreen,
@@ -751,7 +751,7 @@ ATIEnterVT
* This function restores the server's virtual console to its state on server
* entry.
*/
-_X_EXPORT void
+void
ATILeaveVT
(
int iScreen,
@@ -780,7 +780,7 @@ ATILeaveVT
*
* This function frees all driver data related to a screen.
*/
-_X_EXPORT void
+void
ATIFreeScreen
(
int iScreen,
diff --git a/src/atidri.c b/src/atidri.c
index d017040c..bc862a89 100644
--- a/src/atidri.c
+++ b/src/atidri.c
@@ -1194,13 +1194,13 @@ Bool ATIDRIScreenInit( ScreenPtr pScreen )
/* Check the DRI version */
DRIQueryVersion( &major, &minor, &patch );
- if ( major != DRIINFO_MAJOR_VERSION || minor < DRIINFO_MINOR_VERSION ) {
+ if ( major != DRIINFO_MAJOR_VERSION || minor < 0 ) {
xf86DrvMsg( pScreen->myNum, X_ERROR,
"[dri] ATIDRIScreenInit failed because of a version mismatch.\n"
"[dri] libdri version is %d.%d.%d but version %d.%d.x is needed.\n"
"[dri] Disabling the DRI.\n",
major, minor, patch,
- DRIINFO_MAJOR_VERSION, DRIINFO_MINOR_VERSION );
+ DRIINFO_MAJOR_VERSION, 0 );
return FALSE;
}
@@ -1266,9 +1266,10 @@ Bool ATIDRIScreenInit( ScreenPtr pScreen )
ErrorF( "[dri] Data does not fit in SAREA\n" );
return FALSE;
}
- xf86DrvMsg( pScreenInfo->scrnIndex, X_INFO, "[drm] SAREA %d+%d: %d\n",
- sizeof(XF86DRISAREARec), sizeof(ATISAREAPrivRec),
- sizeof(XF86DRISAREARec) + sizeof(ATISAREAPrivRec) );
+ xf86DrvMsg( pScreenInfo->scrnIndex, X_INFO, "[drm] SAREA %u+%u: %u\n",
+ (unsigned)sizeof(XF86DRISAREARec),
+ (unsigned)sizeof(ATISAREAPrivRec),
+ (unsigned)(sizeof(XF86DRISAREARec) + sizeof(ATISAREAPrivRec)) );
pDRIInfo->SAREASize = SAREA_MAX;
pATIDRI = (ATIDRIPtr) xnfcalloc( sizeof(ATIDRIRec), 1 );
diff --git a/src/atifillin.c b/src/atifillin.c
deleted file mode 100644
index dcbcb3c8..00000000
--- a/src/atifillin.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright 2004 Adam Jackson.
- *
- * 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, sub
- * license, 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
- * THE AUTHORS 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.
- */
-
-/*
- * atifillin.c: fill in a ScrnInfoPtr with the relevant information for
- * atimisc.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "atifillin.h"
-
-_X_EXPORT void ATIFillInScreenInfo(ScrnInfoPtr pScreenInfo)
-{
- pScreenInfo->driverVersion = ATI_VERSION_CURRENT;
- pScreenInfo->driverName = ATI_DRIVER_NAME;
- pScreenInfo->name = ATI_NAME;
- pScreenInfo->PreInit = ATIPreInit;
- pScreenInfo->ScreenInit = ATIScreenInit;
- pScreenInfo->SwitchMode = ATISwitchMode;
- pScreenInfo->AdjustFrame = ATIAdjustFrame;
- pScreenInfo->EnterVT = ATIEnterVT;
- pScreenInfo->LeaveVT = ATILeaveVT;
- pScreenInfo->FreeScreen = ATIFreeScreen;
- pScreenInfo->ValidMode = ATIValidMode;
-}
diff --git a/src/atifillin.h b/src/atifillin.h
deleted file mode 100644
index 7d5e54da..00000000
--- a/src/atifillin.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright 2004 Adam Jackson.
- *
- * 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, sub
- * license, 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
- * THE AUTHORS 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.
- */
-
-/*
- * atifillin.h: header for atifillin.c.
- */
-
-#ifndef ATI_FILLIN_H
-#define ATI_FILLIN_H
-
-/* include headers corresponding to fields touched by ATIFillInScreenInfo() */
-
-#include "ativersion.h"
-#include "atipreinit.h"
-#include "atiscreen.h"
-#include "aticonsole.h"
-#include "atiadjust.h"
-#include "ativalid.h"
-
-extern void ATIFillInScreenInfo(ScrnInfoPtr);
-
-#endif
diff --git a/src/atimach64probe.c b/src/atimach64probe.c
index 47340a56..c5330cc7 100644
--- a/src/atimach64probe.c
+++ b/src/atimach64probe.c
@@ -26,14 +26,19 @@
#include "ati.h"
#include "atichip.h"
-#include "atifillin.h"
-#include "atimodule.h"
#include "atimach64io.h"
#include "atimach64probe.h"
#include "atioption.h"
#include "ativersion.h"
-static SymTabRec
+/* include headers corresponding to ScrnInfoPtr fields */
+#include "atipreinit.h"
+#include "atiscreen.h"
+#include "aticonsole.h"
+#include "atiadjust.h"
+#include "ativalid.h"
+
+SymTabRec
Mach64Chipsets[] = {
{ATI_CHIP_88800GXC, "ATI 88800GX-C"},
{ATI_CHIP_88800GXD, "ATI 88800GX-D"},
@@ -101,7 +106,7 @@ Mach64PciChipsets[] = {
{-1, -1, RES_UNDEFINED}
};
-const OptionInfoRec *
+_X_EXPORT const OptionInfoRec *
Mach64AvailableOptions(int chipid, int busid)
{
/*
@@ -112,24 +117,39 @@ Mach64AvailableOptions(int chipid, int busid)
}
/*
+ * Mach64Identify --
+ *
+ * Print the driver's list of chipset names.
+ */
+_X_EXPORT void
+Mach64Identify
+(
+ int flags
+)
+{
+ xf86Msg(X_INFO, "%s: %s\n", ATI_NAME,
+ "Driver for ATI Mach64 chipsets");
+}
+
+/*
* Mach64Probe --
*
* This function is called once, at the start of the first server generation to
* do a minimal probe for supported hardware.
*/
-Bool
+_X_EXPORT Bool
Mach64Probe(DriverPtr pDriver, int flags)
{
- GDevPtr *devSections;
- int *usedChips;
- int numDevSections;
- int numUsed;
- Bool ProbeSuccess = FALSE;
+ GDevPtr *devSections;
+ int *usedChips;
+ int numDevSections;
+ int numUsed;
+ Bool ProbeSuccess = FALSE;
- if ((numDevSections = xf86MatchDevice(ATI_DRIVER_NAME, &devSections)) <= 0)
+ if (xf86GetPciVideoInfo() == NULL)
return FALSE;
- if (xf86GetPciVideoInfo() == NULL)
+ if ((numDevSections = xf86MatchDevice(ATI_DRIVER_NAME, &devSections)) <= 0)
return FALSE;
numUsed = xf86MatchPciInstances(ATI_DRIVER_NAME, PCI_VENDOR_ATI,
@@ -148,8 +168,6 @@ Mach64Probe(DriverPtr pDriver, int flags)
for (i = 0; i < numUsed; i++) {
ScrnInfoPtr pScrn;
- EntityInfoPtr pEnt;
- pciVideoPtr pVideo;
pScrn = xf86ConfigPciEntity(NULL, 0, usedChips[i], Mach64PciChipsets,
0, 0, 0, 0, NULL);
@@ -157,30 +175,24 @@ Mach64Probe(DriverPtr pDriver, int flags)
if (!pScrn)
continue;
- pEnt = xf86GetEntityInfo(usedChips[i]);
- pVideo = xf86GetPciInfoForEntity(usedChips[i]);
-
-#ifdef XFree86LOADER
-
- if (!xf86LoadSubModule(pScrn, "atimisc"))
- {
- xf86Msg(X_ERROR,
- ATI_NAME ": Failed to load \"atimisc\" module.\n");
- xf86DeleteScreen(pScrn->scrnIndex, 0);
- continue;
- }
-
- xf86LoaderReqSymLists(ATISymbols, NULL);
-
-#endif
-
- ATIFillInScreenInfo(pScrn);
-
- pScrn->Probe = Mach64Probe;
+ pScrn->driverVersion = ATI_VERSION_CURRENT;
+ pScrn->driverName = ATI_DRIVER_NAME;
+ pScrn->name = ATI_NAME;
+ pScrn->Probe = Mach64Probe;
+ pScrn->PreInit = ATIPreInit;
+ pScrn->ScreenInit = ATIScreenInit;
+ pScrn->SwitchMode = ATISwitchMode;
+ pScrn->AdjustFrame = ATIAdjustFrame;
+ pScrn->EnterVT = ATIEnterVT;
+ pScrn->LeaveVT = ATILeaveVT;
+ pScrn->FreeScreen = ATIFreeScreen;
+ pScrn->ValidMode = ATIValidMode;
ProbeSuccess = TRUE;
}
}
+ xfree(usedChips);
+
return ProbeSuccess;
}
diff --git a/src/atimach64probe.h b/src/atimach64probe.h
index 4e474ca3..65ced985 100644
--- a/src/atimach64probe.h
+++ b/src/atimach64probe.h
@@ -25,7 +25,10 @@
#include "xf86str.h"
+extern SymTabRec Mach64Chipsets[];
+
extern const OptionInfoRec * Mach64AvailableOptions(int, int);
+extern void Mach64Identify(int);
extern Bool Mach64Probe(DriverPtr, int);
#endif /* ___ATIMACH64PROBE_H___ */
diff --git a/src/atimach64xv.c b/src/atimach64xv.c
index 997fa699..67bececf 100644
--- a/src/atimach64xv.c
+++ b/src/atimach64xv.c
@@ -979,6 +979,9 @@ ATIMach64PutImage
if (pATI->ActiveSurface)
return Success;
+ if (DstH < 16)
+ return Success;
+
if (!ATIMach64ClipVideo(pScreenInfo, pATI, ImageID,
SrcX, SrcY, SrcW, SrcH,
DstX, DstY, &DstW, &DstH,
diff --git a/src/atimodule.c b/src/atimodule.c
index 05456e7c..6aa9a2e7 100644
--- a/src/atimodule.c
+++ b/src/atimodule.c
@@ -34,47 +34,25 @@
const char *ATISymbols[] =
{
- "ATIPreInit",
- "ATIScreenInit",
- "ATISwitchMode",
- "ATIAdjustFrame",
- "ATIEnterVT",
- "ATILeaveVT",
- "ATIFreeScreen",
- "ATIValidMode",
- "ATIOptionsWeak",
- "ATIFillInScreenInfo",
+ "Mach64Identify",
+ "Mach64Probe",
+ "Mach64AvailableOptions",
NULL
};
const char *R128Symbols[] =
{
- "R128PreInit",
- "R128ScreenInit",
- "R128SwitchMode",
- "R128AdjustFrame",
- "R128EnterVT",
- "R128LeaveVT",
- "R128FreeScreen",
- "R128ValidMode",
- "R128OptionsWeak",
- "R128FillInScreenInfo",
+ "R128Identify",
+ "R128Probe",
+ "R128AvailableOptions",
NULL
};
const char *RADEONSymbols[] =
{
- "RADEONPreInit",
- "RADEONScreenInit",
- "RADEONSwitchMode",
- "RADEONAdjustFrame",
- "RADEONEnterVT",
- "RADEONLeaveVT",
- "RADEONFreeScreen",
- "RADEONValidMode",
- "RADEONOptionsWeak",
- "RADEONHandleMessage",
- "RADEONFillInScreenInfo",
+ "RADEONIdentify",
+ "RADEONProbe",
+ "RADEONAvailableOptions",
NULL
};
diff --git a/src/atipreinit.c b/src/atipreinit.c
index 018f2fb1..8114f512 100644
--- a/src/atipreinit.c
+++ b/src/atipreinit.c
@@ -41,6 +41,7 @@
#include "atimach64.h"
#include "atimach64accel.h"
#include "atimach64io.h"
+#include "atimach64probe.h"
#include "atimode.h"
#include "atioption.h"
#include "atipreinit.h"
@@ -128,7 +129,7 @@ ATIPrintNoiseIfRequested
* This function is only called once per screen at the start of the first
* server generation.
*/
-_X_EXPORT Bool
+Bool
ATIPreInit
(
ScrnInfoPtr pScreenInfo,
@@ -955,7 +956,8 @@ ATIPreInit
/* Report what was found */
xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED,
- "%s graphics controller detected.\n", ATIChipNames[pATI->Chip]);
+ "%s graphics controller detected.\n",
+ xf86TokenToString(Mach64Chipsets, pATI->Chip));
{
Message = Buffer + snprintf(Buffer, SizeOf(Buffer), "Chip type %04X",
diff --git a/src/atiprobe.c b/src/atiprobe.c
index b82ea5f8..cddcc613 100644
--- a/src/atiprobe.c
+++ b/src/atiprobe.c
@@ -31,7 +31,6 @@
#include "atibus.h"
#include "atichip.h"
#include "atimach64io.h"
-#include "atimodule.h"
#include "atiprobe.h"
#include "ativersion.h"
#include "atividmem.h"
diff --git a/src/atiscreen.c b/src/atiscreen.c
index 58b0bdaa..bc579347 100644
--- a/src/atiscreen.c
+++ b/src/atiscreen.c
@@ -349,7 +349,7 @@ ATIMach64SetupMemXAA
*
* This function is called by DIX to initialise the screen.
*/
-_X_EXPORT Bool
+Bool
ATIScreenInit
(
int iScreen,
diff --git a/src/ativalid.c b/src/ativalid.c
index 8a92e82e..51cf5ae8 100644
--- a/src/ativalid.c
+++ b/src/ativalid.c
@@ -35,7 +35,7 @@
*
* This checks for hardware-related limits on mode timings.
*/
-_X_EXPORT ModeStatus
+ModeStatus
ATIValidMode
(
int iScreen,
diff --git a/src/local_xf86Rename.h b/src/local_xf86Rename.h
new file mode 100644
index 00000000..51021709
--- /dev/null
+++ b/src/local_xf86Rename.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright © 2006 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#define XF86NAME(x) radeon_##x
diff --git a/src/r128_dri.c b/src/r128_dri.c
index 21a13c17..fc91421d 100644
--- a/src/r128_dri.c
+++ b/src/r128_dri.c
@@ -988,13 +988,13 @@ Bool R128DRIScreenInit(ScreenPtr pScreen)
/* Check the DRI version */
DRIQueryVersion(&major, &minor, &patch);
- if (major != DRIINFO_MAJOR_VERSION || minor < DRIINFO_MINOR_VERSION) {
+ if (major != DRIINFO_MAJOR_VERSION || minor < 0) {
xf86DrvMsg(pScreen->myNum, X_ERROR,
"[dri] R128DRIScreenInit failed because of a version mismatch.\n"
"[dri] libdri version is %d.%d.%d but version %d.%d.x is needed.\n"
"[dri] Disabling the DRI.\n",
major, minor, patch,
- DRIINFO_MAJOR_VERSION, DRIINFO_MINOR_VERSION);
+ DRIINFO_MAJOR_VERSION, 0);
return FALSE;
}
diff --git a/src/r128_driver.c b/src/r128_driver.c
index 81c9015c..6e26a6ef 100644
--- a/src/r128_driver.c
+++ b/src/r128_driver.c
@@ -182,7 +182,7 @@ static const OptionInfoRec R128Options[] = {
{ -1, NULL, OPTV_NONE, {0}, FALSE }
};
-_X_EXPORT const OptionInfoRec *R128OptionsWeak(void) { return R128Options; }
+const OptionInfoRec *R128OptionsWeak(void) { return R128Options; }
R128RAMRec R128RAM[] = { /* Memory Specifications
From RAGE 128 Software Development
@@ -2044,7 +2044,7 @@ R128ProbeDDC(ScrnInfoPtr pScrn, int indx)
}
/* R128PreInit is called once at server startup. */
-_X_EXPORT Bool R128PreInit(ScrnInfoPtr pScrn, int flags)
+Bool R128PreInit(ScrnInfoPtr pScrn, int flags)
{
R128InfoPtr info;
xf86Int10InfoPtr pInt10 = NULL;
@@ -2334,7 +2334,7 @@ R128BlockHandler(int i, pointer blockData, pointer pTimeout, pointer pReadmask)
}
/* Called at the start of each server generation. */
-_X_EXPORT Bool R128ScreenInit(int scrnIndex, ScreenPtr pScreen,
+Bool R128ScreenInit(int scrnIndex, ScreenPtr pScreen,
int argc, char **argv)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
@@ -4238,7 +4238,7 @@ static Bool R128SaveScreen(ScreenPtr pScreen, int mode)
* The workaround is to switch the mode, then switch to another VT, then
* switch back. --AGD
*/
-_X_EXPORT Bool R128SwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
+Bool R128SwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
R128InfoPtr info = R128PTR(pScrn);
@@ -4251,12 +4251,15 @@ _X_EXPORT Bool R128SwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
}
/* Used to disallow modes that are not supported by the hardware. */
-_X_EXPORT ModeStatus R128ValidMode(int scrnIndex, DisplayModePtr mode,
+ModeStatus R128ValidMode(int scrnIndex, DisplayModePtr mode,
Bool verbose, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
R128InfoPtr info = R128PTR(pScrn);
+ if (info->BIOSDisplay == R128_BIOS_DISPLAY_CRT)
+ return MODE_OK;
+
if(info->isDFP) {
if(info->PanelXRes < mode->CrtcHDisplay ||
info->PanelYRes < mode->CrtcVDisplay)
@@ -4327,7 +4330,7 @@ _X_EXPORT ModeStatus R128ValidMode(int scrnIndex, DisplayModePtr mode,
/* Adjust viewport into virtual desktop such that (0,0) in viewport space
is (x,y) in virtual space. */
-_X_EXPORT void R128AdjustFrame(int scrnIndex, int x, int y, int flags)
+void R128AdjustFrame(int scrnIndex, int x, int y, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
R128InfoPtr info = R128PTR(pScrn);
@@ -4363,7 +4366,7 @@ _X_EXPORT void R128AdjustFrame(int scrnIndex, int x, int y, int flags)
/* Called when VT switching back to the X server. Reinitialize the video
mode. */
-_X_EXPORT Bool R128EnterVT(int scrnIndex, int flags)
+Bool R128EnterVT(int scrnIndex, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
R128InfoPtr info = R128PTR(pScrn);
@@ -4396,7 +4399,7 @@ _X_EXPORT Bool R128EnterVT(int scrnIndex, int flags)
/* Called when VT switching away from the X server. Restore the original
text mode. */
-_X_EXPORT void R128LeaveVT(int scrnIndex, int flags)
+void R128LeaveVT(int scrnIndex, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
R128InfoPtr info = R128PTR(pScrn);
@@ -4466,7 +4469,7 @@ static Bool R128CloseScreen(int scrnIndex, ScreenPtr pScreen)
return (*pScreen->CloseScreen)(scrnIndex, pScreen);
}
-_X_EXPORT void R128FreeScreen(int scrnIndex, int flags)
+void R128FreeScreen(int scrnIndex, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
R128InfoPtr info = R128PTR(pScrn);
@@ -4605,18 +4608,3 @@ static int r128_set_backlight_enable(ScrnInfoPtr pScrn, int on)
return 0;
}
-
-_X_EXPORT void R128FillInScreenInfo(ScrnInfoPtr pScrn)
-{
- pScrn->driverVersion = R128_VERSION_CURRENT;
- pScrn->driverName = R128_DRIVER_NAME;
- pScrn->name = R128_NAME;
- pScrn->PreInit = R128PreInit;
- pScrn->ScreenInit = R128ScreenInit;
- pScrn->SwitchMode = R128SwitchMode;
- pScrn->AdjustFrame = R128AdjustFrame;
- pScrn->EnterVT = R128EnterVT;
- pScrn->LeaveVT = R128LeaveVT;
- pScrn->FreeScreen = R128FreeScreen;
- pScrn->ValidMode = R128ValidMode;
-}
diff --git a/src/r128_probe.c b/src/r128_probe.c
index 96e78974..81ff663a 100644
--- a/src/r128_probe.c
+++ b/src/r128_probe.c
@@ -41,7 +41,6 @@
* Modified by Marc Aurele La France <tsi@xfree86.org> for ATI driver merge.
*/
-#include "atimodule.h"
#include "ativersion.h"
#include "r128_probe.h"
@@ -107,7 +106,7 @@ PciChipsets R128PciChipsets[] = {
int gR128EntityIndex = -1;
/* Return the options for supported chipset 'n'; NULL otherwise */
-const OptionInfoRec *
+_X_EXPORT const OptionInfoRec *
R128AvailableOptions(int chipid, int busid)
{
int i;
@@ -126,7 +125,7 @@ R128AvailableOptions(int chipid, int busid)
}
/* Return the string name for supported chipset 'n'; NULL otherwise. */
-void
+_X_EXPORT void
R128Identify(int flags)
{
xf86PrintChipsets(R128_NAME,
@@ -135,7 +134,7 @@ R128Identify(int flags)
}
/* Return TRUE if chipset is present; FALSE otherwise. */
-Bool
+_X_EXPORT Bool
R128Probe(DriverPtr drv, int flags)
{
int numUsed;
@@ -194,22 +193,18 @@ R128Probe(DriverPtr drv, int flags)
if((pScrn = xf86ConfigPciEntity(pScrn, 0, usedChips[i],
R128PciChipsets, 0, 0, 0, 0, 0)))
{
-
-#ifdef XFree86LOADER
-
- if (!xf86LoadSubModule(pScrn, "r128")) {
- xf86Msg(X_ERROR,
- R128_NAME ": Failed to load \"r128\" module.\n");
- xf86DeleteScreen(pScrn->scrnIndex, 0);
- continue;
- }
-
- xf86LoaderReqSymLists(R128Symbols, NULL);
-
-#endif
-
+ pScrn->driverVersion = R128_VERSION_CURRENT;
+ pScrn->driverName = R128_DRIVER_NAME;
+ pScrn->name = R128_NAME;
pScrn->Probe = R128Probe;
- R128FillInScreenInfo(pScrn);
+ pScrn->PreInit = R128PreInit;
+ pScrn->ScreenInit = R128ScreenInit;
+ pScrn->SwitchMode = R128SwitchMode;
+ pScrn->AdjustFrame = R128AdjustFrame;
+ pScrn->EnterVT = R128EnterVT;
+ pScrn->LeaveVT = R128LeaveVT;
+ pScrn->FreeScreen = R128FreeScreen;
+ pScrn->ValidMode = R128ValidMode;
foundScreen = TRUE;
diff --git a/src/r128_probe.h b/src/r128_probe.h
index 91502963..180e52a9 100644
--- a/src/r128_probe.h
+++ b/src/r128_probe.h
@@ -73,6 +73,4 @@ extern ModeStatus R128ValidMode(int, DisplayModePtr, Bool, int);
extern const OptionInfoRec * R128OptionsWeak(void);
-extern void R128FillInScreenInfo(ScrnInfoPtr);
-
#endif /* _R128_PROBE_H_ */
diff --git a/src/radeon.h b/src/radeon.h
index 5bb005b9..fa2bccdf 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -39,6 +39,7 @@
#include <stdlib.h> /* For abs() */
#include <unistd.h> /* For usleep() */
+#include <sys/time.h> /* For gettimeofday() */
#include "xf86str.h"
#include "compiler.h"
@@ -65,6 +66,8 @@
#include "xf86xv.h"
#include "radeon_probe.h"
+#include "radeon_tv.h"
+
/* DRI support */
#ifdef XF86DRI
#define _XF86DRI_SERVER_
@@ -77,6 +80,9 @@
#endif
#endif
+#include "xf86Crtc.h"
+#include "X11/Xatom.h"
+
/* Render support */
#ifdef RENDER
#include "picturestr.h"
@@ -115,21 +121,8 @@ typedef enum {
OPTION_ACCEL_DFS,
#endif
#endif
- OPTION_PANEL_OFF,
OPTION_DDC_MODE,
- OPTION_MONITOR_LAYOUT,
OPTION_IGNORE_EDID,
- OPTION_FBDEV,
- OPTION_MERGEDFB,
- OPTION_CRT2HSYNC,
- OPTION_CRT2VREFRESH,
- OPTION_CRT2POS,
- OPTION_METAMODES,
- OPTION_MERGEDDPI,
- OPTION_RADEONXINERAMA,
- OPTION_CRT2ISSCRN0,
- OPTION_MERGEDFBNONRECT,
- OPTION_MERGEDFBMOUSER,
OPTION_DISP_PRIORITY,
OPTION_PANEL_SIZE,
OPTION_MIN_DOTCLOCK,
@@ -157,39 +150,17 @@ typedef enum {
OPTION_LVDS_PROBE_PLL,
OPTION_ACCELMETHOD,
OPTION_CONSTANTDPI,
- OPTION_REVERSE_DISPLAY,
- OPTION_DRI
+ OPTION_CONNECTORTABLE,
+ OPTION_DRI,
+ OPTION_DEFAULT_CONNECTOR_TABLE
} RADEONOpts;
-/* ------- mergedfb support ------------- */
- /* Psuedo Xinerama support */
-#define NEED_REPLIES /* ? */
-#define EXTENSION_PROC_ARGS void *
-#include "extnsionst.h" /* required */
-#include <X11/extensions/panoramiXproto.h> /* required */
-#define RADEON_XINERAMA_MAJOR_VERSION 1
-#define RADEON_XINERAMA_MINOR_VERSION 1
-
-
-/* Relative merge position */
-typedef enum {
- radeonLeftOf,
- radeonRightOf,
- radeonAbove,
- radeonBelow,
- radeonClone
-} RADEONScrn2Rel;
-
-typedef struct _region {
- int x0,x1,y0,y1;
-} region;
-/* ------------------------------------- */
-
-#define RADEON_DEBUG 1 /* Turn off debugging output */
#define RADEON_IDLE_RETRY 16 /* Fall out of idle loops after this count */
#define RADEON_TIMEOUT 2000000 /* Fall out of wait loops after this count */
+#define RADEON_VSYNC_TIMEOUT 20000 /* Maximum wait for VSYNC (in usecs) */
+
/* Buffer are aligned on 4096 byte boundaries */
#define RADEON_BUFFER_ALIGN 0x00000fff
#define RADEON_VBIOS_SIZE 0x00010000
@@ -198,22 +169,28 @@ typedef struct _region {
* for something else.
*/
-#if RADEON_DEBUG
-#define RADEONTRACE(x) \
-do { \
- ErrorF("(**) %s(%d): ", RADEON_NAME, pScrn->scrnIndex); \
- ErrorF x; \
-} while(0)
-#else
-#define RADEONTRACE(x) do { } while(0)
-#endif
+#define RADEON_LOGLEVEL_DEBUG 4
+/* for Xv, outputs */
+#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
/* Other macros */
#define RADEON_ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
#define RADEON_ALIGN(x,bytes) (((x) + ((bytes) - 1)) & ~((bytes) - 1))
#define RADEONPTR(pScrn) ((RADEONInfoPtr)(pScrn)->driverPrivate)
+typedef struct {
+ int revision;
+ CARD16 rr1_offset;
+ CARD16 rr2_offset;
+ CARD16 dyn_clk_offset;
+ CARD16 pll_offset;
+ CARD16 mem_config_offset;
+ CARD16 mem_reset_offset;
+ CARD16 short_mem_offset;
+ CARD16 rr3_offset;
+ CARD16 rr4_offset;
+} RADEONBIOSInitTable;
typedef struct {
/* Common registers */
@@ -262,10 +239,11 @@ typedef struct {
CARD32 disp_merge_cntl;
CARD32 grph_buffer_cntl;
CARD32 crtc_more_cntl;
+ CARD32 crtc_tile_x0_y0;
/* CRTC2 registers */
CARD32 crtc2_gen_cntl;
-
+ CARD32 dac_macro_cntl;
CARD32 dac2_cntl;
CARD32 disp_output_cntl;
CARD32 disp_tv_out_cntl;
@@ -279,6 +257,8 @@ typedef struct {
CARD32 crtc2_offset;
CARD32 crtc2_offset_cntl;
CARD32 crtc2_pitch;
+ CARD32 crtc2_tile_x0_y0;
+
/* Flat panel registers */
CARD32 fp_crtc_h_total_disp;
CARD32 fp_crtc_v_total_disp;
@@ -306,7 +286,7 @@ typedef struct {
unsigned ppll_ref_div;
unsigned ppll_div_3;
CARD32 htotal_cntl;
- CARD32 vclk_cntl;
+ CARD32 vclk_ecp_cntl;
/* Computed values for PLL2 */
CARD32 dot_clock_freq_2;
@@ -325,7 +305,54 @@ typedef struct {
CARD32 palette[256];
CARD32 palette2[256];
- CARD32 tv_dac_cntl;
+ CARD32 rs480_unk_e30;
+ CARD32 rs480_unk_e34;
+ CARD32 rs480_unk_e38;
+ CARD32 rs480_unk_e3c;
+
+ /* TV out registers */
+ CARD32 tv_master_cntl;
+ CARD32 tv_htotal;
+ CARD32 tv_hsize;
+ CARD32 tv_hdisp;
+ CARD32 tv_hstart;
+ CARD32 tv_vtotal;
+ CARD32 tv_vdisp;
+ CARD32 tv_timing_cntl;
+ CARD32 tv_vscaler_cntl1;
+ CARD32 tv_vscaler_cntl2;
+ CARD32 tv_sync_size;
+ CARD32 tv_vrestart;
+ CARD32 tv_hrestart;
+ CARD32 tv_frestart;
+ CARD32 tv_ftotal;
+ CARD32 tv_clock_sel_cntl;
+ CARD32 tv_clkout_cntl;
+ CARD32 tv_data_delay_a;
+ CARD32 tv_data_delay_b;
+ CARD32 tv_dac_cntl;
+ CARD32 tv_pll_cntl;
+ CARD32 tv_pll_cntl1;
+ CARD32 tv_pll_fine_cntl;
+ CARD32 tv_modulator_cntl1;
+ CARD32 tv_modulator_cntl2;
+ CARD32 tv_frame_lock_cntl;
+ CARD32 tv_pre_dac_mux_cntl;
+ CARD32 tv_rgb_cntl;
+ CARD32 tv_y_saw_tooth_cntl;
+ CARD32 tv_y_rise_cntl;
+ CARD32 tv_y_fall_cntl;
+ CARD32 tv_uv_adr;
+ CARD32 tv_upsamp_and_gain_cntl;
+ CARD32 tv_gain_limit_settings;
+ CARD32 tv_linear_gain_settings;
+ CARD32 tv_crc_cntl;
+ CARD32 tv_sync_cntl;
+ CARD32 gpiopad_a;
+ CARD32 pll_test_cntl;
+
+ CARD16 h_code_timing[MAX_H_CODE_TIMING_LEN];
+ CARD16 v_code_timing[MAX_V_CODE_TIMING_LEN];
} RADEONSaveRec, *RADEONSavePtr;
@@ -402,11 +429,6 @@ typedef enum {
} RADEONCardType;
typedef struct {
- CARD32 freq;
- CARD32 value;
-}RADEONTMDSPll;
-
-typedef struct {
EntityInfoPtr pEnt;
pciVideoPtr PciInfo;
PCITAG PciTag;
@@ -414,8 +436,6 @@ typedef struct {
RADEONChipFamily ChipFamily;
RADEONErrata ChipErrata;
- Bool FBDev;
-
unsigned long LinearAddr; /* Frame buffer physical address */
unsigned long MMIOAddr; /* MMIO region physical address */
unsigned long BIOSAddr; /* BIOS physical address */
@@ -438,36 +458,16 @@ typedef struct {
unsigned long FbMapSize; /* Size of frame buffer, in bytes */
unsigned long FbSecureSize; /* Size of secured fb area at end of
framebuffer */
- int Flags; /* Saved copy of mode flags */
-
- /* VE/M6 support */
- RADEONMonitorType DisplayType; /* Monitor connected on */
- RADEONDDCType DDCType;
- RADEONConnectorType ConnectorType;
Bool IsMobility; /* Mobile chips for laptops */
Bool IsIGP; /* IGP chips */
Bool HasSingleDAC; /* only TVDAC on chip */
- Bool IsSecondary; /* Second Screen */
- Bool IsPrimary; /* Primary Screen */
- Bool IsSwitching; /* Flag for switching mode */
- Bool OverlayOnCRTC2;
Bool ddc_mode; /* Validate mode by matching exactly
* the modes supported in DDC data
*/
Bool R300CGWorkaround;
/* EDID or BIOS values for FPs */
- int PanelXRes;
- int PanelYRes;
- int HOverPlus;
- int HSyncWidth;
- int HBlank;
- int VOverPlus;
- int VSyncWidth;
- int VBlank;
- int PanelPwrDly;
- int DotClock;
int RefDivider;
int FeedbackDivider;
int PostDivider;
@@ -476,11 +476,9 @@ typedef struct {
Bool ddc_bios;
Bool ddc1;
Bool ddc2;
- I2CBusPtr pI2CBus;
- CARD32 DDCReg;
RADEONPLLRec pll;
- RADEONTMDSPll tmds_pll[4];
+
int RamWidth;
float sclk; /* in MHz */
float mclk; /* in MHz */
@@ -497,6 +495,8 @@ typedef struct {
#ifdef USE_EXA
ExaDriverPtr exa;
+ int exaSyncMarker;
+ int exaMarkerSynced;
int engineMode;
#define EXA_ENGINEMODE_UNKNOWN 0
#define EXA_ENGINEMODE_2D 1
@@ -605,6 +605,7 @@ typedef struct {
Bool allowPageFlip; /* Enable 3d page flipping */
#ifdef DAMAGE
DamagePtr pDamage;
+ RegionRec driRegion;
#endif
Bool have3DWindows; /* Are there any 3d clients? */
@@ -614,7 +615,6 @@ typedef struct {
unsigned long gartOffset;
unsigned char *AGP; /* Map */
int agpMode;
- int agpFastWrite;
CARD32 pciCommand;
@@ -774,42 +774,10 @@ typedef struct {
/* X itself has the 3D context */
Bool XInited3D;
- /* merged fb stuff, also covers clone modes */
- Bool MergedFB;
- RADEONScrn2Rel CRT2Position;
- char * CRT2HSync;
- char * CRT2VRefresh;
- char * MetaModes;
- ScrnInfoPtr CRT2pScrn;
- DisplayModePtr CRT1Modes;
- DisplayModePtr CRT1CurrentMode;
- int CRT1frameX0;
- int CRT1frameY0;
- int CRT1frameX1;
- int CRT1frameY1;
- RADEONMonitorType MergeType;
- RADEONDDCType MergeDDCType;
- void (*PointerMoved)(int index, int x, int y);
- /* pseudo xinerama support for mergedfb */
- int maxCRT1_X1, maxCRT1_X2, maxCRT1_Y1, maxCRT1_Y2;
- int maxCRT2_X1, maxCRT2_X2, maxCRT2_Y1, maxCRT2_Y2;
- int maxClone_X1, maxClone_X2, maxClone_Y1, maxClone_Y2;
- Bool UseRADEONXinerama;
- Bool CRT2IsScrn0;
- ExtensionEntry *XineramaExtEntry;
- int RADEONXineramaVX, RADEONXineramaVY;
- Bool AtLeastOneNonClone;
- int MergedFBXDPI, MergedFBYDPI;
- Bool NoVirtual;
- int CRT1XOffs, CRT1YOffs, CRT2XOffs, CRT2YOffs;
- int MBXNR1XMAX, MBXNR1YMAX, MBXNR2XMAX, MBXNR2YMAX;
- Bool NonRect, HaveNonRect, HaveOffsRegions, MouseRestrictions;
- region NonRectDead, OffDead1, OffDead2;
+ DisplayModePtr currentMode, savedCurrentMode;
int constantDPI; /* -1 = auto, 0 = off, 1 = on */
int RADEONDPIVX, RADEONDPIVY;
- RADEONScrn2Rel MergedDPISRel;
- int RADEONMergedDPIVX, RADEONMergedDPIVY, RADEONMergedDPIRot;
/* special handlings for DELL triple-head server */
Bool IsDellServer;
@@ -820,7 +788,22 @@ typedef struct {
int MaxLines;
CARD32 tv_dac_adj;
+ CARD32 tv_dac_enable_mask;
+
+ Bool want_vblank_interrupts;
+ RADEONBIOSConnector BiosConnector[RADEON_MAX_BIOS_CONNECTOR];
+ RADEONBIOSInitTable BiosTable;
+
+ /* save crtc state for console restore */
+ Bool crtc_on;
+ Bool crtc2_on;
+
+ Bool InternalTVOut;
+ int tvdac_use_count;
+ Rotation rotation;
+ void (*PointerMoved)(int, int, int);
+ CreateScreenResourcesProcPtr CreateScreenResources;
} RADEONInfoRec, *RADEONInfoPtr;
#define RADEONWaitForFifo(pScrn, entries) \
@@ -839,7 +822,7 @@ extern void RADEONWaitForIdleCP(ScrnInfoPtr pScrn);
#endif
extern void RADEONDoAdjustFrame(ScrnInfoPtr pScrn, int x, int y,
- int clone);
+ Bool clone);
extern void RADEONEngineReset(ScrnInfoPtr pScrn);
extern void RADEONEngineFlush(ScrnInfoPtr pScrn);
@@ -858,6 +841,7 @@ extern Bool RADEONAccelInit(ScreenPtr pScreen);
extern Bool RADEONSetupMemEXA (ScreenPtr pScreen);
extern Bool RADEONDrawInitMMIO(ScreenPtr pScreen);
#ifdef XF86DRI
+extern unsigned long long RADEONTexOffsetStart(PixmapPtr pPix);
extern Bool RADEONGetDatatypeBpp(int bpp, CARD32 *type);
extern Bool RADEONGetPixmapOffsetPitch(PixmapPtr pPix,
CARD32 *pitch_offset);
@@ -892,19 +876,47 @@ extern void RADEONPllErrataAfterData(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);
-
+extern Bool RADEONGetLVDSInfoFromBIOS (xf86OutputPtr output);
+extern Bool RADEONGetTMDSInfoFromBIOS (xf86OutputPtr output);
+extern Bool RADEONGetTVInfoFromBIOS (xf86OutputPtr output);
+extern Bool RADEONGetHardCodedEDIDFromBIOS (xf86OutputPtr output);
+
+extern void RADEONRestoreMemMapRegisters(ScrnInfoPtr pScrn,
+ RADEONSavePtr restore);
+extern void RADEONRestoreCommonRegisters(ScrnInfoPtr pScrn,
+ RADEONSavePtr restore);
+extern void RADEONRestoreCrtcRegisters(ScrnInfoPtr pScrn,
+ RADEONSavePtr restore);
+extern void RADEONRestoreDACRegisters(ScrnInfoPtr pScrn,
+ RADEONSavePtr restore);
+extern void RADEONRestoreFPRegisters(ScrnInfoPtr pScrn,
+ RADEONSavePtr restore);
+extern void RADEONRestoreFP2Registers(ScrnInfoPtr pScrn,
+ RADEONSavePtr restore);
+extern void RADEONRestoreLVDSRegisters(ScrnInfoPtr pScrn,
+ RADEONSavePtr restore);
+extern void RADEONRestoreRMXRegisters(ScrnInfoPtr pScrn,
+ RADEONSavePtr restore);
+extern void RADEONRestorePLLRegisters(ScrnInfoPtr pScrn,
+ RADEONSavePtr restore);
+extern void RADEONRestoreCrtc2Registers(ScrnInfoPtr pScrn,
+ RADEONSavePtr restore);
+extern void RADEONRestorePLL2Registers(ScrnInfoPtr pScrn,
+ RADEONSavePtr restore);
+
+extern void RADEONInitMemMapRegisters(ScrnInfoPtr pScrn,
+ RADEONSavePtr save,
+ RADEONInfoPtr info);
extern void RADEONInitDispBandwidth(ScrnInfoPtr pScrn);
extern Bool RADEONI2cInit(ScrnInfoPtr pScrn);
extern void RADEONSetSyncRangeFromEdid(ScrnInfoPtr pScrn, int flag);
-extern void RADEONSetupConnectors(ScrnInfoPtr pScrn);
-extern Bool RADEONMapControllers(ScrnInfoPtr pScrn);
-extern void RADEONEnableDisplay(ScrnInfoPtr pScrn, RADEONConnector* pPort, BOOL bEnable);
+extern Bool RADEONSetupConnectors(ScrnInfoPtr pScrn);
+extern void RADEONPrintPortMap(ScrnInfoPtr pScrn);
+extern void RADEONEnableDisplay(xf86OutputPtr pPort, BOOL bEnable);
extern void RADEONDisableDisplays(ScrnInfoPtr pScrn);
extern void RADEONGetPanelInfo(ScrnInfoPtr pScrn);
-extern void RADEONGetTVDacAdjInfo(ScrnInfoPtr pScrn);
+extern void RADEONGetTVDacAdjInfo(xf86OutputPtr output);
+extern void RADEONUnblank(ScrnInfoPtr pScrn);
extern void RADEONUnblank(ScrnInfoPtr pScrn);
extern void RADEONBlank(ScrnInfoPtr pScrn);
extern void RADEONDisplayPowerManagementSet(ScrnInfoPtr pScrn,
@@ -912,13 +924,48 @@ extern void RADEONDisplayPowerManagementSet(ScrnInfoPtr pScrn,
int flags);
extern Bool RADEONAllocateControllers(ScrnInfoPtr pScrn);
extern Bool RADEONAllocateConnectors(ScrnInfoPtr pScrn);
-extern RADEONConnector *RADEONGetCrtcConnector(ScrnInfoPtr pScrn, int crtc_num);
extern int RADEONValidateMergeModes(ScrnInfoPtr pScrn);
extern int RADEONValidateDDCModes(ScrnInfoPtr pScrn1, char **ppModeName,
RADEONMonitorType DisplayType, int crtc2);
-extern int RADEONValidateFPModes(ScrnInfoPtr pScrn, char **ppModeName);
+extern int RADEONValidateFPModes(xf86OutputPtr output, char **ppModeName, DisplayModePtr *modeList);
extern void RADEONSetPitch (ScrnInfoPtr pScrn);
-
+extern void RADEONUpdateHVPosition(xf86OutputPtr output, DisplayModePtr mode);
+
+DisplayModePtr
+RADEONProbeOutputModes(xf86OutputPtr output);
+extern Bool RADEONInit2(ScrnInfoPtr pScrn, DisplayModePtr crtc1,
+ DisplayModePtr crtc2, int crtc_mask,
+ RADEONSavePtr save, RADEONMonitorType montype);
+
+void
+radeon_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y);
+void
+radeon_crtc_show_cursor (xf86CrtcPtr crtc);
+void
+radeon_crtc_hide_cursor (xf86CrtcPtr crtc);
+void
+radeon_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y);
+void
+radeon_crtc_set_cursor_colors (xf86CrtcPtr crtc, int bg, int fg);
+void
+radeon_crtc_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image);
+void
+RADEONEnableOutputs(ScrnInfoPtr pScrn, int crtc_num);
+
+extern void RADEONAdjustCrtcRegistersForTV(ScrnInfoPtr pScrn, RADEONSavePtr save,
+ DisplayModePtr mode, xf86OutputPtr output);
+extern void RADEONAdjustPLLRegistersForTV(ScrnInfoPtr pScrn, RADEONSavePtr save,
+ DisplayModePtr mode, xf86OutputPtr output);
+extern void RADEONAdjustCrtc2RegistersForTV(ScrnInfoPtr pScrn, RADEONSavePtr save,
+ DisplayModePtr mode, xf86OutputPtr output);
+extern void RADEONAdjustPLL2RegistersForTV(ScrnInfoPtr pScrn, RADEONSavePtr save,
+ DisplayModePtr mode, xf86OutputPtr output);
+extern void RADEONInitTVRegisters(xf86OutputPtr output, RADEONSavePtr save,
+ DisplayModePtr mode, BOOL IsPrimary);
+
+extern void RADEONRestoreTVRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore);
+extern void RADEONRestoreTVRestarts(ScrnInfoPtr pScrn, RADEONSavePtr restore);
+extern void RADEONRestoreTVTimingTables(ScrnInfoPtr pScrn, RADEONSavePtr restore);
#ifdef XF86DRI
#ifdef USE_XAA
@@ -937,6 +984,7 @@ extern drmBufPtr RADEONCPGetBuffer(ScrnInfoPtr pScrn);
extern void RADEONCPFlushIndirect(ScrnInfoPtr pScrn, int discard);
extern void RADEONCPReleaseIndirect(ScrnInfoPtr pScrn);
extern int RADEONCPStop(ScrnInfoPtr pScrn, RADEONInfoPtr info);
+extern Bool RADEONDRISetVBlankInterrupt(ScrnInfoPtr pScrn, Bool on);
extern void RADEONHostDataParams(ScrnInfoPtr pScrn, CARD8 *dst,
CARD32 pitch, int cpp,
@@ -964,6 +1012,16 @@ do { \
info->CPStarted = TRUE; \
} while (0)
+#define RADEONCP_RELEASE(pScrn, info) \
+do { \
+ if (info->CPInUse) { \
+ RADEON_PURGE_CACHE(); \
+ RADEON_WAIT_UNTIL_IDLE(); \
+ RADEONCPReleaseIndirect(pScrn); \
+ info->CPInUse = FALSE; \
+ } \
+} while (0)
+
#define RADEONCP_STOP(pScrn, info) \
do { \
int _ret; \
@@ -1128,14 +1186,6 @@ do { \
ADVANCE_RING(); \
} while (0)
-#define RADEON_FLUSH_CACHE() \
-do { \
- BEGIN_RING(2); \
- OUT_RING(CP_PACKET0(RADEON_RB3D_DSTCACHE_CTLSTAT, 0)); \
- OUT_RING(RADEON_RB3D_DC_FLUSH); \
- ADVANCE_RING(); \
-} while (0)
-
#define RADEON_PURGE_CACHE() \
do { \
BEGIN_RING(2); \
@@ -1176,4 +1226,21 @@ static __inline__ void RADEON_SYNC(RADEONInfoPtr info, ScrnInfoPtr pScrn)
#endif
}
+static __inline__ void radeon_init_timeout(struct timeval *endtime,
+ unsigned int timeout)
+{
+ gettimeofday(endtime, NULL);
+ endtime->tv_usec += timeout;
+ endtime->tv_sec += endtime->tv_usec / 1000000;
+ endtime->tv_usec %= 1000000;
+}
+
+static __inline__ int radeon_timedout(const struct timeval *endtime)
+{
+ struct timeval now;
+ gettimeofday(&now, NULL);
+ return now.tv_sec == endtime->tv_sec ?
+ now.tv_usec > endtime->tv_usec : now.tv_sec > endtime->tv_sec;
+}
+
#endif /* _RADEON_H_ */
diff --git a/src/radeon_accel.c b/src/radeon_accel.c
index 41859c4a..b739988f 100644
--- a/src/radeon_accel.c
+++ b/src/radeon_accel.c
@@ -134,9 +134,10 @@ void RADEONWaitForFifoFunction(ScrnInfoPtr pScrn, int entries)
INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK;
if (info->fifo_slots >= entries) return;
}
- RADEONTRACE(("FIFO timed out: %u entries, stat=0x%08x\n",
- INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK,
- INREG(RADEON_RBBM_STATUS)));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "FIFO timed out: %u entries, stat=0x%08x\n",
+ INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK,
+ INREG(RADEON_RBBM_STATUS));
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"FIFO timed out, resetting engine...\n");
RADEONEngineReset(pScrn);
@@ -165,8 +166,9 @@ void RADEONEngineFlush(ScrnInfoPtr pScrn)
break;
}
if (i == RADEON_TIMEOUT) {
- RADEONTRACE(("DC flush timeout: %x\n",
- INREG(RADEON_RB3D_DSTCACHE_CTLSTAT)));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "DC flush timeout: %x\n",
+ INREG(RADEON_RB3D_DSTCACHE_CTLSTAT));
}
}
@@ -296,9 +298,10 @@ void RADEONEngineRestore(ScrnInfoPtr pScrn)
RADEONInfoPtr info = RADEONPTR(pScrn);
unsigned char *RADEONMMIO = info->MMIO;
- RADEONTRACE(("EngineRestore (%d/%d)\n",
- info->CurrentLayout.pixel_code,
- info->CurrentLayout.bitsPerPixel));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "EngineRestore (%d/%d)\n",
+ info->CurrentLayout.pixel_code,
+ info->CurrentLayout.bitsPerPixel);
/* Setup engine location. This shouldn't be necessary since we
* set them appropriately before any accel ops, but let's avoid
@@ -347,9 +350,10 @@ void RADEONEngineInit(ScrnInfoPtr pScrn)
RADEONInfoPtr info = RADEONPTR(pScrn);
unsigned char *RADEONMMIO = info->MMIO;
- RADEONTRACE(("EngineInit (%d/%d)\n",
- info->CurrentLayout.pixel_code,
- info->CurrentLayout.bitsPerPixel));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "EngineInit (%d/%d)\n",
+ info->CurrentLayout.pixel_code,
+ info->CurrentLayout.bitsPerPixel);
OUTREG(RADEON_RB3D_CNTL, 0);
@@ -362,15 +366,17 @@ void RADEONEngineInit(ScrnInfoPtr pScrn)
case 24: info->datatype = 5; break;
case 32: info->datatype = 6; break;
default:
- RADEONTRACE(("Unknown depth/bpp = %d/%d (code = %d)\n",
- info->CurrentLayout.depth,
- info->CurrentLayout.bitsPerPixel,
- info->CurrentLayout.pixel_code));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "Unknown depth/bpp = %d/%d (code = %d)\n",
+ info->CurrentLayout.depth,
+ info->CurrentLayout.bitsPerPixel,
+ info->CurrentLayout.pixel_code);
}
info->pitch = ((info->CurrentLayout.displayWidth / 8) *
(info->CurrentLayout.pixel_bytes == 3 ? 3 : 1));
- RADEONTRACE(("Pitch for acceleration = %d\n", info->pitch));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "Pitch for acceleration = %d\n", info->pitch);
info->dp_gui_master_cntl =
((info->datatype << RADEON_GMC_DST_DATATYPE_SHIFT)
diff --git a/src/radeon_accelfuncs.c b/src/radeon_accelfuncs.c
index 784b0745..212131fd 100644
--- a/src/radeon_accelfuncs.c
+++ b/src/radeon_accelfuncs.c
@@ -1204,8 +1204,14 @@ FUNC_NAME(RADEONAccelInit)(ScreenPtr pScreen, XAAInfoRecPtr a)
hardware accel two point lines */
miSetZeroLineBias(pScreen, (OCTANT5 | OCTANT6 | OCTANT7 | OCTANT8));
- a->SubsequentSolidTwoPointLine
- = FUNC_NAME(RADEONSubsequentSolidTwoPointLine);
+#ifdef ACCEL_CP
+ /* RV280s lock up with this using the CP for reasons to be determined.
+ * See https://bugs.freedesktop.org/show_bug.cgi?id=5986 .
+ */
+ if (info->ChipFamily != CHIP_FAMILY_RV280)
+#endif
+ a->SubsequentSolidTwoPointLine
+ = FUNC_NAME(RADEONSubsequentSolidTwoPointLine);
/* Disabled on RV200 and newer because it does not pass XTest */
if (info->ChipFamily < CHIP_FAMILY_RV200) {
diff --git a/src/radeon_bios.c b/src/radeon_bios.c
index 1d4c9bbb..b24c4817 100644
--- a/src/radeon_bios.c
+++ b/src/radeon_bios.c
@@ -34,12 +34,27 @@
#include "xf86.h"
#include "xf86_OSproc.h"
+#include "xf86PciInfo.h"
#include "radeon.h"
#include "radeon_reg.h"
#include "radeon_macros.h"
#include "radeon_probe.h"
#include "vbe.h"
+int RADEONBIOSApplyConnectorQuirks(ScrnInfoPtr pScrn, int connector_found)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+
+ /* quirk for compaq nx6125 - the bios lies about the VGA DDC */
+ if (info->PciInfo->subsysVendor == PCI_VENDOR_HP) {
+ if (info->PciInfo->subsysCard == 0x308b) {
+ if (info->BiosConnector[1].DDCType == DDC_CRT2)
+ info->BiosConnector[1].DDCType = DDC_MONID;
+ }
+ }
+ return connector_found;
+}
+
/* Read the Video BIOS block and the FP registers (if applicable). */
Bool RADEONGetBIOSInfo(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
{
@@ -126,11 +141,191 @@ Bool RADEONGetBIOSInfo(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
return TRUE;
}
+static Bool RADEONGetATOMConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
+{
+ RADEONInfoPtr info = RADEONPTR (pScrn);
+ int offset, i, tmp, tmp0, crtc, portinfo, gpio;
+
+ if (!info->VBIOS) return FALSE;
+
+ offset = RADEON_BIOS16(info->MasterDataStart + 22);
+
+ if (offset) {
+ tmp = RADEON_BIOS16(offset + 4);
+ for (i = 0; i < 8; i++) {
+ if (tmp & (1 << i)) {
+ info->BiosConnector[i].valid = TRUE;
+ portinfo = RADEON_BIOS16(offset + 6 + i * 2);
+ info->BiosConnector[i].DACType = (portinfo & 0xf) - 1;
+ info->BiosConnector[i].ConnectorType = (portinfo >> 4) & 0xf;
+ crtc = (portinfo >> 8) & 0xf;
+ tmp0 = RADEON_BIOS16(info->MasterDataStart + 24);
+ gpio = RADEON_BIOS16(tmp0 + 4 + 27 * crtc) * 4;
+ switch(gpio) {
+ case RADEON_GPIO_MONID:
+ info->BiosConnector[i].DDCType = DDC_MONID;
+ break;
+ case RADEON_GPIO_DVI_DDC:
+ info->BiosConnector[i].DDCType = DDC_DVI;
+ break;
+ case RADEON_GPIO_VGA_DDC:
+ info->BiosConnector[i].DDCType = DDC_VGA;
+ break;
+ case RADEON_GPIO_CRT2_DDC:
+ info->BiosConnector[i].DDCType = DDC_CRT2;
+ break;
+ case RADEON_LCD_GPIO_MASK:
+ info->BiosConnector[i].DDCType = DDC_LCD;
+ break;
+ default:
+ info->BiosConnector[i].DDCType = DDC_NONE_DETECTED;
+ break;
+ }
+
+ if (i == 3)
+ info->BiosConnector[i].TMDSType = TMDS_INT;
+ else if (i == 7)
+ info->BiosConnector[i].TMDSType = TMDS_EXT;
+ else
+ info->BiosConnector[i].TMDSType = TMDS_UNKNOWN;
+
+ } else {
+ info->BiosConnector[i].valid = FALSE;
+ }
+ }
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "No Device Info Table found!\n");
+ return FALSE;
+ }
+
+ /* DVI-I ports have 2 entries: one for analog, one for digital. combine them */
+ if (info->BiosConnector[0].valid && info->BiosConnector[7].valid) {
+ info->BiosConnector[7].DACType = info->BiosConnector[0].DACType;
+ info->BiosConnector[0].valid = FALSE;
+ }
+
+ if (info->BiosConnector[4].valid && info->BiosConnector[3].valid) {
+ info->BiosConnector[3].DACType = info->BiosConnector[4].DACType;
+ info->BiosConnector[4].valid = FALSE;
+ }
+
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Bios Connector table: \n");
+ for (i = 0; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
+ if (info->BiosConnector[i].valid) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Port%d: DDCType-%d, DACType-%d, TMDSType-%d, ConnectorType-%d\n",
+ i, info->BiosConnector[i].DDCType, info->BiosConnector[i].DACType,
+ info->BiosConnector[i].TMDSType, info->BiosConnector[i].ConnectorType);
+ }
+ }
+
+ return TRUE;
+}
+
+static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
+{
+ RADEONInfoPtr info = RADEONPTR (pScrn);
+ int offset, i, entry, tmp, tmp0, tmp1;
+
+ if (!info->VBIOS) return FALSE;
+
+ offset = RADEON_BIOS16(info->ROMHeaderStart + 0x50);
+ if (offset) {
+ for (i = 0; i < 4; i++) {
+ entry = offset + 2 + i*2;
+
+ if (!RADEON_BIOS16(entry)) {
+ break;
+ }
+ info->BiosConnector[i].valid = TRUE;
+ tmp = RADEON_BIOS16(entry);
+ info->BiosConnector[i].ConnectorType = (tmp >> 12) & 0xf;
+ info->BiosConnector[i].DDCType = (tmp >> 8) & 0xf;
+ info->BiosConnector[i].DACType = tmp & 0x1;
+ info->BiosConnector[i].TMDSType = tmp & 0x10;
+
+ }
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "No Connector Info Table found!\n");
+ return FALSE;
+ }
+
+ /* check LVDS table */
+ if (info->IsMobility) {
+ offset = RADEON_BIOS16(info->ROMHeaderStart + 0x40);
+ if (offset) {
+ info->BiosConnector[4].valid = TRUE;
+ info->BiosConnector[4].ConnectorType = CONNECTOR_PROPRIETARY;
+ info->BiosConnector[4].DACType = DAC_NONE;
+ info->BiosConnector[4].TMDSType = TMDS_NONE;
+
+ tmp = RADEON_BIOS16(info->ROMHeaderStart + 0x42);
+ if (tmp) {
+ tmp0 = RADEON_BIOS16(tmp + 0x15);
+ if (tmp0) {
+ tmp1 = RADEON_BIOS8(tmp0+2) & 0x07;
+ if (tmp1) {
+ info->BiosConnector[4].DDCType = tmp1;
+ if (info->BiosConnector[4].DDCType > DDC_LCD) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Unknown DDCType %d found\n",
+ info->BiosConnector[4].DDCType);
+ info->BiosConnector[4].DDCType = DDC_NONE_DETECTED;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "LCD DDC Info Table found!\n");
+ }
+ }
+ } else {
+ info->BiosConnector[4].DDCType = DDC_NONE_DETECTED;
+ }
+ }
+ }
+
+ /* check TV table */
+ if (info->InternalTVOut) {
+ offset = RADEON_BIOS16(info->ROMHeaderStart + 0x32);
+ if (offset) {
+ if (RADEON_BIOS8(offset + 6) == 'T') {
+ info->BiosConnector[5].valid = TRUE;
+ /* assume s-video for now */
+ info->BiosConnector[5].ConnectorType = CONNECTOR_STV;
+ info->BiosConnector[5].DACType = DAC_TVDAC;
+ info->BiosConnector[5].TMDSType = TMDS_NONE;
+ info->BiosConnector[5].DDCType = DDC_NONE_DETECTED;
+ }
+ }
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Bios Connector table: \n");
+ for (i = 0; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
+ if (info->BiosConnector[i].valid) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Port%d: DDCType-%d, DACType-%d, TMDSType-%d, ConnectorType-%d\n",
+ i, info->BiosConnector[i].DDCType, info->BiosConnector[i].DACType,
+ info->BiosConnector[i].TMDSType, info->BiosConnector[i].ConnectorType);
+ }
+ }
+
+ return TRUE;
+}
+
+Bool RADEONGetConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
+{
+ RADEONInfoPtr info = RADEONPTR (pScrn);
+
+ if(!info->VBIOS) return FALSE;
+
+ if (info->IsAtomBios)
+ return RADEONGetATOMConnectorInfoFromBIOS(pScrn);
+ else
+ return RADEONGetLegacyConnectorInfoFromBIOS(pScrn);
+}
+
+#if 0
Bool RADEONGetConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
{
RADEONInfoPtr info = RADEONPTR (pScrn);
- RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
int i = 0, j, tmp, tmp0=0, tmp1=0;
+ RADEONBIOSConnector tempConnector;
if(!info->VBIOS) return FALSE;
@@ -148,46 +343,49 @@ Bool RADEONGetConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
/* sharing same port with id[0] */
if (((portinfo>>8) & 0xf) == id[0]) {
if (i == 3)
- pRADEONEnt->PortInfo[0]->TMDSType = TMDS_INT;
+ info->BiosConnector[0].TMDSType = TMDS_INT;
else if (i == 7)
- pRADEONEnt->PortInfo[0]->TMDSType = TMDS_EXT;
+ info->BiosConnector[0].TMDSType = TMDS_EXT;
- if (pRADEONEnt->PortInfo[0]->DACType == DAC_UNKNOWN)
- pRADEONEnt->PortInfo[0]->DACType = (portinfo & 0xf) - 1;
+ if (info->BiosConnector[0].DACType == DAC_UNKNOWN)
+ info->BiosConnector[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;
+ info->BiosConnector[crtc].DACType = (portinfo & 0xf) - 1;
+ info->BiosConnector[crtc].ConnectorType = (portinfo>>4) & 0xf;
if (i == 3)
- pRADEONEnt->PortInfo[crtc]->TMDSType = TMDS_INT;
+ info->BiosConnector[crtc].TMDSType = TMDS_INT;
else if (i == 7)
- pRADEONEnt->PortInfo[crtc]->TMDSType = TMDS_EXT;
+ info->BiosConnector[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;
+ info->BiosConnector[crtc].DDCType = DDC_MONID;
break;
case RADEON_GPIO_DVI_DDC:
- pRADEONEnt->PortInfo[crtc]->DDCType = DDC_DVI;
+ info->BiosConnector[crtc].DDCType = DDC_DVI;
break;
case RADEON_GPIO_VGA_DDC:
- pRADEONEnt->PortInfo[crtc]->DDCType = DDC_VGA;
+ info->BiosConnector[crtc].DDCType = DDC_VGA;
break;
case RADEON_GPIO_CRT2_DDC:
- pRADEONEnt->PortInfo[crtc]->DDCType = DDC_CRT2;
+ info->BiosConnector[crtc].DDCType = DDC_CRT2;
+ break;
+ case RADEON_LCD_GPIO_MASK:
+ info->BiosConnector[crtc].DDCType = DDC_LCD;
break;
default:
- pRADEONEnt->PortInfo[crtc]->DDCType = DDC_NONE_DETECTED;
+ info->BiosConnector[crtc].DDCType = DDC_NONE_DETECTED;
break;
}
} else {
- pRADEONEnt->PortInfo[crtc]->DDCType = DDC_NONE_DETECTED;
+ info->BiosConnector[crtc].DDCType = DDC_NONE_DETECTED;
}
crtc++;
} else {
@@ -197,22 +395,28 @@ Bool RADEONGetConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
for (j=0; j<2; j++) {
if (((portinfo>>8) & 0xf) == id[j]) {
if (i == 3)
- pRADEONEnt->PortInfo[j]->TMDSType = TMDS_INT;
+ info->BiosConnector[j].TMDSType = TMDS_INT;
else if (i == 7)
- pRADEONEnt->PortInfo[j]->TMDSType = TMDS_EXT;
+ info->BiosConnector[j].TMDSType = TMDS_EXT;
- if (pRADEONEnt->PortInfo[j]->DACType == DAC_UNKNOWN)
- pRADEONEnt->PortInfo[j]->DACType = (portinfo & 0xf) - 1;
+ if (info->BiosConnector[j].DACType == DAC_UNKNOWN)
+ info->BiosConnector[j].DACType = (portinfo & 0xf) - 1;
}
}
}
}
}
+ /* R4xx seem to get the connector table backwards */
+ tempConnector = info->BiosConnector[0];
+ info->BiosConnector[0] = info->BiosConnector[1];
+ info->BiosConnector[1] = tempConnector;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Bios Connector table: \n");
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);
+ i, info->BiosConnector[i].DDCType, info->BiosConnector[i].DACType,
+ info->BiosConnector[i].TMDSType, info->BiosConnector[i].ConnectorType);
}
} else {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "No Device Info Table found!\n");
@@ -239,25 +443,27 @@ Bool RADEONGetConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
tmp0 = RADEON_BIOS16(tmp + i*2);
if (((tmp0 >> 12) & 0x0f) == 0) continue; /* no connector */
if (connector_found > 0) {
- if (pRADEONEnt->PortInfo[tmp1]->DDCType == ((tmp0 >> 8) & 0x0f))
+ if (info->BiosConnector[tmp1].DDCType == ((tmp0 >> 8) & 0x0f))
continue; /* same 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;
+ info->BiosConnector[tmp1].DDCType = (tmp0 >> 8) & 0x0f;
+ if (info->BiosConnector[tmp1].DDCType > DDC_CRT2)
+ info->BiosConnector[tmp1].DDCType = DDC_NONE_DETECTED;
+ info->BiosConnector[tmp1].DACType = (tmp0 & 0x01) ? DAC_TVDAC : DAC_PRIMARY;
+ info->BiosConnector[tmp1].ConnectorType = (tmp0 >> 12) & 0x0f;
+ if (info->BiosConnector[tmp1].ConnectorType > CONNECTOR_UNSUPPORTED)
+ info->BiosConnector[tmp1].ConnectorType = CONNECTOR_UNSUPPORTED;
+ info->BiosConnector[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;
+ if (((info->BiosConnector[tmp1].ConnectorType != CONNECTOR_DVI_D) &&
+ (info->BiosConnector[tmp1].ConnectorType != CONNECTOR_DVI_I)) &&
+ info->BiosConnector[tmp1].TMDSType == TMDS_INT)
+ info->BiosConnector[tmp1].TMDSType = TMDS_UNKNOWN;
connector_found += (tmp1 + 1);
}
@@ -267,69 +473,52 @@ Bool RADEONGetConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
}
if (info->IsMobility) {
- /* For the cases where only one VGA connector is found,
- we assume LVDS is not listed in the connector table,
- add it in here as the first port.
- */
- if ((connector_found < 3) && (pRADEONEnt->PortInfo[tmp1]->ConnectorType == CONNECTOR_CRT)) {
- if (connector_found == 1) {
- memcpy (&pRADEONEnt->PortInfo[1], &pRADEONEnt->PortInfo[0],
- sizeof (pRADEONEnt->PortInfo[0]));
- }
- pRADEONEnt->PortInfo[0]->DACType = DAC_TVDAC;
- pRADEONEnt->PortInfo[0]->TMDSType = TMDS_UNKNOWN;
- pRADEONEnt->PortInfo[0]->DDCType = DDC_NONE_DETECTED;
- pRADEONEnt->PortInfo[0]->ConnectorType = CONNECTOR_PROPRIETARY;
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "LVDS port is not in connector table, added in.\n");
- if (connector_found == 0) connector_found = 1;
- else connector_found = 3;
- }
-
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;
- if (pRADEONEnt->PortInfo[0]->DDCType > DDC_CRT2) {
+ info->BiosConnector[0].DDCType = tmp1;
+ if (info->BiosConnector[0].DDCType > DDC_LCD) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Unknown DDCType %d found\n",
- pRADEONEnt->PortInfo[0]->DDCType);
- pRADEONEnt->PortInfo[0]->DDCType = DDC_NONE_DETECTED;
+ info->BiosConnector[0].DDCType);
+ info->BiosConnector[0].DDCType = DDC_NONE_DETECTED;
}
xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "LCD DDC Info Table found!\n");
}
}
}
} else if (connector_found == 2) {
- memcpy (&pRADEONEnt->PortInfo[0], &pRADEONEnt->PortInfo[1],
- sizeof (pRADEONEnt->PortInfo[0]));
- pRADEONEnt->PortInfo[1]->DACType = DAC_UNKNOWN;
- pRADEONEnt->PortInfo[1]->TMDSType = TMDS_UNKNOWN;
- pRADEONEnt->PortInfo[1]->DDCType = DDC_NONE_DETECTED;
- pRADEONEnt->PortInfo[1]->ConnectorType = CONNECTOR_NONE;
+ memcpy (&info->BiosConnector[0], &info->BiosConnector[1],
+ sizeof (info->BiosConnector[0]));
+ info->BiosConnector[1].DACType = DAC_UNKNOWN;
+ info->BiosConnector[1].TMDSType = TMDS_UNKNOWN;
+ info->BiosConnector[1].DDCType = DDC_NONE_DETECTED;
+ info->BiosConnector[1].ConnectorType = CONNECTOR_NONE;
connector_found = 1;
}
+ connector_found = RADEONBIOSApplyConnectorQuirks(pScrn, connector_found);
+
if (connector_found == 0) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "No connector found in Connector Info Table.\n");
} else {
- xf86DrvMsg(0, X_INFO, "Connector0: DDCType-%d, DACType-%d, TMDSType-%d, ConnectorType-%d\n",
- pRADEONEnt->PortInfo[0]->DDCType, pRADEONEnt->PortInfo[0]->DACType,
- pRADEONEnt->PortInfo[0]->TMDSType, pRADEONEnt->PortInfo[0]->ConnectorType);
+ xf86DrvMsg(0, X_INFO, "Bios Connector0: DDCType-%d, DACType-%d, TMDSType-%d, ConnectorType-%d\n",
+ info->BiosConnector[0].DDCType, info->BiosConnector[0].DACType,
+ info->BiosConnector[0].TMDSType, info->BiosConnector[0].ConnectorType);
}
if (connector_found == 3) {
- xf86DrvMsg(0, X_INFO, "Connector1: DDCType-%d, DACType-%d, TMDSType-%d, ConnectorType-%d\n",
- pRADEONEnt->PortInfo[1]->DDCType, pRADEONEnt->PortInfo[1]->DACType,
- pRADEONEnt->PortInfo[1]->TMDSType, pRADEONEnt->PortInfo[1]->ConnectorType);
+ xf86DrvMsg(0, X_INFO, "Bios Connector1: DDCType-%d, DACType-%d, TMDSType-%d, ConnectorType-%d\n",
+ info->BiosConnector[1].DDCType, info->BiosConnector[1].DACType,
+ info->BiosConnector[1].TMDSType, info->BiosConnector[1].ConnectorType);
}
#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;
+ //info->BiosConnector[1].DDCType = (RADEON_BIOS8(tmp0 + 7) & 0x07);
+ //info->BiosConnector[1].ConnectorType = CONNECTOR_DVI_I;
+ //info->BiosConnector[1].TMDSType = TMDS_EXT;
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "External TMDS found.\n");
} else {
@@ -341,6 +530,100 @@ Bool RADEONGetConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
}
return TRUE;
}
+#endif
+
+Bool RADEONGetTVInfoFromBIOS (xf86OutputPtr output) {
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+ int offset, refclk, stds;
+
+ if (!info->VBIOS) return FALSE;
+
+ if (info->IsAtomBios) {
+ /* no idea where TV table is on ATOM bios */
+ return FALSE;
+ } else {
+ offset = RADEON_BIOS16(info->ROMHeaderStart + 0x32);
+ if (offset) {
+ if (RADEON_BIOS8(offset + 6) == 'T') {
+ switch (RADEON_BIOS8(offset + 7) & 0xf) {
+ case 1:
+ radeon_output->default_tvStd = TV_STD_NTSC;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: NTSC\n");
+ break;
+ case 2:
+ radeon_output->default_tvStd = TV_STD_PAL;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: PAL\n");
+ break;
+ case 3:
+ radeon_output->default_tvStd = TV_STD_PAL_M;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: PAL-M\n");
+ break;
+ case 4:
+ radeon_output->default_tvStd = TV_STD_PAL_60;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: PAL-60\n");
+ break;
+ case 5:
+ radeon_output->default_tvStd = TV_STD_NTSC_J;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: NTSC-J\n");
+ break;
+ case 6:
+ radeon_output->default_tvStd = TV_STD_SCART_PAL;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: SCART-PAL\n");
+ break;
+ default:
+ radeon_output->default_tvStd = TV_STD_NTSC;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Unknown TV standard; defaulting to NTSC\n");
+ break;
+ }
+ radeon_output->tvStd = radeon_output->default_tvStd;
+
+ refclk = (RADEON_BIOS8(offset + 9) >> 2) & 0x3;
+ if (refclk == 0)
+ radeon_output->TVRefClk = 29.498928713; /* MHz */
+ else if (refclk == 1)
+ radeon_output->TVRefClk = 28.636360000;
+ else if (refclk == 2)
+ radeon_output->TVRefClk = 14.318180000;
+ else if (refclk == 3)
+ radeon_output->TVRefClk = 27.000000000;
+
+ radeon_output->SupportedTVStds = radeon_output->default_tvStd;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "TV standards supported by chip: ");
+ stds = RADEON_BIOS8(offset + 10) & 0x1f;
+ if (stds & TV_STD_NTSC) {
+ radeon_output->SupportedTVStds |= TV_STD_NTSC;
+ ErrorF("NTSC ");
+ }
+ if (stds & TV_STD_PAL) {
+ radeon_output->SupportedTVStds |= TV_STD_PAL;
+ ErrorF("PAL ");
+ }
+ if (stds & TV_STD_PAL_M) {
+ radeon_output->SupportedTVStds |= TV_STD_PAL_M;
+ ErrorF("PAL-M ");
+ }
+ if (stds & TV_STD_PAL_60) {
+ radeon_output->SupportedTVStds |= TV_STD_PAL_60;
+ ErrorF("PAL-60 ");
+ }
+ if (stds & TV_STD_NTSC_J) {
+ radeon_output->SupportedTVStds |= TV_STD_NTSC_J;
+ ErrorF("NTSC-J ");
+ }
+ if (stds & TV_STD_SCART_PAL) {
+ radeon_output->SupportedTVStds |= TV_STD_SCART_PAL;
+ ErrorF("SCART-PAL");
+ }
+ ErrorF("\n");
+
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
/* Read PLL parameters from BIOS block. Default to typical values if there
is no BIOS. */
@@ -370,8 +653,11 @@ Bool RADEONGetClockInfoFromBIOS (ScrnInfoPtr pScrn)
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);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ref_freq: %d, min_pll: %u, "
+ "max_pll: %u, xclk: %d, sclk: %f, mclk: %f\n",
+ pll->reference_freq, (unsigned)pll->min_pll_freq,
+ (unsigned)pll->max_pll_freq, pll->xclk, info->sclk,
+ info->mclk);
} else {
pll_info_block = RADEON_BIOS16 (info->ROMHeaderStart + 0x30);
@@ -390,9 +676,11 @@ Bool RADEONGetClockInfoFromBIOS (ScrnInfoPtr pScrn)
return TRUE;
}
-Bool RADEONGetLVDSInfoFromBIOS (ScrnInfoPtr pScrn)
+Bool RADEONGetLVDSInfoFromBIOS (xf86OutputPtr output)
{
- RADEONInfoPtr info = RADEONPTR(pScrn);
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
unsigned long tmp, i;
if (!info->VBIOS) return FALSE;
@@ -400,26 +688,29 @@ Bool RADEONGetLVDSInfoFromBIOS (ScrnInfoPtr pScrn)
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;
+ radeon_output->PanelXRes = RADEON_BIOS16(tmp+6);
+ radeon_output->PanelYRes = RADEON_BIOS16(tmp+10);
+ radeon_output->DotClock = RADEON_BIOS16(tmp+4)*10;
+ radeon_output->HBlank = RADEON_BIOS16(tmp+8);
+ radeon_output->HOverPlus = RADEON_BIOS16(tmp+14);
+ radeon_output->HSyncWidth = RADEON_BIOS16(tmp+16);
+ radeon_output->VBlank = RADEON_BIOS16(tmp+12);
+ radeon_output->VOverPlus = RADEON_BIOS16(tmp+18);
+ radeon_output->VSyncWidth = RADEON_BIOS16(tmp+20);
+ radeon_output->PanelPwrDly = RADEON_BIOS16(tmp+40);
+
+ if (radeon_output->PanelPwrDly > 2000 || radeon_output->PanelPwrDly < 0)
+ radeon_output->PanelPwrDly = 2000;
+
+ radeon_output->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);
+ radeon_output->PanelXRes, radeon_output->PanelYRes, radeon_output->DotClock,
+ radeon_output->HBlank, radeon_output->HOverPlus, radeon_output->HSyncWidth,
+ radeon_output->VBlank, radeon_output->VOverPlus, radeon_output->VSyncWidth);
} else {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"No LVDS Info Table found in BIOS!\n");
@@ -444,14 +735,14 @@ Bool RADEONGetLVDSInfoFromBIOS (ScrnInfoPtr pScrn)
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Panel ID string: %s\n", stmp);
- info->PanelXRes = RADEON_BIOS16(tmp+25);
- info->PanelYRes = RADEON_BIOS16(tmp+27);
+ radeon_output->PanelXRes = RADEON_BIOS16(tmp+25);
+ radeon_output->PanelYRes = RADEON_BIOS16(tmp+27);
xf86DrvMsg(0, X_INFO, "Panel Size from BIOS: %dx%d\n",
- info->PanelXRes, info->PanelYRes);
+ radeon_output->PanelXRes, radeon_output->PanelYRes);
- info->PanelPwrDly = RADEON_BIOS16(tmp+44);
- if (info->PanelPwrDly > 2000 || info->PanelPwrDly < 0)
- info->PanelPwrDly = 2000;
+ radeon_output->PanelPwrDly = RADEON_BIOS16(tmp+44);
+ if (radeon_output->PanelPwrDly > 2000 || radeon_output->PanelPwrDly < 0)
+ radeon_output->PanelPwrDly = 2000;
/* some panels only work well with certain divider combinations.
*/
@@ -472,20 +763,20 @@ Bool RADEONGetLVDSInfoFromBIOS (ScrnInfoPtr pScrn)
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) -
+ if ((RADEON_BIOS16(tmp0) == radeon_output->PanelXRes) &&
+ (RADEON_BIOS16(tmp0+2) == radeon_output->PanelYRes)) {
+ radeon_output->HBlank = (RADEON_BIOS16(tmp0+17) -
RADEON_BIOS16(tmp0+19)) * 8;
- info->HOverPlus = (RADEON_BIOS16(tmp0+21) -
+ radeon_output->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_output->HSyncWidth = RADEON_BIOS8(tmp0+23) * 8;
+ radeon_output->VBlank = (RADEON_BIOS16(tmp0+24) -
RADEON_BIOS16(tmp0+26));
- info->VOverPlus = ((RADEON_BIOS16(tmp0+28) & 0x7ff) -
+ radeon_output->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;
+ radeon_output->VSyncWidth = ((RADEON_BIOS16(tmp0+28) & 0xf800) >> 11);
+ radeon_output->DotClock = RADEON_BIOS16(tmp0+9) * 10;
+ radeon_output->Flags = 0;
}
}
}
@@ -493,9 +784,11 @@ Bool RADEONGetLVDSInfoFromBIOS (ScrnInfoPtr pScrn)
return TRUE;
}
-Bool RADEONGetHardCodedEDIDFromBIOS (ScrnInfoPtr pScrn)
+Bool RADEONGetHardCodedEDIDFromBIOS (xf86OutputPtr output)
{
- RADEONInfoPtr info = RADEONPTR(pScrn);
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
unsigned long tmp;
char EDID[256];
@@ -511,24 +804,26 @@ Bool RADEONGetHardCodedEDIDFromBIOS (ScrnInfoPtr pScrn)
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);*/
+ radeon_output->DotClock = (*(CARD16*)(EDID+54)) * 10;
+ radeon_output->PanelXRes = (*(CARD8*)(EDID+56)) + ((*(CARD8*)(EDID+58))>>4)*256;
+ radeon_output->HBlank = (*(CARD8*)(EDID+57)) + ((*(CARD8*)(EDID+58)) & 0xf)*256;
+ radeon_output->HOverPlus = (*(CARD8*)(EDID+62)) + ((*(CARD8*)(EDID+65)>>6)*256);
+ radeon_output->HSyncWidth = (*(CARD8*)(EDID+63)) + (((*(CARD8*)(EDID+65)>>4) & 3)*256);
+ radeon_output->PanelYRes = (*(CARD8*)(EDID+59)) + ((*(CARD8*)(EDID+61))>>4)*256;
+ radeon_output->VBlank = ((*(CARD8*)(EDID+60)) + ((*(CARD8*)(EDID+61)) & 0xf)*256);
+ radeon_output->VOverPlus = (((*(CARD8*)(EDID+64))>>4) + (((*(CARD8*)(EDID+65)>>2) & 3)*16));
+ radeon_output->VSyncWidth = (((*(CARD8*)(EDID+64)) & 0xf) + ((*(CARD8*)(EDID+65)) & 3)*256);
+ radeon_output->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)
+Bool RADEONGetTMDSInfoFromBIOS (xf86OutputPtr output)
{
- RADEONInfoPtr info = RADEONPTR(pScrn);
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
CARD32 tmp, maxfreq;
int i, n;
@@ -540,18 +835,19 @@ Bool RADEONGetTMDSInfoFromBIOS (ScrnInfoPtr pScrn)
maxfreq = RADEON_BIOS16(tmp+4);
for (i=0; i<4; i++) {
- info->tmds_pll[i].freq = RADEON_BIOS16(tmp+i*6+6);
+ radeon_output->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_output->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);
+ "TMDS PLL from BIOS: %u %x\n",
+ (unsigned)radeon_output->tmds_pll[i].freq,
+ (unsigned)radeon_output->tmds_pll[i].value);
- if (maxfreq == info->tmds_pll[i].freq) {
- info->tmds_pll[i].freq = 0xffffffff;
+ if (maxfreq == radeon_output->tmds_pll[i].freq) {
+ radeon_output->tmds_pll[i].freq = 0xffffffff;
break;
}
}
@@ -567,8 +863,8 @@ Bool RADEONGetTMDSInfoFromBIOS (ScrnInfoPtr pScrn)
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);
+ radeon_output->tmds_pll[i].value = RADEON_BIOS32(tmp+i*10+0x08);
+ radeon_output->tmds_pll[i].freq = RADEON_BIOS16(tmp+i*10+0x10);
}
return TRUE;
} else if (RADEON_BIOS8(tmp) == 4) {
@@ -576,31 +872,475 @@ Bool RADEONGetTMDSInfoFromBIOS (ScrnInfoPtr pScrn)
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);
+ radeon_output->tmds_pll[i].value = RADEON_BIOS32(tmp+stride+0x08);
+ radeon_output->tmds_pll[i].freq = RADEON_BIOS16(tmp+stride+0x10);
if (i == 0) stride += 10;
else stride += 6;
}
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;
}
+
+/* support for init from bios tables
+ *
+ * Based heavily on the netbsd radeonfb driver
+ * Written by Garrett D'Amore
+ * Copyright (c) 2006 Itronix Inc.
+ *
+ */
+
+/* bios table defines */
+
+#define RADEON_TABLE_ENTRY_FLAG_MASK 0xe000
+#define RADEON_TABLE_ENTRY_INDEX_MASK 0x1fff
+#define RADEON_TABLE_ENTRY_COMMAND_MASK 0x00ff
+
+#define RADEON_TABLE_FLAG_WRITE_INDEXED 0x0000
+#define RADEON_TABLE_FLAG_WRITE_DIRECT 0x2000
+#define RADEON_TABLE_FLAG_MASK_INDEXED 0x4000
+#define RADEON_TABLE_FLAG_MASK_DIRECT 0x6000
+#define RADEON_TABLE_FLAG_DELAY 0x8000
+#define RADEON_TABLE_FLAG_SCOMMAND 0xa000
+
+#define RADEON_TABLE_SCOMMAND_WAIT_MC_BUSY_MASK 0x03
+#define RADEON_TABLE_SCOMMAND_WAIT_MEM_PWRUP_COMPLETE 0x08
+
+#define RADEON_PLL_FLAG_MASK 0xc0
+#define RADEON_PLL_INDEX_MASK 0x3f
+
+#define RADEON_PLL_FLAG_WRITE 0x00
+#define RADEON_PLL_FLAG_MASK_BYTE 0x40
+#define RADEON_PLL_FLAG_WAIT 0x80
+
+#define RADEON_PLL_WAIT_150MKS 1
+#define RADEON_PLL_WAIT_5MS 2
+#define RADEON_PLL_WAIT_MC_BUSY_MASK 3
+#define RADEON_PLL_WAIT_DLL_READY_MASK 4
+#define RADEON_PLL_WAIT_CHK_SET_CLK_PWRMGT_CNTL24 5
+
+static CARD16
+RADEONValidateBIOSOffset(ScrnInfoPtr pScrn, CARD16 offset)
+{
+ RADEONInfoPtr info = RADEONPTR (pScrn);
+ CARD8 revision = RADEON_BIOS8(offset - 1);
+
+ if (revision > 0x10) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Bad revision %d for BIOS table\n", revision);
+ return 0;
+ }
+
+ if (offset < 0x60) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Bad offset 0x%x for BIOS Table\n", offset);
+ return 0;
+ }
+
+ return offset;
+}
+
+Bool
+RADEONGetBIOSInitTableOffsets(ScrnInfoPtr pScrn)
+{
+ RADEONInfoPtr info = RADEONPTR (pScrn);
+ CARD8 val;
+
+ if (!info->VBIOS) {
+ return FALSE;
+ } else {
+ if (info->IsAtomBios) {
+ return FALSE;
+ } else {
+ info->BiosTable.revision = RADEON_BIOS8(info->ROMHeaderStart + 4);
+ info->BiosTable.rr1_offset = RADEON_BIOS16(info->ROMHeaderStart + 0x0c);
+ if (info->BiosTable.rr1_offset) {
+ info->BiosTable.rr1_offset =
+ RADEONValidateBIOSOffset(pScrn, info->BiosTable.rr1_offset);
+ }
+ if (info->BiosTable.revision > 0x09)
+ return TRUE;
+ info->BiosTable.rr2_offset = RADEON_BIOS16(info->ROMHeaderStart + 0x4e);
+ if (info->BiosTable.rr2_offset) {
+ info->BiosTable.rr2_offset =
+ RADEONValidateBIOSOffset(pScrn, info->BiosTable.rr2_offset);
+ }
+ info->BiosTable.dyn_clk_offset = RADEON_BIOS16(info->ROMHeaderStart + 0x52);
+ if (info->BiosTable.dyn_clk_offset) {
+ info->BiosTable.dyn_clk_offset =
+ RADEONValidateBIOSOffset(pScrn, info->BiosTable.dyn_clk_offset);
+ }
+ info->BiosTable.pll_offset = RADEON_BIOS16(info->ROMHeaderStart + 0x46);
+ if (info->BiosTable.pll_offset) {
+ info->BiosTable.pll_offset =
+ RADEONValidateBIOSOffset(pScrn, info->BiosTable.pll_offset);
+ }
+ info->BiosTable.mem_config_offset = RADEON_BIOS16(info->ROMHeaderStart + 0x48);
+ if (info->BiosTable.mem_config_offset) {
+ info->BiosTable.mem_config_offset =
+ RADEONValidateBIOSOffset(pScrn, info->BiosTable.mem_config_offset);
+ }
+ if (info->BiosTable.mem_config_offset) {
+ info->BiosTable.mem_reset_offset = info->BiosTable.mem_config_offset;
+ if (info->BiosTable.mem_reset_offset) {
+ while (RADEON_BIOS8(info->BiosTable.mem_reset_offset))
+ info->BiosTable.mem_reset_offset++;
+ info->BiosTable.mem_reset_offset++;
+ info->BiosTable.mem_reset_offset += 2;
+ }
+ }
+ if (info->BiosTable.mem_config_offset) {
+ info->BiosTable.short_mem_offset = info->BiosTable.mem_config_offset;
+ if ((info->BiosTable.short_mem_offset != 0) &&
+ (RADEON_BIOS8(info->BiosTable.short_mem_offset - 2) <= 64))
+ info->BiosTable.short_mem_offset +=
+ RADEON_BIOS8(info->BiosTable.short_mem_offset - 3);
+ }
+ if (info->BiosTable.rr2_offset) {
+ info->BiosTable.rr3_offset = info->BiosTable.rr2_offset;
+ if (info->BiosTable.rr3_offset) {
+ while ((val = RADEON_BIOS8(info->BiosTable.rr3_offset + 1)) != 0) {
+ if (val & 0x40)
+ info->BiosTable.rr3_offset += 10;
+ else if (val & 0x80)
+ info->BiosTable.rr3_offset += 4;
+ else
+ info->BiosTable.rr3_offset += 6;
+ }
+ info->BiosTable.rr3_offset += 2;
+ }
+ }
+
+ if (info->BiosTable.rr3_offset) {
+ info->BiosTable.rr4_offset = info->BiosTable.rr3_offset;
+ if (info->BiosTable.rr4_offset) {
+ while ((val = RADEON_BIOS8(info->BiosTable.rr4_offset + 1)) != 0) {
+ if (val & 0x40)
+ info->BiosTable.rr4_offset += 10;
+ else if (val & 0x80)
+ info->BiosTable.rr4_offset += 4;
+ else
+ info->BiosTable.rr4_offset += 6;
+ }
+ info->BiosTable.rr4_offset += 2;
+ }
+ }
+
+ if (info->BiosTable.rr3_offset + 1 == info->BiosTable.pll_offset) {
+ info->BiosTable.rr3_offset = 0;
+ info->BiosTable.rr4_offset = 0;
+ }
+
+ return TRUE;
+
+ }
+ }
+}
+
+static void
+RADEONRestoreBIOSRegBlock(ScrnInfoPtr pScrn, CARD16 table_offset)
+{
+ RADEONInfoPtr info = RADEONPTR (pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ CARD16 offset = table_offset;
+ CARD16 value, flag, index, count;
+ CARD32 andmask, ormask, val, channel_complete_mask;
+ CARD8 command;
+
+ if (offset == 0)
+ return;
+
+ while ((value = RADEON_BIOS16(offset)) != 0) {
+ flag = value & RADEON_TABLE_ENTRY_FLAG_MASK;
+ index = value & RADEON_TABLE_ENTRY_INDEX_MASK;
+ command = value & RADEON_TABLE_ENTRY_COMMAND_MASK;
+
+ offset += 2;
+
+ switch (flag) {
+ case RADEON_TABLE_FLAG_WRITE_INDEXED:
+ val = RADEON_BIOS32(offset);
+ ErrorF("WRITE INDEXED: 0x%x 0x%x\n",
+ index, (unsigned)val);
+ OUTREG(RADEON_MM_INDEX, index);
+ OUTREG(RADEON_MM_DATA, val);
+ offset += 4;
+ break;
+
+ case RADEON_TABLE_FLAG_WRITE_DIRECT:
+ val = RADEON_BIOS32(offset);
+ ErrorF("WRITE DIRECT: 0x%x 0x%x\n", index, (unsigned)val);
+ OUTREG(index, val);
+ offset += 4;
+ break;
+
+ case RADEON_TABLE_FLAG_MASK_INDEXED:
+ andmask = RADEON_BIOS32(offset);
+ offset += 4;
+ ormask = RADEON_BIOS32(offset);
+ offset += 4;
+ ErrorF("MASK INDEXED: 0x%x 0x%x 0x%x\n",
+ index, (unsigned)andmask, (unsigned)ormask);
+ OUTREG(RADEON_MM_INDEX, index);
+ val = INREG(RADEON_MM_DATA);
+ val = (val & andmask) | ormask;
+ OUTREG(RADEON_MM_DATA, val);
+ break;
+
+ case RADEON_TABLE_FLAG_MASK_DIRECT:
+ andmask = RADEON_BIOS32(offset);
+ offset += 4;
+ ormask = RADEON_BIOS32(offset);
+ offset += 4;
+ ErrorF("MASK DIRECT: 0x%x 0x%x 0x%x\n",
+ index, (unsigned)andmask, (unsigned)ormask);
+ val = INREG(index);
+ val = (val & andmask) | ormask;
+ OUTREG(index, val);
+ break;
+
+ case RADEON_TABLE_FLAG_DELAY:
+ count = RADEON_BIOS16(offset);
+ ErrorF("delay: %d\n", count);
+ usleep(count);
+ offset += 2;
+ break;
+
+ case RADEON_TABLE_FLAG_SCOMMAND:
+ ErrorF("SCOMMAND 0x%x\n", command);
+ switch (command) {
+ case RADEON_TABLE_SCOMMAND_WAIT_MC_BUSY_MASK:
+ count = RADEON_BIOS16(offset);
+ ErrorF("SCOMMAND_WAIT_MC_BUSY_MASK %d\n", count);
+ while (count--) {
+ if (!(INPLL(pScrn, RADEON_CLK_PWRMGT_CNTL) &
+ RADEON_MC_BUSY))
+ break;
+ }
+ break;
+
+ case RADEON_TABLE_SCOMMAND_WAIT_MEM_PWRUP_COMPLETE:
+ count = RADEON_BIOS16(offset);
+ ErrorF("SCOMMAND_WAIT_MEM_PWRUP_COMPLETE %d\n", count);
+ /* may need to take into account how many memory channels
+ * each card has
+ */
+ if (IS_R300_VARIANT)
+ channel_complete_mask = R300_MEM_PWRUP_COMPLETE;
+ else
+ channel_complete_mask = RADEON_MEM_PWRUP_COMPLETE;
+ while (count--) {
+ /* XXX: may need indexed access */
+ if ((INREG(RADEON_MEM_STR_CNTL) &
+ channel_complete_mask) ==
+ channel_complete_mask)
+ break;
+ }
+ break;
+
+ }
+ offset += 2;
+ break;
+ }
+ }
+}
+
+static void
+RADEONRestoreBIOSMemBlock(ScrnInfoPtr pScrn, CARD16 table_offset)
+{
+ RADEONInfoPtr info = RADEONPTR (pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ CARD16 offset = table_offset;
+ CARD16 count;
+ CARD32 ormask, val, channel_complete_mask;
+ CARD8 index;
+
+ if (offset == 0)
+ return;
+
+ while ((index = RADEON_BIOS8(offset)) != 0xff) {
+ offset++;
+ if (index == 0x0f) {
+ count = 20000;
+ ErrorF("MEM_WAIT_MEM_PWRUP_COMPLETE %d\n", count);
+ /* may need to take into account how many memory channels
+ * each card has
+ */
+ if (IS_R300_VARIANT)
+ channel_complete_mask = R300_MEM_PWRUP_COMPLETE;
+ else
+ channel_complete_mask = RADEON_MEM_PWRUP_COMPLETE;
+ while (count--) {
+ /* XXX: may need indexed access */
+ if ((INREG(RADEON_MEM_STR_CNTL) &
+ channel_complete_mask) ==
+ channel_complete_mask)
+ break;
+ }
+ } else {
+ ormask = RADEON_BIOS16(offset);
+ offset += 2;
+
+ ErrorF("INDEX RADEON_MEM_SDRAM_MODE_REG %x %x\n",
+ RADEON_SDRAM_MODE_MASK, (unsigned)ormask);
+
+ /* can this use direct access? */
+ OUTREG(RADEON_MM_INDEX, RADEON_MEM_SDRAM_MODE_REG);
+ val = INREG(RADEON_MM_DATA);
+ val = (val & RADEON_SDRAM_MODE_MASK) | ormask;
+ OUTREG(RADEON_MM_DATA, val);
+
+ ormask = (CARD32)index << 24;
+
+ ErrorF("INDEX RADEON_MEM_SDRAM_MODE_REG %x %x\n",
+ RADEON_B3MEM_RESET_MASK, (unsigned)ormask);
+
+ /* can this use direct access? */
+ OUTREG(RADEON_MM_INDEX, RADEON_MEM_SDRAM_MODE_REG);
+ val = INREG(RADEON_MM_DATA);
+ val = (val & RADEON_B3MEM_RESET_MASK) | ormask;
+ OUTREG(RADEON_MM_DATA, val);
+ }
+ }
+}
+
+static void
+RADEONRestoreBIOSPllBlock(ScrnInfoPtr pScrn, CARD16 table_offset)
+{
+ RADEONInfoPtr info = RADEONPTR (pScrn);
+ CARD16 offset = table_offset;
+ CARD8 index, shift;
+ CARD32 andmask, ormask, val, clk_pwrmgt_cntl;
+ CARD16 count;
+
+ if (offset == 0)
+ return;
+
+ while ((index = RADEON_BIOS8(offset)) != 0) {
+ offset++;
+
+ switch (index & RADEON_PLL_FLAG_MASK) {
+ case RADEON_PLL_FLAG_WAIT:
+ switch (index & RADEON_PLL_INDEX_MASK) {
+ case RADEON_PLL_WAIT_150MKS:
+ ErrorF("delay: 150 us\n");
+ usleep(150);
+ break;
+ case RADEON_PLL_WAIT_5MS:
+ ErrorF("delay: 5 ms\n");
+ usleep(5000);
+ break;
+
+ case RADEON_PLL_WAIT_MC_BUSY_MASK:
+ count = 1000;
+ ErrorF("PLL_WAIT_MC_BUSY_MASK %d\n", count);
+ while (count--) {
+ if (!(INPLL(pScrn, RADEON_CLK_PWRMGT_CNTL) &
+ RADEON_MC_BUSY))
+ break;
+ }
+ break;
+
+ case RADEON_PLL_WAIT_DLL_READY_MASK:
+ count = 1000;
+ ErrorF("PLL_WAIT_DLL_READY_MASK %d\n", count);
+ while (count--) {
+ if (INPLL(pScrn, RADEON_CLK_PWRMGT_CNTL) &
+ RADEON_DLL_READY)
+ break;
+ }
+ break;
+
+ case RADEON_PLL_WAIT_CHK_SET_CLK_PWRMGT_CNTL24:
+ ErrorF("PLL_WAIT_CHK_SET_CLK_PWRMGT_CNTL24\n");
+ clk_pwrmgt_cntl = INPLL(pScrn, RADEON_CLK_PWRMGT_CNTL);
+ if (clk_pwrmgt_cntl & RADEON_CG_NO1_DEBUG_0) {
+ val = INPLL(pScrn, RADEON_MCLK_CNTL);
+ /* is this right? */
+ val = (val & 0xFFFF0000) | 0x1111; /* seems like we should clear these... */
+ OUTPLL(pScrn, RADEON_MCLK_CNTL, val);
+ usleep(10000);
+ OUTPLL(pScrn, RADEON_CLK_PWRMGT_CNTL,
+ clk_pwrmgt_cntl & ~RADEON_CG_NO1_DEBUG_0);
+ usleep(10000);
+ }
+ break;
+ }
+ break;
+
+ case RADEON_PLL_FLAG_MASK_BYTE:
+ shift = RADEON_BIOS8(offset) * 8;
+ offset++;
+
+ andmask =
+ (((CARD32)RADEON_BIOS8(offset)) << shift) |
+ ~((CARD32)0xff << shift);
+ offset++;
+
+ ormask = ((CARD32)RADEON_BIOS8(offset)) << shift;
+ offset++;
+
+ ErrorF("PLL_MASK_BYTE 0x%x 0x%x 0x%x 0x%x\n",
+ index, shift, (unsigned)andmask, (unsigned)ormask);
+ val = INPLL(pScrn, index);
+ val = (val & andmask) | ormask;
+ OUTPLL(pScrn, index, val);
+ break;
+
+ case RADEON_PLL_FLAG_WRITE:
+ val = RADEON_BIOS32(offset);
+ ErrorF("PLL_WRITE 0x%x 0x%x\n", index, (unsigned)val);
+ OUTPLL(pScrn, index, val);
+ offset += 4;
+ break;
+ }
+ }
+}
+
+Bool
+RADEONPostCardFromBIOSTables(ScrnInfoPtr pScrn)
+{
+ RADEONInfoPtr info = RADEONPTR (pScrn);
+
+ if (!info->VBIOS) {
+ return FALSE;
+ } else {
+ if (info->IsAtomBios) {
+ return FALSE;
+ } else {
+ if (info->BiosTable.rr1_offset) {
+ ErrorF("rr1 restore, 0x%x\n", info->BiosTable.rr1_offset);
+ RADEONRestoreBIOSRegBlock(pScrn, info->BiosTable.rr1_offset);
+ }
+ if (info->BiosTable.revision < 0x09) {
+ if (info->BiosTable.pll_offset) {
+ ErrorF("pll restore, 0x%x\n", info->BiosTable.pll_offset);
+ RADEONRestoreBIOSPllBlock(pScrn, info->BiosTable.pll_offset);
+ }
+ if (info->BiosTable.rr2_offset) {
+ ErrorF("rr2 restore, 0x%x\n", info->BiosTable.rr2_offset);
+ RADEONRestoreBIOSRegBlock(pScrn, info->BiosTable.rr2_offset);
+ }
+ if (info->BiosTable.rr4_offset) {
+ ErrorF("rr4 restore, 0x%x\n", info->BiosTable.rr4_offset);
+ RADEONRestoreBIOSRegBlock(pScrn, info->BiosTable.rr4_offset);
+ }
+ if (info->BiosTable.mem_reset_offset) {
+ ErrorF("mem reset restore, 0x%x\n", info->BiosTable.mem_reset_offset);
+ RADEONRestoreBIOSMemBlock(pScrn, info->BiosTable.mem_reset_offset);
+ }
+ if (info->BiosTable.rr3_offset) {
+ ErrorF("rr3 restore, 0x%x\n", info->BiosTable.rr3_offset);
+ RADEONRestoreBIOSRegBlock(pScrn, info->BiosTable.rr3_offset);
+ }
+ if (info->BiosTable.dyn_clk_offset) {
+ ErrorF("dyn_clk restore, 0x%x\n", info->BiosTable.dyn_clk_offset);
+ RADEONRestoreBIOSPllBlock(pScrn, info->BiosTable.dyn_clk_offset);
+ }
+ }
+ }
+ }
+ return TRUE;
+}
diff --git a/src/radeon_common.h b/src/radeon_common.h
index 3f2c6aba..467addf4 100644
--- a/src/radeon_common.h
+++ b/src/radeon_common.h
@@ -420,6 +420,8 @@ typedef union {
#define RADEON_PARAM_SAREA_HANDLE 9
#define RADEON_PARAM_GART_TEX_HANDLE 10
#define RADEON_PARAM_SCRATCH_OFFSET 11
+#define RADEON_PARAM_CARD_TYPE 12
+#define RADEON_PARAM_VBLANK_CRTC 13 /* VBLANK CRTC */
typedef struct drm_radeon_getparam {
int param;
@@ -473,7 +475,7 @@ typedef struct drm_radeon_set_param {
#define RADEON_SETPARAM_PCIGART_LOCATION 3
#define RADEON_SETPARAM_NEW_MEMMAP 4
#define RADEON_SETPARAM_PCIGART_TABLE_SIZE 5
-
+#define RADEON_SETPARAM_VBLANK_CRTC 6 /* VBLANK CRTC */
/* 1.14: Clients can allocate/free a surface
*/
typedef struct drm_radeon_surface_alloc {
@@ -486,4 +488,7 @@ typedef struct drm_radeon_surface_free {
unsigned int address;
} drmRadeonSurfaceFree;
+#define DRM_RADEON_VBLANK_CRTC1 1
+#define DRM_RADEON_VBLANK_CRTC2 2
+
#endif
diff --git a/src/radeon_commonfuncs.c b/src/radeon_commonfuncs.c
index 70f7ddc1..6a999af5 100644
--- a/src/radeon_commonfuncs.c
+++ b/src/radeon_commonfuncs.c
@@ -156,9 +156,10 @@ void FUNC_NAME(RADEONWaitForIdle)(ScrnInfoPtr pScrn)
#endif
#if 0
- RADEONTRACE(("WaitForIdle (entering): %d entries, stat=0x%08x\n",
- INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK,
- INREG(RADEON_RBBM_STATUS)));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "WaitForIdle (entering): %d entries, stat=0x%08x\n",
+ INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK,
+ INREG(RADEON_RBBM_STATUS));
#endif
/* Wait for the engine to go idle */
@@ -171,9 +172,10 @@ void FUNC_NAME(RADEONWaitForIdle)(ScrnInfoPtr pScrn)
return;
}
}
- RADEONTRACE(("Idle timed out: %u entries, stat=0x%08x\n",
- INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK,
- INREG(RADEON_RBBM_STATUS)));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "Idle timed out: %u entries, stat=0x%08x\n",
+ INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK,
+ INREG(RADEON_RBBM_STATUS));
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Idle timed out, resetting engine...\n");
RADEONEngineReset(pScrn);
diff --git a/src/radeon_crtc.c b/src/radeon_crtc.c
new file mode 100644
index 00000000..e976e2c9
--- /dev/null
+++ b/src/radeon_crtc.c
@@ -0,0 +1,1317 @@
+/*
+ * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
+ * VA Linux Systems Inc., Fremont, California.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+#include <stdio.h>
+
+/* X and server generic header files */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "vgaHW.h"
+#include "xf86Modes.h"
+
+/* Driver data structures */
+#include "radeon.h"
+#include "radeon_reg.h"
+#include "radeon_macros.h"
+#include "radeon_probe.h"
+#include "radeon_version.h"
+
+#ifdef XF86DRI
+#define _XF86DRI_SERVER_
+#include "radeon_dri.h"
+#include "radeon_sarea.h"
+#include "sarea.h"
+#endif
+
+void radeon_crtc_load_lut(xf86CrtcPtr crtc);
+
+static void
+radeon_crtc_dpms(xf86CrtcPtr crtc, int mode)
+{
+ int mask;
+ ScrnInfoPtr pScrn = crtc->scrn;
+ RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+
+ mask = radeon_crtc->crtc_id ? (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS | RADEON_CRTC2_HSYNC_DIS | RADEON_CRTC2_DISP_REQ_EN_B) : (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS | RADEON_CRTC_VSYNC_DIS);
+
+
+ switch(mode) {
+ case DPMSModeOn:
+ if (radeon_crtc->crtc_id) {
+ OUTREGP(RADEON_CRTC2_GEN_CNTL, 0, ~mask);
+ } else {
+ OUTREGP(RADEON_CRTC_GEN_CNTL, 0, ~RADEON_CRTC_DISP_REQ_EN_B);
+ OUTREGP(RADEON_CRTC_EXT_CNTL, 0, ~mask);
+ }
+ break;
+ case DPMSModeStandby:
+ if (radeon_crtc->crtc_id) {
+ OUTREGP(RADEON_CRTC2_GEN_CNTL, (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_HSYNC_DIS), ~mask);
+ } else {
+ OUTREGP(RADEON_CRTC_GEN_CNTL, 0, ~RADEON_CRTC_DISP_REQ_EN_B);
+ OUTREGP(RADEON_CRTC_EXT_CNTL, (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS), ~mask);
+ }
+ break;
+ case DPMSModeSuspend:
+ if (radeon_crtc->crtc_id) {
+ OUTREGP(RADEON_CRTC2_GEN_CNTL, (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS), ~mask);
+ } else {
+ OUTREGP(RADEON_CRTC_GEN_CNTL, 0, ~RADEON_CRTC_DISP_REQ_EN_B);
+ OUTREGP(RADEON_CRTC_EXT_CNTL, (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_VSYNC_DIS), ~mask);
+ }
+ break;
+ case DPMSModeOff:
+ if (radeon_crtc->crtc_id) {
+ OUTREGP(RADEON_CRTC2_GEN_CNTL, mask, ~mask);
+ } else {
+ OUTREGP(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_DISP_REQ_EN_B, ~RADEON_CRTC_DISP_REQ_EN_B);
+ OUTREGP(RADEON_CRTC_EXT_CNTL, mask, ~mask);
+ }
+ break;
+ }
+
+ if (mode != DPMSModeOff)
+ radeon_crtc_load_lut(crtc);
+}
+
+static Bool
+radeon_crtc_mode_fixup(xf86CrtcPtr crtc, DisplayModePtr mode,
+ DisplayModePtr adjusted_mode)
+{
+ return TRUE;
+}
+
+static void
+radeon_crtc_mode_prepare(xf86CrtcPtr crtc)
+{
+ radeon_crtc_dpms(crtc, DPMSModeOff);
+}
+
+/* Define common registers for requested video mode */
+static void
+RADEONInitCommonRegisters(RADEONSavePtr save, RADEONInfoPtr info)
+{
+ save->ovr_clr = 0;
+ save->ovr_wid_left_right = 0;
+ save->ovr_wid_top_bottom = 0;
+ save->ov0_scale_cntl = 0;
+ save->subpic_cntl = 0;
+ save->viph_control = 0;
+ save->i2c_cntl_1 = 0;
+ save->rbbm_soft_reset = 0;
+ save->cap0_trig_cntl = 0;
+ save->cap1_trig_cntl = 0;
+ save->bus_cntl = info->BusCntl;
+ /*
+ * If bursts are enabled, turn on discards
+ * Radeon doesn't have write bursts
+ */
+ if (save->bus_cntl & (RADEON_BUS_READ_BURST))
+ save->bus_cntl |= RADEON_BUS_RD_DISCARD_EN;
+}
+
+static void
+RADEONInitSurfaceCntl(xf86CrtcPtr crtc, RADEONSavePtr save)
+{
+ ScrnInfoPtr pScrn = crtc->scrn;
+
+ save->surface_cntl = 0;
+
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ /* We must set both apertures as they can be both used to map the entire
+ * video memory. -BenH.
+ */
+ switch (pScrn->bitsPerPixel) {
+ case 16:
+ save->surface_cntl |= RADEON_NONSURF_AP0_SWP_16BPP;
+ save->surface_cntl |= RADEON_NONSURF_AP1_SWP_16BPP;
+ break;
+
+ case 32:
+ save->surface_cntl |= RADEON_NONSURF_AP0_SWP_32BPP;
+ save->surface_cntl |= RADEON_NONSURF_AP1_SWP_32BPP;
+ break;
+ }
+#endif
+
+}
+
+static Bool
+RADEONInitCrtcBase(xf86CrtcPtr crtc, RADEONSavePtr save,
+ int x, int y)
+{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ int Base;
+#ifdef XF86DRI
+ RADEONSAREAPrivPtr pSAREAPriv;
+ XF86DRISAREAPtr pSAREA;
+#endif
+
+ save->crtc_offset = pScrn->fbOffset;
+#ifdef XF86DRI
+ if (info->allowPageFlip)
+ save->crtc_offset_cntl = RADEON_CRTC_OFFSET_FLIP_CNTL;
+ else
+#endif
+ save->crtc_offset_cntl = 0;
+
+ if (info->tilingEnabled && (crtc->rotatedData == NULL)) {
+ if (IS_R300_VARIANT)
+ save->crtc_offset_cntl |= (R300_CRTC_X_Y_MODE_EN |
+ R300_CRTC_MICRO_TILE_BUFFER_DIS |
+ R300_CRTC_MACRO_TILE_EN);
+ else
+ save->crtc_offset_cntl |= RADEON_CRTC_TILE_EN;
+ }
+ else {
+ if (IS_R300_VARIANT)
+ save->crtc_offset_cntl &= ~(R300_CRTC_X_Y_MODE_EN |
+ R300_CRTC_MICRO_TILE_BUFFER_DIS |
+ R300_CRTC_MACRO_TILE_EN);
+ else
+ save->crtc_offset_cntl &= ~RADEON_CRTC_TILE_EN;
+ }
+
+ Base = pScrn->fbOffset;
+
+ if (info->tilingEnabled && (crtc->rotatedData == NULL)) {
+ if (IS_R300_VARIANT) {
+ /* On r300/r400 when tiling is enabled crtc_offset is set to the address of
+ * the surface. the x/y offsets are handled by the X_Y tile reg for each crtc
+ * Makes tiling MUCH easier.
+ */
+ save->crtc_tile_x0_y0 = x | (y << 16);
+ Base &= ~0x7ff;
+ } else {
+ /* note we cannot really simply use the info->ModeReg.crtc_offset_cntl value, since the
+ drm might have set FLIP_CNTL since we wrote that. Unfortunately FLIP_CNTL causes
+ flickering when scrolling vertically in a virtual screen, possibly because crtc will
+ pick up the new offset value at the end of each scanline, but the new offset_cntl value
+ only after a vsync. We'd probably need to wait (in drm) for vsync and only then update
+ OFFSET and OFFSET_CNTL, if the y coord has changed. Seems hard to fix. */
+ /*save->crtc_offset_cntl = INREG(RADEON_CRTC_OFFSET_CNTL) & ~0xf;*/
+#if 0
+ /* try to get rid of flickering when scrolling at least for 2d */
+#ifdef XF86DRI
+ if (!info->have3DWindows)
+#endif
+ save->crtc_offset_cntl &= ~RADEON_CRTC_OFFSET_FLIP_CNTL;
+#endif
+
+ int byteshift = info->CurrentLayout.bitsPerPixel >> 4;
+ /* crtc uses 256(bytes)x8 "half-tile" start addresses? */
+ int tile_addr = (((y >> 3) * info->CurrentLayout.displayWidth + x) >> (8 - byteshift)) << 11;
+ Base += tile_addr + ((x << byteshift) % 256) + ((y % 8) << 8);
+ save->crtc_offset_cntl = save->crtc_offset_cntl | (y % 16);
+ }
+ }
+ else {
+ int offset = y * info->CurrentLayout.displayWidth + x;
+ switch (info->CurrentLayout.pixel_code) {
+ case 15:
+ case 16: offset *= 2; break;
+ case 24: offset *= 3; break;
+ case 32: offset *= 4; break;
+ }
+ Base += offset;
+ }
+
+ if (crtc->rotatedData != NULL) {
+ Base = pScrn->fbOffset + (char *)crtc->rotatedData - (char *)info->FB;
+ }
+
+ Base &= ~7; /* 3 lower bits are always 0 */
+
+
+#ifdef XF86DRI
+ if (info->directRenderingInited) {
+ /* note cannot use pScrn->pScreen since this is unitialized when called from
+ RADEONScreenInit, and we need to call from there to get mergedfb + pageflip working */
+ /*** NOTE: r3/4xx will need sarea and drm pageflip updates to handle the xytile regs for
+ *** pageflipping!
+ ***/
+ pSAREAPriv = DRIGetSAREAPrivate(screenInfo.screens[pScrn->scrnIndex]);
+ /* can't get at sarea in a semi-sane way? */
+ pSAREA = (void *)((char*)pSAREAPriv - sizeof(XF86DRISAREARec));
+
+ pSAREA->frame.x = (Base / info->CurrentLayout.pixel_bytes)
+ % info->CurrentLayout.displayWidth;
+ pSAREA->frame.y = (Base / info->CurrentLayout.pixel_bytes)
+ / info->CurrentLayout.displayWidth;
+ pSAREA->frame.width = pScrn->frameX1 - x + 1;
+ pSAREA->frame.height = pScrn->frameY1 - y + 1;
+
+ if (pSAREAPriv->pfCurrentPage == 1) {
+ Base += info->backOffset - info->frontOffset;
+ }
+ }
+#endif
+ save->crtc_offset = Base;
+
+ return TRUE;
+
+}
+
+/* Define CRTC registers for requested video mode */
+static Bool
+RADEONInitCrtcRegisters(xf86CrtcPtr crtc, RADEONSavePtr save,
+ DisplayModePtr mode)
+{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ int format;
+ int hsync_start;
+ int hsync_wid;
+ int vsync_wid;
+
+ switch (info->CurrentLayout.pixel_code) {
+ case 4: format = 1; break;
+ case 8: format = 2; break;
+ case 15: format = 3; break; /* 555 */
+ case 16: format = 4; break; /* 565 */
+ case 24: format = 5; break; /* RGB */
+ case 32: format = 6; break; /* xRGB */
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Unsupported pixel depth (%d)\n",
+ info->CurrentLayout.bitsPerPixel);
+ return FALSE;
+ }
+
+ save->bios_4_scratch = info->SavedReg.bios_4_scratch;
+ save->crtc_gen_cntl = (RADEON_CRTC_EXT_DISP_EN
+ | RADEON_CRTC_EN
+ | (format << 8)
+ | ((mode->Flags & V_DBLSCAN)
+ ? RADEON_CRTC_DBL_SCAN_EN
+ : 0)
+ | ((mode->Flags & V_CSYNC)
+ ? RADEON_CRTC_CSYNC_EN
+ : 0)
+ | ((mode->Flags & V_INTERLACE)
+ ? RADEON_CRTC_INTERLACE_EN
+ : 0));
+
+ save->crtc_ext_cntl |= (RADEON_XCRT_CNT_EN|
+ RADEON_CRTC_VSYNC_DIS |
+ RADEON_CRTC_HSYNC_DIS |
+ RADEON_CRTC_DISPLAY_DIS);
+
+ save->disp_merge_cntl = info->SavedReg.disp_merge_cntl;
+ save->disp_merge_cntl &= ~RADEON_DISP_RGB_OFFSET_EN;
+
+ 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->crtc_h_total_disp = ((((mode->CrtcHTotal / 8) - 1) & 0x3ff)
+ | ((((mode->CrtcHDisplay / 8) - 1) & 0x1ff)
+ << 16));
+
+ hsync_wid = (mode->CrtcHSyncEnd - mode->CrtcHSyncStart) / 8;
+ if (!hsync_wid) hsync_wid = 1;
+ if (hsync_wid > 0x3f) hsync_wid = 0x3f;
+ hsync_start = mode->CrtcHSyncStart - 8;
+
+ save->crtc_h_sync_strt_wid = ((hsync_start & 0x1fff)
+ | (hsync_wid << 16)
+ | ((mode->Flags & V_NHSYNC)
+ ? RADEON_CRTC_H_SYNC_POL
+ : 0));
+
+ /* This works for double scan mode. */
+ save->crtc_v_total_disp = (((mode->CrtcVTotal - 1) & 0xffff)
+ | ((mode->CrtcVDisplay - 1) << 16));
+
+ vsync_wid = mode->CrtcVSyncEnd - mode->CrtcVSyncStart;
+ if (!vsync_wid) vsync_wid = 1;
+ if (vsync_wid > 0x1f) vsync_wid = 0x1f;
+
+ save->crtc_v_sync_strt_wid = (((mode->CrtcVSyncStart - 1) & 0xfff)
+ | (vsync_wid << 16)
+ | ((mode->Flags & V_NVSYNC)
+ ? RADEON_CRTC_V_SYNC_POL
+ : 0));
+
+ save->crtc_pitch = (((pScrn->displayWidth * pScrn->bitsPerPixel) +
+ ((pScrn->bitsPerPixel * 8) -1)) /
+ (pScrn->bitsPerPixel * 8));
+ save->crtc_pitch |= save->crtc_pitch << 16;
+
+ save->fp_h_sync_strt_wid = save->crtc_h_sync_strt_wid;
+ save->fp_v_sync_strt_wid = save->crtc_v_sync_strt_wid;
+ save->fp_crtc_h_total_disp = save->crtc_h_total_disp;
+ save->fp_crtc_v_total_disp = save->crtc_v_total_disp;
+
+ 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));
+ }
+
+ return TRUE;
+}
+
+static Bool
+RADEONInitCrtc2Base(xf86CrtcPtr crtc, RADEONSavePtr save,
+ int x, int y)
+{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ int Base;
+#ifdef XF86DRI
+ RADEONSAREAPrivPtr pSAREAPriv;
+ XF86DRISAREAPtr pSAREA;
+#endif
+
+ /* It seems all fancy options apart from pflip can be safely disabled
+ */
+ save->crtc2_offset = pScrn->fbOffset;
+#ifdef XF86DRI
+ if (info->allowPageFlip)
+ save->crtc2_offset_cntl = RADEON_CRTC_OFFSET_FLIP_CNTL;
+ else
+#endif
+ save->crtc2_offset_cntl = 0;
+
+ if (info->tilingEnabled && (crtc->rotatedData == NULL)) {
+ if (IS_R300_VARIANT)
+ save->crtc2_offset_cntl |= (R300_CRTC_X_Y_MODE_EN |
+ R300_CRTC_MICRO_TILE_BUFFER_DIS |
+ R300_CRTC_MACRO_TILE_EN);
+ else
+ save->crtc2_offset_cntl |= RADEON_CRTC_TILE_EN;
+ }
+ else {
+ if (IS_R300_VARIANT)
+ save->crtc2_offset_cntl &= ~(R300_CRTC_X_Y_MODE_EN |
+ R300_CRTC_MICRO_TILE_BUFFER_DIS |
+ R300_CRTC_MACRO_TILE_EN);
+ else
+ save->crtc2_offset_cntl &= ~RADEON_CRTC_TILE_EN;
+ }
+
+ Base = pScrn->fbOffset;
+
+ if (info->tilingEnabled && (crtc->rotatedData == NULL)) {
+ if (IS_R300_VARIANT) {
+ /* On r300/r400 when tiling is enabled crtc_offset is set to the address of
+ * the surface. the x/y offsets are handled by the X_Y tile reg for each crtc
+ * Makes tiling MUCH easier.
+ */
+ save->crtc2_tile_x0_y0 = x | (y << 16);
+ Base &= ~0x7ff;
+ } else {
+ /* note we cannot really simply use the info->ModeReg.crtc_offset_cntl value, since the
+ drm might have set FLIP_CNTL since we wrote that. Unfortunately FLIP_CNTL causes
+ flickering when scrolling vertically in a virtual screen, possibly because crtc will
+ pick up the new offset value at the end of each scanline, but the new offset_cntl value
+ only after a vsync. We'd probably need to wait (in drm) for vsync and only then update
+ OFFSET and OFFSET_CNTL, if the y coord has changed. Seems hard to fix. */
+ /*save->crtc2_offset_cntl = INREG(RADEON_CRTC2_OFFSET_CNTL) & ~0xf;*/
+#if 0
+ /* try to get rid of flickering when scrolling at least for 2d */
+#ifdef XF86DRI
+ if (!info->have3DWindows)
+#endif
+ save->crtc2_offset_cntl &= ~RADEON_CRTC_OFFSET_FLIP_CNTL;
+#endif
+
+ int byteshift = info->CurrentLayout.bitsPerPixel >> 4;
+ /* crtc uses 256(bytes)x8 "half-tile" start addresses? */
+ int tile_addr = (((y >> 3) * info->CurrentLayout.displayWidth + x) >> (8 - byteshift)) << 11;
+ Base += tile_addr + ((x << byteshift) % 256) + ((y % 8) << 8);
+ save->crtc2_offset_cntl = save->crtc_offset_cntl | (y % 16);
+ }
+ }
+ else {
+ int offset = y * info->CurrentLayout.displayWidth + x;
+ switch (info->CurrentLayout.pixel_code) {
+ case 15:
+ case 16: offset *= 2; break;
+ case 24: offset *= 3; break;
+ case 32: offset *= 4; break;
+ }
+ Base += offset;
+ }
+
+ if (crtc->rotatedData != NULL) {
+ Base = pScrn->fbOffset + (char *)crtc->rotatedData - (char *)info->FB;
+ }
+
+ Base &= ~7; /* 3 lower bits are always 0 */
+
+#ifdef XF86DRI
+ if (info->directRenderingInited) {
+ /* note cannot use pScrn->pScreen since this is unitialized when called from
+ RADEONScreenInit, and we need to call from there to get mergedfb + pageflip working */
+ /*** NOTE: r3/4xx will need sarea and drm pageflip updates to handle the xytile regs for
+ *** pageflipping!
+ ***/
+ pSAREAPriv = DRIGetSAREAPrivate(screenInfo.screens[pScrn->scrnIndex]);
+ /* can't get at sarea in a semi-sane way? */
+ pSAREA = (void *)((char*)pSAREAPriv - sizeof(XF86DRISAREARec));
+
+ pSAREAPriv->crtc2_base = Base;
+
+ if (pSAREAPriv->pfCurrentPage == 1) {
+ Base += info->backOffset - info->frontOffset;
+ }
+ }
+#endif
+ save->crtc2_offset = Base;
+
+ return TRUE;
+}
+
+/* Define CRTC2 registers for requested video mode */
+static Bool
+RADEONInitCrtc2Registers(xf86CrtcPtr crtc, RADEONSavePtr save,
+ DisplayModePtr mode)
+{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ int format;
+ int hsync_start;
+ int hsync_wid;
+ int vsync_wid;
+
+ switch (info->CurrentLayout.pixel_code) {
+ case 4: format = 1; break;
+ case 8: format = 2; break;
+ case 15: format = 3; break; /* 555 */
+ case 16: format = 4; break; /* 565 */
+ case 24: format = 5; break; /* RGB */
+ case 32: format = 6; break; /* xRGB */
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Unsupported pixel depth (%d)\n",
+ info->CurrentLayout.bitsPerPixel);
+ return FALSE;
+ }
+
+ save->crtc2_h_total_disp =
+ ((((mode->CrtcHTotal / 8) - 1) & 0x3ff)
+ | ((((mode->CrtcHDisplay / 8) - 1) & 0x1ff) << 16));
+
+ hsync_wid = (mode->CrtcHSyncEnd - mode->CrtcHSyncStart) / 8;
+ if (!hsync_wid) hsync_wid = 1;
+ if (hsync_wid > 0x3f) hsync_wid = 0x3f;
+ hsync_start = mode->CrtcHSyncStart - 8;
+
+ save->crtc2_h_sync_strt_wid = ((hsync_start & 0x1fff)
+ | (hsync_wid << 16)
+ | ((mode->Flags & V_NHSYNC)
+ ? RADEON_CRTC_H_SYNC_POL
+ : 0));
+
+ /* This works for double scan mode. */
+ save->crtc2_v_total_disp = (((mode->CrtcVTotal - 1) & 0xffff)
+ | ((mode->CrtcVDisplay - 1) << 16));
+
+ vsync_wid = mode->CrtcVSyncEnd - mode->CrtcVSyncStart;
+ if (!vsync_wid) vsync_wid = 1;
+ if (vsync_wid > 0x1f) vsync_wid = 0x1f;
+
+ save->crtc2_v_sync_strt_wid = (((mode->CrtcVSyncStart - 1) & 0xfff)
+ | (vsync_wid << 16)
+ | ((mode->Flags & V_NVSYNC)
+ ? RADEON_CRTC2_V_SYNC_POL
+ : 0));
+
+ save->crtc2_pitch = ((pScrn->displayWidth * pScrn->bitsPerPixel) +
+ ((pScrn->bitsPerPixel * 8) -1)) / (pScrn->bitsPerPixel * 8);
+ save->crtc2_pitch |= save->crtc2_pitch << 16;
+
+ /* check to see if TV DAC is enabled for another crtc and keep it enabled */
+ if (save->crtc2_gen_cntl & RADEON_CRTC2_CRT2_ON)
+ save->crtc2_gen_cntl = RADEON_CRTC2_CRT2_ON;
+ else
+ save->crtc2_gen_cntl = 0;
+
+ save->crtc2_gen_cntl |= (RADEON_CRTC2_EN
+ | (format << 8)
+ | RADEON_CRTC2_VSYNC_DIS
+ | RADEON_CRTC2_HSYNC_DIS
+ | RADEON_CRTC2_DISP_DIS
+ | ((mode->Flags & V_DBLSCAN)
+ ? RADEON_CRTC2_DBL_SCAN_EN
+ : 0)
+ | ((mode->Flags & V_CSYNC)
+ ? RADEON_CRTC2_CSYNC_EN
+ : 0)
+ | ((mode->Flags & V_INTERLACE)
+ ? RADEON_CRTC2_INTERLACE_EN
+ : 0));
+
+ save->disp2_merge_cntl = info->SavedReg.disp2_merge_cntl;
+ save->disp2_merge_cntl &= ~(RADEON_DISP2_RGB_OFFSET_EN);
+
+ save->fp_h2_sync_strt_wid = save->crtc2_h_sync_strt_wid;
+ save->fp_v2_sync_strt_wid = save->crtc2_v_sync_strt_wid;
+
+ if (info->ChipFamily == CHIP_FAMILY_RS400) {
+ save->rs480_unk_e30 = 0x105DC1CC; /* because I'm worth it */
+ save->rs480_unk_e34 = 0x2749D000; /* AMD really should */
+ save->rs480_unk_e38 = 0x29ca71dc; /* release docs */
+ save->rs480_unk_e3c = 0x28FBC3AC; /* this is so a trade secret */
+ }
+
+ return TRUE;
+}
+
+
+/* Compute n/d with rounding */
+static int RADEONDiv(int n, int d)
+{
+ return (n + (d / 2)) / d;
+}
+
+/* Define PLL registers for requested video mode */
+static void
+RADEONInitPLLRegisters(ScrnInfoPtr pScrn, RADEONInfoPtr info,
+ RADEONSavePtr save, RADEONPLLPtr pll,
+ double dot_clock)
+{
+ unsigned long freq = dot_clock * 100;
+
+ struct {
+ int divider;
+ int bitvalue;
+ } *post_div, post_divs[] = {
+ /* From RAGE 128 VR/RAGE 128 GL Register
+ * Reference Manual (Technical Reference
+ * Manual P/N RRG-G04100-C Rev. 0.04), page
+ * 3-17 (PLL_DIV_[3:0]).
+ */
+ { 1, 0 }, /* VCLK_SRC */
+ { 2, 1 }, /* VCLK_SRC/2 */
+ { 4, 2 }, /* VCLK_SRC/4 */
+ { 8, 3 }, /* VCLK_SRC/8 */
+ { 3, 4 }, /* VCLK_SRC/3 */
+ { 16, 5 }, /* VCLK_SRC/16 */
+ { 6, 6 }, /* VCLK_SRC/6 */
+ { 12, 7 }, /* VCLK_SRC/12 */
+ { 0, 0 }
+ };
+
+ if (info->UseBiosDividers) {
+ save->ppll_ref_div = info->RefDivider;
+ save->ppll_div_3 = info->FeedbackDivider | (info->PostDivider << 16);
+ save->htotal_cntl = 0;
+ return;
+ }
+
+ if (freq > pll->max_pll_freq) freq = pll->max_pll_freq;
+ if (freq * 12 < pll->min_pll_freq) freq = pll->min_pll_freq / 12;
+
+ for (post_div = &post_divs[0]; post_div->divider; ++post_div) {
+ save->pll_output_freq = post_div->divider * freq;
+
+ if (save->pll_output_freq >= pll->min_pll_freq
+ && save->pll_output_freq <= pll->max_pll_freq) break;
+ }
+
+ if (!post_div->divider) {
+ save->pll_output_freq = freq;
+ post_div = &post_divs[0];
+ }
+
+ save->dot_clock_freq = freq;
+ save->feedback_div = RADEONDiv(pll->reference_div
+ * save->pll_output_freq,
+ pll->reference_freq);
+ save->post_div = post_div->divider;
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "dc=%u, of=%u, fd=%d, pd=%d\n",
+ (unsigned)save->dot_clock_freq,
+ (unsigned)save->pll_output_freq,
+ save->feedback_div,
+ save->post_div);
+
+ save->ppll_ref_div = pll->reference_div;
+ save->ppll_div_3 = (save->feedback_div | (post_div->bitvalue << 16));
+ save->htotal_cntl = 0;
+
+ save->vclk_ecp_cntl = (info->SavedReg.vclk_ecp_cntl &
+ ~RADEON_VCLK_SRC_SEL_MASK) | RADEON_VCLK_SRC_SEL_PPLLCLK;
+
+}
+
+/* Define PLL2 registers for requested video mode */
+static void
+RADEONInitPLL2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save,
+ RADEONPLLPtr pll, double dot_clock,
+ int no_odd_postdiv)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned long freq = dot_clock * 100;
+
+ struct {
+ int divider;
+ int bitvalue;
+ } *post_div, post_divs[] = {
+ /* From RAGE 128 VR/RAGE 128 GL Register
+ * Reference Manual (Technical Reference
+ * Manual P/N RRG-G04100-C Rev. 0.04), page
+ * 3-17 (PLL_DIV_[3:0]).
+ */
+ { 1, 0 }, /* VCLK_SRC */
+ { 2, 1 }, /* VCLK_SRC/2 */
+ { 4, 2 }, /* VCLK_SRC/4 */
+ { 8, 3 }, /* VCLK_SRC/8 */
+ { 3, 4 }, /* VCLK_SRC/3 */
+ { 6, 6 }, /* VCLK_SRC/6 */
+ { 12, 7 }, /* VCLK_SRC/12 */
+ { 0, 0 }
+ };
+
+ if (freq > pll->max_pll_freq) freq = pll->max_pll_freq;
+ if (freq * 12 < pll->min_pll_freq) freq = pll->min_pll_freq / 12;
+
+ for (post_div = &post_divs[0]; post_div->divider; ++post_div) {
+ /* Odd post divider value don't work properly on the second digital
+ * output
+ */
+ if (no_odd_postdiv && (post_div->divider & 1))
+ continue;
+ save->pll_output_freq_2 = post_div->divider * freq;
+ if (save->pll_output_freq_2 >= pll->min_pll_freq
+ && save->pll_output_freq_2 <= pll->max_pll_freq) break;
+ }
+
+ if (!post_div->divider) {
+ save->pll_output_freq_2 = freq;
+ post_div = &post_divs[0];
+ }
+
+ save->dot_clock_freq_2 = freq;
+ save->feedback_div_2 = RADEONDiv(pll->reference_div
+ * save->pll_output_freq_2,
+ pll->reference_freq);
+ save->post_div_2 = post_div->divider;
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "dc=%u, of=%u, fd=%d, pd=%d\n",
+ (unsigned)save->dot_clock_freq_2,
+ (unsigned)save->pll_output_freq_2,
+ save->feedback_div_2,
+ save->post_div_2);
+
+ save->p2pll_ref_div = pll->reference_div;
+ save->p2pll_div_0 = (save->feedback_div_2 |
+ (post_div->bitvalue << 16));
+ save->htotal_cntl2 = 0;
+
+ save->pixclks_cntl = ((info->SavedReg.pixclks_cntl &
+ ~(RADEON_PIX2CLK_SRC_SEL_MASK)) |
+ RADEON_PIX2CLK_SRC_SEL_P2PLLCLK);
+
+}
+
+static void
+radeon_update_tv_routing(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+ /* pixclks_cntl controls tv clock routing */
+ OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, restore->pixclks_cntl);
+}
+
+static void
+radeon_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
+ DisplayModePtr adjusted_mode, int x, int y)
+{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ Bool tilingOld = info->tilingEnabled;
+ int i = 0;
+ double dot_clock = 0;
+ Bool no_odd_post_div = FALSE;
+ Bool update_tv_routing = FALSE;
+
+
+ if (info->allowColorTiling) {
+ info->tilingEnabled = (adjusted_mode->Flags & (V_DBLSCAN | V_INTERLACE)) ? FALSE : TRUE;
+#ifdef XF86DRI
+ if (info->directRenderingEnabled && (info->tilingEnabled != tilingOld)) {
+ RADEONSAREAPrivPtr pSAREAPriv;
+ if (RADEONDRISetParam(pScrn, RADEON_SETPARAM_SWITCH_TILING, (info->tilingEnabled ? 1 : 0)) < 0)
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[drm] failed changing tiling status\n");
+ pSAREAPriv = DRIGetSAREAPrivate(pScrn->pScreen);
+ info->tilingEnabled = pSAREAPriv->tiling_enabled ? TRUE : FALSE;
+ }
+#endif
+ }
+
+ for (i = 0; i < xf86_config->num_output; i++) {
+ xf86OutputPtr output = xf86_config->output[i];
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+
+ if (output->crtc == crtc) {
+ if (radeon_output->MonType != MT_CRT)
+ no_odd_post_div = TRUE;
+ }
+ }
+
+ ErrorF("init memmap\n");
+ RADEONInitMemMapRegisters(pScrn, &info->ModeReg, info);
+ ErrorF("init common\n");
+ RADEONInitCommonRegisters(&info->ModeReg, info);
+
+ RADEONInitSurfaceCntl(crtc, &info->ModeReg);
+
+ switch (radeon_crtc->crtc_id) {
+ case 0:
+ ErrorF("init crtc1\n");
+ RADEONInitCrtcRegisters(crtc, &info->ModeReg, adjusted_mode);
+ RADEONInitCrtcBase(crtc, &info->ModeReg, x, y);
+ dot_clock = adjusted_mode->Clock / 1000.0;
+ if (dot_clock) {
+ ErrorF("init pll1\n");
+ RADEONInitPLLRegisters(pScrn, info, &info->ModeReg, &info->pll, dot_clock);
+ } else {
+ info->ModeReg.ppll_ref_div = info->SavedReg.ppll_ref_div;
+ info->ModeReg.ppll_div_3 = info->SavedReg.ppll_div_3;
+ info->ModeReg.htotal_cntl = info->SavedReg.htotal_cntl;
+ }
+ break;
+ case 1:
+ ErrorF("init crtc2\n");
+ RADEONInitCrtc2Registers(crtc, &info->ModeReg, adjusted_mode);
+ RADEONInitCrtc2Base(crtc, &info->ModeReg, x, y);
+ dot_clock = adjusted_mode->Clock / 1000.0;
+ if (dot_clock) {
+ ErrorF("init pll2\n");
+ RADEONInitPLL2Registers(pScrn, &info->ModeReg, &info->pll, dot_clock, no_odd_post_div);
+ }
+ break;
+ }
+
+ for (i = 0; i < xf86_config->num_output; i++) {
+ xf86OutputPtr output = xf86_config->output[i];
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+
+ if (output->crtc == crtc) {
+ if (radeon_output->MonType == MT_STV || radeon_output->MonType == MT_CTV) {
+ switch (radeon_crtc->crtc_id) {
+ case 0:
+ RADEONAdjustCrtcRegistersForTV(pScrn, &info->ModeReg, adjusted_mode, output);
+ RADEONAdjustPLLRegistersForTV(pScrn, &info->ModeReg, adjusted_mode, output);
+ update_tv_routing = TRUE;
+ break;
+ case 1:
+ RADEONAdjustCrtc2RegistersForTV(pScrn, &info->ModeReg, adjusted_mode, output);
+ RADEONAdjustPLL2RegistersForTV(pScrn, &info->ModeReg, adjusted_mode, output);
+ break;
+ }
+ }
+ }
+ }
+
+ ErrorF("restore memmap\n");
+ RADEONRestoreMemMapRegisters(pScrn, &info->ModeReg);
+ ErrorF("restore common\n");
+ RADEONRestoreCommonRegisters(pScrn, &info->ModeReg);
+
+ switch (radeon_crtc->crtc_id) {
+ case 0:
+ ErrorF("restore crtc1\n");
+ RADEONRestoreCrtcRegisters(pScrn, &info->ModeReg);
+ ErrorF("restore pll1\n");
+ RADEONRestorePLLRegisters(pScrn, &info->ModeReg);
+ break;
+ case 1:
+ ErrorF("restore crtc2\n");
+ RADEONRestoreCrtc2Registers(pScrn, &info->ModeReg);
+ ErrorF("restore pll2\n");
+ RADEONRestorePLL2Registers(pScrn, &info->ModeReg);
+ break;
+ }
+
+ /* pixclks_cntl handles tv-out clock routing */
+ if (update_tv_routing)
+ radeon_update_tv_routing(pScrn, &info->ModeReg);
+
+ if (info->DispPriority)
+ RADEONInitDispBandwidth(pScrn);
+
+ if (info->tilingEnabled != tilingOld) {
+ /* need to redraw front buffer, I guess this can be considered a hack ? */
+ xf86EnableDisableFBAccess(pScrn->scrnIndex, FALSE);
+ RADEONChangeSurfaces(pScrn);
+ xf86EnableDisableFBAccess(pScrn->scrnIndex, TRUE);
+ /* xf86SetRootClip would do, but can't access that here */
+ }
+
+ /* reset ecp_div for Xv */
+ info->ecp_div = -1;
+
+}
+
+static void
+radeon_crtc_mode_commit(xf86CrtcPtr crtc)
+{
+ radeon_crtc_dpms(crtc, DPMSModeOn);
+}
+
+void radeon_crtc_load_lut(xf86CrtcPtr crtc)
+{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ int i;
+
+ if (!crtc->enabled)
+ return;
+
+ PAL_SELECT(radeon_crtc->crtc_id);
+
+ for (i = 0; i < 256; i++) {
+ OUTPAL(i, radeon_crtc->lut_r[i], radeon_crtc->lut_g[i], radeon_crtc->lut_b[i]);
+ }
+
+}
+
+
+static void
+radeon_crtc_gamma_set(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green,
+ CARD16 *blue, int size)
+{
+ RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+ ScrnInfoPtr pScrn = crtc->scrn;
+ int i, j;
+
+ if (pScrn->depth == 16) {
+ for (i = 0; i < 64; i++) {
+ if (i <= 31) {
+ for (j = 0; j < 8; j++) {
+ radeon_crtc->lut_r[i * 8 + j] = red[i] >> 8;
+ radeon_crtc->lut_b[i * 8 + j] = blue[i] >> 8;
+ }
+ }
+
+ for (j = 0; j < 4; j++) {
+ radeon_crtc->lut_g[i * 4 + j] = green[i] >> 8;
+ }
+ }
+ } else {
+ for (i = 0; i < 256; i++) {
+ radeon_crtc->lut_r[i] = red[i] >> 8;
+ radeon_crtc->lut_g[i] = green[i] >> 8;
+ radeon_crtc->lut_b[i] = blue[i] >> 8;
+ }
+ }
+
+ radeon_crtc_load_lut(crtc);
+}
+
+static Bool
+radeon_crtc_lock(xf86CrtcPtr crtc)
+{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+
+#ifdef XF86DRI
+ if (info->CPStarted && pScrn->pScreen) {
+ DRILock(pScrn->pScreen, 0);
+ if (info->accelOn)
+ RADEON_SYNC(info, pScrn);
+ return TRUE;
+ }
+#endif
+ if (info->accelOn)
+ RADEON_SYNC(info, pScrn);
+
+ return FALSE;
+
+}
+
+static void
+radeon_crtc_unlock(xf86CrtcPtr crtc)
+{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+
+#ifdef XF86DRI
+ if (info->CPStarted && pScrn->pScreen) DRIUnlock(pScrn->pScreen);
+#endif
+
+ if (info->accelOn)
+ RADEON_SYNC(info, pScrn);
+}
+
+#ifdef USE_XAA
+/**
+ * Allocates memory from the XF86 linear allocator, but also purges
+ * memory if possible to cause the allocation to succeed.
+ */
+static FBLinearPtr
+radeon_xf86AllocateOffscreenLinear(ScreenPtr pScreen, int length,
+ int granularity,
+ MoveLinearCallbackProcPtr moveCB,
+ RemoveLinearCallbackProcPtr removeCB,
+ pointer privData)
+{
+ FBLinearPtr linear;
+ int max_size;
+
+ linear = xf86AllocateOffscreenLinear(pScreen, length, granularity, moveCB,
+ removeCB, privData);
+ if (linear != NULL)
+ return linear;
+
+ /* The above allocation didn't succeed, so purge unlocked stuff and try
+ * again.
+ */
+ xf86QueryLargestOffscreenLinear(pScreen, &max_size, granularity,
+ PRIORITY_EXTREME);
+
+ if (max_size < length)
+ return NULL;
+
+ xf86PurgeUnlockedOffscreenAreas(pScreen);
+
+ linear = xf86AllocateOffscreenLinear(pScreen, length, granularity, moveCB,
+ removeCB, privData);
+
+ return linear;
+}
+#endif
+
+/**
+ * Allocates memory for a locked-in-framebuffer shadow of the given
+ * width and height for this CRTC's rotated shadow framebuffer.
+ */
+
+static void *
+radeon_crtc_shadow_allocate (xf86CrtcPtr crtc, int width, int height)
+{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ ScreenPtr pScreen = pScrn->pScreen;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+ unsigned long rotate_pitch;
+ unsigned long rotate_offset;
+ int align = 4096, size;
+ int cpp = pScrn->bitsPerPixel / 8;
+
+ rotate_pitch = pScrn->displayWidth * cpp;
+ size = rotate_pitch * height;
+
+#ifdef USE_EXA
+ /* We could get close to what we want here by just creating a pixmap like
+ * normal, but we have to lock it down in framebuffer, and there is no
+ * setter for offscreen area locking in EXA currently. So, we just
+ * allocate offscreen memory and fake up a pixmap header for it.
+ */
+ if (info->useEXA) {
+ assert(radeon_crtc->rotate_mem_exa == NULL);
+
+ radeon_crtc->rotate_mem_exa = exaOffscreenAlloc(pScreen, size, align,
+ TRUE, NULL, NULL);
+ if (radeon_crtc->rotate_mem_exa == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Couldn't allocate shadow memory for rotated CRTC\n");
+ return NULL;
+ }
+ rotate_offset = radeon_crtc->rotate_mem_exa->offset;
+ }
+#endif /* USE_EXA */
+#ifdef USE_XAA
+ if (!info->useEXA) {
+ /* The XFree86 linear allocator operates in units of screen pixels,
+ * sadly.
+ */
+ size = (size + cpp - 1) / cpp;
+ align = (align + cpp - 1) / cpp;
+
+ assert(radeon_crtc->rotate_mem_xaa == NULL);
+
+ radeon_crtc->rotate_mem_xaa =
+ radeon_xf86AllocateOffscreenLinear(pScreen, size, align,
+ NULL, NULL, NULL);
+ if (radeon_crtc->rotate_mem_xaa == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Couldn't allocate shadow memory for rotated CRTC\n");
+ return NULL;
+ }
+#ifdef XF86DRI
+ rotate_offset = info->frontOffset +
+ radeon_crtc->rotate_mem_xaa->offset * cpp;
+#endif
+ }
+#endif /* USE_XAA */
+
+ return info->FB + rotate_offset;
+}
+
+/**
+ * Creates a pixmap for this CRTC's rotated shadow framebuffer.
+ */
+static PixmapPtr
+radeon_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height)
+{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ unsigned long rotate_pitch;
+ PixmapPtr rotate_pixmap;
+ int cpp = pScrn->bitsPerPixel / 8;
+
+ if (!data)
+ data = radeon_crtc_shadow_allocate(crtc, width, height);
+
+ rotate_pitch = pScrn->displayWidth * cpp;
+
+ rotate_pixmap = GetScratchPixmapHeader(pScrn->pScreen,
+ width, height,
+ pScrn->depth,
+ pScrn->bitsPerPixel,
+ rotate_pitch,
+ data);
+
+ if (rotate_pixmap == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Couldn't allocate shadow pixmap for rotated CRTC\n");
+ }
+
+ return rotate_pixmap;
+}
+
+static void
+radeon_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data)
+{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+
+ if (rotate_pixmap)
+ FreeScratchPixmapHeader(rotate_pixmap);
+
+ if (data) {
+#ifdef USE_EXA
+ if (info->useEXA && radeon_crtc->rotate_mem_exa != NULL) {
+ exaOffscreenFree(pScrn->pScreen, radeon_crtc->rotate_mem_exa);
+ radeon_crtc->rotate_mem_exa = NULL;
+ }
+#endif /* USE_EXA */
+#ifdef USE_XAA
+ if (!info->useEXA) {
+ xf86FreeOffscreenLinear(radeon_crtc->rotate_mem_xaa);
+ radeon_crtc->rotate_mem_xaa = NULL;
+ }
+#endif /* USE_XAA */
+ }
+}
+
+static const xf86CrtcFuncsRec radeon_crtc_funcs = {
+ .dpms = radeon_crtc_dpms,
+ .save = NULL, /* XXX */
+ .restore = NULL, /* XXX */
+ .mode_fixup = radeon_crtc_mode_fixup,
+ .prepare = radeon_crtc_mode_prepare,
+ .mode_set = radeon_crtc_mode_set,
+ .commit = radeon_crtc_mode_commit,
+ .gamma_set = radeon_crtc_gamma_set,
+ .lock = radeon_crtc_lock,
+ .unlock = radeon_crtc_unlock,
+ .shadow_create = radeon_crtc_shadow_create,
+ .shadow_allocate = radeon_crtc_shadow_allocate,
+ .shadow_destroy = radeon_crtc_shadow_destroy,
+ .set_cursor_colors = radeon_crtc_set_cursor_colors,
+ .set_cursor_position = radeon_crtc_set_cursor_position,
+ .show_cursor = radeon_crtc_show_cursor,
+ .hide_cursor = radeon_crtc_hide_cursor,
+ .load_cursor_argb = radeon_crtc_load_cursor_argb,
+ .destroy = NULL, /* XXX */
+};
+
+Bool RADEONAllocateControllers(ScrnInfoPtr pScrn)
+{
+ RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
+
+ if (pRADEONEnt->Controller[0])
+ return TRUE;
+
+ pRADEONEnt->pCrtc[0] = xf86CrtcCreate(pScrn, &radeon_crtc_funcs);
+ if (!pRADEONEnt->pCrtc[0])
+ return FALSE;
+
+ pRADEONEnt->Controller[0] = xnfcalloc(sizeof(RADEONCrtcPrivateRec), 1);
+ if (!pRADEONEnt->Controller[0])
+ return FALSE;
+
+ pRADEONEnt->pCrtc[0]->driver_private = pRADEONEnt->Controller[0];
+ pRADEONEnt->Controller[0]->crtc_id = 0;
+
+ if (!pRADEONEnt->HasCRTC2)
+ return TRUE;
+
+ pRADEONEnt->pCrtc[1] = xf86CrtcCreate(pScrn, &radeon_crtc_funcs);
+ if (!pRADEONEnt->pCrtc[1])
+ return FALSE;
+
+ pRADEONEnt->Controller[1] = xnfcalloc(sizeof(RADEONCrtcPrivateRec), 1);
+ if (!pRADEONEnt->Controller[1])
+ {
+ xfree(pRADEONEnt->Controller[0]);
+ return FALSE;
+ }
+
+ pRADEONEnt->pCrtc[1]->driver_private = pRADEONEnt->Controller[1];
+ pRADEONEnt->Controller[1]->crtc_id = 1;
+ return TRUE;
+}
+
+/**
+ * In the current world order, there are lists of modes per output, which may
+ * or may not include the mode that was asked to be set by XFree86's mode
+ * selection. Find the closest one, in the following preference order:
+ *
+ * - Equality
+ * - Closer in size to the requested mode, but no larger
+ * - Closer in refresh rate to the requested mode.
+ */
+DisplayModePtr
+RADEONCrtcFindClosestMode(xf86CrtcPtr crtc, DisplayModePtr pMode)
+{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ DisplayModePtr pBest = NULL, pScan = NULL;
+ int i;
+
+ /* Assume that there's only one output connected to the given CRTC. */
+ for (i = 0; i < xf86_config->num_output; i++)
+ {
+ xf86OutputPtr output = xf86_config->output[i];
+ if (output->crtc == crtc && output->probed_modes != NULL)
+ {
+ pScan = output->probed_modes;
+ break;
+ }
+ }
+
+ /* If the pipe doesn't have any detected modes, just let the system try to
+ * spam the desired mode in.
+ */
+ if (pScan == NULL) {
+ RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "No crtc mode list for crtc %d,"
+ "continuing with desired mode\n", radeon_crtc->crtc_id);
+ return pMode;
+ }
+
+ for (; pScan != NULL; pScan = pScan->next) {
+ assert(pScan->VRefresh != 0.0);
+
+ /* If there's an exact match, we're done. */
+ if (xf86ModesEqual(pScan, pMode)) {
+ pBest = pMode;
+ break;
+ }
+
+ /* Reject if it's larger than the desired mode. */
+ if (pScan->HDisplay > pMode->HDisplay ||
+ pScan->VDisplay > pMode->VDisplay)
+ {
+ continue;
+ }
+
+ if (pBest == NULL) {
+ pBest = pScan;
+ continue;
+ }
+
+ /* Find if it's closer to the right size than the current best
+ * option.
+ */
+ if ((pScan->HDisplay > pBest->HDisplay &&
+ pScan->VDisplay >= pBest->VDisplay) ||
+ (pScan->HDisplay >= pBest->HDisplay &&
+ pScan->VDisplay > pBest->VDisplay))
+ {
+ pBest = pScan;
+ continue;
+ }
+
+ /* Find if it's still closer to the right refresh than the current
+ * best resolution.
+ */
+ if (pScan->HDisplay == pBest->HDisplay &&
+ pScan->VDisplay == pBest->VDisplay &&
+ (fabs(pScan->VRefresh - pMode->VRefresh) <
+ fabs(pBest->VRefresh - pMode->VRefresh))) {
+ pBest = pScan;
+ }
+ }
+
+ if (pBest == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "No suitable mode found to program for the pipe.\n"
+ " continuing with desired mode %dx%d@%.1f\n",
+ pMode->HDisplay, pMode->VDisplay, pMode->VRefresh);
+ } else if (!xf86ModesEqual(pBest, pMode)) {
+ RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+ int crtc = radeon_crtc->crtc_id;
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Choosing pipe %d's mode %dx%d@%.1f instead of xf86 "
+ "mode %dx%d@%.1f\n", crtc,
+ pBest->HDisplay, pBest->VDisplay, pBest->VRefresh,
+ pMode->HDisplay, pMode->VDisplay, pMode->VRefresh);
+ pMode = pBest;
+ }
+ return pMode;
+}
+
diff --git a/src/radeon_cursor.c b/src/radeon_cursor.c
index a45198ae..f19f2bc0 100644
--- a/src/radeon_cursor.c
+++ b/src/radeon_cursor.c
@@ -31,7 +31,7 @@
#endif
#define RADEONCTRACE(x)
-/* #define RADEONCTRACE(x) RADEONTRACE(x) */
+/*#define RADEONCTRACE(x) RADEONTRACE(x) */
/*
* Authors:
@@ -55,24 +55,13 @@
#include "radeon_version.h"
#include "radeon_reg.h"
#include "radeon_macros.h"
-#include "radeon_mergedfb.h"
/* X and server generic header files */
#include "xf86.h"
-/* Mono ARGB cursor colours (premultiplied). */
-static CARD32 mono_cursor_color[] = {
- 0x00000000, /* White, fully transparent. */
- 0x00000000, /* Black, fully transparent. */
- 0xffffffff, /* White, fully opaque. */
- 0xff000000, /* Black, fully opaque. */
-};
-
#define CURSOR_WIDTH 64
#define CURSOR_HEIGHT 64
-#define COMMON_CURSOR_SWAPPING_START() RADEON_SYNC(info, pScrn)
-
/*
* The cursor bits are always 32bpp. On MSBFirst buses,
* configure byte swapping to swap 32 bit units when writing
@@ -84,7 +73,6 @@ static CARD32 mono_cursor_color[] = {
#define CURSOR_SWAPPING_DECL_MMIO unsigned char *RADEONMMIO = info->MMIO;
#define CURSOR_SWAPPING_START() \
do { \
- COMMON_CURSOR_SWAPPING_START(); \
OUTREG(RADEON_SURFACE_CNTL, \
(info->ModeReg.surface_cntl | \
RADEON_NONSURF_AP0_SWP_32BPP | RADEON_NONSURF_AP1_SWP_32BPP) & \
@@ -96,278 +84,151 @@ static CARD32 mono_cursor_color[] = {
#else
#define CURSOR_SWAPPING_DECL_MMIO
-#define CURSOR_SWAPPING_START() \
- do { \
- COMMON_CURSOR_SWAPPING_START(); \
- } while (0)
+#define CURSOR_SWAPPING_START()
#define CURSOR_SWAPPING_END()
#endif
-
-/* Set cursor foreground and background colors */
-static void RADEONSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
+void
+radeon_crtc_show_cursor (xf86CrtcPtr crtc)
{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- CARD32 *pixels = (CARD32 *)(pointer)(info->FB + info->cursor_offset + pScrn->fbOffset);
- int pixel, i;
- CURSOR_SWAPPING_DECL_MMIO
-
- RADEONCTRACE(("RADEONSetCursorColors\n"));
-
-#ifdef ARGB_CURSOR
- /* Don't recolour cursors set with SetCursorARGB. */
- if (info->cursor_argb)
- return;
-#endif
+ ScrnInfoPtr pScrn = crtc->scrn;
+ RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+ int crtc_id = radeon_crtc->crtc_id;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
- fg |= 0xff000000;
- bg |= 0xff000000;
+ if (crtc_id == 0)
+ OUTREGP(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_CUR_EN | 2 << 20,
+ ~(RADEON_CRTC_CUR_EN | RADEON_CRTC_CUR_MODE_MASK));
+ else if (crtc_id == 1)
+ OUTREGP(RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_CUR_EN | 2 << 20,
+ ~(RADEON_CRTC2_CUR_EN | RADEON_CRTC2_CUR_MODE_MASK));
+}
- /* Don't recolour the image if we don't have to. */
- if (fg == info->cursor_fg && bg == info->cursor_bg)
- return;
+void
+radeon_crtc_hide_cursor (xf86CrtcPtr crtc)
+{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+ int crtc_id = radeon_crtc->crtc_id;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
- CURSOR_SWAPPING_START();
+ if (crtc_id == 0)
+ OUTREGP(RADEON_CRTC_GEN_CNTL, 0, ~RADEON_CRTC_CUR_EN);
+ else if (crtc_id == 1)
+ OUTREGP(RADEON_CRTC2_GEN_CNTL, 0, ~RADEON_CRTC2_CUR_EN);
- /* Note: We assume that the pixels are either fully opaque or fully
- * transparent, so we won't premultiply them, and we can just
- * check for non-zero pixel values; those are either fg or bg
- */
- for (i = 0; i < CURSOR_WIDTH * CURSOR_HEIGHT; i++, pixels++)
- if ((pixel = *pixels))
- *pixels = (pixel == info->cursor_fg) ? fg : bg;
- CURSOR_SWAPPING_END();
- info->cursor_fg = fg;
- info->cursor_bg = bg;
}
-
-/* Set cursor position to (x,y) with offset into cursor bitmap at
- * (xorigin,yorigin)
- */
-static void RADEONSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
+void
+radeon_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+ int crtc_id = radeon_crtc->crtc_id;
RADEONInfoPtr info = RADEONPTR(pScrn);
unsigned char *RADEONMMIO = info->MMIO;
- xf86CursorInfoPtr cursor = info->cursor;
- int xorigin = 0;
- int yorigin = 0;
- int total_y = pScrn->frameY1 - pScrn->frameY0;
- int stride = 256;
-
- if(info->MergedFB) {
- RADEONCTRACE(("RADEONSetCursorPositionMerged\n"));
- RADEONSetCursorPositionMerged(pScrn, x, y);
- return;
- }
-
- RADEONCTRACE(("RADEONSetCursorPosition\n"));
+ int xorigin = 0, yorigin = 0;
+ int stride = 256;
+ DisplayModePtr mode = &crtc->mode;
if (x < 0) xorigin = -x+1;
if (y < 0) yorigin = -y+1;
- if (y > total_y) y = total_y;
- if (info->Flags & V_DBLSCAN) y *= 2;
- if (xorigin >= cursor->MaxWidth) xorigin = cursor->MaxWidth - 1;
- if (yorigin >= cursor->MaxHeight) yorigin = cursor->MaxHeight - 1;
+ if (xorigin >= CURSOR_WIDTH) xorigin = CURSOR_WIDTH - 1;
+ if (yorigin >= CURSOR_HEIGHT) yorigin = CURSOR_HEIGHT - 1;
- if (!info->IsSecondary) {
+ if (mode->Flags & V_INTERLACE)
+ y /= 2;
+ else if (mode->Flags & V_DBLSCAN)
+ y *= 2;
+
+ if (crtc_id == 0) {
OUTREG(RADEON_CUR_HORZ_VERT_OFF, (RADEON_CUR_LOCK
| (xorigin << 16)
| yorigin));
OUTREG(RADEON_CUR_HORZ_VERT_POSN, (RADEON_CUR_LOCK
| ((xorigin ? 0 : x) << 16)
| (yorigin ? 0 : y)));
- RADEONCTRACE(("cursor_offset: 0x%x, yorigin: %d, stride: %d\n",
- info->cursor_offset + pScrn->fbOffset, yorigin, stride));
+ RADEONCTRACE(("cursor_offset: 0x%x, yorigin: %d, stride: %d, temp %08X\n",
+ info->cursor_offset + pScrn->fbOffset, yorigin, stride, temp));
OUTREG(RADEON_CUR_OFFSET,
info->cursor_offset + pScrn->fbOffset + yorigin * stride);
- } else {
+ } else if (crtc_id == 1) {
OUTREG(RADEON_CUR2_HORZ_VERT_OFF, (RADEON_CUR2_LOCK
| (xorigin << 16)
| yorigin));
OUTREG(RADEON_CUR2_HORZ_VERT_POSN, (RADEON_CUR2_LOCK
- | ((xorigin ? 0 : x) << 16)
- | (yorigin ? 0 : y)));
+ | ((xorigin ? 0 : x) << 16)
+ | (yorigin ? 0 : y)));
+ RADEONCTRACE(("cursor_offset2: 0x%x, yorigin: %d, stride: %d, temp %08X\n",
+ info->cursor_offset + pScrn->fbOffset, yorigin, stride, temp));
OUTREG(RADEON_CUR2_OFFSET,
- info->cursor_offset + pScrn->fbOffset + yorigin * stride);
+ info->cursor_offset + pScrn->fbOffset + yorigin * stride);
}
}
-/* Copy cursor image from `image' to video memory. RADEONSetCursorPosition
- * will be called after this, so we can ignore xorigin and yorigin.
- */
-static void RADEONLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *image)
+void
+radeon_crtc_set_cursor_colors (xf86CrtcPtr crtc, int bg, int fg)
{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
- CARD8 *s = (CARD8 *)(pointer)image;
- CARD32 *d = (CARD32 *)(pointer)(info->FB + info->cursor_offset + pScrn->fbOffset);
- CARD32 save1 = 0;
- CARD32 save2 = 0;
- CARD8 chunk;
- CARD32 i, j;
-
- RADEONCTRACE(("RADEONLoadCursorImage (at %x)\n", info->cursor_offset));
-
- if (!info->IsSecondary) {
- save1 = INREG(RADEON_CRTC_GEN_CNTL) & ~(CARD32) (3 << 20);
- save1 |= (CARD32) (2 << 20);
- OUTREG(RADEON_CRTC_GEN_CNTL, save1 & (CARD32)~RADEON_CRTC_CUR_EN);
- }
+ ScrnInfoPtr pScrn = crtc->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ CARD32 *pixels = (CARD32 *)(pointer)(info->FB + info->cursor_offset + pScrn->fbOffset);
+ int pixel, i;
+ CURSOR_SWAPPING_DECL_MMIO
- if (info->IsSecondary || info->MergedFB) {
- save2 = INREG(RADEON_CRTC2_GEN_CNTL) & ~(CARD32) (3 << 20);
- save2 |= (CARD32) (2 << 20);
- OUTREG(RADEON_CRTC2_GEN_CNTL, save2 & (CARD32)~RADEON_CRTC2_CUR_EN);
- }
+ RADEONCTRACE(("RADEONSetCursorColors\n"));
#ifdef ARGB_CURSOR
- info->cursor_argb = FALSE;
+ /* Don't recolour cursors set with SetCursorARGB. */
+ if (info->cursor_argb)
+ return;
#endif
- /*
- * Convert the bitmap to ARGB32.
- *
- * HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 always places
- * source in the low bit of the pair and mask in the high bit,
- * and MSBFirst machines set HARDWARE_CURSOR_BIT_ORDER_MSBFIRST
- * (which actually bit swaps the image) to make the bits LSBFirst
- */
- CURSOR_SWAPPING_START();
-#define ARGB_PER_CHUNK (8 * sizeof (chunk) / 2)
- for (i = 0; i < (CURSOR_WIDTH * CURSOR_HEIGHT / ARGB_PER_CHUNK); i++) {
- chunk = *s++;
- for (j = 0; j < ARGB_PER_CHUNK; j++, chunk >>= 2)
- *d++ = mono_cursor_color[chunk & 3];
- }
- CURSOR_SWAPPING_END();
-
- info->cursor_bg = mono_cursor_color[2];
- info->cursor_fg = mono_cursor_color[3];
-
- if (!info->IsSecondary)
- OUTREG(RADEON_CRTC_GEN_CNTL, save1);
-
- if (info->IsSecondary || info->MergedFB)
- OUTREG(RADEON_CRTC2_GEN_CNTL, save2);
-
-}
-
-/* Hide hardware cursor. */
-static void RADEONHideCursor(ScrnInfoPtr pScrn)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
-
- RADEONCTRACE(("RADEONHideCursor\n"));
-
- if (info->IsSecondary || info->MergedFB)
- OUTREGP(RADEON_CRTC2_GEN_CNTL, 0, ~RADEON_CRTC2_CUR_EN);
-
- if (!info->IsSecondary)
- OUTREGP(RADEON_CRTC_GEN_CNTL, 0, ~RADEON_CRTC_CUR_EN);
-}
-
-/* Show hardware cursor. */
-static void RADEONShowCursor(ScrnInfoPtr pScrn)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
-
- RADEONCTRACE(("RADEONShowCursor\n"));
+ fg |= 0xff000000;
+ bg |= 0xff000000;
- if (info->IsSecondary || info->MergedFB)
- OUTREGP(RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_CUR_EN,
- ~RADEON_CRTC2_CUR_EN);
+ /* Don't recolour the image if we don't have to. */
+ if (fg == info->cursor_fg && bg == info->cursor_bg)
+ return;
- if (!info->IsSecondary)
- OUTREGP(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_CUR_EN,
- ~RADEON_CRTC_CUR_EN);
-}
+ CURSOR_SWAPPING_START();
-/* Determine if hardware cursor is in use. */
-static Bool RADEONUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- RADEONInfoPtr info = RADEONPTR(pScrn);
+ /* Note: We assume that the pixels are either fully opaque or fully
+ * transparent, so we won't premultiply them, and we can just
+ * check for non-zero pixel values; those are either fg or bg
+ */
+ for (i = 0; i < CURSOR_WIDTH * CURSOR_HEIGHT; i++, pixels++)
+ if ((pixel = *pixels))
+ *pixels = (pixel == info->cursor_fg) ? fg : bg;
- return info->cursor ? TRUE : FALSE;
+ CURSOR_SWAPPING_END();
+ info->cursor_fg = fg;
+ info->cursor_bg = bg;
}
#ifdef ARGB_CURSOR
-#include "cursorstr.h"
-static Bool RADEONUseHWCursorARGB (ScreenPtr pScreen, CursorPtr pCurs)
-{
- if (RADEONUseHWCursor(pScreen, pCurs) &&
- pCurs->bits->height <= CURSOR_HEIGHT && pCurs->bits->width <= CURSOR_WIDTH)
- return TRUE;
- return FALSE;
-}
-
-static void RADEONLoadCursorARGB (ScrnInfoPtr pScrn, CursorPtr pCurs)
+void
+radeon_crtc_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image)
{
+ ScrnInfoPtr pScrn = crtc->scrn;
RADEONInfoPtr info = RADEONPTR(pScrn);
unsigned char *RADEONMMIO = info->MMIO;
CARD32 *d = (CARD32 *)(pointer)(info->FB + info->cursor_offset + pScrn->fbOffset);
- int x, y, w, h;
- CARD32 save1 = 0;
- CARD32 save2 = 0;
- CARD32 *image = pCurs->bits->argb;
- CARD32 *i;
RADEONCTRACE(("RADEONLoadCursorARGB\n"));
- if (!info->IsSecondary) {
- save1 = INREG(RADEON_CRTC_GEN_CNTL) & ~(CARD32) (3 << 20);
- save1 |= (CARD32) (2 << 20);
- OUTREG(RADEON_CRTC_GEN_CNTL, save1 & (CARD32)~RADEON_CRTC_CUR_EN);
- }
-
- if (info->IsSecondary || info->MergedFB) {
- save2 = INREG(RADEON_CRTC2_GEN_CNTL) & ~(CARD32) (3 << 20);
- save2 |= (CARD32) (2 << 20);
- OUTREG(RADEON_CRTC2_GEN_CNTL, save2 & (CARD32)~RADEON_CRTC2_CUR_EN);
- }
-
-#ifdef ARGB_CURSOR
info->cursor_argb = TRUE;
-#endif
CURSOR_SWAPPING_START();
- w = pCurs->bits->width;
- if (w > CURSOR_WIDTH)
- w = CURSOR_WIDTH;
- h = pCurs->bits->height;
- if (h > CURSOR_HEIGHT)
- h = CURSOR_HEIGHT;
- for (y = 0; y < h; y++)
- {
- i = image;
- image += pCurs->bits->width;
- for (x = 0; x < w; x++)
- *d++ = *i++;
- /* pad to the right with transparent */
- for (; x < CURSOR_WIDTH; x++)
- *d++ = 0;
- }
- /* pad below with transparent */
- for (; y < CURSOR_HEIGHT; y++)
- for (x = 0; x < CURSOR_WIDTH; x++)
- *d++ = 0;
+ memcpy (d, image, CURSOR_HEIGHT * CURSOR_WIDTH * 4);
CURSOR_SWAPPING_END ();
-
- if (!info->IsSecondary)
- OUTREG(RADEON_CRTC_GEN_CNTL, save1);
-
- if (info->IsSecondary || info->MergedFB)
- OUTREG(RADEON_CRTC2_GEN_CNTL, save2);
-
}
#endif
@@ -378,39 +239,12 @@ Bool RADEONCursorInit(ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
RADEONInfoPtr info = RADEONPTR(pScrn);
- xf86CursorInfoPtr cursor;
int width;
int width_bytes;
int height;
int size_bytes;
- if (!(cursor = info->cursor = xf86CreateCursorInfoRec())) return FALSE;
- cursor->MaxWidth = CURSOR_WIDTH;
- cursor->MaxHeight = CURSOR_HEIGHT;
- cursor->Flags = (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP
- | HARDWARE_CURSOR_AND_SOURCE_WITH_MASK
-#if X_BYTE_ORDER == X_BIG_ENDIAN
- /* this is a lie --
- * HARDWARE_CURSOR_BIT_ORDER_MSBFIRST
- * actually inverts the bit order, so
- * this switches to LSBFIRST
- */
- | HARDWARE_CURSOR_BIT_ORDER_MSBFIRST
-#endif
- | HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1);
-
- cursor->SetCursorColors = RADEONSetCursorColors;
- cursor->SetCursorPosition = RADEONSetCursorPosition;
- cursor->LoadCursorImage = RADEONLoadCursorImage;
- cursor->HideCursor = RADEONHideCursor;
- cursor->ShowCursor = RADEONShowCursor;
- cursor->UseHWCursor = RADEONUseHWCursor;
-
-#ifdef ARGB_CURSOR
- cursor->UseHWCursorARGB = RADEONUseHWCursorARGB;
- cursor->LoadCursorARGB = RADEONLoadCursorARGB;
-#endif
size_bytes = CURSOR_WIDTH * 4 * CURSOR_HEIGHT;
width = pScrn->displayWidth;
width_bytes = width * (pScrn->bitsPerPixel / 8);
@@ -440,5 +274,17 @@ Bool RADEONCursorInit(ScreenPtr pScreen)
}
#endif
- return xf86InitCursor(pScreen, cursor);
+ return xf86_cursors_init (pScreen, CURSOR_WIDTH, CURSOR_HEIGHT,
+ (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ /* this is a lie --
+ * HARDWARE_CURSOR_BIT_ORDER_MSBFIRST
+ * actually inverts the bit order, so
+ * this switches to LSBFIRST
+ */
+ HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
+#endif
+ HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
+ HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 |
+ HARDWARE_CURSOR_ARGB));
}
diff --git a/src/radeon_display.c b/src/radeon_display.c
index d661c17b..fa80e104 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -36,8 +36,8 @@
/* X and server generic header files */
#include "xf86.h"
#include "xf86_OSproc.h"
-#include "fbdevhw.h"
#include "vgaHW.h"
+#include "xf86Modes.h"
/* Driver data structures */
#include "radeon.h"
@@ -45,97 +45,9 @@
#include "radeon_macros.h"
#include "radeon_probe.h"
#include "radeon_version.h"
-#include "radeon_mergedfb.h"
extern int getRADEONEntityIndex(void);
-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"
-};
-
-
-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*/
- {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RADEON*/
- {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RV100*/
- {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RS100*/
- {{15000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RV200*/
- {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RS200*/
- {{15000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_R200*/
- {{15500, 0x81b}, {0xffffffff, 0x83f}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RV250*/
- {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RS300*/
- {{13000, 0x400f4}, {15000, 0x400f7}, {0xffffffff, 0x40111}, {0, 0}}, /*CHIP_FAMILY_RV280*/
- {{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*/
- {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RV410*/ /* FIXME: just values from r420 used... */
- {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RS400*/ /* FIXME: just values from rv380 used... */
-};
-
static const CARD32 default_tvdac_adj [CHIP_FAMILY_LAST] =
{
0x00000000, /* unknown */
@@ -158,53 +70,6 @@ static const CARD32 default_tvdac_adj [CHIP_FAMILY_LAST] =
0x00780000, /* rs400 */ /* FIXME: just values from rv380 used... */
};
-static void RADEONI2CGetBits(I2CBusPtr b, int *Clock, int *data)
-{
- ScrnInfoPtr pScrn = xf86Screens[b->scrnIndex];
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned long val;
- unsigned char *RADEONMMIO = info->MMIO;
-
- /* Get the result */
- val = INREG(info->DDCReg);
-
- *Clock = (val & RADEON_GPIO_Y_1) != 0;
- *data = (val & RADEON_GPIO_Y_0) != 0;
-}
-
-static void RADEONI2CPutBits(I2CBusPtr b, int Clock, int data)
-{
- ScrnInfoPtr pScrn = xf86Screens[b->scrnIndex];
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned long val;
- unsigned char *RADEONMMIO = info->MMIO;
-
- val = INREG(info->DDCReg) & (CARD32)~(RADEON_GPIO_EN_0 | RADEON_GPIO_EN_1);
- val |= (Clock ? 0:RADEON_GPIO_EN_1);
- val |= (data ? 0:RADEON_GPIO_EN_0);
- OUTREG(info->DDCReg, val);
-
- /* read back to improve reliability on some cards. */
- val = INREG(info->DDCReg);
-}
-
-Bool RADEONI2cInit(ScrnInfoPtr pScrn)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
-
- info->pI2CBus = xf86CreateI2CBusRec();
- if (!info->pI2CBus) return FALSE;
-
- info->pI2CBus->BusName = "DDC";
- info->pI2CBus->scrnIndex = pScrn->scrnIndex;
- info->pI2CBus->I2CPutBits = RADEONI2CPutBits;
- info->pI2CBus->I2CGetBits = RADEONI2CGetBits;
- info->pI2CBus->AcknTimeout = 5;
-
- if (!xf86I2CBusInit(info->pI2CBus)) return FALSE;
- return TRUE;
-}
-
void RADEONSetSyncRangeFromEdid(ScrnInfoPtr pScrn, int flag)
{
MonPtr mon = pScrn->monitor;
@@ -293,1137 +158,21 @@ void RADEONSetSyncRangeFromEdid(ScrnInfoPtr pScrn, int flag)
}
}
-static RADEONMonitorType
-RADEONCrtIsPhysicallyConnected(ScrnInfoPtr pScrn, int IsCrtDac)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
- int bConnected = 0;
-
- /* the monitor either wasn't connected or it is a non-DDC CRT.
- * try to probe it
- */
- if(IsCrtDac) {
- unsigned long ulOrigVCLK_ECP_CNTL;
- unsigned long ulOrigDAC_CNTL;
- unsigned long ulOrigDAC_MACRO_CNTL;
- unsigned long ulOrigDAC_EXT_CNTL;
- unsigned long ulOrigCRTC_EXT_CNTL;
- unsigned long ulData;
- unsigned long ulMask;
-
- ulOrigVCLK_ECP_CNTL = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
-
- ulData = ulOrigVCLK_ECP_CNTL;
- ulData &= ~(RADEON_PIXCLK_ALWAYS_ONb
- | RADEON_PIXCLK_DAC_ALWAYS_ONb);
- ulMask = ~(RADEON_PIXCLK_ALWAYS_ONb
- |RADEON_PIXCLK_DAC_ALWAYS_ONb);
- OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL, ulData, ulMask);
-
- ulOrigCRTC_EXT_CNTL = INREG(RADEON_CRTC_EXT_CNTL);
- ulData = ulOrigCRTC_EXT_CNTL;
- ulData |= RADEON_CRTC_CRT_ON;
- OUTREG(RADEON_CRTC_EXT_CNTL, ulData);
-
- ulOrigDAC_EXT_CNTL = INREG(RADEON_DAC_EXT_CNTL);
- ulData = ulOrigDAC_EXT_CNTL;
- ulData &= ~RADEON_DAC_FORCE_DATA_MASK;
- ulData |= (RADEON_DAC_FORCE_BLANK_OFF_EN
- |RADEON_DAC_FORCE_DATA_EN
- |RADEON_DAC_FORCE_DATA_SEL_MASK);
- if ((info->ChipFamily == CHIP_FAMILY_RV250) ||
- (info->ChipFamily == CHIP_FAMILY_RV280))
- ulData |= (0x01b6 << RADEON_DAC_FORCE_DATA_SHIFT);
- else
- ulData |= (0x01ac << RADEON_DAC_FORCE_DATA_SHIFT);
-
- OUTREG(RADEON_DAC_EXT_CNTL, ulData);
-
- /* turn on power so testing can go through */
- ulOrigDAC_CNTL = INREG(RADEON_DAC_CNTL);
- ulOrigDAC_CNTL &= ~RADEON_DAC_PDWN;
- OUTREG(RADEON_DAC_CNTL, ulOrigDAC_CNTL);
-
- ulOrigDAC_MACRO_CNTL = INREG(RADEON_DAC_MACRO_CNTL);
- ulOrigDAC_MACRO_CNTL &= ~(RADEON_DAC_PDWN_R | RADEON_DAC_PDWN_G |
- RADEON_DAC_PDWN_B);
- OUTREG(RADEON_DAC_MACRO_CNTL, ulOrigDAC_MACRO_CNTL);
-
- /* Enable comparators and set DAC range to PS2 (VGA) output level */
- ulData = ulOrigDAC_CNTL;
- ulData |= RADEON_DAC_CMP_EN;
- ulData &= ~RADEON_DAC_RANGE_CNTL_MASK;
- ulData |= 0x2;
- OUTREG(RADEON_DAC_CNTL, ulData);
-
- /* Settle down */
- usleep(10000);
-
- /* Read comparators */
- ulData = INREG(RADEON_DAC_CNTL);
- bConnected = (RADEON_DAC_CMP_OUTPUT & ulData)?1:0;
-
- /* Restore things */
- ulData = ulOrigVCLK_ECP_CNTL;
- ulMask = 0xFFFFFFFFL;
- OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL, ulData, ulMask);
-
- OUTREG(RADEON_DAC_CNTL, ulOrigDAC_CNTL );
- OUTREG(RADEON_DAC_EXT_CNTL, ulOrigDAC_EXT_CNTL );
- OUTREG(RADEON_CRTC_EXT_CNTL, ulOrigCRTC_EXT_CNTL);
-
- if (!bConnected) {
- /* Power DAC down if CRT is not connected */
- ulOrigDAC_MACRO_CNTL = INREG(RADEON_DAC_MACRO_CNTL);
- ulOrigDAC_MACRO_CNTL |= (RADEON_DAC_PDWN_R | RADEON_DAC_PDWN_G |
- RADEON_DAC_PDWN_B);
- OUTREG(RADEON_DAC_MACRO_CNTL, ulOrigDAC_MACRO_CNTL);
-
- ulData = INREG(RADEON_DAC_CNTL);
- ulData |= RADEON_DAC_PDWN;
- OUTREG(RADEON_DAC_CNTL, ulData);
- }
- } else { /* TV DAC */
-
- /* This doesn't seem to work reliably (maybe worse on some OEM cards),
- for now we always return false. If one wants to connected a
- non-DDC monitor on the DVI port when CRT port is also connected,
- he will need to explicitly tell the driver in the config file
- with Option MonitorLayout.
- */
- bConnected = FALSE;
-
-#if 0
- if (info->ChipFamily == CHIP_FAMILY_R200) {
- unsigned long ulOrigGPIO_MONID;
- unsigned long ulOrigFP2_GEN_CNTL;
- unsigned long ulOrigDISP_OUTPUT_CNTL;
- unsigned long ulOrigCRTC2_GEN_CNTL;
- unsigned long ulOrigDISP_LIN_TRANS_GRPH_A;
- unsigned long ulOrigDISP_LIN_TRANS_GRPH_B;
- unsigned long ulOrigDISP_LIN_TRANS_GRPH_C;
- unsigned long ulOrigDISP_LIN_TRANS_GRPH_D;
- unsigned long ulOrigDISP_LIN_TRANS_GRPH_E;
- unsigned long ulOrigDISP_LIN_TRANS_GRPH_F;
- unsigned long ulOrigCRTC2_H_TOTAL_DISP;
- unsigned long ulOrigCRTC2_V_TOTAL_DISP;
- unsigned long ulOrigCRTC2_H_SYNC_STRT_WID;
- unsigned long ulOrigCRTC2_V_SYNC_STRT_WID;
- unsigned long ulData, i;
-
- ulOrigGPIO_MONID = INREG(RADEON_GPIO_MONID);
- ulOrigFP2_GEN_CNTL = INREG(RADEON_FP2_GEN_CNTL);
- ulOrigDISP_OUTPUT_CNTL = INREG(RADEON_DISP_OUTPUT_CNTL);
- ulOrigCRTC2_GEN_CNTL = INREG(RADEON_CRTC2_GEN_CNTL);
- ulOrigDISP_LIN_TRANS_GRPH_A = INREG(RADEON_DISP_LIN_TRANS_GRPH_A);
- ulOrigDISP_LIN_TRANS_GRPH_B = INREG(RADEON_DISP_LIN_TRANS_GRPH_B);
- ulOrigDISP_LIN_TRANS_GRPH_C = INREG(RADEON_DISP_LIN_TRANS_GRPH_C);
- ulOrigDISP_LIN_TRANS_GRPH_D = INREG(RADEON_DISP_LIN_TRANS_GRPH_D);
- ulOrigDISP_LIN_TRANS_GRPH_E = INREG(RADEON_DISP_LIN_TRANS_GRPH_E);
- ulOrigDISP_LIN_TRANS_GRPH_F = INREG(RADEON_DISP_LIN_TRANS_GRPH_F);
-
- ulOrigCRTC2_H_TOTAL_DISP = INREG(RADEON_CRTC2_H_TOTAL_DISP);
- ulOrigCRTC2_V_TOTAL_DISP = INREG(RADEON_CRTC2_V_TOTAL_DISP);
- ulOrigCRTC2_H_SYNC_STRT_WID = INREG(RADEON_CRTC2_H_SYNC_STRT_WID);
- ulOrigCRTC2_V_SYNC_STRT_WID = INREG(RADEON_CRTC2_V_SYNC_STRT_WID);
-
- ulData = INREG(RADEON_GPIO_MONID);
- ulData &= ~RADEON_GPIO_A_0;
- OUTREG(RADEON_GPIO_MONID, ulData);
-
- OUTREG(RADEON_FP2_GEN_CNTL, 0x0a000c0c);
-
- OUTREG(RADEON_DISP_OUTPUT_CNTL, 0x00000012);
-
- OUTREG(RADEON_CRTC2_GEN_CNTL, 0x06000000);
- OUTREG(RADEON_DISP_LIN_TRANS_GRPH_A, 0x00000000);
- OUTREG(RADEON_DISP_LIN_TRANS_GRPH_B, 0x000003f0);
- OUTREG(RADEON_DISP_LIN_TRANS_GRPH_C, 0x00000000);
- OUTREG(RADEON_DISP_LIN_TRANS_GRPH_D, 0x000003f0);
- OUTREG(RADEON_DISP_LIN_TRANS_GRPH_E, 0x00000000);
- OUTREG(RADEON_DISP_LIN_TRANS_GRPH_F, 0x000003f0);
- OUTREG(RADEON_CRTC2_H_TOTAL_DISP, 0x01000008);
- OUTREG(RADEON_CRTC2_H_SYNC_STRT_WID, 0x00000800);
- OUTREG(RADEON_CRTC2_V_TOTAL_DISP, 0x00080001);
- OUTREG(RADEON_CRTC2_V_SYNC_STRT_WID, 0x00000080);
-
- for (i = 0; i < 200; i++) {
- ulData = INREG(RADEON_GPIO_MONID);
- bConnected = (ulData & RADEON_GPIO_Y_0)?1:0;
- if (!bConnected) break;
-
- usleep(1000);
- }
-
- OUTREG(RADEON_DISP_LIN_TRANS_GRPH_A, ulOrigDISP_LIN_TRANS_GRPH_A);
- OUTREG(RADEON_DISP_LIN_TRANS_GRPH_B, ulOrigDISP_LIN_TRANS_GRPH_B);
- OUTREG(RADEON_DISP_LIN_TRANS_GRPH_C, ulOrigDISP_LIN_TRANS_GRPH_C);
- OUTREG(RADEON_DISP_LIN_TRANS_GRPH_D, ulOrigDISP_LIN_TRANS_GRPH_D);
- OUTREG(RADEON_DISP_LIN_TRANS_GRPH_E, ulOrigDISP_LIN_TRANS_GRPH_E);
- OUTREG(RADEON_DISP_LIN_TRANS_GRPH_F, ulOrigDISP_LIN_TRANS_GRPH_F);
- OUTREG(RADEON_CRTC2_H_TOTAL_DISP, ulOrigCRTC2_H_TOTAL_DISP);
- OUTREG(RADEON_CRTC2_V_TOTAL_DISP, ulOrigCRTC2_V_TOTAL_DISP);
- OUTREG(RADEON_CRTC2_H_SYNC_STRT_WID, ulOrigCRTC2_H_SYNC_STRT_WID);
- OUTREG(RADEON_CRTC2_V_SYNC_STRT_WID, ulOrigCRTC2_V_SYNC_STRT_WID);
- OUTREG(RADEON_CRTC2_GEN_CNTL, ulOrigCRTC2_GEN_CNTL);
- OUTREG(RADEON_DISP_OUTPUT_CNTL, ulOrigDISP_OUTPUT_CNTL);
- OUTREG(RADEON_FP2_GEN_CNTL, ulOrigFP2_GEN_CNTL);
- OUTREG(RADEON_GPIO_MONID, ulOrigGPIO_MONID);
- } else {
- unsigned long ulOrigPIXCLKSDATA;
- unsigned long ulOrigTV_MASTER_CNTL;
- unsigned long ulOrigTV_DAC_CNTL;
- unsigned long ulOrigTV_PRE_DAC_MUX_CNTL;
- unsigned long ulOrigDAC_CNTL2;
- unsigned long ulData;
- unsigned long ulMask;
-
- ulOrigPIXCLKSDATA = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
-
- ulData = ulOrigPIXCLKSDATA;
- ulData &= ~(RADEON_PIX2CLK_ALWAYS_ONb
- | RADEON_PIX2CLK_DAC_ALWAYS_ONb);
- ulMask = ~(RADEON_PIX2CLK_ALWAYS_ONb
- | RADEON_PIX2CLK_DAC_ALWAYS_ONb);
- OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, ulData, ulMask);
-
- ulOrigTV_MASTER_CNTL = INREG(RADEON_TV_MASTER_CNTL);
- ulData = ulOrigTV_MASTER_CNTL;
- ulData &= ~RADEON_TVCLK_ALWAYS_ONb;
- OUTREG(RADEON_TV_MASTER_CNTL, ulData);
-
- ulOrigDAC_CNTL2 = INREG(RADEON_DAC_CNTL2);
- ulData = ulOrigDAC_CNTL2;
- ulData &= ~RADEON_DAC2_DAC2_CLK_SEL;
- OUTREG(RADEON_DAC_CNTL2, ulData);
-
- ulOrigTV_DAC_CNTL = INREG(RADEON_TV_DAC_CNTL);
-
- ulData = 0x00880213;
- OUTREG(RADEON_TV_DAC_CNTL, ulData);
-
- ulOrigTV_PRE_DAC_MUX_CNTL = INREG(RADEON_TV_PRE_DAC_MUX_CNTL);
-
- ulData = (RADEON_Y_RED_EN
- | RADEON_C_GRN_EN
- | RADEON_CMP_BLU_EN
- | RADEON_RED_MX_FORCE_DAC_DATA
- | RADEON_GRN_MX_FORCE_DAC_DATA
- | RADEON_BLU_MX_FORCE_DAC_DATA);
- 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(10000);
-
- ulData = INREG(RADEON_TV_DAC_CNTL);
- bConnected = (ulData & RADEON_TV_DAC_CMPOUT)?1:0;
-
- ulData = ulOrigPIXCLKSDATA;
- ulMask = 0xFFFFFFFFL;
- OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, ulData, ulMask);
-
- OUTREG(RADEON_TV_MASTER_CNTL, ulOrigTV_MASTER_CNTL);
- OUTREG(RADEON_DAC_CNTL2, ulOrigDAC_CNTL2);
- OUTREG(RADEON_TV_DAC_CNTL, ulOrigTV_DAC_CNTL);
- OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, ulOrigTV_PRE_DAC_MUX_CNTL);
- }
-#endif
- }
-
- return(bConnected ? MT_CRT : MT_NONE);
-}
-
-
-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;
- switch(DDCType)
- {
- case DDC_MONID:
- info->DDCReg = RADEON_GPIO_MONID;
- break;
- case DDC_DVI:
- info->DDCReg = RADEON_GPIO_DVI_DDC;
- break;
- case DDC_VGA:
- info->DDCReg = RADEON_GPIO_VGA_DDC;
- break;
- case DDC_CRT2:
- info->DDCReg = RADEON_GPIO_CRT2_DDC;
- break;
- default:
- info->DDCReg = DDCReg;
- return MT_NONE;
- }
-
- /* Read and output monitor info using DDC2 over I2C bus */
- if (info->pI2CBus && info->ddc2) {
- OUTREG(info->DDCReg, INREG(info->DDCReg) &
- (CARD32)~(RADEON_GPIO_A_0 | RADEON_GPIO_A_1));
-
- /* For some old monitors (like Compaq Presario FP500), we need
- * following process to initialize/stop DDC
- */
- OUTREG(info->DDCReg, INREG(info->DDCReg) & ~(RADEON_GPIO_EN_1));
- for (j = 0; j < 3; j++) {
- OUTREG(info->DDCReg,
- INREG(info->DDCReg) & ~(RADEON_GPIO_EN_0));
- usleep(13000);
-
- OUTREG(info->DDCReg,
- INREG(info->DDCReg) & ~(RADEON_GPIO_EN_1));
- for (i = 0; i < 10; i++) {
- usleep(15000);
- if (INREG(info->DDCReg) & RADEON_GPIO_Y_1)
- break;
- }
- if (i == 10) continue;
-
- usleep(15000);
-
- OUTREG(info->DDCReg, INREG(info->DDCReg) | RADEON_GPIO_EN_0);
- usleep(15000);
-
- OUTREG(info->DDCReg, INREG(info->DDCReg) | RADEON_GPIO_EN_1);
- usleep(15000);
- OUTREG(info->DDCReg,
- INREG(info->DDCReg) & ~(RADEON_GPIO_EN_0));
- usleep(15000);
- *MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex, info->pI2CBus);
-
- OUTREG(info->DDCReg, INREG(info->DDCReg) | RADEON_GPIO_EN_1);
- OUTREG(info->DDCReg, INREG(info->DDCReg) | RADEON_GPIO_EN_0);
- usleep(15000);
- OUTREG(info->DDCReg,
- INREG(info->DDCReg) & ~(RADEON_GPIO_EN_1));
- for (i = 0; i < 5; i++) {
- usleep(15000);
- if (INREG(info->DDCReg) & RADEON_GPIO_Y_1)
- break;
- }
- usleep(15000);
- OUTREG(info->DDCReg,
- INREG(info->DDCReg) & ~(RADEON_GPIO_EN_0));
- usleep(15000);
-
- OUTREG(info->DDCReg, INREG(info->DDCReg) | RADEON_GPIO_EN_1);
- OUTREG(info->DDCReg, INREG(info->DDCReg) | RADEON_GPIO_EN_0);
- usleep(15000);
- if(*MonInfo) break;
- }
- } else {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "DDC2/I2C is not properly initialized\n");
- MonType = MT_NONE;
- }
-
- OUTREG(info->DDCReg, INREG(info->DDCReg) &
- ~(RADEON_GPIO_EN_0 | RADEON_GPIO_EN_1));
-
- if (*MonInfo) {
- if ((*MonInfo)->rawData[0x14] & 0x80) {
- /* Note some laptops have a DVI output that uses internal TMDS,
- * when its DVI is enabled by hotkey, LVDS panel is not used.
- * In this case, the laptop is configured as DVI+VGA as a normal
- * desktop card.
- * Also for laptop, when X starts with lid closed (no DVI connection)
- * both LDVS and TMDS are disable, we still need to treat it as a LVDS panel.
- */
- if (port->TMDSType == TMDS_EXT) MonType = MT_DFP;
- else {
- if ((INREG(RADEON_FP_GEN_CNTL) & RADEON_FP_EN_TMDS) || !info->IsMobility)
- MonType = MT_DFP;
- else
- MonType = MT_LCD;
- }
- } else MonType = MT_CRT;
- } else MonType = MT_NONE;
-
- info->DDCReg = DDCReg;
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "DDC Type: %d, Detected Type: %d\n", DDCType, MonType);
-
- return MonType;
-}
-
-static void RADEONGetPanelInfoFromReg (ScrnInfoPtr pScrn)
-{
- 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);
-
- 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_horz_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;
- }
-
- if (xf86ReturnOptValBool(info->Options, OPTION_LVDS_PROBE_PLL, TRUE)) {
- CARD32 ppll_div_sel, ppll_val;
-
- ppll_div_sel = INREG8(RADEON_CLOCK_CNTL_INDEX + 1) & 0x3;
- RADEONPllErrataAfterIndex(info);
- ppll_val = INPLL(pScrn, RADEON_PPLL_DIV_0 + ppll_div_sel);
- if ((ppll_val & 0x000707ff) == 0x1bb)
- goto noprobe;
- info->FeedbackDivider = ppll_val & 0x7ff;
- info->PostDivider = (ppll_val >> 16) & 0x7;
- info->RefDivider = info->pll.reference_div;
- info->UseBiosDividers = TRUE;
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Existing panel PLL dividers will be used.\n");
- }
- noprobe:
-
- 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);
-}
-
-
-/* BIOS may not have right panel size, we search through all supported
- * DDC modes looking for the maximum panel size.
- */
-static void RADEONUpdatePanelSize(ScrnInfoPtr pScrn)
-{
- int j;
- RADEONInfoPtr info = RADEONPTR (pScrn);
- xf86MonPtr ddc = pScrn->monitor->DDC;
- DisplayModePtr p;
-
- if ((info->UseBiosDividers && info->DotClock != 0) || (ddc == NULL))
- return;
-
- /* Go thru detailed timing table first */
- for (j = 0; j < 4; j++) {
- if (ddc->det_mon[j].type == 0) {
- struct detailed_timings *d_timings =
- &ddc->det_mon[j].section.d_timings;
- int match = 0;
-
- /* If we didn't get a panel clock or guessed one, try to match the
- * mode with the panel size. We do that because we _need_ a panel
- * clock, or ValidateFPModes will fail, even when UseBiosDividers
- * is set.
- */
- if (info->DotClock == 0 &&
- info->PanelXRes == d_timings->h_active &&
- info->PanelYRes == d_timings->v_active)
- match = 1;
-
- /* If we don't have a BIOS provided panel data with fixed dividers,
- * check for a larger panel size
- */
- if (info->PanelXRes < d_timings->h_active &&
- info->PanelYRes < d_timings->v_active &&
- !info->UseBiosDividers)
- match = 1;
-
- if (match) {
- info->PanelXRes = d_timings->h_active;
- info->PanelYRes = d_timings->v_active;
- info->DotClock = d_timings->clock / 1000;
- info->HOverPlus = d_timings->h_sync_off;
- info->HSyncWidth = d_timings->h_sync_width;
- info->HBlank = d_timings->h_blanking;
- info->VOverPlus = d_timings->v_sync_off;
- info->VSyncWidth = d_timings->v_sync_width;
- info->VBlank = d_timings->v_blanking;
- info->Flags = (d_timings->interlaced ? V_INTERLACE : 0);
- if (d_timings->sync == 3) {
- switch (d_timings->misc) {
- case 0: info->Flags |= V_NHSYNC | V_NVSYNC; break;
- case 1: info->Flags |= V_PHSYNC | V_NVSYNC; break;
- case 2: info->Flags |= V_NHSYNC | V_PVSYNC; break;
- case 3: info->Flags |= V_PHSYNC | V_PVSYNC; break;
- }
- }
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel infos found from DDC detailed: %dx%d\n",
- info->PanelXRes, info->PanelYRes);
- }
- }
- }
-
- if (info->UseBiosDividers && info->DotClock != 0)
- return;
-
- /* Search thru standard VESA modes from EDID */
- for (j = 0; j < 8; j++) {
- if ((info->PanelXRes < ddc->timings2[j].hsize) &&
- (info->PanelYRes < ddc->timings2[j].vsize)) {
- for (p = pScrn->monitor->Modes; p && p->next; p = p->next->next) {
- if ((ddc->timings2[j].hsize == p->HDisplay) &&
- (ddc->timings2[j].vsize == p->VDisplay)) {
- float refresh =
- (float)p->Clock * 1000.0 / p->HTotal / p->VTotal;
-
- if (abs((float)ddc->timings2[j].refresh - refresh) < 1.0) {
- /* Is this good enough? */
- info->PanelXRes = ddc->timings2[j].hsize;
- info->PanelYRes = ddc->timings2[j].vsize;
- info->HBlank = p->HTotal - p->HDisplay;
- info->HOverPlus = p->HSyncStart - p->HDisplay;
- info->HSyncWidth = p->HSyncEnd - p->HSyncStart;
- info->VBlank = p->VTotal - p->VDisplay;
- info->VOverPlus = p->VSyncStart - p->VDisplay;
- info->VSyncWidth = p->VSyncEnd - p->VSyncStart;
- info->DotClock = p->Clock;
- info->Flags = p->Flags;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel infos found from DDC VESA/EDID: %dx%d\n",
- info->PanelXRes, info->PanelYRes);
- }
- }
- }
- }
- }
-}
-
-static Bool RADEONGetLVDSInfo (ScrnInfoPtr pScrn)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
-
- if (!RADEONGetLVDSInfoFromBIOS(pScrn))
- RADEONGetPanelInfoFromReg(pScrn);
-
- /* The panel size we collected from BIOS may not be the
- * maximum size supported by the panel. If not, we update
- * it now. These will be used if no matching mode can be
- * found from EDID data.
- */
- RADEONUpdatePanelSize(pScrn);
-
- 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;
-}
-
-static void RADEONGetTMDSInfo(ScrnInfoPtr pScrn)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- int i;
-
- for (i=0; i<4; i++) {
- info->tmds_pll[i].value = 0;
- info->tmds_pll[i].freq = 0;
- }
-
- 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;
- }
-}
-
-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 {
-
- if(info->DisplayType == MT_LCD) {
- RADEONGetLVDSInfo(pScrn);
- if (info->MergeType == MT_DFP) {
- RADEONGetTMDSInfo(pScrn);
- }
- } else if ((info->DisplayType == MT_DFP) || (info->MergeType == MT_DFP)) {
- RADEONGetTMDSInfo(pScrn);
- if (!pScrn->monitor->DDC)
- RADEONGetHardCodedEDIDFromBIOS(pScrn);
- else if (!info->IsSecondary)
- RADEONUpdatePanelSize(pScrn);
- }
- }
-}
-
-void RADEONGetTVDacAdjInfo(ScrnInfoPtr pScrn)
+void RADEONGetTVDacAdjInfo(xf86OutputPtr output)
{
- RADEONInfoPtr info = RADEONPTR(pScrn);
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
/* Todo: get this setting from BIOS */
- info->tv_dac_adj = default_tvdac_adj[info->ChipFamily];
+ radeon_output->tv_dac_adj = default_tvdac_adj[info->ChipFamily];
if (info->IsMobility) { /* some mobility chips may different */
if (info->ChipFamily == CHIP_FAMILY_RV250)
- info->tv_dac_adj = 0x00880000;
+ radeon_output->tv_dac_adj = 0x00880000;
}
}
/*
- * initialise the static data sos we don't have to re-do at randr change */
-void RADEONSetupConnectors(ScrnInfoPtr pScrn)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
- const char *s;
- Bool ignore_edid = FALSE;
- int i = 0, second = 0, max_mt = 5;
-
- /* We first get the information about all connectors from BIOS.
- * 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;
- }
- pRADEONEnt->Controller[0]->IsUsed = FALSE;
- pRADEONEnt->Controller[1]->IsUsed = FALSE;
- pRADEONEnt->Controller[0]->IsActive = FALSE;
- pRADEONEnt->Controller[1]->IsActive = FALSE;
-
- if (!RADEONGetConnectorInfoFromBIOS(pScrn) ||
- ((pRADEONEnt->PortInfo[0]->DDCType == 0) &&
- (pRADEONEnt->PortInfo[1]->DDCType == 0))) {
- /* Below is the most common setting, but may not be true */
- pRADEONEnt->PortInfo[0]->MonType = MT_UNKNOWN;
- pRADEONEnt->PortInfo[0]->MonInfo = NULL;
- pRADEONEnt->PortInfo[0]->DDCType = DDC_DVI;
- pRADEONEnt->PortInfo[0]->DACType = DAC_TVDAC;
- pRADEONEnt->PortInfo[0]->TMDSType = TMDS_INT;
- pRADEONEnt->PortInfo[0]->ConnectorType = CONNECTOR_DVI_I;
-
- pRADEONEnt->PortInfo[1]->MonType = MT_UNKNOWN;
- pRADEONEnt->PortInfo[1]->MonInfo = NULL;
- pRADEONEnt->PortInfo[1]->DDCType = DDC_VGA;
- pRADEONEnt->PortInfo[1]->DACType = DAC_PRIMARY;
- pRADEONEnt->PortInfo[1]->TMDSType = TMDS_EXT;
- pRADEONEnt->PortInfo[1]->ConnectorType = CONNECTOR_CRT;
-
-
- /* Some cards have the DDC lines swapped and we have no way to
- * detect it yet (Mac cards)
- */
- if (xf86ReturnOptValBool(info->Options, OPTION_REVERSE_DDC, FALSE)) {
- pRADEONEnt->PortInfo[0]->DDCType = DDC_VGA;
- pRADEONEnt->PortInfo[1]->DDCType = DDC_DVI;
- }
- }
-
- /* 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 */
- /* On my Inspiron 8600 both internal and external ports are
- marked DAC_PRIMARY in BIOS. So be extra careful - only
- swap when the first port is not DAC_PRIMARY */
- if ((!(pRADEONEnt->PortInfo[0]->ConnectorType == CONNECTOR_PROPRIETARY)) && (pRADEONEnt->PortInfo[1]->DACType == DAC_PRIMARY) &&
- (pRADEONEnt->PortInfo[0]->DACType != DAC_PRIMARY)) {
- RADEONConnector *connector;
- connector = pRADEONEnt->PortInfo[0];
- pRADEONEnt->PortInfo[0] = pRADEONEnt->PortInfo[1];
- pRADEONEnt->PortInfo[1] = connector;
- }
- }
-
- 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 (!pRADEONEnt->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.
- * For example, you can config your laptop with
- * Option "MonitorLayout" "LVDS, CRT"
- * Option "CloneHSync" "40-150"
- * Option "CloneVRefresh" "60-120"
- * With these options, you can connect in your CRT monitor later
- * after the X server has started.
- */
- 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 1st port \n");
-
- for (i = 0; i < max_mt; i++)
- {
- if (strcmp(s2, MonTypeName[i]) == 0)
- {
- pRADEONEnt->PortInfo[1]->MonType = MonTypeID[i];
- break;
- }
-
- }
- if (i == max_mt)
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Invalid Monitor type specified for 2nd port \n");
-
- 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 0
- 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;
- }
-#endif
-
- /* some thinkpads and powerbooks use lvds and internal tmds
- * at the same time. --AGD
- */
- if ((pRADEONEnt->PortInfo[0]->MonType == MT_LCD) &&
- (pRADEONEnt->PortInfo[1]->MonType == MT_DFP)) {
- pRADEONEnt->PortInfo[1]->DDCType = DDC_DVI;
- pRADEONEnt->PortInfo[0]->DDCType = DDC_MONID;
- pRADEONEnt->PortInfo[1]->TMDSType = TMDS_INT;
- pRADEONEnt->PortInfo[1]->ConnectorType = CONNECTOR_DVI_I;
- pRADEONEnt->PortInfo[0]->TMDSType = TMDS_UNKNOWN;
- }
-
- }
-}
-
-static RADEONMonitorType RADEONPortCheckNonDDC(ScrnInfoPtr pScrn, int connector)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
-
- if (info->IsMobility) {
- switch(connector) {
- case 0:
- /* non-DDC laptop panel connected on primary */
- if (INREG(RADEON_BIOS_4_SCRATCH) & 4)
- return MT_LCD;
- break;
- case 1:
- /* non-DDC TMDS panel connected through DVO */
- if (INREG(RADEON_FP2_GEN_CNTL) & RADEON_FP2_ON)
- return MT_DFP;
- break;
- default:
- break;
- }
- }
- return MT_NONE;
-}
-
-/* Primary Head (DVI or Laptop Int. panel)*/
-/* A ddc capable display connected on DVI port */
-/* Secondary Head (mostly VGA, can be DVI on some OEM boards)*/
-void RADEONConnectorFindMonitor(ScrnInfoPtr pScrn, int connector)
-{
- RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
- RADEONConnector *pPort = pRADEONEnt->PortInfo[connector];
-
- if (pPort->MonType == MT_UNKNOWN) {
- if ((pPort->MonType = RADEONDisplayDDCConnected(pScrn,
- pPort->DDCType,
- pPort)));
- else if((pPort->MonType = RADEONPortCheckNonDDC(pScrn, connector)));
- else
- pPort->MonType = RADEONCrtIsPhysicallyConnected(pScrn, !(pPort->DACType));
- }
-}
-
-static void RADEONQueryConnectedDisplays(ScrnInfoPtr pScrn)
-{
-
- RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
- const char *s;
- Bool ignore_edid = FALSE;
-
- /* 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");
- }
-
- if ((s = xf86GetOptValString(info->Options, OPTION_MONITOR_LAYOUT))) {
- 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]);
- }
- }
- else {
- /* force monitor redetection */
- pRADEONEnt->PortInfo[0]->MonType = MT_UNKNOWN;
- pRADEONEnt->PortInfo[1]->MonType = MT_UNKNOWN;
- }
-
-
- if (pRADEONEnt->PortInfo[0]->MonType == MT_UNKNOWN || pRADEONEnt->PortInfo[1]->MonType == MT_UNKNOWN) {
-
- if ((!pRADEONEnt->HasCRTC2) && (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->PortInfo[1]->MonType = MT_NONE;
- pRADEONEnt->PortInfo[1]->MonInfo = NULL;
- pRADEONEnt->PortInfo[1]->DDCType = DDC_NONE_DETECTED;
- pRADEONEnt->PortInfo[1]->DACType = DAC_UNKNOWN;
- pRADEONEnt->PortInfo[1]->TMDSType = TMDS_UNKNOWN;
- pRADEONEnt->PortInfo[1]->ConnectorType = CONNECTOR_NONE;
-
- pRADEONEnt->PortInfo[0]->crtc_num = 1;
- pRADEONEnt->PortInfo[1]->crtc_num = 2;
-
- return;
- }
-
- RADEONConnectorFindMonitor(pScrn, 0);
- RADEONConnectorFindMonitor(pScrn, 1);
-
- }
-
- 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 1st port ----------------------\n");
- xf86PrintEDID( pRADEONEnt->PortInfo[0]->MonInfo );
- }
-
- if (pRADEONEnt->PortInfo[1]->MonInfo) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID data from the display on 2nd port -----------------------\n");
- xf86PrintEDID( pRADEONEnt->PortInfo[1]->MonInfo );
- }
- }
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "\n");
-
- return;
-}
-
-Bool RADEONMapControllers(ScrnInfoPtr pScrn)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
- Bool head_reversed = FALSE;
- RADEONConnector *connector;
-
- info->MergeType = MT_NONE;
-
- if (!info->IsSecondary) {
- RADEONQueryConnectedDisplays(pScrn);
-
- pRADEONEnt->PortInfo[0]->crtc_num = 1;
- pRADEONEnt->PortInfo[1]->crtc_num = 2;
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Port1:\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,
- "Port2:\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]);
-
- /* no display detected on primary port*/
- if (pRADEONEnt->PortInfo[0]->MonType == MT_NONE) {
- if (pRADEONEnt->PortInfo[1]->MonType != MT_NONE) {
- /* Only one detected on secondary, let it to be primary */
- pRADEONEnt->PortInfo[0]->crtc_num = 2;
- pRADEONEnt->PortInfo[1]->crtc_num = 1;
- head_reversed = TRUE;
- } else {
- /* None detected, Default to a CRT connected */
- pRADEONEnt->PortInfo[0]->MonType = MT_CRT;
- }
- }
-
- if ((pRADEONEnt->PortInfo[0]->MonType == MT_LCD) &&
- (pRADEONEnt->PortInfo[1]->MonType == MT_CRT)) {
- if (!(INREG(RADEON_LVDS_GEN_CNTL) & RADEON_LVDS_ON)) {
- /* LCD is switched off, don't turn it on, otherwise it may casue lockup due to SS issue. */
- pRADEONEnt->PortInfo[0]->crtc_num = 2;
- pRADEONEnt->PortInfo[1]->crtc_num = 1;
- pRADEONEnt->PortInfo[0]->MonType = MT_NONE;
- head_reversed = TRUE;
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "LCD is switched off, only CRT will be used\n");
- }
- }
-
- if ((pRADEONEnt->PortInfo[0]->MonType != MT_NONE) &&
- (pRADEONEnt->PortInfo[1]->MonType != MT_NONE)) {
- if (xf86ReturnOptValBool(info->Options, OPTION_REVERSE_DISPLAY, FALSE)) {
- if (info->IsMobility) {
- /* Don't reverse display for mobility chips, as only CRTC1 path has RMX which
- will be required by many LCD panels
- */
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Reverse Display cannot be used for mobility chip\n");
- } else {
- pRADEONEnt->PortInfo[0]->crtc_num = 2;
- pRADEONEnt->PortInfo[1]->crtc_num = 1;
- head_reversed = TRUE;
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Primary and Secondary mapping is reversed\n");
- }
- }
- }
-
- if (pRADEONEnt->HasSecondary && pRADEONEnt->PortInfo[1]->MonType == MT_NONE) {
- pRADEONEnt->HasSecondary = FALSE;
- }
- }
-
- if(pRADEONEnt->HasCRTC2) {
- if(info->IsSecondary) {
- connector = RADEONGetCrtcConnector(pScrn, 2);
- pRADEONEnt->Controller[1]->binding = 2;
- if (connector) {
- info->DisplayType = connector->MonType;
- pScrn->monitor->DDC = connector->MonInfo;
- }
- } else {
- connector = RADEONGetCrtcConnector(pScrn, 1);
- pRADEONEnt->Controller[0]->binding = 1;
- if (connector) {
- info->DisplayType = connector->MonType;
- pScrn->monitor->DDC = connector->MonInfo;
- }
- }
-
- if(!pRADEONEnt->HasSecondary) {
- connector = RADEONGetCrtcConnector(pScrn, 2);
- if (connector)
- info->MergeType = connector->MonType;
- if (info->MergeType)
- pRADEONEnt->Controller[1]->binding = 1;
- }
- } else {
- connector = RADEONGetCrtcConnector(pScrn, 1);
- if (connector) {
- if (connector->MonType == MT_NONE)
- connector->MonType = MT_CRT;
- info->DisplayType = connector->MonType;
- pScrn->monitor->DDC = connector->MonInfo;
- }
- connector = RADEONGetCrtcConnector(pScrn, 2);
- if (connector)
- connector->MonType = MT_NONE;
- pRADEONEnt->Controller[1]->binding = 1;
- }
-
- if (!info->IsSecondary) {
- connector = RADEONGetCrtcConnector(pScrn, 2);
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "---- Primary Head: Port%d ---- \n", head_reversed?2:1);
- if (connector->MonType != MT_NONE)
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "---- Secondary Head: Port%d ----\n", head_reversed?1:2);
- else
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "---- Secondary Head: Not used ----\n");
- }
-
- info->HBlank = 0;
- info->HOverPlus = 0;
- info->HSyncWidth = 0;
- info->VBlank = 0;
- info->VOverPlus = 0;
- info->VSyncWidth = 0;
- info->DotClock = 0;
- info->UseBiosDividers = FALSE;
-
- info->OverlayOnCRTC2 = FALSE;
-
- return TRUE;
-}
-
-/*
* Powering done DAC, needed for DPMS problem with ViewSonic P817 (or its variant).
*
*/
@@ -1436,8 +185,7 @@ static void RADEONDacPowerSet(ScrnInfoPtr pScrn, Bool IsOn, Bool IsPrimaryDAC)
CARD32 dac_cntl;
CARD32 dac_macro_cntl = 0;
dac_cntl = INREG(RADEON_DAC_CNTL);
- if ((!info->IsMobility) || (info->ChipFamily == CHIP_FAMILY_RV350))
- dac_macro_cntl = INREG(RADEON_DAC_MACRO_CNTL);
+ dac_macro_cntl = INREG(RADEON_DAC_MACRO_CNTL);
if (IsOn) {
dac_cntl &= ~RADEON_DAC_PDWN;
dac_macro_cntl &= ~(RADEON_DAC_PDWN_R |
@@ -1450,8 +198,7 @@ static void RADEONDacPowerSet(ScrnInfoPtr pScrn, Bool IsOn, Bool IsPrimaryDAC)
RADEON_DAC_PDWN_B);
}
OUTREG(RADEON_DAC_CNTL, dac_cntl);
- if ((!info->IsMobility) || (info->ChipFamily == CHIP_FAMILY_RV350))
- OUTREG(RADEON_DAC_MACRO_CNTL, dac_macro_cntl);
+ OUTREG(RADEON_DAC_MACRO_CNTL, dac_macro_cntl);
} else {
CARD32 tv_dac_cntl;
CARD32 fp2_gen_cntl;
@@ -1528,6 +275,13 @@ void RADEONDisableDisplays(ScrnInfoPtr pScrn) {
}
RADEONDacPowerSet(pScrn, FALSE, FALSE);
+ /* turn off tv-out */
+ if (info->InternalTVOut) {
+ tmp = INREG(RADEON_TV_MASTER_CNTL);
+ tmp &= ~RADEON_TV_ON;
+ OUTREG(RADEON_TV_MASTER_CNTL, tmp);
+ }
+
/* FP 1 */
tmp = INREG(RADEON_FP_GEN_CNTL);
tmp &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN);
@@ -1539,39 +293,47 @@ void RADEONDisableDisplays(ScrnInfoPtr pScrn) {
OUTREG(RADEON_FP2_GEN_CNTL, tmp);
/* LVDS */
- tmpPixclksCntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
- if (info->IsMobility || info->IsIGP) {
- /* Asic bug, when turning off LVDS_ON, we have to make sure
- RADEON_PIXCLK_LVDS_ALWAYS_ON bit is off
- */
- OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, 0, ~RADEON_PIXCLK_LVDS_ALWAYS_ONb);
- }
- tmp = INREG(RADEON_LVDS_GEN_CNTL);
- tmp |= (RADEON_LVDS_ON | RADEON_LVDS_DISPLAY_DIS);
- tmp &= ~(RADEON_LVDS_BLON);
- OUTREG(RADEON_LVDS_GEN_CNTL, tmp);
- if (info->IsMobility || info->IsIGP) {
- OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmpPixclksCntl);
+ if (info->IsMobility) {
+ tmpPixclksCntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
+ if (info->IsMobility || info->IsIGP) {
+ /* Asic bug, when turning off LVDS_ON, we have to make sure
+ RADEON_PIXCLK_LVDS_ALWAYS_ON bit is off
+ */
+ OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, 0, ~RADEON_PIXCLK_LVDS_ALWAYS_ONb);
+ }
+ tmp = INREG(RADEON_LVDS_GEN_CNTL);
+ tmp |= RADEON_LVDS_DISPLAY_DIS;
+ tmp &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON);
+ OUTREG(RADEON_LVDS_GEN_CNTL, tmp);
+ if (info->IsMobility || info->IsIGP) {
+ OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmpPixclksCntl);
+ }
}
}
/* This is to be used enable/disable displays dynamically */
-void RADEONEnableDisplay(ScrnInfoPtr pScrn, RADEONConnector* pPort, BOOL bEnable)
+void RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable)
{
+ ScrnInfoPtr pScrn = output->scrn;
RADEONInfoPtr info = RADEONPTR(pScrn);
RADEONSavePtr save = &info->ModeReg;
unsigned char * RADEONMMIO = info->MMIO;
unsigned long tmp;
+ RADEONOutputPrivatePtr radeon_output;
+ int tv_dac_change = 0;
+ radeon_output = output->driver_private;
if (bEnable) {
- if (pPort->MonType == MT_CRT) {
- if (pPort->DACType == DAC_PRIMARY) {
+ ErrorF("enable montype: %d\n", radeon_output->MonType);
+ if (radeon_output->MonType == MT_CRT) {
+ if (radeon_output->DACType == DAC_PRIMARY) {
tmp = INREG(RADEON_CRTC_EXT_CNTL);
tmp |= RADEON_CRTC_CRT_ON;
OUTREG(RADEON_CRTC_EXT_CNTL, tmp);
save->crtc_ext_cntl |= RADEON_CRTC_CRT_ON;
- } else if (pPort->DACType == DAC_TVDAC) {
+ RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY));
+ } else if (radeon_output->DACType == DAC_TVDAC) {
if (info->ChipFamily == CHIP_FAMILY_R200) {
tmp = INREG(RADEON_FP2_GEN_CNTL);
tmp |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN);
@@ -1579,41 +341,50 @@ void RADEONEnableDisplay(ScrnInfoPtr pScrn, RADEONConnector* pPort, BOOL bEnable
save->fp2_gen_cntl |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN);
} else {
tmp = INREG(RADEON_CRTC2_GEN_CNTL);
- tmp |= RADEON_CRTC2_CRT2_ON;
+ tmp |= RADEON_CRTC2_CRT2_ON;
OUTREG(RADEON_CRTC2_GEN_CNTL, tmp);
save->crtc2_gen_cntl |= RADEON_CRTC2_CRT2_ON;
}
+ tv_dac_change = 1;
}
- RADEONDacPowerSet(pScrn, bEnable, (pPort->DACType == DAC_PRIMARY));
- } else if (pPort->MonType == MT_DFP) {
- if (pPort->TMDSType == TMDS_INT) {
+ } else if (radeon_output->MonType == MT_DFP) {
+ if (radeon_output->TMDSType == TMDS_INT) {
tmp = INREG(RADEON_FP_GEN_CNTL);
tmp |= (RADEON_FP_FPON | RADEON_FP_TMDS_EN);
OUTREG(RADEON_FP_GEN_CNTL, tmp);
save->fp_gen_cntl |= (RADEON_FP_FPON | RADEON_FP_TMDS_EN);
- } else if (pPort->TMDSType == TMDS_EXT) {
+ } else if (radeon_output->TMDSType == TMDS_EXT) {
tmp = INREG(RADEON_FP2_GEN_CNTL);
tmp |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN);
OUTREG(RADEON_FP2_GEN_CNTL, tmp);
save->fp2_gen_cntl |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN);
}
- } else if (pPort->MonType == MT_LCD) {
+ } else if (radeon_output->MonType == MT_LCD) {
tmp = INREG(RADEON_LVDS_GEN_CNTL);
tmp |= (RADEON_LVDS_ON | RADEON_LVDS_BLON);
tmp &= ~(RADEON_LVDS_DISPLAY_DIS);
- usleep (info->PanelPwrDly * 1000);
+ usleep (radeon_output->PanelPwrDly * 1000);
OUTREG(RADEON_LVDS_GEN_CNTL, tmp);
save->lvds_gen_cntl |= (RADEON_LVDS_ON | RADEON_LVDS_BLON);
save->lvds_gen_cntl &= ~(RADEON_LVDS_DISPLAY_DIS);
- }
+ } else if (radeon_output->MonType == MT_STV ||
+ radeon_output->MonType == MT_CTV) {
+ tmp = INREG(RADEON_TV_MASTER_CNTL);
+ tmp |= RADEON_TV_ON;
+ OUTREG(RADEON_TV_MASTER_CNTL, tmp);
+ tv_dac_change = 2;
+ radeon_output->tv_on = TRUE;
+ }
} else {
- if (pPort->MonType == MT_CRT || pPort->MonType == NONE) {
- if (pPort->DACType == DAC_PRIMARY) {
+ ErrorF("disable montype: %d\n", radeon_output->MonType);
+ if (radeon_output->MonType == MT_CRT) {
+ if (radeon_output->DACType == DAC_PRIMARY) {
tmp = INREG(RADEON_CRTC_EXT_CNTL);
- tmp &= ~RADEON_CRTC_CRT_ON;
+ tmp &= ~RADEON_CRTC_CRT_ON;
OUTREG(RADEON_CRTC_EXT_CNTL, tmp);
save->crtc_ext_cntl &= ~RADEON_CRTC_CRT_ON;
- } else if (pPort->DACType == DAC_TVDAC) {
+ RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY));
+ } else if (radeon_output->DACType == DAC_TVDAC) {
if (info->ChipFamily == CHIP_FAMILY_R200) {
tmp = INREG(RADEON_FP2_GEN_CNTL);
tmp &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
@@ -1625,26 +396,21 @@ void RADEONEnableDisplay(ScrnInfoPtr pScrn, RADEONConnector* pPort, BOOL bEnable
OUTREG(RADEON_CRTC2_GEN_CNTL, tmp);
save->crtc2_gen_cntl &= ~RADEON_CRTC2_CRT2_ON;
}
+ tv_dac_change = 1;
}
- RADEONDacPowerSet(pScrn, bEnable, (pPort->DACType == DAC_PRIMARY));
- }
-
- if (pPort->MonType == MT_DFP || pPort->MonType == NONE) {
- if (pPort->TMDSType == TMDS_INT) {
+ } else if (radeon_output->MonType == MT_DFP) {
+ if (radeon_output->TMDSType == TMDS_INT) {
tmp = INREG(RADEON_FP_GEN_CNTL);
tmp &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN);
OUTREG(RADEON_FP_GEN_CNTL, tmp);
save->fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN);
- } else if (pPort->TMDSType == TMDS_EXT) {
+ } else if (radeon_output->TMDSType == TMDS_EXT) {
tmp = INREG(RADEON_FP2_GEN_CNTL);
tmp &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
OUTREG(RADEON_FP2_GEN_CNTL, tmp);
save->fp2_gen_cntl &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
}
- }
-
- if (pPort->MonType == MT_LCD ||
- (pPort->MonType == NONE && pPort->ConnectorType == CONNECTOR_PROPRIETARY)) {
+ } else if (radeon_output->MonType == MT_LCD) {
unsigned long tmpPixclksCntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
if (info->IsMobility || info->IsIGP) {
/* Asic bug, when turning off LVDS_ON, we have to make sure
@@ -1653,21 +419,39 @@ void RADEONEnableDisplay(ScrnInfoPtr pScrn, RADEONConnector* pPort, BOOL bEnable
OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, 0, ~RADEON_PIXCLK_LVDS_ALWAYS_ONb);
}
tmp = INREG(RADEON_LVDS_GEN_CNTL);
- tmp |= (RADEON_LVDS_ON | RADEON_LVDS_DISPLAY_DIS);
- tmp &= ~(RADEON_LVDS_BLON);
+ tmp |= RADEON_LVDS_DISPLAY_DIS;
+ tmp &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON);
OUTREG(RADEON_LVDS_GEN_CNTL, tmp);
- save->lvds_gen_cntl |= (RADEON_LVDS_ON | RADEON_LVDS_DISPLAY_DIS);
- save->lvds_gen_cntl &= ~(RADEON_LVDS_BLON);
+ save->lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS;
+ save->lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON);
if (info->IsMobility || info->IsIGP) {
OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmpPixclksCntl);
}
- }
+ } else if (radeon_output->MonType == MT_STV || radeon_output->MonType == MT_CTV) {
+ tmp = INREG(RADEON_TV_MASTER_CNTL);
+ tmp &= ~RADEON_TV_ON;
+ OUTREG(RADEON_TV_MASTER_CNTL, tmp);
+ tv_dac_change = 2;
+ radeon_output->tv_on = FALSE;
+ }
+ }
+
+ if (tv_dac_change) {
+ if (bEnable)
+ info->tv_dac_enable_mask |= tv_dac_change;
+ else
+ info->tv_dac_enable_mask &= ~tv_dac_change;
+
+ if (bEnable && info->tv_dac_enable_mask)
+ RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY));
+ else if (!bEnable && info->tv_dac_enable_mask == 0)
+ RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY));
+
}
}
/* Calculate display buffer watermark to prevent buffer underflow */
-void RADEONInitDispBandwidth2(ScrnInfoPtr pScrn, RADEONInfoPtr info, RADEONInfoPtr info2,
- DisplayModePtr mode1, DisplayModePtr mode2)
+void RADEONInitDispBandwidth2(ScrnInfoPtr pScrn, RADEONInfoPtr info, int pixel_bytes2, DisplayModePtr mode1, DisplayModePtr mode2)
{
RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
unsigned char *RADEONMMIO = info->MMIO;
@@ -1705,7 +489,7 @@ void RADEONInitDispBandwidth2(ScrnInfoPtr pScrn, RADEONInfoPtr info, RADEONInfoP
*/
if ((info->DispPriority == 2) && IS_R300_VARIANT) {
CARD32 mc_init_misc_lat_timer = INREG(R300_MC_INIT_MISC_LAT_TIMER);
- if (pRADEONEnt->Controller[1]->IsActive) {
+ if (pRADEONEnt->pCrtc[1]->enabled) {
mc_init_misc_lat_timer |= 0x1100; /* display 0 and 1 */
} else {
mc_init_misc_lat_timer |= 0x0100; /* display 0 only */
@@ -1717,11 +501,6 @@ void RADEONInitDispBandwidth2(ScrnInfoPtr pScrn, RADEONInfoPtr info, RADEONInfoP
/* R420 and RV410 family not supported yet */
if (info->ChipFamily == CHIP_FAMILY_R420 || info->ChipFamily == CHIP_FAMILY_RV410) return;
- if (pRADEONEnt->pSecondaryScrn) {
- if (info->IsSecondary) return;
- info2 = RADEONPTR(pRADEONEnt->pSecondaryScrn);
- } else if (pRADEONEnt->Controller[1]->binding == 1) info2 = info;
-
/*
* Determine if there is enough bandwidth for current display mode
*/
@@ -1734,8 +513,8 @@ void RADEONInitDispBandwidth2(ScrnInfoPtr pScrn, RADEONInfoPtr info, RADEONInfoP
pix_clk2 = 0;
peak_disp_bw = (pix_clk * info->CurrentLayout.pixel_bytes);
- if (info2)
- peak_disp_bw += (pix_clk2 * info2->CurrentLayout.pixel_bytes);
+ if (pixel_bytes2)
+ peak_disp_bw += (pix_clk2 * pixel_bytes2);
if (peak_disp_bw >= mem_bw * min_mem_eff) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
@@ -1875,8 +654,8 @@ void RADEONInitDispBandwidth2(ScrnInfoPtr pScrn, RADEONInfoPtr info, RADEONInfoP
Find the drain rate of the display buffer.
*/
disp_drain_rate = pix_clk / (16.0/info->CurrentLayout.pixel_bytes);
- if (info2)
- disp_drain_rate2 = pix_clk2 / (16.0/info2->CurrentLayout.pixel_bytes);
+ if (pixel_bytes2)
+ disp_drain_rate2 = pix_clk2 / (16.0/pixel_bytes2);
else
disp_drain_rate2 = 0;
@@ -1925,11 +704,13 @@ void RADEONInitDispBandwidth2(ScrnInfoPtr pScrn, RADEONInfoPtr info, RADEONInfoP
OUTREG(RADEON_GRPH_BUFFER_CNTL, ((temp & ~RADEON_GRPH_CRITICAL_POINT_MASK) |
(critical_point << RADEON_GRPH_CRITICAL_POINT_SHIFT)));
- RADEONTRACE(("GRPH_BUFFER_CNTL from %x to %x\n",
- (unsigned int)info->SavedReg.grph_buffer_cntl, INREG(RADEON_GRPH_BUFFER_CNTL)));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "GRPH_BUFFER_CNTL from %x to %x\n",
+ (unsigned int)info->SavedReg.grph_buffer_cntl,
+ INREG(RADEON_GRPH_BUFFER_CNTL));
if (mode2) {
- stop_req = mode2->HDisplay * info2->CurrentLayout.pixel_bytes / 16;
+ stop_req = mode2->HDisplay * pixel_bytes2 / 16;
if (stop_req > max_stop_req) stop_req = max_stop_req;
@@ -1973,427 +754,81 @@ void RADEONInitDispBandwidth2(ScrnInfoPtr pScrn, RADEONInfoPtr info, RADEONInfoP
OUTREG(RADEON_GRPH2_BUFFER_CNTL, ((temp & ~RADEON_GRPH_CRITICAL_POINT_MASK) |
(critical_point2 << RADEON_GRPH_CRITICAL_POINT_SHIFT)));
- RADEONTRACE(("GRPH2_BUFFER_CNTL from %x to %x\n",
- (unsigned int)info->SavedReg.grph2_buffer_cntl, INREG(RADEON_GRPH2_BUFFER_CNTL)));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "GRPH2_BUFFER_CNTL from %x to %x\n",
+ (unsigned int)info->SavedReg.grph2_buffer_cntl,
+ INREG(RADEON_GRPH2_BUFFER_CNTL));
}
}
void RADEONInitDispBandwidth(ScrnInfoPtr pScrn)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
DisplayModePtr mode1, mode2;
- RADEONInfoPtr info2 = NULL;
-
- if (pRADEONEnt->pSecondaryScrn) {
- if (info->IsSecondary) return;
- info2 = RADEONPTR(pRADEONEnt->pSecondaryScrn);
- } else if (pRADEONEnt->Controller[1]->binding == 1) info2 = info;
+ int pixel_bytes2 = 0;
mode1 = info->CurrentLayout.mode;
- if (info->MergedFB) {
- mode1 = ((RADEONMergedDisplayModePtr)info->CurrentLayout.mode->Private)->CRT1;
- mode2 = ((RADEONMergedDisplayModePtr)info->CurrentLayout.mode->Private)->CRT2;
- } else if ((pRADEONEnt->HasSecondary) && info2) {
- mode2 = info2->CurrentLayout.mode;
- } else {
- mode2 = NULL;
- }
+ mode2 = NULL;
+ pixel_bytes2 = info->CurrentLayout.pixel_bytes;
- RADEONInitDispBandwidth2(pScrn, info, info2, mode1, mode2);
-}
+ if (xf86_config->num_crtc == 2) {
+ pixel_bytes2 = 0;
+ mode2 = NULL;
-static void RADEONBlankSet(ScrnInfoPtr pScrn, RADEONConnector *pPort)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
-
- switch(pPort->MonType) {
- case MT_LCD:
- OUTREGP(RADEON_LVDS_GEN_CNTL, RADEON_LVDS_DISPLAY_DIS, ~RADEON_LVDS_DISPLAY_DIS);
- break;
+ if (xf86_config->crtc[1]->enabled && xf86_config->crtc[0]->enabled) {
+ pixel_bytes2 = info->CurrentLayout.pixel_bytes;
+ mode1 = &xf86_config->crtc[0]->mode;
+ mode2 = &xf86_config->crtc[1]->mode;
+ } else if (xf86_config->crtc[0]->enabled) {
+ mode1 = &xf86_config->crtc[0]->mode;
+ } else if (xf86_config->crtc[1]->enabled) {
+ mode1 = &xf86_config->crtc[1]->mode;
+ } else
+ return;
+ }
- case MT_CRT:
- if ((info->ChipFamily == CHIP_FAMILY_R200) &&
- (pPort->DACType == DAC_TVDAC))
- OUTREGP(RADEON_FP2_GEN_CNTL, RADEON_FP2_BLANK_EN, ~RADEON_FP2_BLANK_EN);
-
- break;
- case MT_DFP:
- if (pPort->TMDSType == TMDS_EXT)
- OUTREGP(RADEON_FP2_GEN_CNTL, RADEON_FP2_BLANK_EN, ~RADEON_FP2_BLANK_EN);
- else
- OUTREGP(RADEON_FP_GEN_CNTL, RADEON_FP_BLANK_EN, ~RADEON_FP_BLANK_EN);
-
- break;
- case MT_NONE:
- default:
- break;
- }
+ RADEONInitDispBandwidth2(pScrn, info, pixel_bytes2, mode1, mode2);
}
-/* Blank screen */
void RADEONBlank(ScrnInfoPtr pScrn)
{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
- RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
- RADEONConnector *pPort;
-
- if (!pRADEONEnt->HasSecondary ||
- (pRADEONEnt->HasSecondary && !info->IsSwitching) ||
- (info->IsSwitching && (!info->IsSecondary))) {
- pPort = RADEONGetCrtcConnector(pScrn, 1);
- if (pPort)
- RADEONBlankSet(pScrn, pPort);
- OUTREGP (RADEON_CRTC_EXT_CNTL,
- RADEON_CRTC_DISPLAY_DIS |
- RADEON_CRTC_VSYNC_DIS |
- RADEON_CRTC_HSYNC_DIS,
- ~(RADEON_CRTC_DISPLAY_DIS |
- RADEON_CRTC_VSYNC_DIS |
- RADEON_CRTC_HSYNC_DIS));
-
- if (!pRADEONEnt->HasCRTC2) return;
-
- if (pRADEONEnt->Controller[1]->binding == 1) {
- pPort = RADEONGetCrtcConnector(pScrn, 2);
- if (pPort)
- RADEONBlankSet(pScrn, pPort);
- OUTREGP (RADEON_CRTC2_GEN_CNTL,
- RADEON_CRTC2_DISP_DIS |
- RADEON_CRTC2_VSYNC_DIS |
- RADEON_CRTC2_HSYNC_DIS,
- ~(RADEON_CRTC2_DISP_DIS |
- RADEON_CRTC2_VSYNC_DIS |
- RADEON_CRTC2_HSYNC_DIS));
- }
- }
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ xf86OutputPtr output;
+ xf86CrtcPtr crtc;
+ int o, c;
- if ((pRADEONEnt->HasSecondary && !info->IsSwitching) ||
- (info->IsSwitching && info->IsSecondary)) {
- pPort = RADEONGetCrtcConnector(pScrn, 2);
- if (pPort)
- RADEONBlankSet(pScrn, pPort);
- OUTREGP (RADEON_CRTC2_GEN_CNTL,
- RADEON_CRTC2_DISP_DIS |
- RADEON_CRTC2_VSYNC_DIS |
- RADEON_CRTC2_HSYNC_DIS,
- ~(RADEON_CRTC2_DISP_DIS |
- RADEON_CRTC2_VSYNC_DIS |
- RADEON_CRTC2_HSYNC_DIS));
- }
-}
-
-static void RADEONUnblankSet(ScrnInfoPtr pScrn, RADEONConnector *pPort)
-{
- RADEONInfoPtr info = RADEONPTR (pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
+ for (c = 0; c < xf86_config->num_crtc; c++) {
+ crtc = xf86_config->crtc[c];
+ for (o = 0; o < xf86_config->num_output; o++) {
+ output = xf86_config->output[o];
+ if (output->crtc != crtc)
+ continue;
- switch(pPort->MonType) {
- case MT_LCD:
- OUTREGP(RADEON_LVDS_GEN_CNTL, 0, ~RADEON_LVDS_DISPLAY_DIS);
- break;
- case MT_CRT:
- if ((info->ChipFamily == CHIP_FAMILY_R200) &&
- (pPort->DACType == DAC_TVDAC))
- OUTREGP(RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_BLANK_EN);
- break;
- case MT_DFP:
- if (pPort->TMDSType == TMDS_EXT)
- OUTREGP(RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_BLANK_EN);
- else
- OUTREGP(RADEON_FP_GEN_CNTL, 0, ~RADEON_FP_BLANK_EN);
- break;
- case MT_NONE:
- default:
- break;
+ output->funcs->dpms(output, DPMSModeOff);
+ }
+ crtc->funcs->dpms(crtc, DPMSModeOff);
}
}
-/* Unblank screen */
void RADEONUnblank(ScrnInfoPtr pScrn)
{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
- RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
- RADEONConnector *pPort;
-
- if (!pRADEONEnt->HasSecondary || (info->IsSwitching && !info->IsSecondary)) {
- pPort = RADEONGetCrtcConnector(pScrn, 1);
- if (pPort)
- RADEONUnblankSet(pScrn, pPort);
- OUTREGP(RADEON_CRTC_EXT_CNTL,
- 0,
- ~(RADEON_CRTC_DISPLAY_DIS |
- RADEON_CRTC_VSYNC_DIS |
- RADEON_CRTC_HSYNC_DIS));
-
- if (!pRADEONEnt->HasCRTC2) return;
-
- if (pRADEONEnt->Controller[1]->binding == 1) {
- pPort = RADEONGetCrtcConnector(pScrn, 2);
- if (pPort)
- RADEONUnblankSet(pScrn, pPort);
- OUTREGP(RADEON_CRTC2_GEN_CNTL, 0,
- ~(RADEON_CRTC2_DISP_DIS |
- RADEON_CRTC2_VSYNC_DIS |
- RADEON_CRTC2_HSYNC_DIS));
- }
- }
-
- if (info->IsSwitching && info->IsSecondary) {
- pPort = RADEONGetCrtcConnector(pScrn, 2);
- if (pPort)
- RADEONUnblankSet(pScrn, pPort);
- OUTREGP(RADEON_CRTC2_GEN_CNTL, 0,
- ~(RADEON_CRTC2_DISP_DIS |
- RADEON_CRTC2_VSYNC_DIS |
- RADEON_CRTC2_HSYNC_DIS));
- }
-}
-
-static void RADEONDPMSSetOn(ScrnInfoPtr pScrn, RADEONConnector *pPort)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
- RADEONMonitorType MonType;
- RADEONTmdsType TmdsType;
- RADEONDacType DacType;
-
- MonType = pPort->MonType;
- TmdsType = pPort->TMDSType;
- DacType = pPort->DACType;
-
- switch(MonType) {
- case MT_LCD:
- OUTREGP (RADEON_LVDS_GEN_CNTL, RADEON_LVDS_BLON, ~RADEON_LVDS_BLON);
- usleep (info->PanelPwrDly * 1000);
- OUTREGP (RADEON_LVDS_GEN_CNTL, RADEON_LVDS_ON, ~RADEON_LVDS_ON);
- break;
- case MT_DFP:
- if (TmdsType == TMDS_EXT) {
- 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_DVO_EN,
- ~RADEON_FP2_DVO_EN);
- }
- } else
- OUTREGP (RADEON_FP_GEN_CNTL, (RADEON_FP_FPON | RADEON_FP_TMDS_EN),
- ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN));
- break;
- case MT_CRT:
- default:
- RADEONDacPowerSet(pScrn, TRUE, (DacType == DAC_PRIMARY));
- break;
- }
-}
-
-static void RADEONDPMSSetOff(ScrnInfoPtr pScrn, RADEONConnector *pPort)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
- RADEONMonitorType MonType;
- RADEONTmdsType TmdsType;
- RADEONDacType DacType;
- unsigned long tmpPixclksCntl;
-
- MonType = pPort->MonType;
- TmdsType = pPort->TMDSType;
- DacType = pPort->DACType;
-
- switch(MonType) {
- case MT_LCD:
- tmpPixclksCntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
- if (info->IsMobility || info->IsIGP) {
- /* Asic bug, when turning off LVDS_ON, we have to make sure
- RADEON_PIXCLK_LVDS_ALWAYS_ON bit is off
- */
- OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, 0, ~RADEON_PIXCLK_LVDS_ALWAYS_ONb);
- }
- OUTREGP (RADEON_LVDS_GEN_CNTL, 0,
- ~(RADEON_LVDS_BLON | RADEON_LVDS_ON));
- if (info->IsMobility || info->IsIGP) {
- OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmpPixclksCntl);
- }
- break;
- case MT_DFP:
- if (TmdsType == TMDS_EXT) {
- 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_DVO_EN);
- }
- } else
- OUTREGP (RADEON_FP_GEN_CNTL, 0, ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN));
- break;
- case MT_CRT:
- default:
- RADEONDacPowerSet(pScrn, FALSE, (DacType == DAC_PRIMARY));
- break;
- }
-}
-
-
-/* Sets VESA Display Power Management Signaling (DPMS) Mode */
-void RADEONDisplayPowerManagementSet(ScrnInfoPtr pScrn,
- int PowerManagementMode,
- int flags)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
- RADEONConnector *pPort;
- if (!pScrn->vtSema) return;
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ xf86OutputPtr output;
+ xf86CrtcPtr crtc;
+ int o, c;
- RADEONTRACE(("RADEONDisplayPowerManagementSet(%d,0x%x)\n", PowerManagementMode, flags));
+ for (c = 0; c < xf86_config->num_crtc; c++) {
+ crtc = xf86_config->crtc[c];
+ if(!crtc->enabled)
+ continue;
+ crtc->funcs->dpms(crtc, DPMSModeOn);
+ for (o = 0; o < xf86_config->num_output; o++) {
+ output = xf86_config->output[o];
+ if (output->crtc != crtc)
+ continue;
-#ifdef XF86DRI
- if (info->CPStarted) DRILock(pScrn->pScreen, 0);
-#endif
-
- if (info->accelOn)
- RADEON_SYNC(info, pScrn);
-
- if (info->FBDev) {
- fbdevHWDPMSSet(pScrn, PowerManagementMode, flags);
- } else {
- int mask1 = (RADEON_CRTC_DISPLAY_DIS |
- RADEON_CRTC_HSYNC_DIS |
- RADEON_CRTC_VSYNC_DIS);
- int mask2 = (RADEON_CRTC2_DISP_DIS |
- RADEON_CRTC2_VSYNC_DIS |
- RADEON_CRTC2_HSYNC_DIS);
-
- switch (PowerManagementMode) {
- case DPMSModeOn:
- /* Screen: On; HSync: On, VSync: On */
- if (info->IsSecondary)
- OUTREGP(RADEON_CRTC2_GEN_CNTL, 0, ~mask2);
- else {
- if (pRADEONEnt->Controller[1]->binding == 1)
- OUTREGP(RADEON_CRTC2_GEN_CNTL, 0, ~mask2);
- OUTREGP(RADEON_CRTC_EXT_CNTL, 0, ~mask1);
- }
- break;
-
- case DPMSModeStandby:
- /* Screen: Off; HSync: Off, VSync: On */
- if (info->IsSecondary)
- OUTREGP(RADEON_CRTC2_GEN_CNTL,
- (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_HSYNC_DIS),
- ~mask2);
- else {
- if (pRADEONEnt->Controller[1]->binding == 1)
- OUTREGP(RADEON_CRTC2_GEN_CNTL,
- (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_HSYNC_DIS),
- ~mask2);
- OUTREGP(RADEON_CRTC_EXT_CNTL,
- (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS),
- ~mask1);
- }
- break;
-
- case DPMSModeSuspend:
- /* Screen: Off; HSync: On, VSync: Off */
- if (info->IsSecondary)
- OUTREGP(RADEON_CRTC2_GEN_CNTL,
- (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS),
- ~mask2);
- else {
- if (pRADEONEnt->Controller[1]->binding == 1)
- OUTREGP(RADEON_CRTC2_GEN_CNTL,
- (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS),
- ~mask2);
- OUTREGP(RADEON_CRTC_EXT_CNTL,
- (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_VSYNC_DIS),
- ~mask1);
- }
- break;
-
- case DPMSModeOff:
- /* Screen: Off; HSync: Off, VSync: Off */
- if (info->IsSecondary)
- OUTREGP(RADEON_CRTC2_GEN_CNTL, mask2, ~mask2);
- else {
- if (pRADEONEnt->Controller[1]->binding == 1)
- OUTREGP(RADEON_CRTC2_GEN_CNTL, mask2, ~mask2);
- OUTREGP(RADEON_CRTC_EXT_CNTL, mask1, ~mask1);
- }
- break;
+ output->funcs->dpms(output, DPMSModeOn);
}
-
- if (PowerManagementMode == DPMSModeOn) {
- pPort = RADEONGetCrtcConnector(pScrn, info->IsSecondary ? 2 : 1);
- RADEONDPMSSetOn(pScrn, pPort);
- if (pRADEONEnt->Controller[1]->binding == 1) {
- pPort = RADEONGetCrtcConnector(pScrn, 2);
- RADEONDPMSSetOn(pScrn, pPort);
- }
- } else if ((PowerManagementMode == DPMSModeOff) ||
- (PowerManagementMode == DPMSModeSuspend) ||
- (PowerManagementMode == DPMSModeStandby)) {
- pPort = RADEONGetCrtcConnector(pScrn, info->IsSecondary ? 2 : 1);
- RADEONDPMSSetOff(pScrn, pPort);
- if (pRADEONEnt->Controller[1]->binding == 1) {
- pPort = RADEONGetCrtcConnector(pScrn, 2);
- RADEONDPMSSetOff(pScrn, pPort);
- }
- }
}
-
-#ifdef XF86DRI
- if (info->CPStarted) DRIUnlock(pScrn->pScreen);
-#endif
-}
-
-Bool RADEONAllocateControllers(ScrnInfoPtr pScrn)
-{
- RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
-
- if (pRADEONEnt->Controller[0])
- return TRUE;
-
- pRADEONEnt->Controller[0] = xcalloc(sizeof(RADEONController), 1);
- if (!pRADEONEnt->Controller[0])
- return FALSE;
-
- pRADEONEnt->Controller[1] = xcalloc(sizeof(RADEONController), 1);
- if (!pRADEONEnt->Controller[1])
- {
- xfree(pRADEONEnt->Controller[0]);
- return FALSE;
- }
-
- return TRUE;
-}
-
-Bool RADEONAllocateConnectors(ScrnInfoPtr pScrn)
-{
- RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
- int i;
-
- if (pRADEONEnt->PortInfo[0])
- return TRUE;
-
- /* for now always allocate max connectors */
- for (i = 0 ; i < RADEON_MAX_CONNECTOR; i++) {
- pRADEONEnt->PortInfo[i] = xcalloc(sizeof(RADEONConnector), 1);
- if (!pRADEONEnt->PortInfo[i])
- return FALSE;
- }
-
- return TRUE;
-}
-
-RADEONConnector *RADEONGetCrtcConnector(ScrnInfoPtr pScrn, int crtc_num)
-{
- RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
-
- if (pRADEONEnt->PortInfo[0]->crtc_num == crtc_num)
- return pRADEONEnt->PortInfo[0];
- else if (pRADEONEnt->PortInfo[1]->crtc_num == crtc_num)
- return pRADEONEnt->PortInfo[1];
- return NULL;
}
diff --git a/src/radeon_dri.c b/src/radeon_dri.c
index ee6192e9..24018e8b 100644
--- a/src/radeon_dri.c
+++ b/src/radeon_dri.c
@@ -69,7 +69,12 @@ static void RADEONDRITransitionMultiToSingle3d(ScreenPtr pScreen);
static void RADEONDRITransitionSingleToMulti3d(ScreenPtr pScreen);
#ifdef DAMAGE
-static void RADEONDRIRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
+static void RADEONDRIRefreshArea(ScrnInfoPtr pScrn, RegionPtr pReg);
+
+#if (DRIINFO_MAJOR_VERSION > 5 || \
+ (DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 1))
+static void RADEONDRIClipNotify(ScreenPtr pScreen, WindowPtr *ppWin, int num);
+#endif
#endif
/* Initialize the visual configs that are supported by the hardware.
@@ -398,10 +403,10 @@ static void RADEONLeaveServer(ScreenPtr pScreen)
#ifdef DAMAGE
if (info->pDamage) {
RegionPtr pDamageReg = DamageRegion(info->pDamage);
+ int nrects = pDamageReg ? REGION_NUM_RECTS(pDamageReg) : 0;
- if (pDamageReg) {
- RADEONDRIRefreshArea(pScrn, REGION_NUM_RECTS(pDamageReg),
- REGION_RECTS(pDamageReg));
+ if (nrects) {
+ RADEONDRIRefreshArea(pScrn, pDamageReg);
}
}
#endif
@@ -409,13 +414,7 @@ static void RADEONLeaveServer(ScreenPtr pScreen)
/* The CP is always running, but if we've generated any CP commands
* we must flush them to the kernel module now.
*/
- if (info->CPInUse) {
- RADEON_FLUSH_CACHE();
- RADEON_WAIT_UNTIL_IDLE();
- RADEONCPReleaseIndirect(pScrn);
-
- info->CPInUse = FALSE;
- }
+ RADEONCP_RELEASE(pScrn, info);
#ifdef USE_EXA
info->engineMode = EXA_ENGINEMODE_UNKNOWN;
@@ -754,28 +753,6 @@ static Bool RADEONSetAgpMode(RADEONInfoPtr info, ScreenPtr pScreen)
xf86DrvMsg(pScreen->myNum, from, "Using AGP %dx\n", info->agpMode);
- info->agpFastWrite = 0; // Always off by default as it sucks
-
- from = xf86GetOptValInteger(info->Options, OPTION_AGP_FW,
- &info->agpFastWrite) ? X_CONFIG : X_DEFAULT;
-
- if (info->agpFastWrite &&
- (vendor == PCI_VENDOR_AMD) &&
- (device == PCI_CHIP_AMD761)) {
-
- /* Disable fast write for AMD 761 chipset, since they cause
- * lockups when enabled.
- */
- info->agpFastWrite = FALSE;
- from = X_DEFAULT;
- xf86DrvMsg(pScreen->myNum, X_WARNING,
- "[agp] Not enabling Fast Writes on AMD 761 chipset to avoid "
- "lockups");
- }
-
- xf86DrvMsg(pScreen->myNum, from, "AGP Fast Writes %sabled\n",
- info->agpFastWrite ? "en" : "dis");
-
mode &= ~RADEON_AGP_MODE_MASK;
if (is_v3) {
/* only set one mode bit for AGPv3 */
@@ -794,8 +771,26 @@ static Bool RADEONSetAgpMode(RADEONInfoPtr info, ScreenPtr pScreen)
}
}
- if (info->agpFastWrite) mode |= RADEON_AGP_FW_MODE;
- else mode &= ~RADEON_AGP_FW_MODE;
+ /* AGP Fast Writes.
+ * TODO: take into account that certain agp modes don't support fast
+ * writes at all */
+ mode &= ~RADEON_AGP_FW_MODE; /* Disable per default */
+ if (xf86ReturnOptValBool(info->Options, OPTION_AGP_FW, FALSE)) {
+ xf86DrvMsg(pScreen->myNum, X_WARNING,
+ "WARNING: Using the AGPFastWrite option is not recommended.\n");
+ xf86Msg(X_NONE, "\tThis option does not provide much of a noticable speed"
+ " boost, while it\n\twill probably hard lock your machine."
+ " All bets are off!\n");
+
+ /* Black list some host/AGP bridges. */
+ if ((vendor == PCI_VENDOR_AMD) && (device == PCI_CHIP_AMD761))
+ xf86DrvMsg(pScreen->myNum, X_PROBED, "Ignoring AGPFastWrite option "
+ "for the AMD 761 northbridge.\n");
+ else {
+ xf86DrvMsg(pScreen->myNum, X_CONFIG, "Enabling AGP Fast Writes.\n");
+ mode |= RADEON_AGP_FW_MODE;
+ }
+ } /* Don't mention this otherwise, so that people don't get funny ideas */
xf86DrvMsg(pScreen->myNum, X_INFO,
"[agp] Mode 0x%08lx [AGP 0x%04x/0x%04x; Card 0x%04x/0x%04x]\n",
@@ -1250,7 +1245,7 @@ Bool RADEONDRIGetVersion(ScrnInfoPtr pScrn)
/* Check the DRI version */
DRIQueryVersion(&major, &minor, &patch);
- if (major != DRIINFO_MAJOR_VERSION || minor < DRIINFO_MINOR_VERSION) {
+ if (major != DRIINFO_MAJOR_VERSION || minor < 0) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"[dri] RADEONDRIGetVersion failed because of a version "
"mismatch.\n"
@@ -1258,7 +1253,7 @@ Bool RADEONDRIGetVersion(ScrnInfoPtr pScrn)
"needed.\n"
"[dri] Disabling DRI.\n",
major, minor, patch,
- DRIINFO_MAJOR_VERSION, DRIINFO_MINOR_VERSION);
+ DRIINFO_MAJOR_VERSION, 0);
return FALSE;
}
@@ -1358,6 +1353,29 @@ Bool RADEONDRIGetVersion(ScrnInfoPtr pScrn)
return TRUE;
}
+Bool RADEONDRISetVBlankInterrupt(ScrnInfoPtr pScrn, Bool on)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ int value = 0;
+
+ if (info->directRenderingEnabled && info->pKernelDRMVersion->version_minor >= 28) {
+ if (on) {
+ if (xf86_config->num_crtc > 1 && xf86_config->crtc[1]->enabled)
+ value = DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2;
+ else
+ value = DRM_RADEON_VBLANK_CRTC1;
+ }
+
+ if (RADEONDRISetParam(pScrn, RADEON_SETPARAM_VBLANK_CRTC, value)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "RADEON Vblank Crtc Setup Failed %d\n", value);
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+
/* Initialize the screen-specific data structures for the DRI and the
* Radeon. This is the main entry point to the device-specific
* initialization code. It calls device-independent DRI functions to
@@ -1477,10 +1495,31 @@ Bool RADEONDRIScreenInit(ScreenPtr pScreen)
pDRIInfo->TransitionTo3d = RADEONDRITransitionTo3d;
pDRIInfo->TransitionSingleToMulti3D = RADEONDRITransitionSingleToMulti3d;
pDRIInfo->TransitionMultiToSingle3D = RADEONDRITransitionMultiToSingle3d;
+#if defined(DAMAGE) && (DRIINFO_MAJOR_VERSION > 5 || \
+ (DRIINFO_MAJOR_VERSION == 5 && \
+ DRIINFO_MINOR_VERSION >= 1))
+ pDRIInfo->ClipNotify = RADEONDRIClipNotify;
+#endif
pDRIInfo->createDummyCtx = TRUE;
pDRIInfo->createDummyCtxPriv = FALSE;
+#ifdef USE_EXA
+ if (info->useEXA) {
+#if DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 3
+ int major, minor, patch;
+
+ DRIQueryVersion(&major, &minor, &patch);
+
+ if (minor >= 3)
+#endif
+#if DRIINFO_MAJOR_VERSION > 5 || \
+ (DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 3)
+ pDRIInfo->texOffsetStart = RADEONTexOffsetStart;
+#endif
+ }
+#endif
+
if (!DRIScreenInit(pScreen, pDRIInfo, &info->drmFD)) {
xf86DrvMsg(pScreen->myNum, X_ERROR,
"[dri] DRIScreenInit failed. Disabling DRI.\n");
@@ -1646,6 +1685,9 @@ Bool RADEONDRIFinishScreenInit(ScreenPtr pScreen)
info->DRICloseScreen = pScreen->CloseScreen;
pScreen->CloseScreen = RADEONDRIDoCloseScreen;
+ /* disable vblank at startup */
+ RADEONDRISetVBlankInterrupt (pScrn, FALSE);
+
return TRUE;
}
@@ -1696,20 +1738,15 @@ void RADEONDRIStop(ScreenPtr pScreen)
RADEONInfoPtr info = RADEONPTR(pScrn);
RING_LOCALS;
- RADEONTRACE(("RADEONDRIStop\n"));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "RADEONDRIStop\n");
/* Stop the CP */
if (info->directRenderingInited) {
/* If we've generated any CP commands, we must flush them to the
* kernel module now.
*/
- if (info->CPInUse) {
- RADEON_FLUSH_CACHE();
- RADEON_WAIT_UNTIL_IDLE();
- RADEONCPReleaseIndirect(pScrn);
-
- info->CPInUse = FALSE;
- }
+ RADEONCP_RELEASE(pScrn, info);
RADEONCP_STOP(pScrn, info);
}
info->directRenderingInited = FALSE;
@@ -1724,9 +1761,15 @@ void RADEONDRICloseScreen(ScreenPtr pScreen)
RADEONInfoPtr info = RADEONPTR(pScrn);
drmRadeonInit drmInfo;
- RADEONTRACE(("RADEONDRICloseScreen\n"));
-
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "RADEONDRICloseScreen\n");
+
+#ifdef DAMAGE
+ REGION_UNINIT(pScreen, &info->driRegion);
+#endif
+
if (info->irq) {
+ RADEONDRISetVBlankInterrupt (pScrn, FALSE);
drmCtlUninstHandler(info->drmFD);
info->irq = 0;
info->ModeReg.gen_int_cntl = 0;
@@ -1819,15 +1862,17 @@ void RADEONDRICloseScreen(ScreenPtr pScreen)
*/
-static void RADEONDRIRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+static void RADEONDRIRefreshArea(ScrnInfoPtr pScrn, RegionPtr pReg)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
- int i;
+ int i, num;
ScreenPtr pScreen = pScrn->pScreen;
RADEONSAREAPrivPtr pSAREAPriv = DRIGetSAREAPrivate(pScreen);
#ifdef USE_EXA
PixmapPtr pPix = pScreen->GetScreenPixmap(pScreen);
#endif
+ RegionRec region;
+ BoxPtr pbox;
if (!info->directRenderingInited || !info->CPStarted)
return;
@@ -1838,6 +1883,17 @@ static void RADEONDRIRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
if (!pSAREAPriv->pfAllowPageFlip && pSAREAPriv->pfCurrentPage == 0)
return;
+ REGION_NULL(pScreen, &region);
+ REGION_SUBTRACT(pScreen, &region, pReg, &info->driRegion);
+
+ num = REGION_NUM_RECTS(&region);
+
+ if (!num) {
+ goto out;
+ }
+
+ pbox = REGION_RECTS(&region);
+
/* pretty much a hack. */
#ifdef USE_EXA
@@ -1858,7 +1914,7 @@ static void RADEONDRIRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
if (!info->useEXA) {
/* Make sure accel has been properly inited */
if (info->accel == NULL || info->accel->SetupForScreenToScreenCopy == NULL)
- return;
+ goto out;
if (info->tilingEnabled)
info->dst_pitch_offset |= RADEON_DST_TILE_MACRO;
(*info->accel->SetupForScreenToScreenCopy)(pScrn,
@@ -1894,6 +1950,8 @@ static void RADEONDRIRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
info->dst_pitch_offset &= ~RADEON_DST_TILE_MACRO;
#endif
+out:
+ REGION_NULL(pScreen, &region);
DamageEmpty(info->pDamage);
}
@@ -1907,16 +1965,13 @@ static void RADEONEnablePageFlip(ScreenPtr pScreen)
if (info->allowPageFlip) {
RADEONSAREAPrivPtr pSAREAPriv = DRIGetSAREAPrivate(pScreen);
+ BoxRec box = { .x1 = 0, .y1 = 0, .x2 = pScrn->virtualX - 1,
+ .y2 = pScrn->virtualY - 1 };
+ RegionPtr pReg = REGION_CREATE(pScreen, &box, 1);
pSAREAPriv->pfAllowPageFlip = 1;
-
-#ifdef USE_XAA
- if (!info->useEXA) {
- BoxRec box = { .x1 = 0, .y1 = 0, .x2 = pScrn->virtualX - 1,
- .y2 = pScrn->virtualY - 1 };
- RADEONDRIRefreshArea(pScrn, 1, &box);
- }
-#endif
+ RADEONDRIRefreshArea(pScrn, pReg);
+ REGION_DESTROY(pScreen, pReg);
}
#endif
}
@@ -2023,6 +2078,9 @@ static void RADEONDRITransitionTo3d(ScreenPtr pScreen)
RADEONChangeSurfaces(pScrn);
RADEONEnablePageFlip(pScreen);
+
+ info->want_vblank_interrupts = TRUE;
+ RADEONDRISetVBlankInterrupt(pScrn, TRUE);
if (info->cursor)
xf86ForceHWCursor (pScreen, TRUE);
@@ -2062,10 +2120,40 @@ static void RADEONDRITransitionTo2d(ScreenPtr pScreen)
RADEONChangeSurfaces(pScrn);
+ info->want_vblank_interrupts = FALSE;
+ RADEONDRISetVBlankInterrupt(pScrn, FALSE);
+
if (info->cursor)
xf86ForceHWCursor (pScreen, FALSE);
}
+#if defined(DAMAGE) && (DRIINFO_MAJOR_VERSION > 5 || \
+ (DRIINFO_MAJOR_VERSION == 5 && \
+ DRIINFO_MINOR_VERSION >= 1))
+static void
+RADEONDRIClipNotify(ScreenPtr pScreen, WindowPtr *ppWin, int num)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+
+ REGION_UNINIT(pScreen, &info->driRegion);
+ REGION_NULL(pScreen, &info->driRegion);
+
+ if (num > 0) {
+ int i;
+
+ for (i = 0; i < num; i++) {
+ WindowPtr pWin = ppWin[i];
+
+ if (pWin) {
+ REGION_UNION(pScreen, &info->driRegion, &pWin->clipList,
+ &info->driRegion);
+ }
+ }
+ }
+}
+#endif
+
void RADEONDRIAllocatePCIGARTTable(ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index ca0b2016..158e1e46 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -74,7 +74,6 @@
#include "radeon_macros.h"
#include "radeon_probe.h"
#include "radeon_version.h"
-#include "radeon_mergedfb.h"
#ifdef XF86DRI
#define _XF86DRI_SERVER_
@@ -94,15 +93,15 @@
#include "xf86_ansic.h" /* For xf86getsecs() */
#include "xf86_OSproc.h"
#include "xf86RAC.h"
+#include "xf86RandR12.h"
#include "xf86Resources.h"
#include "xf86cmap.h"
#include "vbe.h"
- /* fbdevhw * vgaHW definitions */
+ /* vgaHW definitions */
#ifdef WITH_VGAHW
#include "vgaHW.h"
#endif
-#include "fbdevhw.h"
#define DPMS_SERVER
#include <X11/extensions/dpms.h>
@@ -116,10 +115,7 @@
static Bool RADEONCloseScreen(int scrnIndex, ScreenPtr pScreen);
static Bool RADEONSaveScreen(ScreenPtr pScreen, int mode);
static void RADEONSave(ScrnInfoPtr pScrn);
-static void RADEONRestore(ScrnInfoPtr pScrn);
-static Bool RADEONModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
-static void RADEONGetMergedFBOptions(ScrnInfoPtr pScrn);
static void RADEONSetDynamicClock(ScrnInfoPtr pScrn, int mode);
static void RADEONForceSomeClocks(ScrnInfoPtr pScrn);
static void RADEONSaveMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save);
@@ -128,9 +124,11 @@ static void RADEONSaveMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save);
static void RADEONAdjustMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save);
#endif
-/* psuedo xinerama support */
+DisplayModePtr
+RADEONCrtcFindClosestMode(xf86CrtcPtr crtc, DisplayModePtr pMode);
-extern Bool RADEONnoPanoramiXExtension;
+static void RADEONWaitPLLLock(ScrnInfoPtr pScrn, unsigned nTests,
+ unsigned nWaitLoops, unsigned cntThreshold);
static const OptionInfoRec RADEONOptions[] = {
{ OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE },
@@ -159,19 +157,7 @@ static const OptionInfoRec RADEONOptions[] = {
#endif
#endif
{ OPTION_DDC_MODE, "DDCMode", OPTV_BOOLEAN, {0}, FALSE },
- { OPTION_MONITOR_LAYOUT, "MonitorLayout", OPTV_ANYSTR, {0}, FALSE },
{ OPTION_IGNORE_EDID, "IgnoreEDID", OPTV_BOOLEAN, {0}, FALSE },
- { OPTION_FBDEV, "UseFBDev", OPTV_BOOLEAN, {0}, FALSE },
- { OPTION_MERGEDFB, "MergedFB", OPTV_BOOLEAN, {0}, FALSE },
- { OPTION_CRT2HSYNC, "CRT2HSync", OPTV_ANYSTR, {0}, FALSE },
- { OPTION_CRT2VREFRESH, "CRT2VRefresh", OPTV_ANYSTR, {0}, FALSE },
- { OPTION_CRT2POS, "CRT2Position", OPTV_ANYSTR, {0}, FALSE },
- { OPTION_METAMODES, "MetaModes", OPTV_ANYSTR, {0}, FALSE },
- { OPTION_MERGEDDPI, "MergedDPI", OPTV_ANYSTR, {0}, FALSE },
- { OPTION_RADEONXINERAMA, "MergedXinerama", OPTV_BOOLEAN, {0}, FALSE },
- { OPTION_CRT2ISSCRN0, "MergedXineramaCRT2IsScreen0", OPTV_BOOLEAN, {0}, FALSE },
- { OPTION_MERGEDFBNONRECT, "MergedNonRectangular", OPTV_BOOLEAN, {0}, FALSE },
- { OPTION_MERGEDFBMOUSER, "MergedMouseRestriction", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_DISP_PRIORITY, "DisplayPriority", OPTV_ANYSTR, {0}, FALSE },
{ OPTION_PANEL_SIZE, "PanelSize", OPTV_ANYSTR, {0}, FALSE },
{ OPTION_MIN_DOTCLOCK, "ForceMinDotClock", OPTV_FREQ, {0}, FALSE },
@@ -198,12 +184,13 @@ static const OptionInfoRec RADEONOptions[] = {
{ OPTION_LVDS_PROBE_PLL, "LVDSProbePLL", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_ACCELMETHOD, "AccelMethod", OPTV_STRING, {0}, FALSE },
{ OPTION_CONSTANTDPI, "ConstantDPI", OPTV_BOOLEAN, {0}, FALSE },
- { OPTION_REVERSE_DISPLAY,"ReverseDisplay", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_DRI, "DRI", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_CONNECTORTABLE, "ConnectorTable", OPTV_STRING, {0}, FALSE },
+ { OPTION_DEFAULT_CONNECTOR_TABLE, "DefaultConnectorTable", OPTV_BOOLEAN, {0}, FALSE },
{ -1, NULL, OPTV_NONE, {0}, FALSE }
};
-_X_EXPORT const OptionInfoRec *RADEONOptionsWeak(void) { return RADEONOptions; }
+const OptionInfoRec *RADEONOptionsWeak(void) { return RADEONOptions; }
#ifdef WITH_VGAHW
static const char *vgahwSymbols[] = {
@@ -219,34 +206,6 @@ static const char *vgahwSymbols[] = {
};
#endif
-static const char *fbdevHWSymbols[] = {
- "fbdevHWInit",
- "fbdevHWUseBuildinMode",
-
- "fbdevHWGetVidmem",
-
- "fbdevHWDPMSSet",
-
- /* colormap */
- "fbdevHWLoadPalette",
- /* ScrnInfo hooks */
- "fbdevHWAdjustFrame",
- "fbdevHWEnterVT",
- "fbdevHWLeaveVT",
- "fbdevHWModeInit",
- "fbdevHWRestore",
- "fbdevHWSave",
- "fbdevHWSwitchMode",
- "fbdevHWValidModeWeak",
-
- "fbdevHWMapMMIO",
- "fbdevHWMapVidmem",
- "fbdevHWUnmapMMIO",
- "fbdevHWUnmapVidmem",
-
- NULL
-};
-
static const char *ddcSymbols[] = {
"xf86PrintEDID",
"xf86DoEDID_DDC1",
@@ -407,7 +366,6 @@ void RADEONLoaderRefSymLists(void)
drmSymbols,
driSymbols,
#endif
- fbdevHWSymbols,
vbeSymbols,
int10Symbols,
i2cSymbols,
@@ -441,6 +399,24 @@ struct RADEONInt10Save {
static Bool RADEONMapMMIO(ScrnInfoPtr pScrn);
static Bool RADEONUnmapMMIO(ScrnInfoPtr pScrn);
+#if 0
+static Bool
+RADEONCreateScreenResources (ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+
+ pScreen->CreateScreenResources = info->CreateScreenResources;
+ if (!(*pScreen->CreateScreenResources)(pScreen))
+ return FALSE;
+
+ if (!xf86RandR12CreateScreenResources(pScreen))
+ return FALSE;
+
+ return TRUE;
+}
+#endif
+
RADEONEntPtr RADEONEntPriv(ScrnInfoPtr pScrn)
{
DevUnion *pPriv;
@@ -534,48 +510,6 @@ static Bool RADEONGetRec(ScrnInfoPtr pScrn)
/* Free our private RADEONInfoRec */
static void RADEONFreeRec(ScrnInfoPtr pScrn)
{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- if(info->CRT2HSync) xfree(info->CRT2HSync);
- info->CRT2HSync = NULL;
- if(info->CRT2VRefresh) xfree(info->CRT2VRefresh);
- info->CRT2VRefresh = NULL;
- if(info->MetaModes) xfree(info->MetaModes);
- info->MetaModes = NULL;
- if(info->CRT2pScrn) {
- if(info->CRT2pScrn->modes) {
- while(info->CRT2pScrn->modes)
- xf86DeleteMode(&info->CRT2pScrn->modes, info->CRT2pScrn->modes);
- }
- if(info->CRT2pScrn->monitor) {
- if(info->CRT2pScrn->monitor->Modes) {
- while(info->CRT2pScrn->monitor->Modes)
- xf86DeleteMode(&info->CRT2pScrn->monitor->Modes, info->CRT2pScrn->monitor->Modes);
- }
- if(info->CRT2pScrn->monitor->DDC) xfree(info->CRT2pScrn->monitor->DDC);
- xfree(info->CRT2pScrn->monitor);
- }
- xfree(info->CRT2pScrn);
- info->CRT2pScrn = NULL;
- }
- if(info->CRT1Modes) {
- if(info->CRT1Modes != pScrn->modes) {
- if(pScrn->modes) {
- pScrn->currentMode = pScrn->modes;
- do {
- DisplayModePtr p = pScrn->currentMode->next;
- if(pScrn->currentMode->Private)
- xfree(pScrn->currentMode->Private);
- xfree(pScrn->currentMode);
- pScrn->currentMode = p;
- } while(pScrn->currentMode != pScrn->modes);
- }
- pScrn->currentMode = info->CRT1CurrentMode;
- pScrn->modes = info->CRT1Modes;
- info->CRT1CurrentMode = NULL;
- info->CRT1Modes = NULL;
- }
- }
-
if (!pScrn || !pScrn->driverPrivate) return;
xfree(pScrn->driverPrivate);
pScrn->driverPrivate = NULL;
@@ -588,15 +522,11 @@ static Bool RADEONMapMMIO(ScrnInfoPtr pScrn)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
- if (info->FBDev) {
- info->MMIO = fbdevHWMapMMIO(pScrn);
- } else {
- info->MMIO = xf86MapPciMem(pScrn->scrnIndex,
- VIDMEM_MMIO | VIDMEM_READSIDEEFFECT,
- info->PciTag,
- info->MMIOAddr,
- info->MMIOSize);
- }
+ info->MMIO = xf86MapPciMem(pScrn->scrnIndex,
+ VIDMEM_MMIO | VIDMEM_READSIDEEFFECT,
+ info->PciTag,
+ info->MMIOAddr,
+ info->MMIOSize);
if (!info->MMIO) return FALSE;
return TRUE;
@@ -609,11 +539,8 @@ static Bool RADEONUnmapMMIO(ScrnInfoPtr pScrn)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
- if (info->FBDev)
- fbdevHWUnmapMMIO(pScrn);
- else {
- xf86UnMapVidMem(pScrn->scrnIndex, info->MMIO, info->MMIOSize);
- }
+ xf86UnMapVidMem(pScrn->scrnIndex, info->MMIO, info->MMIOSize);
+
info->MMIO = NULL;
return TRUE;
}
@@ -623,16 +550,13 @@ static Bool RADEONMapFB(ScrnInfoPtr pScrn)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
- if (info->FBDev) {
- info->FB = fbdevHWMapVidmem(pScrn);
- } else {
- RADEONTRACE(("Map: 0x%08lx, 0x%08lx\n", info->LinearAddr, info->FbMapSize));
- info->FB = xf86MapPciMem(pScrn->scrnIndex,
- VIDMEM_FRAMEBUFFER,
- info->PciTag,
- info->LinearAddr,
- info->FbMapSize);
- }
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "Map: 0x%08lx, 0x%08lx\n", info->LinearAddr, info->FbMapSize);
+ info->FB = xf86MapPciMem(pScrn->scrnIndex,
+ VIDMEM_FRAMEBUFFER,
+ info->PciTag,
+ info->LinearAddr,
+ info->FbMapSize);
if (!info->FB) return FALSE;
return TRUE;
@@ -643,10 +567,7 @@ static Bool RADEONUnmapFB(ScrnInfoPtr pScrn)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
- if (info->FBDev)
- fbdevHWUnmapVidmem(pScrn);
- else
- xf86UnMapVidMem(pScrn->scrnIndex, info->FB, info->FbMapSize);
+ xf86UnMapVidMem(pScrn->scrnIndex, info->FB, info->FbMapSize);
info->FB = NULL;
return TRUE;
}
@@ -758,7 +679,7 @@ void RADEONWaitForVerticalSync(ScrnInfoPtr pScrn)
RADEONInfoPtr info = RADEONPTR(pScrn);
unsigned char *RADEONMMIO = info->MMIO;
CARD32 crtc_gen_cntl;
- int i;
+ struct timeval timeout;
crtc_gen_cntl = INREG(RADEON_CRTC_GEN_CNTL);
if ((crtc_gen_cntl & RADEON_CRTC_DISP_REQ_EN_B) ||
@@ -769,10 +690,10 @@ void RADEONWaitForVerticalSync(ScrnInfoPtr pScrn)
OUTREG(RADEON_CRTC_STATUS, RADEON_CRTC_VBLANK_SAVE_CLEAR);
/* Wait for it to go back up */
- for (i = 0; i < RADEON_TIMEOUT/1000; i++) {
- if (INREG(RADEON_CRTC_STATUS) & RADEON_CRTC_VBLANK_SAVE) break;
- usleep(1);
- }
+ radeon_init_timeout(&timeout, RADEON_VSYNC_TIMEOUT);
+ while (!(INREG(RADEON_CRTC_STATUS) & RADEON_CRTC_VBLANK_SAVE) &&
+ !radeon_timedout(&timeout))
+ usleep(100);
}
/* Wait for vertical sync on secondary CRTC */
@@ -781,7 +702,7 @@ void RADEONWaitForVerticalSync2(ScrnInfoPtr pScrn)
RADEONInfoPtr info = RADEONPTR(pScrn);
unsigned char *RADEONMMIO = info->MMIO;
CARD32 crtc2_gen_cntl;
- int i;
+ struct timeval timeout;
crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL);
if ((crtc2_gen_cntl & RADEON_CRTC2_DISP_REQ_EN_B) ||
@@ -792,10 +713,10 @@ void RADEONWaitForVerticalSync2(ScrnInfoPtr pScrn)
OUTREG(RADEON_CRTC2_STATUS, RADEON_CRTC2_VBLANK_SAVE_CLEAR);
/* Wait for it to go back up */
- for (i = 0; i < RADEON_TIMEOUT/1000; i++) {
- if (INREG(RADEON_CRTC2_STATUS) & RADEON_CRTC2_VBLANK_SAVE) break;
- usleep(1);
- }
+ radeon_init_timeout(&timeout, RADEON_VSYNC_TIMEOUT);
+ while (!(INREG(RADEON_CRTC2_STATUS) & RADEON_CRTC2_VBLANK_SAVE) &&
+ !radeon_timedout(&timeout))
+ usleep(100);
}
@@ -953,7 +874,8 @@ static Bool RADEONProbePLLParameters(ScrnInfoPtr pScrn)
if (ref_div < 2) {
CARD32 tmp;
tmp = INPLL(pScrn, RADEON_PPLL_REF_DIV);
- if (IS_R300_VARIANT || (info->ChipFamily == CHIP_FAMILY_RS300))
+ if (IS_R300_VARIANT || (info->ChipFamily == CHIP_FAMILY_RS300)
+ || (info->ChipFamily == CHIP_FAMILY_RS400))
ref_div = (tmp & R300_PPLL_REF_DIV_ACC_MASK) >>
R300_PPLL_REF_DIV_ACC_SHIFT;
else
@@ -1033,7 +955,8 @@ static void RADEONGetClockInfo(ScrnInfoPtr pScrn)
CARD32 tmp;
tmp = INPLL(pScrn, RADEON_PPLL_REF_DIV);
if (IS_R300_VARIANT ||
- (info->ChipFamily == CHIP_FAMILY_RS300)) {
+ (info->ChipFamily == CHIP_FAMILY_RS300) ||
+ (info->ChipFamily == CHIP_FAMILY_RS400)) {
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;
@@ -1083,10 +1006,11 @@ static void RADEONGetClockInfo(ScrnInfoPtr pScrn)
}
xf86DrvMsg (pScrn->scrnIndex, X_INFO,
- "PLL parameters: rf=%d rd=%d min=%ld max=%ld; xclk=%d\n",
+ "PLL parameters: rf=%d rd=%d min=%d max=%d; xclk=%d\n",
pll->reference_freq,
pll->reference_div,
- pll->min_pll_freq, pll->max_pll_freq, pll->xclk);
+ (unsigned)pll->min_pll_freq, (unsigned)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
@@ -1200,7 +1124,7 @@ static Bool RADEONPreInitWeight(ScrnInfoPtr pScrn)
return TRUE;
}
-static void RADEONInitMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save,
+void RADEONInitMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save,
RADEONInfoPtr info)
{
save->mc_fb_location = info->mc_fb_location;
@@ -1214,7 +1138,7 @@ static void RADEONInitMemoryMap(ScrnInfoPtr pScrn)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
unsigned char *RADEONMMIO = info->MMIO;
- unsigned long mem_size;
+ CARD32 mem_size;
CARD32 aper_size;
/* Default to existing values */
@@ -1242,8 +1166,7 @@ static void RADEONInitMemoryMap(ScrnInfoPtr pScrn)
}
#endif
- /* We won't try to change MC_FB_LOCATION when using fbdev */
- if (!info->FBDev) {
+ {
if (info->IsIGP)
info->mc_fb_location = INREG(RADEON_NB_TOM);
else
@@ -1283,10 +1206,15 @@ static void RADEONInitMemoryMap(ScrnInfoPtr pScrn)
*/
info->mc_agp_location = 0xffffffc0;
- RADEONTRACE(("RADEONInitMemoryMap() : \n"));
- RADEONTRACE((" mem_size : 0x%08lx\n", mem_size));
- RADEONTRACE((" MC_FB_LOCATION : 0x%08lx\n", info->mc_fb_location));
- RADEONTRACE((" MC_AGP_LOCATION : 0x%08lx\n", info->mc_agp_location));
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "RADEONInitMemoryMap() : \n");
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ " mem_size : 0x%08x\n", (unsigned)mem_size);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ " MC_FB_LOCATION : 0x%08x\n", (unsigned)info->mc_fb_location);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ " MC_AGP_LOCATION : 0x%08x\n",
+ (unsigned)info->mc_agp_location);
}
static void RADEONGetVRamType(ScrnInfoPtr pScrn)
@@ -1349,8 +1277,8 @@ static CARD32 RADEONGetAccessibleVRAM(ScrnInfoPtr pScrn)
if (info->directRenderingEnabled &&
info->pKernelDRMVersion->version_minor < 23) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "[dri] limiting video memory to one aperture of %ldK\n",
- aper_size);
+ "[dri] limiting video memory to one aperture of %uK\n",
+ (unsigned)aper_size);
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"[dri] detected radeon kernel module version 1.%d but"
" 1.23 or newer is required for full memory mapping.\n",
@@ -1406,9 +1334,7 @@ static Bool RADEONPreInitVRAM(ScrnInfoPtr pScrn)
MessageType from = X_PROBED;
CARD32 accessible, bar_size;
- if (info->FBDev)
- pScrn->videoRam = fbdevHWGetVidmem(pScrn) / 1024;
- else if ((info->IsIGP)) {
+ if ((info->IsIGP)) {
CARD32 tom = INREG(RADEON_NB_TOM);
pScrn->videoRam = (((tom >> 16) -
@@ -1437,8 +1363,8 @@ static Bool RADEONPreInitVRAM(ScrnInfoPtr pScrn)
accessible = bar_size;
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Detected total video RAM=%dK, accessible=%ldK (PCI BAR=%ldK)\n",
- pScrn->videoRam, accessible, bar_size);
+ "Detected total video RAM=%dK, accessible=%uK (PCI BAR=%uK)\n",
+ pScrn->videoRam, (unsigned)accessible, (unsigned)bar_size);
if (pScrn->videoRam > accessible)
pScrn->videoRam = accessible;
@@ -1459,24 +1385,6 @@ static Bool RADEONPreInitVRAM(ScrnInfoPtr pScrn)
xf86DrvMsg(pScrn->scrnIndex, from,
"Mapped VideoRAM: %d kByte (%d bit %s SDRAM)\n", pScrn->videoRam, info->RamWidth, info->IsDDR?"DDR":"SDR");
- /* FIXME: For now, split FB into two equal sections. This should
- * be able to be adjusted by user with a config option. */
- if (info->IsPrimary) {
- pScrn->videoRam /= 2;
- info->MergedFB = FALSE;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Using %dk of videoram for primary head\n",
- pScrn->videoRam);
- }
-
- if (info->IsSecondary) {
- pScrn->videoRam /= 2;
- info->LinearAddr += pScrn->videoRam * 1024;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Using %dk of videoram for secondary head\n",
- pScrn->videoRam);
- }
-
pScrn->videoRam &= ~1023;
info->FbMapSize = pScrn->videoRam * 1024;
@@ -1543,6 +1451,7 @@ static Bool RADEONPreInitChipType(ScrnInfoPtr pScrn)
info->IsIGP = FALSE;
info->IsDellServer = FALSE;
info->HasSingleDAC = FALSE;
+ info->InternalTVOut = TRUE;
switch (info->Chipset) {
case PCI_CHIP_RADEON_LY:
case PCI_CHIP_RADEON_LZ:
@@ -1602,6 +1511,7 @@ static Bool RADEONPreInitChipType(ScrnInfoPtr pScrn)
case PCI_CHIP_R200_QL:
case PCI_CHIP_R200_QM:
info->ChipFamily = CHIP_FAMILY_R200;
+ info->InternalTVOut = FALSE;
break;
case PCI_CHIP_RADEON_LW:
@@ -1713,7 +1623,7 @@ static Bool RADEONPreInitChipType(ScrnInfoPtr pScrn)
case PCI_CHIP_RS482_5974:
info->ChipFamily = CHIP_FAMILY_RS400;
info->IsIGP = TRUE;
- /*info->HasSingleDAC = TRUE;*/ /* ??? */
+ info->HasSingleDAC = TRUE;
break;
case PCI_CHIP_RV410_564A:
@@ -1784,6 +1694,7 @@ static Bool RADEONPreInitChipType(ScrnInfoPtr pScrn)
/* Original Radeon/7200 */
info->ChipFamily = CHIP_FAMILY_RADEON;
pRADEONEnt->HasCRTC2 = FALSE;
+ info->InternalTVOut = FALSE;
}
@@ -1903,10 +1814,15 @@ static Bool RADEONPreInitChipType(ScrnInfoPtr pScrn)
}
}
+
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%s card detected\n",
(info->cardType==CARD_PCI) ? "PCI" :
(info->cardType==CARD_PCIE) ? "PCIE" : "AGP");
+ /* treat PCIE IGP cards as PCI */
+ if (info->cardType == CARD_PCIE && info->IsIGP)
+ info->cardType = CARD_PCI;
+
if ((s = xf86GetOptValString(info->Options, OPTION_BUS_TYPE))) {
if (strcmp(s, "AGP") == 0) {
info->cardType = CARD_AGP;
@@ -1957,9 +1873,7 @@ static void RADEONPreInitDDC(ScrnInfoPtr pScrn)
if (info->ddc2) {
if (xf86LoadSubModule(pScrn, "i2c")) {
xf86LoaderReqSymLists(i2cSymbols,NULL);
- info->ddc2 = RADEONI2cInit(pScrn);
}
- else info->ddc2 = FALSE;
}
}
@@ -1972,398 +1886,6 @@ static Bool RADEONPreInitGamma(ScrnInfoPtr pScrn)
return TRUE;
}
-/* This is called by RADEONPreInit to validate modes and compute
- * parameters for all of the valid modes.
- */
-static Bool RADEONPreInitModes(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- ClockRangePtr clockRanges;
- int modesFound;
- RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
- char *s;
- RADEONConnector *connector;
- /* This option has two purposes:
- *
- * 1. For CRT, if this option is on, xf86ValidateModes (to
- * LOOKUP_BEST_REFRESH) is not going to be used for mode
- * validation. Instead, we'll validate modes by matching exactly
- * the modes supported from the DDC data. This option can be
- * used (a) to enable non-standard modes listed in the Detailed
- * Timings block of EDID, like 2048x1536 (not included in
- * xf86DefModes), (b) to avoid unstable modes for some flat
- * panels working in analog mode (some modes validated by
- * xf86ValidateModes don't really work with these panels).
- *
- * 2. For DFP on primary head, with this option on, the validation
- * routine will try to use supported modes from DDC data first
- * before trying on-chip RMX streching. By default, native mode
- * + RMX streching is used for all non-native modes, it appears
- * more reliable. Some non-native modes listed in the DDC data
- * may not work properly if they are used directly. This seems to
- * only happen to a few panels (haven't nailed this down yet, it
- * may related to the incorrect setting in TMDS_PLL_CNTL when
- * pixel clock is changed). Use this option may give you better
- * refresh rate for some non-native modes. The 2nd DVI port will
- * always use DDC modes directly (only have one on-chip RMX
- * unit).
- *
- * Note: This option will be dismissed if no DDC data is available.
- */
-
- if (info->MergedFB) {
- if (!(pScrn->display->virtualX))
- info->NoVirtual = TRUE;
- else
- info->NoVirtual = FALSE;
- }
-
- info->ddc_mode =
- xf86ReturnOptValBool(info->Options, OPTION_DDC_MODE, FALSE);
-
- /* don't use RMX if we have a dual-tmds panels */
-
- if ((connector = RADEONGetCrtcConnector(pScrn, 2)))
- if (connector->MonType == MT_DFP)
- info->ddc_mode = TRUE;
- /* don't use RMX if we are Dell Server */
- if (info->IsDellServer)
- {
- info->ddc_mode = TRUE;
- }
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Validating modes on %s head ---------\n",
- info->IsSecondary ? "Secondary" : "Primary");
-
- if (!pRADEONEnt->PortInfo[0]->MonInfo && !pRADEONEnt->PortInfo[1]->MonInfo && info->ddc_mode) {
- info->ddc_mode = FALSE;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "No DDC data available, DDCMode option is dismissed\n");
- }
-
- if ((info->DisplayType == MT_DFP) ||
- (info->DisplayType == MT_LCD)) {
- if ((s = xf86GetOptValString(info->Options, OPTION_PANEL_SIZE))) {
- int PanelX, PanelY;
- DisplayModePtr tmp_mode = NULL;
- if (sscanf(s, "%dx%d", &PanelX, &PanelY) == 2) {
- info->PanelXRes = PanelX;
- info->PanelYRes = PanelY;
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
- "Panel size is forced to: %s\n", s);
-
- /* We can't trust BIOS or DDC timings anymore,
- Use whatever specified in the Modeline.
- If no Modeline specified, we'll just pick the VESA mode at
- 60Hz refresh rate which is likely to be the best for a flat panel.
- */
- info->ddc_mode = FALSE;
- pScrn->monitor->DDC = NULL;
- tmp_mode = pScrn->monitor->Modes;
- while(tmp_mode) {
- if ((tmp_mode->HDisplay == PanelX) &&
- (tmp_mode->VDisplay == PanelY)) {
-
- float refresh =
- (float)tmp_mode->Clock * 1000.0 / tmp_mode->HTotal / tmp_mode->VTotal;
- if ((abs(60.0 - refresh) < 1.0) ||
- (tmp_mode->type == 0)) {
- info->HBlank = tmp_mode->HTotal - tmp_mode->HDisplay;
- info->HOverPlus = tmp_mode->HSyncStart - tmp_mode->HDisplay;
- info->HSyncWidth = tmp_mode->HSyncEnd - tmp_mode->HSyncStart;
- info->VBlank = tmp_mode->VTotal - tmp_mode->VDisplay;
- info->VOverPlus = tmp_mode->VSyncStart - tmp_mode->VDisplay;
- info->VSyncWidth = tmp_mode->VSyncEnd - tmp_mode->VSyncStart;
- info->DotClock = tmp_mode->Clock;
- info->Flags = 0;
- break;
- }
- }
- tmp_mode = tmp_mode->next;
- }
- if (info->DotClock == 0) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "No valid timing info for specified panel size.\n"
- "Please specify the Modeline for this panel\n");
- return FALSE;
- }
- } else {
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
- "Invalid PanelSize value: %s\n", s);
- }
- } else
- RADEONGetPanelInfo(pScrn);
- }
-
- if (pScrn->monitor->DDC) {
- /* If we still don't know sync range yet, let's try EDID.
- *
- * Note that, since we can have dual heads, Xconfigurator
- * may not be able to probe both monitors correctly through
- * vbe probe function (RADEONProbeDDC). Here we provide an
- * additional way to auto-detect sync ranges if they haven't
- * been added to XF86Config manually.
- */
- if (pScrn->monitor->nHsync <= 0)
- RADEONSetSyncRangeFromEdid(pScrn, 1);
- if (pScrn->monitor->nVrefresh <= 0)
- RADEONSetSyncRangeFromEdid(pScrn, 0);
- }
-
- /* Get mode information */
- pScrn->progClock = TRUE;
- clockRanges = xnfcalloc(sizeof(*clockRanges), 1);
- clockRanges->next = NULL;
- clockRanges->minClock = info->pll.min_pll_freq;
- clockRanges->maxClock = info->pll.max_pll_freq * 10;
- clockRanges->clockIndex = -1;
- clockRanges->interlaceAllowed = (info->DisplayType == MT_CRT);
- clockRanges->doubleScanAllowed = (info->DisplayType == MT_CRT);
-
- /* We'll use our own mode validation routine for DFP/LCD, since
- * xf86ValidateModes does not work correctly with the DFP/LCD modes
- * 'stretched' from their native mode.
- */
- if (info->DisplayType == MT_CRT && !info->ddc_mode) {
-
- modesFound =
- xf86ValidateModes(pScrn,
- pScrn->monitor->Modes,
- pScrn->display->modes,
- clockRanges,
- NULL, /* linePitches */
- 8 * 64, /* minPitch */
- 8 * 1024, /* maxPitch */
- info->allowColorTiling ? 2048 :
- 64 * pScrn->bitsPerPixel, /* pitchInc */
- 128, /* minHeight */
- info->MaxLines, /* maxHeight */
- pScrn->display->virtualX,
- pScrn->display->virtualY,
- info->FbMapSize,
- LOOKUP_BEST_REFRESH);
-
- if (modesFound < 1 && info->FBDev) {
- fbdevHWUseBuildinMode(pScrn);
- pScrn->displayWidth = fbdevHWGetLineLength(pScrn)
- / info->CurrentLayout.pixel_bytes;
- modesFound = 1;
- }
-
- if (modesFound == -1) return FALSE;
-
- xf86PruneDriverModes(pScrn);
- if (!modesFound || !pScrn->modes) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
- return FALSE;
- }
-
- } else {
- /* First, free any allocated modes during configuration, since
- * we don't need them
- */
- while (pScrn->modes)
- xf86DeleteMode(&pScrn->modes, pScrn->modes);
- while (pScrn->modePool)
- xf86DeleteMode(&pScrn->modePool, pScrn->modePool);
-
- /* Next try to add DDC modes */
- modesFound = RADEONValidateDDCModes(pScrn, pScrn->display->modes,
- info->DisplayType, 0);
-
- /* If that fails and we're connect to a flat panel, then try to
- * add the flat panel modes
- */
- if (info->DisplayType != MT_CRT) {
-
- /* some panels have DDC, but don't have internal scaler.
- * in this case, we need to validate additional modes
- * by using on-chip RMX.
- */
- int user_modes_asked = 0, user_modes_found = 0, i;
- DisplayModePtr tmp_mode = pScrn->modes;
- while (pScrn->display->modes[user_modes_asked]) user_modes_asked++;
- if (tmp_mode) {
- for (i = 0; i < modesFound; i++) {
- if (tmp_mode->type & M_T_USERDEF) user_modes_found++;
- tmp_mode = tmp_mode->next;
- }
- }
-
- if ((modesFound <= 1) || (user_modes_found < user_modes_asked)) {
- /* when panel size is not valid, try to validate
- * mode using xf86ValidateModes routine
- * This can happen when DDC is disabled.
- */
- if (info->PanelXRes < 320 || info->PanelYRes < 200)
- modesFound =
- xf86ValidateModes(pScrn,
- pScrn->monitor->Modes,
- pScrn->display->modes,
- clockRanges,
- NULL, /* linePitches */
- 8 * 64, /* minPitch */
- 8 * 1024, /* maxPitch */
- info->allowColorTiling ? 2048 :
- 64 * pScrn->bitsPerPixel, /* pitchInc */
- 128, /* minHeight */
- info->MaxLines, /* maxHeight */
- pScrn->display->virtualX,
- pScrn->display->virtualY,
- info->FbMapSize,
- LOOKUP_BEST_REFRESH);
- else if (!info->IsSecondary)
- modesFound = RADEONValidateFPModes(pScrn, pScrn->display->modes);
- }
- }
-
- /* Setup the screen's clockRanges for the VidMode extension */
- if (!pScrn->clockRanges) {
- pScrn->clockRanges = xnfcalloc(sizeof(*(pScrn->clockRanges)), 1);
- memcpy(pScrn->clockRanges, clockRanges, sizeof(*clockRanges));
- pScrn->clockRanges->strategy = LOOKUP_BEST_REFRESH;
- }
-
- /* Fail if we still don't have any valid modes */
- if (modesFound < 1) {
- if (info->DisplayType == MT_CRT) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "No valid DDC modes found for this CRT\n");
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Try turning off the \"DDCMode\" option\n");
- } else {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "No valid mode found for this DFP/LCD\n");
- }
- return FALSE;
- }
- }
-
- xf86SetCrtcForModes(pScrn, 0);
-
- if (pRADEONEnt->HasCRTC2) {
- if (pRADEONEnt->Controller[1]->binding == 1) {
-
- /* If we have 2 screens from the config file, we don't need
- * to do clone thing, let each screen handles one head.
- */
- if (!pRADEONEnt->HasSecondary) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Validating CRTC2 modes for MergedFB ------------ \n");
-
- modesFound = RADEONValidateMergeModes(pScrn);
- if (modesFound < 1) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "No valid mode found for CRTC2, disabling MergedFB\n");
- info->MergedFB = FALSE;
- }
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Total of %d CRTC2 modes found for MergedFB------------ \n",
- modesFound);
- }
- }
- }
-
- pScrn->currentMode = pScrn->modes;
- if(info->MergedFB) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Modes for CRT1: ********************\n");
- }
- xf86PrintModes(pScrn);
-
-
- if (pRADEONEnt->HasCRTC2) {
- if(pRADEONEnt->Controller[1]->binding == 1) {
-
- xf86SetCrtcForModes(info->CRT2pScrn, INTERLACE_HALVE_V);
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Modes for CRT2: ********************\n");
-
- xf86PrintModes(info->CRT2pScrn);
-
- info->CRT1Modes = pScrn->modes;
- info->CRT1CurrentMode = pScrn->currentMode;
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Generating MergedFB mode list\n");
-
- if (info->NoVirtual) {
- pScrn->display->virtualX = 0;
- pScrn->display->virtualY = 0;
- }
- pScrn->modes = RADEONGenerateModeList(pScrn, info->MetaModes,
- info->CRT1Modes, info->CRT2pScrn->modes,
- info->CRT2Position);
-
- if(!pScrn->modes) {
-
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Failed to parse MetaModes or no modes found. MergeFB mode disabled.\n");
- if(info->CRT2pScrn) {
- if(info->CRT2pScrn->modes) {
- while(info->CRT2pScrn->modes)
- xf86DeleteMode(&info->CRT2pScrn->modes, info->CRT2pScrn->modes);
- }
- if(info->CRT2pScrn->monitor) {
- if(info->CRT2pScrn->monitor->Modes) {
- while(info->CRT2pScrn->monitor->Modes)
- xf86DeleteMode(&info->CRT2pScrn->monitor->Modes, info->CRT2pScrn->monitor->Modes);
- }
- if(info->CRT2pScrn->monitor->DDC) xfree(info->CRT2pScrn->monitor->DDC);
- xfree(info->CRT2pScrn->monitor);
- }
- xfree(info->CRT2pScrn);
- info->CRT2pScrn = NULL;
- }
- pScrn->modes = info->CRT1Modes;
- info->CRT1Modes = NULL;
- info->MergedFB = FALSE;
-
- }
- }
- }
-
- if (info->MergedFB) {
- /* If no virtual dimension was given by the user,
- * calculate a sane one now. Adapts pScrn->virtualX,
- * pScrn->virtualY and pScrn->displayWidth.
- */
- RADEONRecalcDefaultVirtualSize(pScrn);
- info->CRT2pScrn->virtualX = pScrn->virtualX;
- info->CRT2pScrn->virtualY = pScrn->virtualY;
- RADEONSetPitch(pScrn);
- RADEONSetPitch(info->CRT2pScrn);
-
- pScrn->modes = pScrn->modes->next; /* We get the last from GenerateModeList() */
- pScrn->currentMode = pScrn->modes;
-
- /* Update CurrentLayout */
- info->CurrentLayout.mode = pScrn->currentMode;
- info->CurrentLayout.displayWidth = pScrn->displayWidth;
- }
-
- /* Set DPI */
- /* xf86SetDpi(pScrn, 0, 0); */
-
- if (info->MergedFB) {
- RADEONMergedFBSetDpi(pScrn, info->CRT2pScrn, info->CRT2Position);
- } else {
- xf86SetDpi(pScrn, 0, 0);
- info->RADEONDPIVX = pScrn->virtualX;
- info->RADEONDPIVY = pScrn->virtualY;
- }
-
- /* Get ScreenInit function */
- if (!xf86LoadSubModule(pScrn, "fb")) return FALSE;
-
- xf86LoaderReqSymLists(fbSymbols, NULL);
-
- info->CurrentLayout.displayWidth = pScrn->displayWidth;
- info->CurrentLayout.mode = pScrn->currentMode;
-
- return TRUE;
-}
-
/* This is called by RADEONPreInit to initialize the hardware cursor */
static Bool RADEONPreInitCursor(ScrnInfoPtr pScrn)
{
@@ -2500,18 +2022,6 @@ static Bool RADEONPreInitDRI(ScrnInfoPtr pScrn)
info->pLibDRMVersion = NULL;
info->pKernelDRMVersion = NULL;
- if (xf86IsEntityShared(info->pEnt->index)) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Direct Rendering Disabled -- "
- "Dual-head configuration is not working with "
- "DRI at present.\n"
- "Please use the radeon MergedFB option if you "
- "want Dual-head with DRI.\n");
- return FALSE;
- }
- if (info->IsSecondary)
- return FALSE;
-
if (info->Chipset == PCI_CHIP_RN50_515E ||
info->Chipset == PCI_CHIP_RN50_5969) {
if (xf86ReturnOptValBool(info->Options, OPTION_DRI, FALSE)) {
@@ -2526,18 +2036,6 @@ static Bool RADEONPreInitDRI(ScrnInfoPtr pScrn)
}
}
- if (info->Chipset == PCI_CHIP_RS400_5A41 ||
- info->Chipset == PCI_CHIP_RS400_5A42 ||
- info->Chipset == PCI_CHIP_RC410_5A61 ||
- info->Chipset == PCI_CHIP_RC410_5A62 ||
- info->Chipset == PCI_CHIP_RS480_5954 ||
- info->Chipset == PCI_CHIP_RS480_5955 ||
- info->Chipset == PCI_CHIP_RS482_5974 ||
- info->Chipset == PCI_CHIP_RS482_5975) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Direct rendering broken on XPRESS 200 and 200M\n");
- return FALSE;
- }
if (!xf86ReturnOptValBool(info->Options, OPTION_DRI, TRUE)) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
@@ -2564,6 +2062,24 @@ static Bool RADEONPreInitDRI(ScrnInfoPtr pScrn)
info->pKernelDRMVersion->version_minor,
info->pKernelDRMVersion->version_patchlevel);
+ if (info->Chipset == PCI_CHIP_RS400_5A41 ||
+ info->Chipset == PCI_CHIP_RS400_5A42 ||
+ info->Chipset == PCI_CHIP_RC410_5A61 ||
+ info->Chipset == PCI_CHIP_RC410_5A62 ||
+ info->Chipset == PCI_CHIP_RS480_5954 ||
+ info->Chipset == PCI_CHIP_RS480_5955 ||
+ info->Chipset == PCI_CHIP_RS482_5974 ||
+ info->Chipset == PCI_CHIP_RS482_5975) {
+
+ if (info->pKernelDRMVersion->version_minor < 27) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Direct rendering broken on XPRESS 200 and 200M with DRI less than 1.27\n");
+ return FALSE;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Direct rendering experimental on RS400/Xpress 200 enabled\n");
+ }
+
if (xf86ReturnOptValBool(info->Options, OPTION_CP_PIO, FALSE)) {
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Forcing CP into PIO mode\n");
info->CPMode = RADEON_DEFAULT_CP_PIO_MODE;
@@ -2702,6 +2218,7 @@ static void RADEONPreInitColorTiling(ScrnInfoPtr pScrn)
info->allowColorTiling = xf86ReturnOptValBool(info->Options,
OPTION_COLOR_TILING, TRUE);
if (IS_R300_VARIANT) {
+ /* this may be 4096 on r4xx -- need to double check */
info->MaxSurfaceWidth = 3968; /* one would have thought 4096...*/
info->MaxLines = 4096;
} else {
@@ -2728,19 +2245,7 @@ static void RADEONPreInitColorTiling(ScrnInfoPtr pScrn)
}
#endif /* XF86DRI */
- if ((info->allowColorTiling) && (info->IsSecondary)) {
- /* can't have tiling on the 2nd head (as long as it can't use drm).
- * We'd never get the surface save/restore (vt switching) right...
- */
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Color tiling disabled for 2nd head\n");
- info->allowColorTiling = FALSE;
- }
- else if ((info->allowColorTiling) && (info->FBDev)) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Color tiling not supported with UseFBDev option\n");
- info->allowColorTiling = FALSE;
- }
- else if (info->allowColorTiling) {
+ if (info->allowColorTiling) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Color tiling enabled by default\n");
} else {
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Color tiling disabled\n");
@@ -2935,28 +2440,39 @@ static Bool RADEONPreInitXv(ScrnInfoPtr pScrn)
return TRUE;
}
-static Bool RADEONPreInitControllers(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
+static void RADEONPreInitBIOS(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
{
- RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONGetBIOSInfo(pScrn, pInt10);
+#if 0
+ RADEONGetBIOSInitTableOffsets(pScrn);
+ RADEONPostCardFromBIOSTables(pScrn);
+#endif
+}
- if (!info->IsSecondary) {
- if (!RADEONAllocateConnectors(pScrn))
- return FALSE;
+static Bool RADEONPreInitControllers(ScrnInfoPtr pScrn)
+{
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+ int i;
- if (!RADEONAllocateControllers(pScrn))
+ if (!RADEONAllocateControllers(pScrn))
return FALSE;
-
- }
- RADEONGetBIOSInfo(pScrn, pInt10);
+ RADEONGetClockInfo(pScrn);
- RADEONSetupConnectors(pScrn);
- RADEONMapControllers(pScrn);
+ if (!RADEONSetupConnectors(pScrn)) {
+ return FALSE;
+ }
+
+ RADEONPrintPortMap(pScrn);
- RADEONGetClockInfo(pScrn);
- RADEONGetPanelInfo(pScrn);
- RADEONGetTVDacAdjInfo(pScrn);
-
+ for (i = 0; i < config->num_output; i++)
+ {
+ xf86OutputPtr output = config->output[i];
+
+ output->status = (*output->funcs->detect) (output);
+ ErrorF("finished output detect: %d\n", i);
+ }
+ ErrorF("finished all detect\n");
return TRUE;
}
@@ -2971,24 +2487,36 @@ RADEONProbeDDC(ScrnInfoPtr pScrn, int indx)
}
}
+static Bool
+RADEONCRTCResize(ScrnInfoPtr scrn, int width, int height)
+{
+ scrn->virtualX = width;
+ scrn->virtualY = height;
+ /* RADEONSetPitch(scrn); */
+ return TRUE;
+}
+
+static const xf86CrtcConfigFuncsRec RADEONCRTCResizeFuncs = {
+ RADEONCRTCResize
+};
+
_X_EXPORT Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags)
{
+ xf86CrtcConfigPtr xf86_config;
RADEONInfoPtr info;
xf86Int10InfoPtr pInt10 = NULL;
void *int10_save = NULL;
const char *s;
MessageType from;
+ int crtc_max_X, crtc_max_Y;
- RADEONTRACE(("RADEONPreInit\n"));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "RADEONPreInit\n");
if (pScrn->numEntities != 1) return FALSE;
if (!RADEONGetRec(pScrn)) return FALSE;
info = RADEONPTR(pScrn);
- info->IsSecondary = FALSE;
- info->IsPrimary = FALSE;
- info->MergedFB = FALSE;
- info->IsSwitching = FALSE;
info->MMIO = NULL;
info->pEnt = xf86GetEntityInfo(pScrn->entityList[pScrn->numEntities - 1]);
@@ -3032,30 +2560,6 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags)
RADEONPreInt10Save(pScrn, &int10_save);
#endif
- if (xf86IsEntityShared(info->pEnt->index)) {
- if (xf86IsPrimInitDone(info->pEnt->index)) {
-
- RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
-
- info->IsSecondary = TRUE;
- if (!pRADEONEnt->HasSecondary) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Only one monitor detected, Second screen "
- "will NOT be created\n");
- goto fail2;
- }
- pRADEONEnt->pSecondaryScrn = pScrn;
- } else {
- RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
-
- info->IsPrimary = TRUE;
-
- xf86SetPrimInitDone(info->pEnt->index);
-
- pRADEONEnt->pPrimaryScrn = pScrn;
- }
- }
-
if (flags & PROBE_DETECT) {
RADEONProbeDDC(pScrn, info->pEnt->index);
RADEONPostInt10Check(pScrn, int10_save);
@@ -3079,6 +2583,11 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags)
pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_VIEWPORT | RAC_CURSOR;
pScrn->monitor = pScrn->confScreen->monitor;
+ /* Allocate an xf86CrtcConfig */
+ xf86CrtcConfigInit (pScrn, &RADEONCRTCResizeFuncs);
+ xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+
+
if (!RADEONPreInitVisual(pScrn))
goto fail;
@@ -3153,63 +2662,94 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags)
"X server will %skeep DPI constant for all screen sizes\n",
info->constantDPI ? "" : "not ");
- if (xf86ReturnOptValBool(info->Options, OPTION_FBDEV, FALSE)) {
- /* check for Linux framebuffer device */
-
- if (xf86LoadSubModule(pScrn, "fbdevhw")) {
- xf86LoaderReqSymLists(fbdevHWSymbols, NULL);
-
- if (fbdevHWInit(pScrn, info->PciInfo, NULL)) {
- pScrn->ValidMode = fbdevHWValidModeWeak();
- info->FBDev = TRUE;
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
- "Using framebuffer device\n");
- } else {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "fbdevHWInit failed, not using framebuffer device\n");
- }
- } else {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Couldn't load fbdevhw module, not using framebuffer device\n");
- }
- }
-
- if (!info->FBDev)
- if (!RADEONPreInitInt10(pScrn, &pInt10))
- goto fail;
+ if (!RADEONPreInitInt10(pScrn, &pInt10))
+ goto fail;
RADEONPostInt10Check(pScrn, int10_save);
if (!RADEONPreInitChipType(pScrn))
goto fail;
+ RADEONPreInitBIOS(pScrn, pInt10);
+
#ifdef XF86DRI
/* PreInit DRI first of all since we need that for getting a proper
* memory map
*/
info->directRenderingEnabled = RADEONPreInitDRI(pScrn);
#endif
-
if (!RADEONPreInitVRAM(pScrn))
goto fail;
RADEONPreInitColorTiling(pScrn);
+ /* we really need an FB manager... */
+ if (pScrn->display->virtualX) {
+ crtc_max_X = pScrn->display->virtualX;
+ crtc_max_Y = pScrn->display->virtualY;
+ if (info->allowColorTiling) {
+ if (crtc_max_X > info->MaxSurfaceWidth)
+ crtc_max_X = info->MaxSurfaceWidth;
+ if (crtc_max_Y > info->MaxLines)
+ crtc_max_Y = info->MaxLines;
+ } else {
+ if (crtc_max_X > 8192)
+ crtc_max_X = 8192;
+ if (crtc_max_Y > 8192)
+ crtc_max_Y = 8192;
+ }
+ } else {
+ if (pScrn->videoRam < 16384) {
+ crtc_max_X = 1600;
+ crtc_max_Y = 1200;
+ } else if (pScrn->videoRam <= 32768) {
+ crtc_max_X = 2048;
+ crtc_max_Y = 1200;
+ } else if (pScrn->videoRam > 32768) {
+ if (IS_R300_VARIANT) {
+ crtc_max_X = 2560;
+ crtc_max_Y = 2048;
+ } else {
+ crtc_max_X = 2048;
+ crtc_max_Y = 2048;
+ }
+ }
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Max desktop size set to %dx%d\n",
+ crtc_max_X, crtc_max_Y);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "For a larger or smaller max desktop size, add a Virtual line to your xorg.conf\n");
+
+ /*xf86CrtcSetSizeRange (pScrn, 320, 200, info->MaxSurfaceWidth, info->MaxLines);*/
+ xf86CrtcSetSizeRange (pScrn, 320, 200, crtc_max_X, crtc_max_Y);
+
RADEONPreInitDDC(pScrn);
- if (!RADEONPreInitControllers(pScrn, pInt10))
+ if (!RADEONPreInitControllers(pScrn))
goto fail;
- /* collect MergedFB options */
- /* only parse mergedfb options on the primary head.
- Mergedfb is already disabled in xinerama/screen based
- multihead */
- if (!info->IsSecondary)
- RADEONGetMergedFBOptions(pScrn);
- if (!RADEONPreInitGamma(pScrn)) goto fail;
+ ErrorF("before xf86InitialConfiguration\n");
+
+ if (!xf86InitialConfiguration (pScrn, FALSE))
+ {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n");
+ goto fail;
+ }
+
+ ErrorF("after xf86InitialConfiguration\n");
- if (!RADEONPreInitModes(pScrn, pInt10)) goto fail;
+ RADEONSetPitch(pScrn);
+
+ /* Set display resolution */
+ xf86SetDpi(pScrn, 0, 0);
+
+ /* Get ScreenInit function */
+ if (!xf86LoadSubModule(pScrn, "fb")) return FALSE;
+
+ xf86LoaderReqSymLists(fbSymbols, NULL);
+
+ if (!RADEONPreInitGamma(pScrn)) goto fail;
if (!RADEONPreInitCursor(pScrn)) goto fail;
@@ -3217,6 +2757,17 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags)
if (!RADEONPreInitXv(pScrn)) goto fail;
+ if (!xf86RandR12PreInit (pScrn))
+ {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "RandR initialization failure\n");
+ goto fail;
+ }
+
+ if (pScrn->modes == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n");
+ goto fail;
+ }
+
/* Free the video bios (if applicable) */
if (info->VBIOS) {
xfree(info->VBIOS);
@@ -3238,10 +2789,6 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags)
fail:
/* Pre-init failed. */
- if (info->IsSecondary) {
- RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
- pRADEONEnt->HasSecondary = FALSE;
- }
/* Free the video bios (if applicable) */
if (info->VBIOS) {
xfree(info->VBIOS);
@@ -3257,7 +2804,6 @@ fail:
vgaHWFreeHWRec(pScrn);
#endif
- fail2:
if(info->MMIO) RADEONUnmapMMIO(pScrn);
info->MMIO = NULL;
@@ -3272,10 +2818,11 @@ static void RADEONLoadPalette(ScrnInfoPtr pScrn, int numColors,
int *indices, LOCO *colors, VisualPtr pVisual)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
int i;
- int idx, j;
- unsigned char r, g, b;
+ int index, j;
+ CARD16 lut_r[256], lut_g[256], lut_b[256];
+ int c;
#ifdef XF86DRI
if (info->CPStarted && pScrn->pScreen) DRILock(pScrn->pScreen, 0);
@@ -3284,112 +2831,60 @@ static void RADEONLoadPalette(ScrnInfoPtr pScrn, int numColors,
if (info->accelOn && pScrn->pScreen)
RADEON_SYNC(info, pScrn);
- if (info->FBDev) {
- fbdevHWLoadPalette(pScrn, numColors, indices, colors, pVisual);
- } else {
- /* If the second monitor is connected, we also need to deal with
- * the secondary palette
- */
- if (info->IsSecondary) j = 1;
- else j = 0;
-
- PAL_SELECT(j);
-
- if (info->CurrentLayout.depth == 15) {
- /* 15bpp mode. This sends 32 values. */
- for (i = 0; i < numColors; i++) {
- idx = indices[i];
- r = colors[idx].red;
- g = colors[idx].green;
- b = colors[idx].blue;
- OUTPAL(idx * 8, r, g, b);
- }
- } else if (info->CurrentLayout.depth == 16) {
- /* 16bpp mode. This sends 64 values.
- *
- * There are twice as many green values as there are values
- * for red and blue. So, we take each red and blue pair,
- * and combine it with each of the two green values.
- */
- for (i = 0; i < numColors; i++) {
- idx = indices[i];
- r = colors[idx / 2].red;
- g = colors[idx].green;
- b = colors[idx / 2].blue;
- RADEONWaitForFifo(pScrn, 32); /* delay */
- OUTPAL(idx * 4, r, g, b);
-
- /* AH - Added to write extra green data - How come this isn't
- * needed on R128? We didn't load the extra green data in the
- * other routine
- */
- if (idx <= 31) {
- r = colors[idx].red;
- g = colors[(idx * 2) + 1].green;
- b = colors[idx].blue;
- RADEONWaitForFifo(pScrn, 32); /* delay */
- OUTPAL(idx * 8, r, g, b);
- }
- }
- } else {
- /* 8bpp mode. This sends 256 values. */
- for (i = 0; i < numColors; i++) {
- idx = indices[i];
- r = colors[idx].red;
- b = colors[idx].blue;
- g = colors[idx].green;
- RADEONWaitForFifo(pScrn, 32); /* delay */
- OUTPAL(idx, r, g, b);
- }
- }
+ {
- if (info->MergedFB) {
- PAL_SELECT(1);
- if (info->CurrentLayout.depth == 15) {
- /* 15bpp mode. This sends 32 values. */
- for (i = 0; i < numColors; i++) {
- idx = indices[i];
- r = colors[idx].red;
- g = colors[idx].green;
- b = colors[idx].blue;
- OUTPAL(idx * 8, r, g, b);
- }
- } else if (info->CurrentLayout.depth == 16) {
- /* 16bpp mode. This sends 64 values.
- *
- * There are twice as many green values as there are values
- * for red and blue. So, we take each red and blue pair,
- * and combine it with each of the two green values.
- */
- for (i = 0; i < numColors; i++) {
- idx = indices[i];
- r = colors[idx / 2].red;
- g = colors[idx].green;
- b = colors[idx / 2].blue;
- OUTPAL(idx * 4, r, g, b);
-
- /* AH - Added to write extra green data - How come
- * this isn't needed on R128? We didn't load the
- * extra green data in the other routine.
- */
- if (idx <= 31) {
- r = colors[idx].red;
- g = colors[(idx * 2) + 1].green;
- b = colors[idx].blue;
- OUTPAL(idx * 8, r, g, b);
- }
- }
- } else {
- /* 8bpp mode. This sends 256 values. */
- for (i = 0; i < numColors; i++) {
- idx = indices[i];
- r = colors[idx].red;
- b = colors[idx].blue;
- g = colors[idx].green;
- OUTPAL(idx, r, g, b);
- }
- }
- }
+ for (c = 0; c < xf86_config->num_crtc; c++) {
+ xf86CrtcPtr crtc = xf86_config->crtc[c];
+ RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+
+ for (i = 0 ; i < 256; i++) {
+ lut_r[i] = radeon_crtc->lut_r[i] << 8;
+ lut_g[i] = radeon_crtc->lut_g[i] << 8;
+ lut_b[i] = radeon_crtc->lut_b[i] << 8;
+ }
+
+ switch (info->CurrentLayout.depth) {
+ case 15:
+ for (i = 0; i < numColors; i++) {
+ index = indices[i];
+ for (j = 0; j < 8; j++) {
+ lut_r[index * 8 + j] = colors[index].red << 8;
+ lut_g[index * 8 + j] = colors[index].green << 8;
+ lut_b[index * 8 + j] = colors[index].blue << 8;
+ }
+ }
+ case 16:
+ for (i = 0; i < numColors; i++) {
+ index = indices[i];
+
+ if (i <= 31) {
+ for (j = 0; j < 8; j++) {
+ lut_r[index * 8 + j] = colors[index].red << 8;
+ lut_b[index * 8 + j] = colors[index].blue << 8;
+ }
+ }
+
+ for (j = 0; j < 4; j++) {
+ lut_g[index * 4 + j] = colors[index].green << 8;
+ }
+ }
+ default:
+ for (i = 0; i < numColors; i++) {
+ index = indices[i];
+ lut_r[index] = colors[index].red << 8;
+ lut_g[index] = colors[index].green << 8;
+ lut_b[index] = colors[index].blue << 8;
+ }
+ break;
+ }
+
+ /* Make the change through RandR */
+#ifdef RANDR_12_INTERFACE
+ RRCrtcGammaSet(crtc->randr_crtc, lut_r, lut_g, lut_b);
+#else
+ crtc->funcs->gamma_set(crtc, lut_r, lut_g, lut_b, 256);
+#endif
+ }
}
#ifdef XF86DRI
@@ -3404,14 +2899,6 @@ static void RADEONBlockHandler(int i, pointer blockData,
ScrnInfoPtr pScrn = xf86Screens[i];
RADEONInfoPtr info = RADEONPTR(pScrn);
-#ifdef XF86DRI
- if (info->directRenderingInited) {
- FLUSH_RING();
- }
-#endif
-#ifdef USE_EXA
- info->engineMode = EXA_ENGINEMODE_UNKNOWN;
-#endif
pScreen->BlockHandler = info->BlockHandler;
(*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
pScreen->BlockHandler = RADEONBlockHandler;
@@ -3423,6 +2910,10 @@ static void RADEONBlockHandler(int i, pointer blockData,
if(info->RenderCallback)
(*info->RenderCallback)(pScrn);
#endif
+
+#ifdef USE_EXA
+ info->engineMode = EXA_ENGINEMODE_UNKNOWN;
+#endif
}
@@ -3682,8 +3173,8 @@ Bool RADEONSetupMemXAA_DRI(int scrnIndex, ScreenPtr pScreen)
info->depthOffset);
if (info->cardType==CARD_PCIE)
xf86DrvMsg(scrnIndex, X_INFO,
- "Will use %d kb for PCI GART table at offset 0x%lx\n",
- info->pciGartSize/1024, info->pciGartOffset);
+ "Will use %d kb for PCI GART table at offset 0x%x\n",
+ info->pciGartSize/1024, (unsigned)info->pciGartOffset);
xf86DrvMsg(scrnIndex, X_INFO,
"Will use %d kb for textures at offset 0x%x\n",
info->textureSize/1024, info->textureOffset);
@@ -3762,27 +3253,65 @@ Bool RADEONSetupMemXAA(int scrnIndex, ScreenPtr pScreen)
}
#endif /* USE_XAA */
+static void
+RADEONPointerMoved(int index, int x, int y)
+{
+ ScrnInfoPtr pScrn = xf86Screens[index];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ int newX = x, newY = y;
+
+ switch (info->rotation) {
+ case RR_Rotate_0:
+ break;
+ case RR_Rotate_90:
+ newX = y;
+ newY = pScrn->pScreen->width - x - 1;
+ break;
+ case RR_Rotate_180:
+ newX = pScrn->pScreen->width - x - 1;
+ newY = pScrn->pScreen->height - y - 1;
+ break;
+ case RR_Rotate_270:
+ newX = pScrn->pScreen->height - y - 1;
+ newY = x;
+ break;
+ }
+
+ (*info->PointerMoved)(index, newX, newY);
+}
+
/* Called at the start of each server generation. */
-_X_EXPORT Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
+Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
int argc, char **argv)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
RADEONInfoPtr info = RADEONPTR(pScrn);
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
int hasDRI = 0;
+ int i;
#ifdef RENDER
int subPixelOrder = SubPixelUnknown;
char* s;
#endif
- RADEONTRACE(("RADEONScreenInit %lx %ld %d\n",
- pScrn->memPhysBase, pScrn->fbOffset, info->frontOffset));
+#ifdef XF86DRI
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "RADEONScreenInit %lx %ld %d\n",
+ pScrn->memPhysBase, pScrn->fbOffset, info->frontOffset);
+#else
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "RADEONScreenInit %lx %ld\n",
+ pScrn->memPhysBase, pScrn->fbOffset);
+#endif
info->accelOn = FALSE;
#ifdef USE_XAA
info->accel = NULL;
#endif
+#ifdef XF86DRI
pScrn->fbOffset = info->frontOffset;
- if (info->IsSecondary) pScrn->fbOffset = pScrn->videoRam * 1024;
+#endif
+
if (!RADEONMapMem(pScrn)) return FALSE;
#ifdef XF86DRI
@@ -3792,9 +3321,14 @@ _X_EXPORT Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
info->PaletteSavedOnVT = FALSE;
+ info->crtc_on = FALSE;
+ info->crtc2_on = FALSE;
+
RADEONSave(pScrn);
- if ((!info->IsSecondary) && info->IsMobility) {
+ RADEONDisableDisplays(pScrn);
+
+ if (info->IsMobility) {
if (xf86ReturnOptValBool(info->Options, OPTION_DYNAMIC_CLOCKS, FALSE)) {
RADEONSetDynamicClock(pScrn, 1);
} else {
@@ -3802,8 +3336,8 @@ _X_EXPORT Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
}
}
- if ((!info->IsSecondary) && (IS_R300_VARIANT || IS_RV100_VARIANT))
- RADEONForceSomeClocks(pScrn);
+ if (IS_R300_VARIANT || IS_RV100_VARIANT)
+ RADEONForceSomeClocks(pScrn);
if (info->allowColorTiling && (pScrn->virtualX > info->MaxSurfaceWidth)) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
@@ -3812,17 +3346,7 @@ _X_EXPORT Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
info->allowColorTiling = FALSE;
}
if (info->allowColorTiling) {
- if (info->MergedFB) {
- if ((((RADEONMergedDisplayModePtr)pScrn->currentMode->Private)->CRT1->Flags &
- (V_DBLSCAN | V_INTERLACE)) ||
- (((RADEONMergedDisplayModePtr)pScrn->currentMode->Private)->CRT2->Flags &
- (V_DBLSCAN | V_INTERLACE)))
- info->tilingEnabled = FALSE;
- else info->tilingEnabled = TRUE;
- }
- else {
- info->tilingEnabled = (pScrn->currentMode->Flags & (V_DBLSCAN | V_INTERLACE)) ? FALSE : TRUE;
- }
+ info->tilingEnabled = (pScrn->currentMode->Flags & (V_DBLSCAN | V_INTERLACE)) ? FALSE : TRUE;
}
/* Visual setup */
@@ -3863,15 +3387,13 @@ _X_EXPORT Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
*/
RADEONInitMemoryMap(pScrn);
- if (!info->IsSecondary) {
- /* empty the surfaces */
- unsigned char *RADEONMMIO = info->MMIO;
- unsigned int i;
- for (i = 0; i < 8; i++) {
- OUTREG(RADEON_SURFACE0_INFO + 16 * i, 0);
- OUTREG(RADEON_SURFACE0_LOWER_BOUND + 16 * i, 0);
- OUTREG(RADEON_SURFACE0_UPPER_BOUND + 16 * i, 0);
- }
+ /* empty the surfaces */
+ unsigned char *RADEONMMIO = info->MMIO;
+ unsigned int j;
+ for (j = 0; j < 8; j++) {
+ OUTREG(RADEON_SURFACE0_INFO + 16 * j, 0);
+ OUTREG(RADEON_SURFACE0_LOWER_BOUND + 16 * j, 0);
+ OUTREG(RADEON_SURFACE0_UPPER_BOUND + 16 * j, 0);
}
#ifdef XF86DRI
@@ -3891,14 +3413,14 @@ _X_EXPORT Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
#endif
/* Initial setup of surfaces */
- if (!info->IsSecondary) {
- RADEONTRACE(("Setting up initial surfaces\n"));
- RADEONChangeSurfaces(pScrn);
- }
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "Setting up initial surfaces\n");
+ RADEONChangeSurfaces(pScrn);
/* Memory manager setup */
- RADEONTRACE(("Setting up accel memmap\n"));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "Setting up accel memmap\n");
#ifdef USE_EXA
if (info->useEXA) {
@@ -3969,6 +3491,7 @@ _X_EXPORT Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
/* Setup DRI after visuals have been established, but before fbScreenInit is
* called. fbScreenInit will eventually call the driver's InitGLXVisuals
* call back. */
+#ifdef XF86DRI
if (info->directRenderingEnabled) {
/* FIXME: When we move to dynamic allocation of back and depth
* buffers, we will want to revisit the following check for 3
@@ -3992,7 +3515,6 @@ _X_EXPORT Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
}
}
-#if defined(XF86DRI)
/* Tell DRI about new memory map */
if (info->directRenderingEnabled && info->newMemoryMap) {
if (RADEONDRISetParam(pScrn, RADEON_SETPARAM_NEW_MEMMAP, 1) < 0) {
@@ -4003,7 +3525,8 @@ _X_EXPORT Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
}
}
#endif
- RADEONTRACE(("Initializing fb layer\n"));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "Initializing fb layer\n");
/* Init fb layer */
if (!fbScreenInit(pScreen, info->FB + pScrn->fbOffset,
@@ -4040,38 +3563,34 @@ _X_EXPORT Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
else if (strcmp(s, "NONE") == 0) subPixelOrder = SubPixelNone;
PictureSetSubpixelOrder (pScreen, subPixelOrder);
}
+#endif
- if (PictureGetSubpixelOrder (pScreen) == SubPixelUnknown) {
- switch (info->DisplayType) {
- case MT_NONE: subPixelOrder = SubPixelUnknown; break;
- case MT_LCD: subPixelOrder = SubPixelHorizontalRGB; break;
- case MT_DFP: subPixelOrder = SubPixelHorizontalRGB; break;
- default: subPixelOrder = SubPixelNone; break;
+ pScrn->vtSema = TRUE;
+
+ for (i = 0; i < xf86_config->num_crtc; i++) {
+ xf86CrtcPtr crtc = xf86_config->crtc[i];
+
+ /* Mark that we'll need to re-set the mode for sure */
+ memset(&crtc->mode, 0, sizeof(crtc->mode));
+ if (!crtc->desiredMode.CrtcHDisplay) {
+ crtc->desiredMode = *RADEONCrtcFindClosestMode (crtc, pScrn->currentMode);
+ crtc->desiredRotation = RR_Rotate_0;
+ crtc->desiredX = 0;
+ crtc->desiredY = 0;
}
- PictureSetSubpixelOrder (pScreen, subPixelOrder);
- }
-#endif
- if (info->FBDev) {
- unsigned char *RADEONMMIO = info->MMIO;
+ if (!xf86CrtcSetMode (crtc, &crtc->desiredMode, crtc->desiredRotation, crtc->desiredX, crtc->desiredY))
+ return FALSE;
- if (!fbdevHWModeInit(pScrn, pScrn->currentMode)) return FALSE;
- pScrn->displayWidth = fbdevHWGetLineLength(pScrn)
- / info->CurrentLayout.pixel_bytes;
- RADEONSaveMemMapRegisters(pScrn, &info->ModeReg);
- info->fbLocation = (info->ModeReg.mc_fb_location & 0xffff) << 16;
- info->ModeReg.surface_cntl = INREG(RADEON_SURFACE_CNTL);
- info->ModeReg.surface_cntl &= ~RADEON_SURF_TRANSLATION_DIS;
- } else {
- if (!RADEONModeInit(pScrn, pScrn->currentMode)) return FALSE;
}
RADEONSaveScreen(pScreen, SCREEN_SAVER_ON);
- pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+ // pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
/* Backing store setup */
- RADEONTRACE(("Initializing backing store\n"));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "Initializing backing store\n");
miInitializeBackingStore(pScreen);
xf86SetBackingStore(pScreen);
@@ -4091,7 +3610,8 @@ _X_EXPORT Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
}
}
if (info->directRenderingEnabled) {
- RADEONTRACE(("DRI Finishing init !\n"));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "DRI Finishing init !\n");
info->directRenderingEnabled = RADEONDRIFinishScreenInit(pScreen);
}
if (info->directRenderingEnabled) {
@@ -4120,18 +3640,15 @@ _X_EXPORT Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
#endif
/* Make sure surfaces are allright since DRI setup may have changed them */
- if (!info->IsSecondary) {
- RADEONTRACE(("Setting up final surfaces\n"));
- RADEONChangeSurfaces(pScrn);
- }
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "Setting up final surfaces\n");
- if(info->MergedFB)
- /* need this here to fix up sarea values */
- RADEONAdjustFrameMerged(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+ RADEONChangeSurfaces(pScrn);
/* Enable aceleration */
if (!xf86ReturnOptValBool(info->Options, OPTION_NOACCEL, FALSE)) {
- RADEONTRACE(("Initializing Acceleration\n"));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "Initializing Acceleration\n");
if (RADEONAccelInit(pScreen)) {
xf86DrvMsg(scrnIndex, X_INFO, "Acceleration enabled\n");
info->accelOn = TRUE;
@@ -4147,10 +3664,12 @@ _X_EXPORT Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
}
/* Init DPMS */
- RADEONTRACE(("Initializing DPMS\n"));
- xf86DPMSInit(pScreen, RADEONDisplayPowerManagementSet, 0);
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "Initializing DPMS\n");
+ xf86DPMSInit(pScreen, xf86DPMSSet, 0);
- RADEONTRACE(("Initializing Cursor\n"));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "Initializing Cursor\n");
/* Set Silken Mouse */
xf86SetSilkenMouse(pScreen);
@@ -4166,9 +3685,9 @@ _X_EXPORT Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
int width, height;
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Using hardware cursor (scanline %ld)\n",
- info->cursor_offset / pScrn->displayWidth
- / info->CurrentLayout.pixel_bytes);
+ "Using hardware cursor (scanline %u)\n",
+ (unsigned)(info->cursor_offset / pScrn->displayWidth
+ / info->CurrentLayout.pixel_bytes));
if (xf86QueryLargestOffscreenArea(pScreen, &width, &height,
0, 0, 0)) {
xf86DrvMsg(scrnIndex, X_INFO,
@@ -4187,42 +3706,16 @@ _X_EXPORT Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
xf86DrvMsg(scrnIndex, X_INFO, "Using software cursor\n");
}
- /* Colormap setup */
- RADEONTRACE(("Initializing color map\n"));
- if (!miCreateDefColormap(pScreen)) return FALSE;
- if (!xf86HandleColormaps(pScreen, 256, info->dac6bits ? 6 : 8,
- RADEONLoadPalette, NULL,
- CMAP_PALETTED_TRUECOLOR
-#if 0 /* This option messes up text mode! (eich@suse.de) */
- | CMAP_LOAD_EVEN_IF_OFFSCREEN
-#endif
- | CMAP_RELOAD_ON_MODE_SWITCH)) return FALSE;
-
/* DGA setup */
- RADEONTRACE(("Initializing DGA\n"));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "Initializing DGA\n");
RADEONDGAInit(pScreen);
- /* Wrap some funcs for MergedFB */
- if(info->MergedFB) {
- info->PointerMoved = pScrn->PointerMoved;
- pScrn->PointerMoved = RADEONMergePointerMoved;
- /* Psuedo xinerama */
- if(info->UseRADEONXinerama) {
- RADEONnoPanoramiXExtension = FALSE;
- RADEONXineramaExtensionInit(pScrn);
- } else {
- info->MouseRestrictions = FALSE;
- }
- }
-
/* Init Xv */
- RADEONTRACE(("Initializing Xv\n"));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "Initializing Xv\n");
RADEONInitVideo(pScreen);
- if(info->MergedFB)
- /* need this here to fix up sarea values */
- RADEONAdjustFrameMerged(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
-
/* Provide SaveScreen & wrap BlockHandler and CloseScreen */
/* Wrap CloseScreen */
info->CloseScreen = pScreen->CloseScreen;
@@ -4231,17 +3724,37 @@ _X_EXPORT Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
info->BlockHandler = pScreen->BlockHandler;
pScreen->BlockHandler = RADEONBlockHandler;
+ if (!xf86CrtcScreenInit (pScreen))
+ return FALSE;
+
+ /* Wrap pointer motion to flip touch screen around */
+ info->PointerMoved = pScrn->PointerMoved;
+ pScrn->PointerMoved = RADEONPointerMoved;
+
+ /* Colormap setup */
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "Initializing color map\n");
+ if (!miCreateDefColormap(pScreen)) return FALSE;
+ if (!xf86HandleColormaps(pScreen, 256, info->dac6bits ? 6 : 8,
+ RADEONLoadPalette, NULL,
+ CMAP_PALETTED_TRUECOLOR
+#if 0 /* This option messes up text mode! (eich@suse.de) */
+ | CMAP_LOAD_EVEN_IF_OFFSCREEN
+#endif
+ | CMAP_RELOAD_ON_MODE_SWITCH)) return FALSE;
+
/* Note unused options */
if (serverGeneration == 1)
xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
- RADEONTRACE(("RADEONScreenInit finished\n"));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "RADEONScreenInit finished\n");
return TRUE;
}
/* Write memory mapping registers */
-static void RADEONRestoreMemMapRegisters(ScrnInfoPtr pScrn,
+void RADEONRestoreMemMapRegisters(ScrnInfoPtr pScrn,
RADEONSavePtr restore)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
@@ -4249,9 +3762,14 @@ static void RADEONRestoreMemMapRegisters(ScrnInfoPtr pScrn,
unsigned char *RADEONMMIO = info->MMIO;
int timeout;
- RADEONTRACE(("RADEONRestoreMemMapRegisters() : \n"));
- RADEONTRACE((" MC_FB_LOCATION : 0x%08lx\n", restore->mc_fb_location));
- RADEONTRACE((" MC_AGP_LOCATION : 0x%08lx\n", restore->mc_agp_location));
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "RADEONRestoreMemMapRegisters() : \n");
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ " MC_FB_LOCATION : 0x%08x\n",
+ (unsigned)restore->mc_fb_location);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ " MC_AGP_LOCATION : 0x%08x\n",
+ (unsigned)restore->mc_agp_location);
/* Write memory mapping registers only if their value change
* since we must ensure no access is done while they are
@@ -4262,7 +3780,8 @@ static void RADEONRestoreMemMapRegisters(ScrnInfoPtr pScrn,
CARD32 crtc_ext_cntl, crtc_gen_cntl, crtc2_gen_cntl=0, ov0_scale_cntl;
CARD32 old_mc_status, status_idle;
- RADEONTRACE((" Map Changed ! Applying ...\n"));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ " Map Changed ! Applying ...\n");
/* Make sure engine is idle. We assume the CCE is stopped
* at this point
@@ -4335,7 +3854,8 @@ static void RADEONRestoreMemMapRegisters(ScrnInfoPtr pScrn,
/* Make sure map fully reached the chip */
(void)INREG(RADEON_MC_FB_LOCATION);
- RADEONTRACE((" Map applied, resetting engine ...\n"));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ " Map applied, resetting engine ...\n");
/* Reset the engine and HDP */
RADEONEngineReset(pScrn);
@@ -4372,7 +3892,8 @@ static void RADEONRestoreMemMapRegisters(ScrnInfoPtr pScrn,
}
}
- RADEONTRACE(("Updating display base addresses...\n"));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "Updating display base addresses...\n");
OUTREG(RADEON_DISPLAY_BASE_ADDR, restore->display_base_addr);
if (pRADEONEnt->HasCRTC2)
@@ -4383,7 +3904,8 @@ static void RADEONRestoreMemMapRegisters(ScrnInfoPtr pScrn,
/* More paranoia delays, wait 100ms */
usleep(100000);
- RADEONTRACE(("Memory map updated.\n"));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "Memory map updated.\n");
}
#ifdef XF86DRI
@@ -4392,21 +3914,19 @@ static void RADEONAdjustMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
RADEONInfoPtr info = RADEONPTR(pScrn);
unsigned char *RADEONMMIO = info->MMIO;
CARD32 fb, agp;
- int fb_loc_changed;
fb = INREG(RADEON_MC_FB_LOCATION);
agp = INREG(RADEON_MC_AGP_LOCATION);
- fb_loc_changed = (fb != info->mc_fb_location);
- if (fb_loc_changed || agp != info->mc_agp_location) {
+ if (fb != info->mc_fb_location || agp != info->mc_agp_location) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"DRI init changed memory map, adjusting ...\n");
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- " MC_FB_LOCATION was: 0x%08lx is: 0x%08lx\n",
- info->mc_fb_location, fb);
+ " MC_FB_LOCATION was: 0x%08x is: 0x%08x\n",
+ (unsigned)info->mc_fb_location, (unsigned)fb);
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- " MC_AGP_LOCATION was: 0x%08lx is: 0x%08lx\n",
- info->mc_agp_location, agp);
+ " MC_AGP_LOCATION was: 0x%08x is: 0x%08x\n",
+ (unsigned)info->mc_agp_location, (unsigned)agp);
info->mc_fb_location = fb;
info->mc_agp_location = agp;
info->fbLocation = (save->mc_fb_location & 0xffff) << 16;
@@ -4417,9 +3937,8 @@ static void RADEONAdjustMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
RADEONInitMemMapRegisters(pScrn, save, info);
- /* If MC_FB_LOCATION was changed, adjust the various offsets */
- if (fb_loc_changed)
- RADEONRestoreMemMapRegisters(pScrn, save);
+ /* Adjust the various offsets */
+ RADEONRestoreMemMapRegisters(pScrn, save);
}
#ifdef USE_EXA
@@ -4447,7 +3966,7 @@ static void RADEONAdjustMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
#endif
/* Write common registers */
-static void RADEONRestoreCommonRegisters(ScrnInfoPtr pScrn,
+void RADEONRestoreCommonRegisters(ScrnInfoPtr pScrn,
RADEONSavePtr restore)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
@@ -4472,55 +3991,62 @@ static void RADEONRestoreCommonRegisters(ScrnInfoPtr pScrn,
* CRT are connected.
*/
if (pRADEONEnt->HasCRTC2 &&
- !info->IsSwitching &&
info->ChipFamily != CHIP_FAMILY_R200 &&
!IS_R300_VARIANT) {
CARD32 tmp;
- RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
- if (pRADEONEnt->HasSecondary || info->MergedFB) {
- tmp = INREG(RADEON_DAC_CNTL2);
- OUTREG(RADEON_DAC_CNTL2, tmp & ~RADEON_DAC2_DAC_CLK_SEL);
- usleep(100000);
- }
+ tmp = INREG(RADEON_DAC_CNTL2);
+ OUTREG(RADEON_DAC_CNTL2, tmp & ~RADEON_DAC2_DAC_CLK_SEL);
+ usleep(100000);
}
}
-/* Write miscellaneous registers which might have been destroyed by an fbdevHW
- * call
- */
-static void RADEONRestoreFBDevRegisters(ScrnInfoPtr pScrn,
- RADEONSavePtr restore)
+void RADEONRestoreDACRegisters(ScrnInfoPtr pScrn,
+ RADEONSavePtr restore)
{
-#ifdef XF86DRI
RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
unsigned char *RADEONMMIO = info->MMIO;
- /* Restore register for vertical blank interrupts */
- if (info->irq) {
- OUTREG(RADEON_GEN_INT_CNTL, restore->gen_int_cntl);
- }
+ if (IS_R300_VARIANT)
+ OUTREGP(RADEON_GPIOPAD_A, restore->gpiopad_a, ~1);
- /* Restore registers for page flipping */
- if (info->allowPageFlip) {
- OUTREG(RADEON_CRTC_OFFSET_CNTL, restore->crtc_offset_cntl);
- if (pRADEONEnt->HasCRTC2) {
- OUTREG(RADEON_CRTC2_OFFSET_CNTL, restore->crtc2_offset_cntl);
- }
+ OUTREGP(RADEON_DAC_CNTL,
+ restore->dac_cntl,
+ RADEON_DAC_RANGE_CNTL |
+ RADEON_DAC_BLANKING);
+
+ OUTREG(RADEON_DAC_CNTL2, restore->dac2_cntl);
+
+ if ((info->ChipFamily != CHIP_FAMILY_RADEON) &&
+ (info->ChipFamily != CHIP_FAMILY_R200))
+ OUTREG (RADEON_TV_DAC_CNTL, restore->tv_dac_cntl);
+
+ OUTREG(RADEON_DISP_OUTPUT_CNTL, restore->disp_output_cntl);
+
+ if ((info->ChipFamily == CHIP_FAMILY_R200) ||
+ IS_R300_VARIANT) {
+ OUTREG(RADEON_DISP_TV_OUT_CNTL, restore->disp_tv_out_cntl);
+ } else {
+ OUTREG(RADEON_DISP_HW_DEBUG, restore->disp_hw_debug);
}
-#endif
+
+ OUTREG(RADEON_DAC_MACRO_CNTL, restore->dac_macro_cntl);
+
+ /* R200 DAC connected via DVO */
+ if (info->ChipFamily == CHIP_FAMILY_R200)
+ OUTREG(RADEON_FP2_GEN_CNTL, restore->fp2_gen_cntl);
}
/* Write CRTC registers */
-static void RADEONRestoreCrtcRegisters(ScrnInfoPtr pScrn,
+void RADEONRestoreCrtcRegisters(ScrnInfoPtr pScrn,
RADEONSavePtr restore)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
unsigned char *RADEONMMIO = info->MMIO;
- RADEONTRACE(("Programming CRTC1, offset: 0x%08lx\n",
- restore->crtc_offset));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "Programming CRTC1, offset: 0x%08x\n",
+ (unsigned)restore->crtc_offset);
/* We prevent the CRTC from hitting the memory controller until
* fully programmed
@@ -4534,11 +4060,6 @@ static void RADEONRestoreCrtcRegisters(ScrnInfoPtr pScrn,
RADEON_CRTC_HSYNC_DIS |
RADEON_CRTC_DISPLAY_DIS);
- OUTREGP(RADEON_DAC_CNTL,
- restore->dac_cntl,
- RADEON_DAC_RANGE_CNTL |
- RADEON_DAC_BLANKING);
-
OUTREG(RADEON_CRTC_H_TOTAL_DISP, restore->crtc_h_total_disp);
OUTREG(RADEON_CRTC_H_SYNC_STRT_WID, restore->crtc_h_sync_strt_wid);
OUTREG(RADEON_CRTC_V_TOTAL_DISP, restore->crtc_v_total_disp);
@@ -4549,8 +4070,11 @@ static void RADEONRestoreCrtcRegisters(ScrnInfoPtr pScrn,
OUTREG(RADEON_FP_CRTC_H_TOTAL_DISP, restore->fp_crtc_h_total_disp);
OUTREG(RADEON_FP_CRTC_V_TOTAL_DISP, restore->fp_crtc_v_total_disp);
- OUTREG(RADEON_CRTC_OFFSET, restore->crtc_offset);
+ if (IS_R300_VARIANT)
+ OUTREG(R300_CRTC_TILE_X0_Y0, restore->crtc_tile_x0_y0);
OUTREG(RADEON_CRTC_OFFSET_CNTL, restore->crtc_offset_cntl);
+ OUTREG(RADEON_CRTC_OFFSET, restore->crtc_offset);
+
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);
@@ -4566,42 +4090,24 @@ static void RADEONRestoreCrtcRegisters(ScrnInfoPtr pScrn,
}
/* Write CRTC2 registers */
-static void RADEONRestoreCrtc2Registers(ScrnInfoPtr pScrn,
+void RADEONRestoreCrtc2Registers(ScrnInfoPtr pScrn,
RADEONSavePtr restore)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
unsigned char *RADEONMMIO = info->MMIO;
- CARD32 crtc2_gen_cntl;
+ /* CARD32 crtc2_gen_cntl;*/
- RADEONTRACE(("Programming CRTC2, offset: 0x%08lx\n",
- restore->crtc2_offset));
-
- crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL) &
- (RADEON_CRTC2_VSYNC_DIS |
- RADEON_CRTC2_HSYNC_DIS |
- RADEON_CRTC2_DISP_DIS);
- crtc2_gen_cntl |= restore->crtc2_gen_cntl;
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "Programming CRTC2, offset: 0x%08x\n",
+ (unsigned)restore->crtc2_offset);
/* We prevent the CRTC from hitting the memory controller until
* fully programmed
*/
OUTREG(RADEON_CRTC2_GEN_CNTL,
- crtc2_gen_cntl | RADEON_CRTC2_DISP_REQ_EN_B);
-
- OUTREG(RADEON_DAC_CNTL2, restore->dac2_cntl);
-
- //OUTREG(RADEON_TV_DAC_CNTL, 0x00280203);
- if ((info->ChipFamily != CHIP_FAMILY_RADEON) &&
- (info->ChipFamily != CHIP_FAMILY_R200))
- OUTREG (RADEON_TV_DAC_CNTL, restore->tv_dac_cntl);
-
- if ((info->ChipFamily == CHIP_FAMILY_R200) ||
- IS_R300_VARIANT) {
- OUTREG(RADEON_DISP_OUTPUT_CNTL, restore->disp_output_cntl);
- OUTREG(RADEON_DISP_TV_OUT_CNTL, restore->disp_tv_out_cntl);
- } else {
- OUTREG(RADEON_DISP_HW_DEBUG, restore->disp_hw_debug);
- }
+ restore->crtc2_gen_cntl | RADEON_CRTC2_VSYNC_DIS |
+ RADEON_CRTC2_HSYNC_DIS | RADEON_CRTC2_DISP_DIS |
+ RADEON_CRTC2_DISP_REQ_EN_B);
OUTREG(RADEON_CRTC2_H_TOTAL_DISP, restore->crtc2_h_total_disp);
OUTREG(RADEON_CRTC2_H_SYNC_STRT_WID, restore->crtc2_h_sync_strt_wid);
@@ -4611,17 +4117,26 @@ static void RADEONRestoreCrtc2Registers(ScrnInfoPtr pScrn,
OUTREG(RADEON_FP_H2_SYNC_STRT_WID, restore->fp_h2_sync_strt_wid);
OUTREG(RADEON_FP_V2_SYNC_STRT_WID, restore->fp_v2_sync_strt_wid);
- OUTREG(RADEON_CRTC2_OFFSET, restore->crtc2_offset);
+ if (IS_R300_VARIANT)
+ OUTREG(R300_CRTC2_TILE_X0_Y0, restore->crtc2_tile_x0_y0);
OUTREG(RADEON_CRTC2_OFFSET_CNTL, restore->crtc2_offset_cntl);
+ OUTREG(RADEON_CRTC2_OFFSET, restore->crtc2_offset);
+
OUTREG(RADEON_CRTC2_PITCH, restore->crtc2_pitch);
OUTREG(RADEON_DISP2_MERGE_CNTL, restore->disp2_merge_cntl);
- OUTREG(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
+ if (info->ChipFamily == CHIP_FAMILY_RS400) {
+ OUTREG(RADEON_RS480_UNK_e30, restore->rs480_unk_e30);
+ OUTREG(RADEON_RS480_UNK_e34, restore->rs480_unk_e34);
+ OUTREG(RADEON_RS480_UNK_e38, restore->rs480_unk_e38);
+ OUTREG(RADEON_RS480_UNK_e3c, restore->rs480_unk_e3c);
+ }
+ OUTREG(RADEON_CRTC2_GEN_CNTL, restore->crtc2_gen_cntl);
}
-/* Write flat panel registers */
-static void RADEONRestoreFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+/* Write TMDS registers */
+void RADEONRestoreFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
@@ -4629,8 +4144,6 @@ static void RADEONRestoreFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
OUTREG(RADEON_TMDS_PLL_CNTL, restore->tmds_pll_cntl);
OUTREG(RADEON_TMDS_TRANSMITTER_CNTL,restore->tmds_transmitter_cntl);
- OUTREG(RADEON_FP_HORZ_STRETCH, restore->fp_horz_stretch);
- OUTREG(RADEON_FP_VERT_STRETCH, restore->fp_vert_stretch);
OUTREG(RADEON_FP_GEN_CNTL, restore->fp_gen_cntl);
/* old AIW Radeon has some BIOS initialization problem
@@ -4640,7 +4153,38 @@ static void RADEONRestoreFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
OUTREG(RADEON_GRPH_BUFFER_CNTL,
INREG(RADEON_GRPH_BUFFER_CNTL) & ~0x7f0000);
+}
+
+/* Write FP2 registers */
+void RADEONRestoreFP2Registers(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+
+ OUTREG(RADEON_FP2_GEN_CNTL, restore->fp2_gen_cntl);
+
+}
+
+/* Write RMX registers */
+void RADEONRestoreRMXRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+
+ OUTREG(RADEON_FP_HORZ_STRETCH, restore->fp_horz_stretch);
+ OUTREG(RADEON_FP_VERT_STRETCH, restore->fp_vert_stretch);
+
+}
+
+/* Write LVDS registers */
+void RADEONRestoreLVDSRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+
if (info->IsMobility) {
+ OUTREG(RADEON_LVDS_GEN_CNTL, restore->lvds_gen_cntl);
+ /*OUTREG(RADEON_LVDS_PLL_CNTL, restore->lvds_pll_cntl);*/
OUTREG(RADEON_BIOS_4_SCRATCH, restore->bios_4_scratch);
OUTREG(RADEON_BIOS_5_SCRATCH, restore->bios_5_scratch);
OUTREG(RADEON_BIOS_6_SCRATCH, restore->bios_6_scratch);
@@ -4648,6 +4192,262 @@ static void RADEONRestoreFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
}
+/* Write to TV FIFO RAM */
+static void RADEONWriteTVFIFO(ScrnInfoPtr pScrn, CARD16 addr,
+ CARD32 value)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ CARD32 tmp;
+ int i = 0;
+
+ OUTREG(RADEON_TV_HOST_WRITE_DATA, value);
+
+ OUTREG(RADEON_TV_HOST_RD_WT_CNTL, addr);
+ OUTREG(RADEON_TV_HOST_RD_WT_CNTL, addr | RADEON_HOST_FIFO_WT);
+
+ do {
+ tmp = INREG(RADEON_TV_HOST_RD_WT_CNTL);
+ if ((tmp & RADEON_HOST_FIFO_WT_ACK) == 0)
+ break;
+ i++;
+ }
+ while (i < 10000);
+ /*while ((tmp & RADEON_HOST_FIFO_WT_ACK) == 0);*/
+
+ OUTREG(RADEON_TV_HOST_RD_WT_CNTL, 0);
+}
+
+/* Read from TV FIFO RAM */
+static CARD32 RADEONReadTVFIFO(ScrnInfoPtr pScrn, CARD16 addr)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ CARD32 tmp;
+ int i = 0;
+
+ OUTREG(RADEON_TV_HOST_RD_WT_CNTL, addr);
+ OUTREG(RADEON_TV_HOST_RD_WT_CNTL, addr | RADEON_HOST_FIFO_RD);
+
+ do {
+ tmp = INREG(RADEON_TV_HOST_RD_WT_CNTL);
+ if ((tmp & RADEON_HOST_FIFO_RD_ACK) == 0)
+ break;
+ i++;
+ }
+ while (i < 10000);
+ /*while ((tmp & RADEON_HOST_FIFO_RD_ACK) == 0);*/
+
+ OUTREG(RADEON_TV_HOST_RD_WT_CNTL, 0);
+
+ return INREG(RADEON_TV_HOST_READ_DATA);
+}
+
+/* Get FIFO addresses of horizontal & vertical code timing tables from
+ * settings of uv_adr register.
+ */
+static CARD16 RADEONGetHTimingTablesAddr(CARD32 tv_uv_adr)
+{
+ CARD16 hTable;
+
+ switch ((tv_uv_adr & RADEON_HCODE_TABLE_SEL_MASK) >> RADEON_HCODE_TABLE_SEL_SHIFT) {
+ case 0:
+ hTable = RADEON_TV_MAX_FIFO_ADDR_INTERNAL;
+ break;
+ case 1:
+ hTable = ((tv_uv_adr & RADEON_TABLE1_BOT_ADR_MASK) >> RADEON_TABLE1_BOT_ADR_SHIFT) * 2;
+ break;
+ case 2:
+ hTable = ((tv_uv_adr & RADEON_TABLE3_TOP_ADR_MASK) >> RADEON_TABLE3_TOP_ADR_SHIFT) * 2;
+ break;
+ default:
+ /* Of course, this should never happen */
+ hTable = 0;
+ break;
+ }
+ return hTable;
+}
+
+static CARD16 RADEONGetVTimingTablesAddr(CARD32 tv_uv_adr)
+{
+ CARD16 vTable;
+
+ switch ((tv_uv_adr & RADEON_VCODE_TABLE_SEL_MASK) >> RADEON_VCODE_TABLE_SEL_SHIFT) {
+ case 0:
+ vTable = ((tv_uv_adr & RADEON_MAX_UV_ADR_MASK) >> RADEON_MAX_UV_ADR_SHIFT) * 2 + 1;
+ break;
+ case 1:
+ vTable = ((tv_uv_adr & RADEON_TABLE1_BOT_ADR_MASK) >> RADEON_TABLE1_BOT_ADR_SHIFT) * 2 + 1;
+ break;
+ case 2:
+ vTable = ((tv_uv_adr & RADEON_TABLE3_TOP_ADR_MASK) >> RADEON_TABLE3_TOP_ADR_SHIFT) * 2 + 1;
+ break;
+ default:
+ /* Of course, this should never happen */
+ vTable = 0;
+ break;
+ }
+ return vTable;
+}
+
+/* Restore horizontal/vertical timing code tables */
+void RADEONRestoreTVTimingTables(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ CARD16 hTable;
+ CARD16 vTable;
+ CARD32 tmp;
+ unsigned i;
+
+ OUTREG(RADEON_TV_UV_ADR, restore->tv_uv_adr);
+ hTable = RADEONGetHTimingTablesAddr(restore->tv_uv_adr);
+ vTable = RADEONGetVTimingTablesAddr(restore->tv_uv_adr);
+
+ for (i = 0; i < MAX_H_CODE_TIMING_LEN; i += 2, hTable--) {
+ tmp = ((CARD32)restore->h_code_timing[ i ] << 14) | ((CARD32)restore->h_code_timing[ i + 1 ]);
+ RADEONWriteTVFIFO(pScrn, hTable, tmp);
+ if (restore->h_code_timing[ i ] == 0 || restore->h_code_timing[ i + 1 ] == 0)
+ break;
+ }
+
+ for (i = 0; i < MAX_V_CODE_TIMING_LEN; i += 2, vTable++) {
+ tmp = ((CARD32)restore->v_code_timing[ i + 1 ] << 14) | ((CARD32)restore->v_code_timing[ i ]);
+ RADEONWriteTVFIFO(pScrn, vTable, tmp);
+ if (restore->v_code_timing[ i ] == 0 || restore->v_code_timing[ i + 1 ] == 0)
+ break;
+ }
+}
+
+/* restore TV PLLs */
+static void RADEONRestoreTVPLLRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+
+ OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVCLK_SRC_SEL_TVPLL);
+ OUTPLL(pScrn, RADEON_TV_PLL_CNTL, restore->tv_pll_cntl);
+ OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, RADEON_TVPLL_RESET, ~RADEON_TVPLL_RESET);
+
+ RADEONWaitPLLLock(pScrn, 200, 800, 135);
+
+ OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVPLL_RESET);
+
+ RADEONWaitPLLLock(pScrn, 300, 160, 27);
+ RADEONWaitPLLLock(pScrn, 200, 800, 135);
+
+ OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, 0, ~0xf);
+ OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, RADEON_TVCLK_SRC_SEL_TVPLL, ~RADEON_TVCLK_SRC_SEL_TVPLL);
+
+ OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, (1 << RADEON_TVPDC_SHIFT), ~RADEON_TVPDC_MASK);
+ OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVPLL_SLEEP);
+}
+
+/* Restore TV horizontal/vertical settings */
+static void RADEONRestoreTVHVRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+
+ OUTREG(RADEON_TV_RGB_CNTL, restore->tv_rgb_cntl);
+
+ OUTREG(RADEON_TV_HTOTAL, restore->tv_htotal);
+ OUTREG(RADEON_TV_HDISP, restore->tv_hdisp);
+ OUTREG(RADEON_TV_HSTART, restore->tv_hstart);
+
+ OUTREG(RADEON_TV_VTOTAL, restore->tv_vtotal);
+ OUTREG(RADEON_TV_VDISP, restore->tv_vdisp);
+
+ OUTREG(RADEON_TV_FTOTAL, restore->tv_ftotal);
+
+ OUTREG(RADEON_TV_VSCALER_CNTL1, restore->tv_vscaler_cntl1);
+ OUTREG(RADEON_TV_VSCALER_CNTL2, restore->tv_vscaler_cntl2);
+
+ OUTREG(RADEON_TV_Y_FALL_CNTL, restore->tv_y_fall_cntl);
+ OUTREG(RADEON_TV_Y_RISE_CNTL, restore->tv_y_rise_cntl);
+ OUTREG(RADEON_TV_Y_SAW_TOOTH_CNTL, restore->tv_y_saw_tooth_cntl);
+}
+
+/* restore TV RESTART registers */
+void RADEONRestoreTVRestarts(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+
+ OUTREG(RADEON_TV_FRESTART, restore->tv_frestart);
+ OUTREG(RADEON_TV_HRESTART, restore->tv_hrestart);
+ OUTREG(RADEON_TV_VRESTART, restore->tv_vrestart);
+}
+
+/* restore tv standard & output muxes */
+static void RADEONRestoreTVOutputStd(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+
+ OUTREG(RADEON_TV_SYNC_CNTL, restore->tv_sync_cntl);
+
+ OUTREG(RADEON_TV_TIMING_CNTL, restore->tv_timing_cntl);
+
+ OUTREG(RADEON_TV_MODULATOR_CNTL1, restore->tv_modulator_cntl1);
+ OUTREG(RADEON_TV_MODULATOR_CNTL2, restore->tv_modulator_cntl2);
+
+ OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, restore->tv_pre_dac_mux_cntl);
+
+ OUTREG(RADEON_TV_CRC_CNTL, restore->tv_crc_cntl);
+}
+
+/* Restore TV out regs */
+void RADEONRestoreTVRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+
+ ErrorF("Entering Restore TV\n");
+
+ OUTREG(RADEON_TV_MASTER_CNTL, (restore->tv_master_cntl
+ | RADEON_TV_ASYNC_RST
+ | RADEON_CRT_ASYNC_RST
+ | RADEON_TV_FIFO_ASYNC_RST));
+
+ /* Temporarily turn the TV DAC off */
+ OUTREG(RADEON_TV_DAC_CNTL, ((restore->tv_dac_cntl & ~RADEON_TV_DAC_NBLANK)
+ | RADEON_TV_DAC_BGSLEEP
+ | RADEON_TV_DAC_RDACPD
+ | RADEON_TV_DAC_GDACPD
+ | RADEON_TV_DAC_BDACPD));
+
+ ErrorF("Restore TV PLL\n");
+ RADEONRestoreTVPLLRegisters(pScrn, restore);
+
+ ErrorF("Restore TVHV\n");
+ RADEONRestoreTVHVRegisters(pScrn, restore);
+
+ OUTREG(RADEON_TV_MASTER_CNTL, (restore->tv_master_cntl
+ | RADEON_TV_ASYNC_RST
+ | RADEON_CRT_ASYNC_RST));
+
+ ErrorF("Restore TV Restarts\n");
+ RADEONRestoreTVRestarts(pScrn, restore);
+
+ ErrorF("Restore Timing Tables\n");
+ RADEONRestoreTVTimingTables(pScrn, restore);
+
+
+ OUTREG(RADEON_TV_MASTER_CNTL, (restore->tv_master_cntl
+ | RADEON_TV_ASYNC_RST));
+
+ ErrorF("Restore TV standard\n");
+ RADEONRestoreTVOutputStd(pScrn, restore);
+
+ OUTREG(RADEON_TV_MASTER_CNTL, restore->tv_master_cntl);
+
+ OUTREG(RADEON_TV_GAIN_LIMIT_SETTINGS, restore->tv_gain_limit_settings);
+ OUTREG(RADEON_TV_LINEAR_GAIN_SETTINGS, restore->tv_linear_gain_settings);
+
+ OUTREG(RADEON_TV_DAC_CNTL, restore->tv_dac_cntl);
+
+ ErrorF("Leaving Restore TV\n");
+}
+
static void RADEONPLLWaitForReadUpdateComplete(ScrnInfoPtr pScrn)
{
int i = 0;
@@ -4694,12 +4494,81 @@ static void RADEONPLL2WriteUpdate(ScrnInfoPtr pScrn)
~(RADEON_P2PLL_ATOMIC_UPDATE_W));
}
+static CARD8 RADEONComputePLLGain(CARD16 reference_freq, CARD16 ref_div,
+ CARD16 fb_div)
+{
+ unsigned vcoFreq;
+
+ if (!ref_div)
+ return 1;
+
+ vcoFreq = ((unsigned)reference_freq * fb_div) / ref_div;
+
+ /*
+ * This is horribly crude: the VCO frequency range is divided into
+ * 3 parts, each part having a fixed PLL gain value.
+ */
+ if (vcoFreq >= 30000)
+ /*
+ * [300..max] MHz : 7
+ */
+ return 7;
+ else if (vcoFreq >= 18000)
+ /*
+ * [180..300) MHz : 4
+ */
+ return 4;
+ else
+ /*
+ * [0..180) MHz : 1
+ */
+ return 1;
+}
+
+/* Wait for PLLs to lock */
+static void RADEONWaitPLLLock(ScrnInfoPtr pScrn, unsigned nTests,
+ unsigned nWaitLoops, unsigned cntThreshold)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ CARD32 savePLLTest;
+ unsigned i;
+ unsigned j;
+
+ OUTREG(RADEON_TEST_DEBUG_MUX, (INREG(RADEON_TEST_DEBUG_MUX) & 0xffff60ff) | 0x100);
+
+ savePLLTest = INPLL(pScrn, RADEON_PLL_TEST_CNTL);
+
+ OUTPLL(pScrn, RADEON_PLL_TEST_CNTL, savePLLTest & ~RADEON_PLL_MASK_READ_B);
+
+ /* XXX: these should probably be OUTPLL to avoid various PLL errata */
+
+ OUTREG8(RADEON_CLOCK_CNTL_INDEX, RADEON_PLL_TEST_CNTL);
+
+ for (i = 0; i < nTests; i++) {
+ OUTREG8(RADEON_CLOCK_CNTL_DATA + 3, 0);
+
+ for (j = 0; j < nWaitLoops; j++)
+ if (INREG8(RADEON_CLOCK_CNTL_DATA + 3) >= cntThreshold)
+ break;
+ }
+
+ OUTPLL(pScrn, RADEON_PLL_TEST_CNTL, savePLLTest);
+
+ OUTREG(RADEON_TEST_DEBUG_MUX, INREG(RADEON_TEST_DEBUG_MUX) & 0xffffe0ff);
+}
+
/* Write PLL registers */
-static void RADEONRestorePLLRegisters(ScrnInfoPtr pScrn,
- RADEONSavePtr restore)
+void RADEONRestorePLLRegisters(ScrnInfoPtr pScrn,
+ RADEONSavePtr restore)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
unsigned char *RADEONMMIO = info->MMIO;
+ CARD8 pllGain;
+
+ pllGain = RADEONComputePLLGain(info->pll.reference_freq,
+ restore->ppll_ref_div & RADEON_PPLL_REF_DIV_MASK,
+ restore->ppll_div_3 & RADEON_PPLL_FB3_DIV_MASK);
if (info->IsMobility) {
/* A temporal workaround for the occational blanking on certain laptop panels.
@@ -4727,10 +4596,12 @@ static void RADEONRestorePLLRegisters(ScrnInfoPtr pScrn,
RADEON_PPLL_CNTL,
RADEON_PPLL_RESET
| RADEON_PPLL_ATOMIC_UPDATE_EN
- | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN,
+ | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN
+ | ((CARD32)pllGain << RADEON_PPLL_PVG_SHIFT),
~(RADEON_PPLL_RESET
| RADEON_PPLL_ATOMIC_UPDATE_EN
- | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN));
+ | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN
+ | RADEON_PPLL_PVG_MASK));
OUTREGP(RADEON_CLOCK_CNTL_INDEX,
RADEON_PLL_DIV_SEL,
@@ -4738,7 +4609,8 @@ static void RADEONRestorePLLRegisters(ScrnInfoPtr pScrn,
RADEONPllErrataAfterIndex(info);
if (IS_R300_VARIANT ||
- (info->ChipFamily == CHIP_FAMILY_RS300)) {
+ (info->ChipFamily == CHIP_FAMILY_RS300) ||
+ (info->ChipFamily == CHIP_FAMILY_RS400)) {
if (restore->ppll_ref_div & R300_PPLL_REF_DIV_ACC_MASK) {
/* When restoring console mode, use saved PPLL_REF_DIV
* setting.
@@ -4778,28 +4650,42 @@ static void RADEONRestorePLLRegisters(ScrnInfoPtr pScrn,
| RADEON_PPLL_ATOMIC_UPDATE_EN
| RADEON_PPLL_VGA_ATOMIC_UPDATE_EN));
- RADEONTRACE(("Wrote: 0x%08x 0x%08x 0x%08lx (0x%08x)\n",
- restore->ppll_ref_div,
- restore->ppll_div_3,
- restore->htotal_cntl,
- INPLL(pScrn, RADEON_PPLL_CNTL)));
- RADEONTRACE(("Wrote: rd=%d, fd=%d, pd=%d\n",
- restore->ppll_ref_div & RADEON_PPLL_REF_DIV_MASK,
- restore->ppll_div_3 & RADEON_PPLL_FB3_DIV_MASK,
- (restore->ppll_div_3 & RADEON_PPLL_POST3_DIV_MASK) >> 16));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "Wrote: 0x%08x 0x%08x 0x%08x (0x%08x)\n",
+ restore->ppll_ref_div,
+ restore->ppll_div_3,
+ (unsigned)restore->htotal_cntl,
+ INPLL(pScrn, RADEON_PPLL_CNTL));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "Wrote: rd=%d, fd=%d, pd=%d\n",
+ restore->ppll_ref_div & RADEON_PPLL_REF_DIV_MASK,
+ restore->ppll_div_3 & RADEON_PPLL_FB3_DIV_MASK,
+ (restore->ppll_div_3 & RADEON_PPLL_POST3_DIV_MASK) >> 16);
usleep(50000); /* Let the clock to lock */
- OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL,
+ /* OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL,
RADEON_VCLK_SRC_SEL_PPLLCLK,
- ~(RADEON_VCLK_SRC_SEL_MASK));
+ ~(RADEON_VCLK_SRC_SEL_MASK));*/
+ OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, restore->vclk_ecp_cntl);
+
+ ErrorF("finished PLL1\n");
+
}
/* Write PLL2 registers */
-static void RADEONRestorePLL2Registers(ScrnInfoPtr pScrn,
- RADEONSavePtr restore)
+void RADEONRestorePLL2Registers(ScrnInfoPtr pScrn,
+ RADEONSavePtr restore)
{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ CARD8 pllGain;
+
+ pllGain = RADEONComputePLLGain(info->pll.reference_freq,
+ restore->p2pll_ref_div & RADEON_P2PLL_REF_DIV_MASK,
+ restore->p2pll_div_0 & RADEON_P2PLL_FB0_DIV_MASK);
+
+
OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL,
RADEON_PIX2CLK_SRC_SEL_CPUCLK,
~(RADEON_PIX2CLK_SRC_SEL_MASK));
@@ -4808,10 +4694,11 @@ static void RADEONRestorePLL2Registers(ScrnInfoPtr pScrn,
RADEON_P2PLL_CNTL,
RADEON_P2PLL_RESET
| RADEON_P2PLL_ATOMIC_UPDATE_EN
- | RADEON_P2PLL_VGA_ATOMIC_UPDATE_EN,
+ | ((CARD32)pllGain << RADEON_P2PLL_PVG_SHIFT),
~(RADEON_P2PLL_RESET
| RADEON_P2PLL_ATOMIC_UPDATE_EN
- | RADEON_P2PLL_VGA_ATOMIC_UPDATE_EN));
+ | RADEON_P2PLL_PVG_MASK));
+
OUTPLLP(pScrn, RADEON_P2PLL_REF_DIV,
restore->p2pll_ref_div,
@@ -4834,24 +4721,30 @@ static void RADEONRestorePLL2Registers(ScrnInfoPtr pScrn,
0,
~(RADEON_P2PLL_RESET
| RADEON_P2PLL_SLEEP
- | RADEON_P2PLL_ATOMIC_UPDATE_EN
- | RADEON_P2PLL_VGA_ATOMIC_UPDATE_EN));
-
- RADEONTRACE(("Wrote: 0x%08lx 0x%08lx 0x%08lx (0x%08x)\n",
- restore->p2pll_ref_div,
- restore->p2pll_div_0,
- restore->htotal_cntl2,
- INPLL(pScrn, RADEON_P2PLL_CNTL)));
- RADEONTRACE(("Wrote: rd=%ld, fd=%ld, pd=%ld\n",
- restore->p2pll_ref_div & RADEON_P2PLL_REF_DIV_MASK,
- restore->p2pll_div_0 & RADEON_P2PLL_FB0_DIV_MASK,
- (restore->p2pll_div_0 & RADEON_P2PLL_POST0_DIV_MASK) >>16));
+ | RADEON_P2PLL_ATOMIC_UPDATE_EN));
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "Wrote2: 0x%08x 0x%08x 0x%08x (0x%08x)\n",
+ (unsigned)restore->p2pll_ref_div,
+ (unsigned)restore->p2pll_div_0,
+ (unsigned)restore->htotal_cntl2,
+ INPLL(pScrn, RADEON_P2PLL_CNTL));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "Wrote2: rd=%u, fd=%u, pd=%u\n",
+ (unsigned)restore->p2pll_ref_div & RADEON_P2PLL_REF_DIV_MASK,
+ (unsigned)restore->p2pll_div_0 & RADEON_P2PLL_FB0_DIV_MASK,
+ (unsigned)((restore->p2pll_div_0 &
+ RADEON_P2PLL_POST0_DIV_MASK) >>16));
usleep(5000); /* Let the clock to lock */
- OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL,
+ /*OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL,
RADEON_PIX2CLK_SRC_SEL_P2PLLCLK,
- ~(RADEON_PIX2CLK_SRC_SEL_MASK));
+ ~(RADEON_PIX2CLK_SRC_SEL_MASK));*/
+ OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, restore->pixclks_cntl);
+
+ ErrorF("finished PLL2\n");
+
}
@@ -5018,156 +4911,24 @@ void RADEONChangeSurfaces(ScrnInfoPtr pScrn)
unsigned int surf_info = swap_pattern;
unsigned char *RADEONMMIO = info->MMIO;
/* we don't need anything like WaitForFifo, no? */
- if (!info->IsSecondary) {
- if (info->tilingEnabled) {
- if (IS_R300_VARIANT)
- surf_info |= (width_bytes / 8) | color_pattern;
- else
- surf_info |= (width_bytes / 16) | color_pattern;
- }
- OUTREG(RADEON_SURFACE0_INFO, surf_info);
- OUTREG(RADEON_SURFACE0_LOWER_BOUND, 0);
- OUTREG(RADEON_SURFACE0_UPPER_BOUND, bufferSize - 1);
+ if (info->tilingEnabled) {
+ if (IS_R300_VARIANT)
+ surf_info |= (width_bytes / 8) | color_pattern;
+ else
+ surf_info |= (width_bytes / 16) | color_pattern;
+ }
+ OUTREG(RADEON_SURFACE0_INFO, surf_info);
+ OUTREG(RADEON_SURFACE0_LOWER_BOUND, 0);
+ OUTREG(RADEON_SURFACE0_UPPER_BOUND, bufferSize - 1);
/* xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"surface0 set to %x, LB 0x%x UB 0x%x\n",
surf_info, 0, bufferSize - 1024);*/
- }
}
/* Update surface images */
RADEONSaveSurfaces(pScrn, &info->ModeReg);
}
-#if 0
-/* Write palette data */
-static void RADEONRestorePalette(ScrnInfoPtr pScrn, RADEONSavePtr restore)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
- int i;
-
- if (!restore->palette_valid) return;
-
- PAL_SELECT(1);
- OUTPAL_START(0);
- for (i = 0; i < 256; i++) {
- RADEONWaitForFifo(pScrn, 32); /* delay */
- OUTPAL_NEXT_CARD32(restore->palette2[i]);
- }
-
- PAL_SELECT(0);
- OUTPAL_START(0);
- for (i = 0; i < 256; i++) {
- RADEONWaitForFifo(pScrn, 32); /* delay */
- OUTPAL_NEXT_CARD32(restore->palette[i]);
- }
-}
-#endif
-
-/* Write out state to define a new video mode */
-static void RADEONRestoreMode(ScrnInfoPtr pScrn, RADEONSavePtr restore)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
- RADEONController* pCRTC1 = pRADEONEnt->Controller[0];
- RADEONController* pCRTC2 = pRADEONEnt->Controller[1];
- RADEONConnector *pPort;
- RADEONTRACE(("RADEONRestoreMode(%p)\n", restore));
-
- /* For Non-dual head card, we don't have private field in the Entity */
- if (!pRADEONEnt->HasCRTC2) {
- RADEONRestoreMemMapRegisters(pScrn, restore);
- RADEONRestoreCommonRegisters(pScrn, restore);
- RADEONRestoreCrtcRegisters(pScrn, restore);
- RADEONRestoreFPRegisters(pScrn, restore);
- RADEONRestorePLLRegisters(pScrn, restore);
- return;
- }
-
- /* Disable all outputs at initial mode set. the ones we want will
- get set by RADEONEnableDisplay()
- */
- if (!info->IsSwitching && !info->IsSecondary)
- RADEONDisableDisplays(pScrn);
-
- /* When changing mode with Dual-head card, care must be taken for
- * the special order in setting registers. CRTC2 has to be set
- * before changing CRTC_EXT register. In the dual-head setup, X
- * server calls this routine twice with primary and secondary pScrn
- * pointers respectively. The calls can come with different
- * order. Regardless the order of X server issuing the calls, we
- * have to ensure we set registers in the right order!!! Otherwise
- * we may get a blank screen.
- *
- * We always restore MemMap first, the saverec should be up to date
- * in all cases
- */
- if (info->IsSwitching) {
- if (info->IsSecondary) {
- RADEONRestoreMemMapRegisters(pScrn, restore);
- RADEONRestoreCommonRegisters(pScrn, restore);
- RADEONRestoreCrtc2Registers(pScrn, restore);
- RADEONRestorePLL2Registers(pScrn, restore);
- RADEONRestoreFPRegisters(pScrn, restore);
- pPort = RADEONGetCrtcConnector(pScrn, 2);
- if (pPort) {
- RADEONEnableDisplay(pScrn, pPort, TRUE);
- pCRTC2->IsActive = TRUE;
- }
- } else {
- RADEONRestoreMemMapRegisters(pScrn, restore);
- RADEONRestoreCommonRegisters(pScrn, restore);
- if (pCRTC2->binding == 1) {
- RADEONRestoreCrtc2Registers(pScrn, restore);
- RADEONRestorePLL2Registers(pScrn, restore);
- }
-
- RADEONRestoreCrtcRegisters(pScrn, restore);
- RADEONRestorePLLRegisters(pScrn, restore);
- RADEONRestoreFPRegisters(pScrn, restore);
- pPort = RADEONGetCrtcConnector(pScrn, 1);
- if (pPort) {
- RADEONEnableDisplay(pScrn, pPort, TRUE);
- pCRTC1->IsActive = TRUE;
- }
- if (pCRTC2->binding == 1) {
- pPort = RADEONGetCrtcConnector(pScrn, 2);
- if (pPort) {
- RADEONEnableDisplay(pScrn, pPort, TRUE);
- pCRTC2->IsActive = TRUE;
- }
- }
- }
- } else {
- RADEONRestoreMemMapRegisters(pScrn, restore);
- RADEONRestoreCommonRegisters(pScrn, restore);
- if ((pCRTC2->binding == 1) || pRADEONEnt->HasSecondary) {
- RADEONRestoreCrtc2Registers(pScrn, restore);
- RADEONRestorePLL2Registers(pScrn, restore);
- }
-
- RADEONRestoreCrtcRegisters(pScrn, restore);
- RADEONRestorePLLRegisters(pScrn, restore);
- RADEONRestoreFPRegisters(pScrn, restore);
- pPort = RADEONGetCrtcConnector(pScrn, 1);
- if (pPort) {
- RADEONEnableDisplay(pScrn, pPort, TRUE);
- pCRTC1->IsActive = TRUE;
- }
- if ((pCRTC2->binding == 1) || pRADEONEnt->HasSecondary) {
- pPort = RADEONGetCrtcConnector(pScrn, 2);
- if (pPort) {
- RADEONEnableDisplay(pScrn, pPort, TRUE);
- pCRTC2->IsActive = TRUE;
- }
- }
- }
-
-#if 0
- RADEONRestorePalette(pScrn, &info->SavedReg);
-#endif
-}
-
/* Read memory map */
static void RADEONSaveMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
{
@@ -5203,29 +4964,6 @@ static void RADEONSaveCommonRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
save->grph2_buffer_cntl = INREG(RADEON_GRPH2_BUFFER_CNTL);
}
-/* Read miscellaneous registers which might be destroyed by an fbdevHW call */
-static void RADEONSaveFBDevRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
-{
-#ifdef XF86DRI
- RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
-
- /* Save register for vertical blank interrupts */
- if (info->irq) {
- save->gen_int_cntl = INREG(RADEON_GEN_INT_CNTL);
- }
-
- /* Save registers for page flipping */
- if (info->allowPageFlip) {
- save->crtc_offset_cntl = INREG(RADEON_CRTC_OFFSET_CNTL);
- if (pRADEONEnt->HasCRTC2) {
- save->crtc2_offset_cntl = INREG(RADEON_CRTC2_OFFSET_CNTL);
- }
- }
-#endif
-}
-
/* Read CRTC registers */
static void RADEONSaveCrtcRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
{
@@ -5234,7 +4972,6 @@ static void RADEONSaveCrtcRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
save->crtc_gen_cntl = INREG(RADEON_CRTC_GEN_CNTL);
save->crtc_ext_cntl = INREG(RADEON_CRTC_EXT_CNTL);
- save->dac_cntl = INREG(RADEON_DAC_CNTL);
save->crtc_h_total_disp = INREG(RADEON_CRTC_H_TOTAL_DISP);
save->crtc_h_sync_strt_wid = INREG(RADEON_CRTC_H_SYNC_STRT_WID);
save->crtc_v_total_disp = INREG(RADEON_CRTC_V_TOTAL_DISP);
@@ -5251,12 +4988,39 @@ static void RADEONSaveCrtcRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
save->disp_merge_cntl = INREG(RADEON_DISP_MERGE_CNTL);
save->crtc_more_cntl = INREG(RADEON_CRTC_MORE_CNTL);
+ if (IS_R300_VARIANT)
+ save->crtc_tile_x0_y0 = INREG(R300_CRTC_TILE_X0_Y0);
+
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);
}
+
+ /* track if the crtc is enabled for text restore */
+ if (save->crtc_ext_cntl & RADEON_CRTC_DISPLAY_DIS)
+ info->crtc_on = FALSE;
+ else
+ info->crtc_on = TRUE;
+
+}
+
+/* Read DAC registers */
+static void RADEONSaveDACRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+
+ save->dac_cntl = INREG(RADEON_DAC_CNTL);
+ save->dac2_cntl = INREG(RADEON_DAC_CNTL2);
+ save->tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
+ save->disp_output_cntl = INREG(RADEON_DISP_OUTPUT_CNTL);
+ save->disp_tv_out_cntl = INREG(RADEON_DISP_TV_OUT_CNTL);
+ save->disp_hw_debug = INREG(RADEON_DISP_HW_DEBUG);
+ save->dac_macro_cntl = INREG(RADEON_DAC_MACRO_CNTL);
+ save->gpiopad_a = INREG(RADEON_GPIOPAD_A);
+
}
/* Read flat panel registers */
@@ -5289,12 +5053,6 @@ static void RADEONSaveCrtc2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save)
RADEONInfoPtr info = RADEONPTR(pScrn);
unsigned char *RADEONMMIO = info->MMIO;
- save->dac2_cntl = INREG(RADEON_DAC_CNTL2);
- save->tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
- save->disp_output_cntl = INREG(RADEON_DISP_OUTPUT_CNTL);
- save->disp_tv_out_cntl = INREG(RADEON_DISP_TV_OUT_CNTL);
- save->disp_hw_debug = INREG (RADEON_DISP_HW_DEBUG);
-
save->crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL);
save->crtc2_h_total_disp = INREG(RADEON_CRTC2_H_TOTAL_DISP);
save->crtc2_h_sync_strt_wid = INREG(RADEON_CRTC2_H_SYNC_STRT_WID);
@@ -5304,10 +5062,120 @@ static void RADEONSaveCrtc2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save)
save->crtc2_offset_cntl = INREG(RADEON_CRTC2_OFFSET_CNTL);
save->crtc2_pitch = INREG(RADEON_CRTC2_PITCH);
+ if (IS_R300_VARIANT)
+ save->crtc2_tile_x0_y0 = INREG(R300_CRTC2_TILE_X0_Y0);
+
save->fp_h2_sync_strt_wid = INREG (RADEON_FP_H2_SYNC_STRT_WID);
save->fp_v2_sync_strt_wid = INREG (RADEON_FP_V2_SYNC_STRT_WID);
+ if (info->ChipFamily == CHIP_FAMILY_RS400) {
+ save->rs480_unk_e30 = INREG(RADEON_RS480_UNK_e30);
+ save->rs480_unk_e34 = INREG(RADEON_RS480_UNK_e34);
+ save->rs480_unk_e38 = INREG(RADEON_RS480_UNK_e38);
+ save->rs480_unk_e3c = INREG(RADEON_RS480_UNK_e3c);
+ }
+
save->disp2_merge_cntl = INREG(RADEON_DISP2_MERGE_CNTL);
+
+ /* track if the crtc is enabled for text restore */
+ if (save->crtc2_gen_cntl & RADEON_CRTC2_DISP_DIS)
+ info->crtc2_on = FALSE;
+ else
+ info->crtc2_on = TRUE;
+
+}
+
+/* Save horizontal/vertical timing code tables */
+static void RADEONSaveTVTimingTables(ScrnInfoPtr pScrn, RADEONSavePtr save)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ CARD16 hTable;
+ CARD16 vTable;
+ CARD32 tmp;
+ unsigned i;
+
+ save->tv_uv_adr = INREG(RADEON_TV_UV_ADR);
+ hTable = RADEONGetHTimingTablesAddr(save->tv_uv_adr);
+ vTable = RADEONGetVTimingTablesAddr(save->tv_uv_adr);
+
+ /*
+ * Reset FIFO arbiter in order to be able to access FIFO RAM
+ */
+
+ OUTREG(RADEON_TV_MASTER_CNTL, (RADEON_TV_ASYNC_RST
+ | RADEON_CRT_ASYNC_RST
+ | RADEON_RESTART_PHASE_FIX
+ | RADEON_CRT_FIFO_CE_EN
+ | RADEON_TV_FIFO_CE_EN
+ | RADEON_TV_ON));
+
+ /*OUTREG(RADEON_TV_MASTER_CNTL, save->tv_master_cntl | RADEON_TV_ON);*/
+
+ ErrorF("saveTimingTables: reading timing tables\n");
+
+ for (i = 0; i < MAX_H_CODE_TIMING_LEN; i += 2) {
+ tmp = RADEONReadTVFIFO(pScrn, hTable--);
+ save->h_code_timing[ i ] = (CARD16)((tmp >> 14) & 0x3fff);
+ save->h_code_timing[ i + 1 ] = (CARD16)(tmp & 0x3fff);
+
+ if (save->h_code_timing[ i ] == 0 || save->h_code_timing[ i + 1 ] == 0)
+ break;
+ }
+
+ for (i = 0; i < MAX_V_CODE_TIMING_LEN; i += 2) {
+ tmp = RADEONReadTVFIFO(pScrn, vTable++);
+ save->v_code_timing[ i ] = (CARD16)(tmp & 0x3fff);
+ save->v_code_timing[ i + 1 ] = (CARD16)((tmp >> 14) & 0x3fff);
+
+ if (save->v_code_timing[ i ] == 0 || save->v_code_timing[ i + 1 ] == 0)
+ break;
+ }
+}
+
+/* read TV regs */
+static void RADEONSaveTVRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+
+ ErrorF("Entering TV Save\n");
+
+ save->tv_crc_cntl = INREG(RADEON_TV_CRC_CNTL);
+ save->tv_frestart = INREG(RADEON_TV_FRESTART);
+ save->tv_hrestart = INREG(RADEON_TV_HRESTART);
+ save->tv_vrestart = INREG(RADEON_TV_VRESTART);
+ save->tv_gain_limit_settings = INREG(RADEON_TV_GAIN_LIMIT_SETTINGS);
+ save->tv_hdisp = INREG(RADEON_TV_HDISP);
+ save->tv_hstart = INREG(RADEON_TV_HSTART);
+ save->tv_htotal = INREG(RADEON_TV_HTOTAL);
+ save->tv_linear_gain_settings = INREG(RADEON_TV_LINEAR_GAIN_SETTINGS);
+ save->tv_master_cntl = INREG(RADEON_TV_MASTER_CNTL);
+ save->tv_rgb_cntl = INREG(RADEON_TV_RGB_CNTL);
+ save->tv_modulator_cntl1 = INREG(RADEON_TV_MODULATOR_CNTL1);
+ save->tv_modulator_cntl2 = INREG(RADEON_TV_MODULATOR_CNTL2);
+ save->tv_pre_dac_mux_cntl = INREG(RADEON_TV_PRE_DAC_MUX_CNTL);
+ save->tv_sync_cntl = INREG(RADEON_TV_SYNC_CNTL);
+ save->tv_timing_cntl = INREG(RADEON_TV_TIMING_CNTL);
+ save->tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
+ save->tv_upsamp_and_gain_cntl = INREG(RADEON_TV_UPSAMP_AND_GAIN_CNTL);
+ save->tv_vdisp = INREG(RADEON_TV_VDISP);
+ save->tv_ftotal = INREG(RADEON_TV_FTOTAL);
+ save->tv_vscaler_cntl1 = INREG(RADEON_TV_VSCALER_CNTL1);
+ save->tv_vscaler_cntl2 = INREG(RADEON_TV_VSCALER_CNTL2);
+ save->tv_vtotal = INREG(RADEON_TV_VTOTAL);
+ save->tv_y_fall_cntl = INREG(RADEON_TV_Y_FALL_CNTL);
+ save->tv_y_rise_cntl = INREG(RADEON_TV_Y_RISE_CNTL);
+ save->tv_y_saw_tooth_cntl = INREG(RADEON_TV_Y_SAW_TOOTH_CNTL);
+
+ save->tv_pll_cntl = INPLL(pScrn, RADEON_TV_PLL_CNTL);
+ save->tv_pll_cntl1 = INPLL(pScrn, RADEON_TV_PLL_CNTL1);
+
+ ErrorF("Save TV timing tables\n");
+
+ RADEONSaveTVTimingTables(pScrn, save);
+
+ ErrorF("TV Save done\n");
}
/* Read PLL registers */
@@ -5316,16 +5184,18 @@ static void RADEONSavePLLRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
save->ppll_ref_div = INPLL(pScrn, RADEON_PPLL_REF_DIV);
save->ppll_div_3 = INPLL(pScrn, RADEON_PPLL_DIV_3);
save->htotal_cntl = INPLL(pScrn, RADEON_HTOTAL_CNTL);
- save->vclk_cntl = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
-
- RADEONTRACE(("Read: 0x%08x 0x%08x 0x%08lx\n",
- save->ppll_ref_div,
- save->ppll_div_3,
- save->htotal_cntl));
- RADEONTRACE(("Read: rd=%d, fd=%d, pd=%d\n",
- save->ppll_ref_div & RADEON_PPLL_REF_DIV_MASK,
- save->ppll_div_3 & RADEON_PPLL_FB3_DIV_MASK,
- (save->ppll_div_3 & RADEON_PPLL_POST3_DIV_MASK) >> 16));
+ save->vclk_ecp_cntl = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "Read: 0x%08x 0x%08x 0x%08x\n",
+ save->ppll_ref_div,
+ save->ppll_div_3,
+ (unsigned)save->htotal_cntl);
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "Read: rd=%d, fd=%d, pd=%d\n",
+ save->ppll_ref_div & RADEON_PPLL_REF_DIV_MASK,
+ save->ppll_div_3 & RADEON_PPLL_FB3_DIV_MASK,
+ (save->ppll_div_3 & RADEON_PPLL_POST3_DIV_MASK) >> 16);
}
/* Read PLL registers */
@@ -5336,14 +5206,17 @@ static void RADEONSavePLL2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save)
save->htotal_cntl2 = INPLL(pScrn, RADEON_HTOTAL2_CNTL);
save->pixclks_cntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
- RADEONTRACE(("Read: 0x%08lx 0x%08lx 0x%08lx\n",
- save->p2pll_ref_div,
- save->p2pll_div_0,
- save->htotal_cntl2));
- RADEONTRACE(("Read: rd=%ld, fd=%ld, pd=%ld\n",
- save->p2pll_ref_div & RADEON_P2PLL_REF_DIV_MASK,
- save->p2pll_div_0 & RADEON_P2PLL_FB0_DIV_MASK,
- (save->p2pll_div_0 & RADEON_P2PLL_POST0_DIV_MASK) >> 16));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "Read: 0x%08x 0x%08x 0x%08x\n",
+ (unsigned)save->p2pll_ref_div,
+ (unsigned)save->p2pll_div_0,
+ (unsigned)save->htotal_cntl2);
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "Read: rd=%u, fd=%u, pd=%u\n",
+ (unsigned)(save->p2pll_ref_div & RADEON_P2PLL_REF_DIV_MASK),
+ (unsigned)(save->p2pll_div_0 & RADEON_P2PLL_FB0_DIV_MASK),
+ (unsigned)((save->p2pll_div_0 & RADEON_P2PLL_POST0_DIV_MASK)
+ >> 16));
}
/* Read palette data */
@@ -5369,27 +5242,25 @@ static void RADEONSavePalette(ScrnInfoPtr pScrn, RADEONSavePtr save)
/* Save state that defines current video mode */
static void RADEONSaveMode(ScrnInfoPtr pScrn, RADEONSavePtr save)
{
- RADEONInfoPtr info = RADEONPTR(pScrn);
-
- RADEONTRACE(("RADEONSaveMode(%p)\n", save));
+ RADEONInfoPtr info = RADEONPTR(pScrn);
- if (info->IsSecondary) {
- RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
- RADEONInfoPtr info0 = RADEONPTR(pRADEONEnt->pPrimaryScrn);
- memcpy(&info->SavedReg, &info0->SavedReg, sizeof(RADEONSaveRec));
- } else {
- RADEONSaveMemMapRegisters(pScrn, save);
- RADEONSaveCommonRegisters(pScrn, save);
- RADEONSavePLLRegisters (pScrn, save);
- RADEONSaveCrtcRegisters (pScrn, save);
- RADEONSaveFPRegisters (pScrn, save);
- RADEONSaveCrtc2Registers (pScrn, save);
- RADEONSavePLL2Registers (pScrn, save);
- /*RADEONSavePalette(pScrn, save);*/
- /*memcpy(&info->ModeReg, &info->SavedReg, sizeof(RADEONSaveRec));*/
- }
-
- RADEONTRACE(("RADEONSaveMode returns %p\n", save));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "RADEONSaveMode(%p)\n", save);
+
+ RADEONSaveMemMapRegisters(pScrn, save);
+ RADEONSaveCommonRegisters(pScrn, save);
+ RADEONSavePLLRegisters(pScrn, save);
+ RADEONSaveCrtcRegisters(pScrn, save);
+ RADEONSaveFPRegisters(pScrn, save);
+ RADEONSaveDACRegisters(pScrn, save);
+ RADEONSaveCrtc2Registers(pScrn, save);
+ RADEONSavePLL2Registers(pScrn, save);
+ if (info->InternalTVOut)
+ RADEONSaveTVRegisters(pScrn, save);
+ /*RADEONSavePalette(pScrn, save);*/
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "RADEONSaveMode returns %p\n", save);
}
/* Save everything needed to restore the original VC state */
@@ -5399,62 +5270,55 @@ static void RADEONSave(ScrnInfoPtr pScrn)
unsigned char *RADEONMMIO = info->MMIO;
RADEONSavePtr save = &info->SavedReg;
- RADEONTRACE(("RADEONSave\n"));
- if (info->FBDev) {
- RADEONSaveMemMapRegisters(pScrn, save);
- fbdevHWSave(pScrn);
- return;
- }
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "RADEONSave\n");
- if (!info->IsSecondary) {
#ifdef WITH_VGAHW
- if (info->VGAAccess) {
- vgaHWPtr hwp = VGAHWPTR(pScrn);
+ if (info->VGAAccess) {
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
- vgaHWUnlock(hwp);
+ vgaHWUnlock(hwp);
# if defined(__powerpc__)
- /* temporary hack to prevent crashing on PowerMacs when trying to
- * read VGA fonts and colormap, will find a better solution
- * in the future. TODO: Check if there's actually some VGA stuff
- * setup in the card at all !!
- */
- vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_MODE); /* Save mode only */
+ /* temporary hack to prevent crashing on PowerMacs when trying to
+ * read VGA fonts and colormap, will find a better solution
+ * in the future. TODO: Check if there's actually some VGA stuff
+ * setup in the card at all !!
+ */
+ vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_MODE); /* Save mode only */
# else
- /* Save mode * & fonts & cmap */
- vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_MODE | VGA_SR_FONTS);
+ /* Save mode * & fonts & cmap */
+ vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_MODE | VGA_SR_FONTS);
# endif
- vgaHWLock(hwp);
- }
-#endif
- save->dp_datatype = INREG(RADEON_DP_DATATYPE);
- save->rbbm_soft_reset = INREG(RADEON_RBBM_SOFT_RESET);
- save->clock_cntl_index = INREG(RADEON_CLOCK_CNTL_INDEX);
- RADEONPllErrataAfterIndex(info);
+ vgaHWLock(hwp);
}
+#endif
+ save->dp_datatype = INREG(RADEON_DP_DATATYPE);
+ save->rbbm_soft_reset = INREG(RADEON_RBBM_SOFT_RESET);
+ save->clock_cntl_index = INREG(RADEON_CLOCK_CNTL_INDEX);
+ RADEONPllErrataAfterIndex(info);
RADEONSaveMode(pScrn, save);
- if (!info->IsSecondary)
- RADEONSaveSurfaces(pScrn, save);
+ RADEONSaveSurfaces(pScrn, save);
}
/* Restore the original (text) mode */
-static void RADEONRestore(ScrnInfoPtr pScrn)
+void RADEONRestore(ScrnInfoPtr pScrn)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
unsigned char *RADEONMMIO = info->MMIO;
RADEONSavePtr restore = &info->SavedReg;
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ xf86CrtcPtr crtc;
- RADEONTRACE(("RADEONRestore\n"));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "RADEONRestore\n");
#if X_BYTE_ORDER == X_BIG_ENDIAN
RADEONWaitForFifo(pScrn, 1);
OUTREG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_NONE);
#endif
- if (info->FBDev) {
- fbdevHWRestore(pScrn);
- return;
- }
RADEONBlank(pScrn);
OUTREG(RADEON_CLOCK_CNTL_INDEX, restore->clock_cntl_index);
@@ -5473,11 +5337,27 @@ static void RADEONRestore(ScrnInfoPtr pScrn)
OUTREG(RADEON_DAC_CNTL2, restore->dac2_cntl);
#endif
- RADEONRestoreMode(pScrn, restore);
- if (!info->IsSecondary)
- RADEONRestoreSurfaces(pScrn, restore);
+ RADEONRestoreMemMapRegisters(pScrn, restore);
+ RADEONRestoreCommonRegisters(pScrn, restore);
-#if 0
+ if (pRADEONEnt->HasCRTC2) {
+ RADEONRestoreCrtc2Registers(pScrn, restore);
+ RADEONRestorePLL2Registers(pScrn, restore);
+ }
+
+ RADEONRestoreCrtcRegisters(pScrn, restore);
+ RADEONRestorePLLRegisters(pScrn, restore);
+ RADEONRestoreRMXRegisters(pScrn, restore);
+ RADEONRestoreFPRegisters(pScrn, restore);
+ RADEONRestoreFP2Registers(pScrn, restore);
+ RADEONRestoreLVDSRegisters(pScrn, restore);
+
+ if (info->InternalTVOut)
+ RADEONRestoreTVRegisters(pScrn, restore);
+
+ RADEONRestoreSurfaces(pScrn, restore);
+
+#if 1
/* Temp fix to "solve" VT switch problems. When switching VTs on
* some systems, the console can either hang or the fonts can be
* corrupted. This hack solves the problem 99% of the time. A
@@ -5489,830 +5369,36 @@ static void RADEONRestore(ScrnInfoPtr pScrn)
#ifdef WITH_VGAHW
if (info->VGAAccess) {
vgaHWPtr hwp = VGAHWPTR(pScrn);
- if (!info->IsSecondary) {
- vgaHWUnlock(hwp);
+ vgaHWUnlock(hwp);
# if defined(__powerpc__)
- /* Temporary hack to prevent crashing on PowerMacs when trying to
- * write VGA fonts, will find a better solution in the future
- */
- vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE );
+ /* Temporary hack to prevent crashing on PowerMacs when trying to
+ * write VGA fonts, will find a better solution in the future
+ */
+ vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE );
# else
- vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE | VGA_SR_FONTS );
+ vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE | VGA_SR_FONTS );
# endif
- vgaHWLock(hwp);
- } else {
- RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
- ScrnInfoPtr pScrn0 = pRADEONEnt->pPrimaryScrn;
- RADEONInfoPtr info0 = RADEONPTR(pScrn0);
- vgaHWPtr hwp0;
-
- if (info0->VGAAccess) {
- hwp0 = VGAHWPTR(pScrn0);
- vgaHWUnlock(hwp0);
-#if defined(__powerpc__)
- vgaHWRestore(pScrn0, &hwp0->SavedReg, VGA_SR_MODE);
-#else
- vgaHWRestore(pScrn0, &hwp0->SavedReg, VGA_SR_MODE | VGA_SR_FONTS );
-#endif
- vgaHWLock(hwp0);
- }
- }
- }
-#endif
- RADEONUnblank(pScrn);
-
-#if 0
- RADEONWaitForVerticalSync(pScrn);
-#endif
-}
-
-/* Define common registers for requested video mode */
-static void RADEONInitCommonRegisters(RADEONSavePtr save, RADEONInfoPtr info)
-{
- save->ovr_clr = 0;
- save->ovr_wid_left_right = 0;
- save->ovr_wid_top_bottom = 0;
- save->ov0_scale_cntl = 0;
- save->subpic_cntl = 0;
- save->viph_control = 0;
- save->i2c_cntl_1 = 0;
- save->rbbm_soft_reset = 0;
- save->cap0_trig_cntl = 0;
- save->cap1_trig_cntl = 0;
- save->bus_cntl = info->BusCntl;
- /*
- * If bursts are enabled, turn on discards
- * Radeon doesn't have write bursts
- */
- if (save->bus_cntl & (RADEON_BUS_READ_BURST))
- save->bus_cntl |= RADEON_BUS_RD_DISCARD_EN;
-}
-
-/* XXX: fix me */
-static void RADEONInitTvDacCntl(ScrnInfoPtr pScrn, RADEONSavePtr save)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- if (info->ChipFamily == CHIP_FAMILY_R420 ||
- info->ChipFamily == CHIP_FAMILY_RV410) {
- save->tv_dac_cntl = info->SavedReg.tv_dac_cntl &
- ~(RADEON_TV_DAC_STD_MASK |
- RADEON_TV_DAC_BGADJ_MASK |
- R420_TV_DAC_DACADJ_MASK |
- R420_TV_DAC_RDACPD |
- R420_TV_DAC_GDACPD |
- R420_TV_DAC_GDACPD |
- R420_TV_DAC_TVENABLE);
- } else {
- save->tv_dac_cntl = info->SavedReg.tv_dac_cntl &
- ~(RADEON_TV_DAC_STD_MASK |
- RADEON_TV_DAC_BGADJ_MASK |
- RADEON_TV_DAC_DACADJ_MASK |
- RADEON_TV_DAC_RDACPD |
- RADEON_TV_DAC_GDACPD |
- RADEON_TV_DAC_GDACPD);
- }
- /* FIXME: doesn't make sense, this just replaces the previous value... */
- save->tv_dac_cntl = (RADEON_TV_DAC_NBLANK |
- RADEON_TV_DAC_NHOLD |
- RADEON_TV_DAC_STD_PS2 |
- info->tv_dac_adj);
-}
-
-static void RADEONInitFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save,
- DisplayModePtr mode, BOOL IsPrimary)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
- int i;
- CARD32 tmp = info->SavedReg.tmds_pll_cntl & 0xfffff;
-
- for (i=0; i<4; i++) {
- if (info->tmds_pll[i].freq == 0) break;
- if ((CARD32)(mode->Clock/10) < info->tmds_pll[i].freq) {
- tmp = info->tmds_pll[i].value ;
- break;
- }
- }
-
- if (IS_R300_VARIANT || (info->ChipFamily == CHIP_FAMILY_RV280)) {
- if (tmp & 0xfff00000)
- save->tmds_pll_cntl = tmp;
- else {
- save->tmds_pll_cntl = info->SavedReg.tmds_pll_cntl & 0xfff00000;
- save->tmds_pll_cntl |= tmp;
- }
- } else save->tmds_pll_cntl = tmp;
-
- save->tmds_transmitter_cntl = info->SavedReg.tmds_transmitter_cntl &
- ~(RADEON_TMDS_TRANSMITTER_PLLRST);
-
- if (IS_R300_VARIANT || (info->ChipFamily == CHIP_FAMILY_R200) || !pRADEONEnt->HasCRTC2)
- save->tmds_transmitter_cntl &= ~(RADEON_TMDS_TRANSMITTER_PLLEN);
- else /* weird, RV chips got this bit reversed? */
- save->tmds_transmitter_cntl |= (RADEON_TMDS_TRANSMITTER_PLLEN);
-
- save->fp_gen_cntl = info->SavedReg.fp_gen_cntl |
- (RADEON_FP_CRTC_DONT_SHADOW_VPAR |
- RADEON_FP_CRTC_DONT_SHADOW_HEND );
-
- if (pScrn->rgbBits == 8)
- save->fp_gen_cntl |= RADEON_FP_PANEL_FORMAT; /* 24 bit format */
- else
- save->fp_gen_cntl &= ~RADEON_FP_PANEL_FORMAT;/* 18 bit format */
-
-
- if (IsPrimary) {
- 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;
- } else {
- if ((IS_R300_VARIANT) || (info->ChipFamily == CHIP_FAMILY_R200)) {
- save->fp_gen_cntl &= ~R200_FP_SOURCE_SEL_MASK;
- save->fp_gen_cntl |= R200_FP_SOURCE_SEL_CRTC2;
- } else
- save->fp_gen_cntl |= RADEON_FP_SEL_CRTC2;
- }
-
-}
-
-static void RADEONInitFP2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save,
- DisplayModePtr mode, BOOL IsPrimary)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
-
- if (pScrn->rgbBits == 8)
- save->fp2_gen_cntl = info->SavedReg.fp2_gen_cntl |
- RADEON_FP2_PANEL_FORMAT; /* 24 bit format, */
- else
- save->fp2_gen_cntl = info->SavedReg.fp2_gen_cntl &
- ~RADEON_FP2_PANEL_FORMAT;/* 18 bit format, */
-
- if (IsPrimary) {
- if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) {
- save->fp2_gen_cntl &= ~(R200_FP2_SOURCE_SEL_MASK |
- RADEON_FP2_DVO_EN |
- RADEON_FP2_DVO_RATE_SEL_SDR);
- if (mode->Flags & RADEON_USE_RMX)
- save->fp2_gen_cntl |= R200_FP2_SOURCE_SEL_RMX;
- } else {
- save->fp2_gen_cntl &= ~(RADEON_FP2_SRC_SEL_CRTC2 |
- RADEON_FP2_DVO_RATE_SEL_SDR);
- }
- /*save->fp2_gen_cntl |= ( RADEON_FP2_ON |
- RADEON_FP2_BLANK_EN |
- RADEON_FP2_DVO_EN);*/
- } else {
- if ((info->ChipFamily == CHIP_FAMILY_R200) || 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_PANEL_FORMAT |
- RADEON_FP2_BLANK_EN |
- RADEON_FP2_ON |
- RADEON_FP2_DVO_EN*/);
- } else {
- save->fp2_gen_cntl &= ~(RADEON_FP2_DVO_RATE_SEL_SDR);
- save->fp2_gen_cntl |= (RADEON_FP2_SRC_SEL_CRTC2 /*|
- RADEON_FP2_PANEL_FORMAT |
- RADEON_FP2_BLANK_EN |
- RADEON_FP2_ON |
- RADEON_FP2_DVO_EN*/);
- }
- }
-
-}
-
-static void RADEONInitLVDSRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save,
- DisplayModePtr mode, BOOL IsPrimary)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
-/* XXX saved but never used??? */
- if (IsPrimary)
- save->lvds_gen_cntl = info->SavedReg.lvds_gen_cntl &
- ~RADEON_LVDS_SEL_CRTC2;
- else
- save->lvds_gen_cntl = info->SavedReg.lvds_gen_cntl |
- RADEON_LVDS_SEL_CRTC2;
-
-}
-
-static void RADEONInitRMXRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save,
- DisplayModePtr mode)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- int xres = mode->HDisplay;
- int yres = mode->VDisplay;
- float Hratio, Vratio;
-
-
- if (info->PanelXRes == 0 || info->PanelYRes == 0) {
- Hratio = 1.0;
- Vratio = 1.0;
- } else {
- if (xres > info->PanelXRes) xres = info->PanelXRes;
- if (yres > info->PanelYRes) yres = info->PanelYRes;
-
- Hratio = (float)xres/(float)info->PanelXRes;
- Vratio = (float)yres/(float)info->PanelYRes;
- }
-
- save->fp_vert_stretch = info->SavedReg.fp_vert_stretch &
- RADEON_VERT_STRETCH_RESERVED;
- save->fp_horz_stretch = info->SavedReg.fp_horz_stretch &
- (RADEON_HORZ_FP_LOOP_STRETCH |
- RADEON_HORZ_AUTO_RATIO_INC);
-
- if (Hratio == 1.0 || !(mode->Flags & RADEON_USE_RMX)) {
- save->fp_horz_stretch |= ((xres/8-1)<<16);
- } else {
- save->fp_horz_stretch |= ((((unsigned long)(Hratio * RADEON_HORZ_STRETCH_RATIO_MAX +
- 0.5)) & RADEON_HORZ_STRETCH_RATIO_MASK) |
- RADEON_HORZ_STRETCH_BLEND |
- RADEON_HORZ_STRETCH_ENABLE |
- ((info->PanelXRes/8-1)<<16));
- }
-
- if (Vratio == 1.0 || !(mode->Flags & RADEON_USE_RMX)) {
- save->fp_vert_stretch |= ((yres-1)<<12);
- } else {
- save->fp_vert_stretch |= ((((unsigned long)(Vratio * RADEON_VERT_STRETCH_RATIO_MAX +
- 0.5)) & RADEON_VERT_STRETCH_RATIO_MASK) |
- RADEON_VERT_STRETCH_ENABLE |
- RADEON_VERT_STRETCH_BLEND |
- ((info->PanelYRes-1)<<12));
- }
-
-}
-
-static void RADEONInitDACRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save,
- DisplayModePtr mode, BOOL IsPrimary)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
-
- if (IsPrimary) {
- if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) {
- save->disp_output_cntl = info->SavedReg.disp_output_cntl &
- ~RADEON_DISP_DAC_SOURCE_MASK;
- } else {
- save->dac2_cntl = info->SavedReg.dac2_cntl & ~(RADEON_DAC2_DAC_CLK_SEL);
- }
- save->dac_cntl = (RADEON_DAC_MASK_ALL
- | RADEON_DAC_VGA_ADR_EN
- | (info->dac6bits ? 0 : RADEON_DAC_8BIT_EN));
-
- } else {
- if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) {
- save->disp_output_cntl = info->SavedReg.disp_output_cntl &
- ~RADEON_DISP_DAC_SOURCE_MASK;
- save->disp_output_cntl |= RADEON_DISP_DAC_SOURCE_CRTC2;
- } else {
- save->dac2_cntl = info->SavedReg.dac2_cntl | RADEON_DAC2_DAC_CLK_SEL;
- }
- }
-}
-
-static void RADEONInitDAC2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save,
- DisplayModePtr mode, BOOL IsPrimary)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
-
- /*0x0028023;*/
- RADEONInitTvDacCntl(pScrn, save);
-
- if (IsPrimary) {
- /*save->crtc2_gen_cntl = info->SavedReg.crtc2_gen_cntl | RADEON_CRTC2_CRT2_ON;*/
- save->dac2_cntl = info->SavedReg.dac2_cntl | RADEON_DAC2_DAC2_CLK_SEL;
- if (IS_R300_VARIANT) {
- save->disp_output_cntl = info->SavedReg.disp_output_cntl &
- ~RADEON_DISP_TVDAC_SOURCE_MASK;
- save->disp_output_cntl |= RADEON_DISP_TVDAC_SOURCE_CRTC;
- } else if (info->ChipFamily == CHIP_FAMILY_R200) {
- save->fp2_gen_cntl = info->SavedReg.fp2_gen_cntl &
- ~(R200_FP2_SOURCE_SEL_MASK |
- RADEON_FP2_DVO_RATE_SEL_SDR);
- /*save->fp2_gen_cntl = info->SavedReg.fp2_gen_cntl |
- (RADEON_FP2_ON |
- RADEON_FP2_BLANK_EN |
- RADEON_FP2_DVO_EN);*/
- } else {
- save->disp_hw_debug = info->SavedReg.disp_hw_debug | RADEON_CRT2_DISP1_SEL;
- }
- } else {
- save->dac2_cntl = info->SavedReg.dac2_cntl | RADEON_DAC2_DAC2_CLK_SEL;
- if (IS_R300_VARIANT) {
- save->dac2_cntl = info->SavedReg.dac2_cntl | RADEON_DAC2_DAC2_CLK_SEL;
- save->disp_output_cntl = info->SavedReg.disp_output_cntl &
- ~RADEON_DISP_TVDAC_SOURCE_MASK;
- save->disp_output_cntl |= RADEON_DISP_TVDAC_SOURCE_CRTC2;
- } else if (info->ChipFamily == CHIP_FAMILY_R200) {
- save->fp2_gen_cntl = info->SavedReg.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_BLANK_EN |
- RADEON_FP2_ON |
- RADEON_FP2_DVO_EN*/);
- /*save->fp_h2_sync_strt_wid = save->crtc2_h_sync_strt_wid;
- save->fp_v2_sync_strt_wid = save->crtc2_v_sync_strt_wid;*/
- } else {
- save->dac2_cntl = info->SavedReg.dac2_cntl | RADEON_DAC2_DAC2_CLK_SEL;
- save->disp_hw_debug = info->SavedReg.disp_hw_debug &
- ~RADEON_CRT2_DISP1_SEL;
- }
- }
-}
-
-static void RADEONInitOutputRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, DisplayModePtr mode, RADEONConnector *pPort, int crtc_num)
-{
- Bool IsPrimary = crtc_num == 1 ? TRUE : FALSE;
-
- if (pPort->MonType == MT_CRT) {
- if (pPort->DACType == DAC_PRIMARY) {
- RADEONInitDACRegisters(pScrn, save, mode, IsPrimary);
- } else {
- RADEONInitDAC2Registers(pScrn, save, mode, IsPrimary);
- }
- } else if (pPort->MonType == MT_LCD) {
- if (crtc_num == 1)
- RADEONInitRMXRegisters(pScrn, save, mode);
- RADEONInitLVDSRegisters(pScrn, save, mode, IsPrimary);
- } else if (pPort->MonType == MT_DFP) {
- if (crtc_num == 1)
- RADEONInitRMXRegisters(pScrn, save, mode);
- if (pPort->TMDSType == TMDS_INT) {
- RADEONInitFPRegisters(pScrn, save, mode, IsPrimary);
- } else {
- RADEONInitFP2Registers(pScrn, save, mode, IsPrimary);
- }
- }
-}
-
-/* Define CRTC registers for requested video mode */
-static Bool RADEONInitCrtcRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save,
- DisplayModePtr mode, RADEONInfoPtr info)
-{
- int format;
- int hsync_start;
- int hsync_wid;
- int vsync_wid;
- RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
-
- pRADEONEnt->Controller[0]->IsUsed = TRUE;
- pRADEONEnt->Controller[0]->IsActive = TRUE;
- pRADEONEnt->Controller[0]->pCurMode = mode;
-
- switch (info->CurrentLayout.pixel_code) {
- case 4: format = 1; break;
- case 8: format = 2; break;
- case 15: format = 3; break; /* 555 */
- case 16: format = 4; break; /* 565 */
- case 24: format = 5; break; /* RGB */
- case 32: format = 6; break; /* xRGB */
- default:
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Unsupported pixel depth (%d)\n",
- info->CurrentLayout.bitsPerPixel);
- return FALSE;
- }
-
- save->bios_4_scratch = info->SavedReg.bios_4_scratch;
- save->crtc_gen_cntl = (RADEON_CRTC_EXT_DISP_EN
- | RADEON_CRTC_EN
- | (format << 8)
- | ((mode->Flags & V_DBLSCAN)
- ? RADEON_CRTC_DBL_SCAN_EN
- : 0)
- | ((mode->Flags & V_CSYNC)
- ? RADEON_CRTC_CSYNC_EN
- : 0)
- | ((mode->Flags & V_INTERLACE)
- ? RADEON_CRTC_INTERLACE_EN
- : 0));
-
- save->crtc_ext_cntl |= (RADEON_CRTC_CRT_ON |
- RADEON_CRTC_VSYNC_DIS |
- RADEON_CRTC_HSYNC_DIS |
- RADEON_CRTC_DISPLAY_DIS);
-
- save->surface_cntl = 0;
- save->disp_merge_cntl = info->SavedReg.disp_merge_cntl;
- save->disp_merge_cntl &= ~RADEON_DISP_RGB_OFFSET_EN;
-
-#if X_BYTE_ORDER == X_BIG_ENDIAN
- /* We must set both apertures as they can be both used to map the entire
- * video memory. -BenH.
- */
- switch (pScrn->bitsPerPixel) {
- case 16:
- save->surface_cntl |= RADEON_NONSURF_AP0_SWP_16BPP;
- save->surface_cntl |= RADEON_NONSURF_AP1_SWP_16BPP;
- break;
-
- case 32:
- save->surface_cntl |= RADEON_NONSURF_AP0_SWP_32BPP;
- save->surface_cntl |= RADEON_NONSURF_AP1_SWP_32BPP;
- break;
+ vgaHWLock(hwp);
}
#endif
- 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;
+ /* need to make sure we don't enable a crtc by accident or we may get a hang */
+ if (info->crtc2_on) {
+ crtc = xf86_config->crtc[1];
+ crtc->funcs->dpms(crtc, DPMSModeOn);
}
-
- if (mode->Flags & RADEON_USE_RMX) {
- mode->CrtcHTotal = mode->CrtcHDisplay + info->HBlank;
- mode->CrtcHSyncStart = mode->CrtcHDisplay + info->HOverPlus;
- mode->CrtcHSyncEnd = mode->CrtcHSyncStart + info->HSyncWidth;
- mode->CrtcVTotal = mode->CrtcVDisplay + info->VBlank;
- mode->CrtcVSyncStart = mode->CrtcVDisplay + info->VOverPlus;
- mode->CrtcVSyncEnd = mode->CrtcVSyncStart + info->VSyncWidth;
- mode->Clock = info->DotClock;
- mode->Flags = info->Flags | RADEON_USE_RMX;
+ if (info->crtc_on) {
+ crtc = xf86_config->crtc[0];
+ crtc->funcs->dpms(crtc, DPMSModeOn);
}
-
-
-
- save->crtc_h_total_disp = ((((mode->CrtcHTotal / 8) - 1) & 0x3ff)
- | ((((mode->CrtcHDisplay / 8) - 1) & 0x1ff)
- << 16));
-
- hsync_wid = (mode->CrtcHSyncEnd - mode->CrtcHSyncStart) / 8;
- if (!hsync_wid) hsync_wid = 1;
- if (hsync_wid > 0x3f) hsync_wid = 0x3f;
- hsync_start = mode->CrtcHSyncStart - 8;
-
- save->crtc_h_sync_strt_wid = ((hsync_start & 0x1fff)
- | (hsync_wid << 16)
- | ((mode->Flags & V_NHSYNC)
- ? RADEON_CRTC_H_SYNC_POL
- : 0));
-
- /* This works for double scan mode. */
- save->crtc_v_total_disp = (((mode->CrtcVTotal - 1) & 0xffff)
- | ((mode->CrtcVDisplay - 1) << 16));
-
- vsync_wid = mode->CrtcVSyncEnd - mode->CrtcVSyncStart;
- if (!vsync_wid) vsync_wid = 1;
- if (vsync_wid > 0x1f) vsync_wid = 0x1f;
-
- save->crtc_v_sync_strt_wid = (((mode->CrtcVSyncStart - 1) & 0xfff)
- | (vsync_wid << 16)
- | ((mode->Flags & V_NVSYNC)
- ? RADEON_CRTC_V_SYNC_POL
- : 0));
-
- save->crtc_offset = pScrn->fbOffset;
- if (info->tilingEnabled) {
- if (IS_R300_VARIANT)
- save->crtc_offset_cntl |= (R300_CRTC_X_Y_MODE_EN |
- R300_CRTC_MICRO_TILE_BUFFER_DIS |
- R300_CRTC_MACRO_TILE_EN);
- else
- save->crtc_offset_cntl |= RADEON_CRTC_TILE_EN;
- }
- else {
- if (IS_R300_VARIANT)
- save->crtc_offset_cntl &= ~(R300_CRTC_X_Y_MODE_EN |
- R300_CRTC_MICRO_TILE_BUFFER_DIS |
- R300_CRTC_MACRO_TILE_EN);
- else
- save->crtc_offset_cntl &= ~RADEON_CRTC_TILE_EN;
- }
-
- save->crtc_pitch = (((pScrn->displayWidth * pScrn->bitsPerPixel) +
- ((pScrn->bitsPerPixel * 8) -1)) /
- (pScrn->bitsPerPixel * 8));
- save->crtc_pitch |= save->crtc_pitch << 16;
-
- save->fp_h_sync_strt_wid = save->crtc_h_sync_strt_wid;
- save->fp_v_sync_strt_wid = save->crtc_v_sync_strt_wid;
- save->fp_crtc_h_total_disp = save->crtc_h_total_disp;
- save->fp_crtc_v_total_disp = save->crtc_v_total_disp;
-
- /* Set following registers for all cases first, if a DFP/LCD is connected on
- internal TMDS/LVDS port, they will be set by RADEONInitFPRegister
- */
- if (!info->IsSwitching) {
- save->fp_gen_cntl = 0;
- save->fp_vert_stretch = info->SavedReg.fp_vert_stretch &
- RADEON_VERT_STRETCH_RESERVED;
- save->fp_horz_stretch = info->SavedReg.fp_horz_stretch &
- (RADEON_HORZ_FP_LOOP_STRETCH |
- RADEON_HORZ_AUTO_RATIO_INC);
- }
-
- /* get the output connected to this CRTC */
- if (pRADEONEnt->PortInfo[0]->crtc_num == 1) {
- RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->PortInfo[0], 1);
- } else if (pRADEONEnt->PortInfo[1]->crtc_num == 1) {
- RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->PortInfo[1], 1);
- }
-
- 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));
- }
-
- return TRUE;
-}
-
-/* Define CRTC2 registers for requested video mode */
-static Bool RADEONInitCrtc2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save,
- DisplayModePtr mode, RADEONInfoPtr info)
-{
- int format;
- int hsync_start;
- int hsync_wid;
- int vsync_wid;
-
- RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
- RADEONInfoPtr info0 = NULL;
- if (info->IsSecondary)
- info0 = RADEONPTR(pRADEONEnt->pPrimaryScrn);
-
- pRADEONEnt->Controller[1]->IsUsed = TRUE;
- pRADEONEnt->Controller[1]->IsActive = TRUE;
- pRADEONEnt->Controller[1]->pCurMode = mode;
-
- switch (info->CurrentLayout.pixel_code) {
- case 4: format = 1; break;
- case 8: format = 2; break;
- case 15: format = 3; break; /* 555 */
- case 16: format = 4; break; /* 565 */
- case 24: format = 5; break; /* RGB */
- case 32: format = 6; break; /* xRGB */
- default:
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Unsupported pixel depth (%d)\n",
- info->CurrentLayout.bitsPerPixel);
- return FALSE;
- }
-
- save->crtc2_h_total_disp =
- ((((mode->CrtcHTotal / 8) - 1) & 0x3ff)
- | ((((mode->CrtcHDisplay / 8) - 1) & 0x1ff) << 16));
-
- hsync_wid = (mode->CrtcHSyncEnd - mode->CrtcHSyncStart) / 8;
- if (!hsync_wid) hsync_wid = 1;
- if (hsync_wid > 0x3f) hsync_wid = 0x3f;
- hsync_start = mode->CrtcHSyncStart - 8;
-
- save->crtc2_h_sync_strt_wid = ((hsync_start & 0x1fff)
- | (hsync_wid << 16)
- | ((mode->Flags & V_NHSYNC)
- ? RADEON_CRTC_H_SYNC_POL
- : 0));
-
- /* This works for double scan mode. */
- save->crtc2_v_total_disp = (((mode->CrtcVTotal - 1) & 0xffff)
- | ((mode->CrtcVDisplay - 1) << 16));
-
- vsync_wid = mode->CrtcVSyncEnd - mode->CrtcVSyncStart;
- if (!vsync_wid) vsync_wid = 1;
- if (vsync_wid > 0x1f) vsync_wid = 0x1f;
-
- save->crtc2_v_sync_strt_wid = (((mode->CrtcVSyncStart - 1) & 0xfff)
- | (vsync_wid << 16)
- | ((mode->Flags & V_NVSYNC)
- ? RADEON_CRTC2_V_SYNC_POL
- : 0));
-
- /* It seems all fancy options apart from pflip can be safely disabled
- */
- save->crtc2_offset = pScrn->fbOffset;
- save->crtc2_offset_cntl &= RADEON_CRTC_OFFSET_FLIP_CNTL;
- if (info->tilingEnabled) {
- if (IS_R300_VARIANT)
- save->crtc2_offset_cntl |= (R300_CRTC_X_Y_MODE_EN |
- R300_CRTC_MICRO_TILE_BUFFER_DIS |
- R300_CRTC_MACRO_TILE_EN);
- else
- save->crtc2_offset_cntl |= RADEON_CRTC_TILE_EN;
- }
- else {
- if (IS_R300_VARIANT)
- save->crtc2_offset_cntl &= ~(R300_CRTC_X_Y_MODE_EN |
- R300_CRTC_MICRO_TILE_BUFFER_DIS |
- R300_CRTC_MACRO_TILE_EN);
- else
- save->crtc2_offset_cntl &= ~RADEON_CRTC_TILE_EN;
- }
-
- save->crtc2_pitch = ((pScrn->displayWidth * pScrn->bitsPerPixel) +
- ((pScrn->bitsPerPixel * 8) -1)) / (pScrn->bitsPerPixel * 8);
- save->crtc2_pitch |= save->crtc2_pitch << 16;
-
- save->crtc2_gen_cntl = (RADEON_CRTC2_EN
- | RADEON_CRTC2_CRT2_ON
- | (format << 8)
- | RADEON_CRTC2_VSYNC_DIS
- | RADEON_CRTC2_HSYNC_DIS
- | RADEON_CRTC2_DISP_DIS
- | ((mode->Flags & V_DBLSCAN)
- ? RADEON_CRTC2_DBL_SCAN_EN
- : 0)
- | ((mode->Flags & V_CSYNC)
- ? RADEON_CRTC2_CSYNC_EN
- : 0)
- | ((mode->Flags & V_INTERLACE)
- ? RADEON_CRTC2_INTERLACE_EN
- : 0));
-
- save->disp2_merge_cntl = info->SavedReg.disp2_merge_cntl;
- save->disp2_merge_cntl &= ~(RADEON_DISP2_RGB_OFFSET_EN);
-
- save->fp_h2_sync_strt_wid = save->crtc2_h_sync_strt_wid;
- save->fp_v2_sync_strt_wid = save->crtc2_v_sync_strt_wid;
-
- /* get the output connected to this CRTC */
- if (pRADEONEnt->PortInfo[0]->crtc_num == 2) {
- RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->PortInfo[0], 2);
- } else if (pRADEONEnt->PortInfo[1]->crtc_num == 2) {
- RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->PortInfo[1], 2);
- }
-
- /* We must set SURFACE_CNTL properly on the second screen too */
- save->surface_cntl = 0;
-#if X_BYTE_ORDER == X_BIG_ENDIAN
- /* We must set both apertures as they can be both used to map the entire
- * video memory. -BenH.
+ /* to restore console mode, DAC registers should be set after every other registers are set,
+ * otherwise,we may get blank screen
*/
- switch (pScrn->bitsPerPixel) {
- case 16:
- save->surface_cntl |= RADEON_NONSURF_AP0_SWP_16BPP;
- save->surface_cntl |= RADEON_NONSURF_AP1_SWP_16BPP;
- break;
+ RADEONRestoreDACRegisters(pScrn, restore);
- case 32:
- save->surface_cntl |= RADEON_NONSURF_AP0_SWP_32BPP;
- save->surface_cntl |= RADEON_NONSURF_AP1_SWP_32BPP;
- break;
- }
+#if 0
+ RADEONWaitForVerticalSync(pScrn);
#endif
-
- return TRUE;
-}
-
-
-/* Define PLL registers for requested video mode */
-static void RADEONInitPLLRegisters(ScrnInfoPtr pScrn, RADEONInfoPtr info,
- RADEONSavePtr save, RADEONPLLPtr pll,
- double dot_clock)
-{
- unsigned long freq = dot_clock * 100;
-
- struct {
- int divider;
- int bitvalue;
- } *post_div, post_divs[] = {
- /* From RAGE 128 VR/RAGE 128 GL Register
- * Reference Manual (Technical Reference
- * Manual P/N RRG-G04100-C Rev. 0.04), page
- * 3-17 (PLL_DIV_[3:0]).
- */
- { 1, 0 }, /* VCLK_SRC */
- { 2, 1 }, /* VCLK_SRC/2 */
- { 4, 2 }, /* VCLK_SRC/4 */
- { 8, 3 }, /* VCLK_SRC/8 */
- { 3, 4 }, /* VCLK_SRC/3 */
- { 16, 5 }, /* VCLK_SRC/16 */
- { 6, 6 }, /* VCLK_SRC/6 */
- { 12, 7 }, /* VCLK_SRC/12 */
- { 0, 0 }
- };
-
- if (info->UseBiosDividers) {
- save->ppll_ref_div = info->RefDivider;
- save->ppll_div_3 = info->FeedbackDivider | (info->PostDivider << 16);
- save->htotal_cntl = 0;
- return;
- }
-
- if (freq > pll->max_pll_freq) freq = pll->max_pll_freq;
- if (freq * 12 < pll->min_pll_freq) freq = pll->min_pll_freq / 12;
-
- for (post_div = &post_divs[0]; post_div->divider; ++post_div) {
- save->pll_output_freq = post_div->divider * freq;
-
- if (save->pll_output_freq >= pll->min_pll_freq
- && save->pll_output_freq <= pll->max_pll_freq) break;
- }
-
- if (!post_div->divider) {
- save->pll_output_freq = freq;
- post_div = &post_divs[0];
- }
-
- save->dot_clock_freq = freq;
- save->feedback_div = RADEONDiv(pll->reference_div
- * save->pll_output_freq,
- pll->reference_freq);
- save->post_div = post_div->divider;
-
- RADEONTRACE(("dc=%ld, of=%ld, fd=%d, pd=%d\n",
- save->dot_clock_freq,
- save->pll_output_freq,
- save->feedback_div,
- save->post_div));
-
- save->ppll_ref_div = pll->reference_div;
- save->ppll_div_3 = (save->feedback_div | (post_div->bitvalue << 16));
- save->htotal_cntl = 0;
-
- save->vclk_cntl = (info->SavedReg.vclk_cntl &
- ~RADEON_VCLK_SRC_SEL_MASK) | RADEON_VCLK_SRC_SEL_PPLLCLK;
-
-}
-
-/* Define PLL2 registers for requested video mode */
-static void RADEONInitPLL2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save,
- RADEONPLLPtr pll, double dot_clock,
- int no_odd_postdiv)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned long freq = dot_clock * 100;
-
- struct {
- int divider;
- int bitvalue;
- } *post_div, post_divs[] = {
- /* From RAGE 128 VR/RAGE 128 GL Register
- * Reference Manual (Technical Reference
- * Manual P/N RRG-G04100-C Rev. 0.04), page
- * 3-17 (PLL_DIV_[3:0]).
- */
- { 1, 0 }, /* VCLK_SRC */
- { 2, 1 }, /* VCLK_SRC/2 */
- { 4, 2 }, /* VCLK_SRC/4 */
- { 8, 3 }, /* VCLK_SRC/8 */
- { 3, 4 }, /* VCLK_SRC/3 */
- { 6, 6 }, /* VCLK_SRC/6 */
- { 12, 7 }, /* VCLK_SRC/12 */
- { 0, 0 }
- };
-
- if (freq > pll->max_pll_freq) freq = pll->max_pll_freq;
- if (freq * 12 < pll->min_pll_freq) freq = pll->min_pll_freq / 12;
-
- for (post_div = &post_divs[0]; post_div->divider; ++post_div) {
- /* Odd post divider value don't work properly on the second digital
- * output
- */
- if (no_odd_postdiv && (post_div->divider & 1))
- continue;
- save->pll_output_freq_2 = post_div->divider * freq;
- if (save->pll_output_freq_2 >= pll->min_pll_freq
- && save->pll_output_freq_2 <= pll->max_pll_freq) break;
- }
-
- if (!post_div->divider) {
- save->pll_output_freq_2 = freq;
- post_div = &post_divs[0];
- }
-
- save->dot_clock_freq_2 = freq;
- save->feedback_div_2 = RADEONDiv(pll->reference_div
- * save->pll_output_freq_2,
- pll->reference_freq);
- save->post_div_2 = post_div->divider;
-
- RADEONTRACE(("dc=%ld, of=%ld, fd=%d, pd=%d\n",
- save->dot_clock_freq_2,
- save->pll_output_freq_2,
- save->feedback_div_2,
- save->post_div_2));
-
- save->p2pll_ref_div = pll->reference_div;
- save->p2pll_div_0 = (save->feedback_div_2 |
- (post_div->bitvalue << 16));
- save->htotal_cntl2 = 0;
-
- save->pixclks_cntl = ((info->SavedReg.pixclks_cntl &
- ~(RADEON_PIX2CLK_SRC_SEL_MASK)) |
- RADEON_PIX2CLK_SRC_SEL_P2PLLCLK);
-
}
#if 0
@@ -6325,177 +5411,22 @@ static void RADEONInitPalette(RADEONSavePtr save)
}
#endif
-/* Define registers for a requested video mode */
-static Bool RADEONInit2(ScrnInfoPtr pScrn, DisplayModePtr crtc1,
- DisplayModePtr crtc2, int crtc_mask,
- RADEONSavePtr save)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
- double dot_clock = crtc1->Clock/1000.0;
- RADEONInfoPtr info0 = NULL;
- ScrnInfoPtr pScrn0 = NULL;
-
-#if RADEON_DEBUG
- ErrorF("%-12.12s %7.2f %4d %4d %4d %4d %4d %4d %4d %4d (%d,%d)",
- crtc1->name,
- dot_clock,
-
- crtc1->HDisplay,
- crtc1->HSyncStart,
- crtc1->HSyncEnd,
- crtc1->HTotal,
-
- crtc1->VDisplay,
- crtc1->VSyncStart,
- crtc1->VSyncEnd,
- crtc1->VTotal,
- pScrn->depth,
- pScrn->bitsPerPixel);
- if (crtc1->Flags & V_DBLSCAN) ErrorF(" D");
- if (crtc1->Flags & V_CSYNC) ErrorF(" C");
- if (crtc1->Flags & V_INTERLACE) ErrorF(" I");
- if (crtc1->Flags & V_PHSYNC) ErrorF(" +H");
- if (crtc1->Flags & V_NHSYNC) ErrorF(" -H");
- if (crtc1->Flags & V_PVSYNC) ErrorF(" +V");
- if (crtc1->Flags & V_NVSYNC) ErrorF(" -V");
- ErrorF("\n");
- ErrorF("%-12.12s %7.2f %4d %4d %4d %4d %4d %4d %4d %4d (%d,%d)",
- crtc1->name,
- dot_clock,
-
- crtc1->CrtcHDisplay,
- crtc1->CrtcHSyncStart,
- crtc1->CrtcHSyncEnd,
- crtc1->CrtcHTotal,
-
- crtc1->CrtcVDisplay,
- crtc1->CrtcVSyncStart,
- crtc1->CrtcVSyncEnd,
- crtc1->CrtcVTotal,
- pScrn->depth,
- pScrn->bitsPerPixel);
- if (crtc1->Flags & V_DBLSCAN) ErrorF(" D");
- if (crtc1->Flags & V_CSYNC) ErrorF(" C");
- if (crtc1->Flags & V_INTERLACE) ErrorF(" I");
- if (crtc1->Flags & V_PHSYNC) ErrorF(" +H");
- if (crtc1->Flags & V_NHSYNC) ErrorF(" -H");
- if (crtc1->Flags & V_PVSYNC) ErrorF(" +V");
- if (crtc1->Flags & V_NVSYNC) ErrorF(" -V");
- ErrorF("\n");
-#endif
-
- info->Flags = crtc1->Flags;
-
- RADEONInitMemMapRegisters(pScrn, save, info);
- RADEONInitCommonRegisters(save, info);
-
- switch(crtc_mask) {
- case 1:
- if (!RADEONInitCrtcRegisters(pScrn, save, crtc1, info))
- return FALSE;
- dot_clock = crtc1->Clock/1000.0;
- if (dot_clock) {
- RADEONInitPLLRegisters(pScrn, info, save, &info->pll, dot_clock);
- } else {
- save->ppll_ref_div = info->SavedReg.ppll_ref_div;
- save->ppll_div_3 = info->SavedReg.ppll_div_3;
- save->htotal_cntl = info->SavedReg.htotal_cntl;
- }
- if (pRADEONEnt->HasSecondary) {
- pScrn0 = pRADEONEnt->pSecondaryScrn;
- info0 = RADEONPTR(pScrn0);
- /* carry over to secondary screen */
- memcpy(&info0->ModeReg, save, sizeof(RADEONSaveRec));
- }
-
- /* Not used for now: */
- /* if (!info->PaletteSavedOnVT) RADEONInitPalette(save); */
- break;
- case 2:
- pScrn0 = pRADEONEnt->pPrimaryScrn;
- info0 = RADEONPTR(pScrn0);
- dot_clock = crtc2->Clock/1000.0;
- if (!RADEONInitCrtc2Registers(pScrn, save, crtc2, info))
- return FALSE;
- RADEONInitPLL2Registers(pScrn, save, &info->pll, dot_clock, info->DisplayType != MT_CRT);
- /* Make sure primary has the same copy */
- memcpy(&info0->ModeReg, save, sizeof(RADEONSaveRec));
- break;
- case 3:
- if (!RADEONInitCrtcRegisters(pScrn, save,
- crtc1, info))
- return FALSE;
- dot_clock = crtc1->Clock / 1000.0;
- if (dot_clock) {
- RADEONInitPLLRegisters(pScrn, info, save, &info->pll, dot_clock);
- } else {
- save->ppll_ref_div = info->SavedReg.ppll_ref_div;
- save->ppll_div_3 = info->SavedReg.ppll_div_3;
- save->htotal_cntl = info->SavedReg.htotal_cntl;
- }
- RADEONInitCrtc2Registers(pScrn, save, crtc2, info);
- dot_clock = crtc2->Clock / 1000.0;
- RADEONInitPLL2Registers(pScrn, save, &info->pll, dot_clock, info->MergeType != MT_CRT);
- break;
- default:
- return FALSE;
- }
-
- RADEONTRACE(("RADEONInit returns %p\n", save));
- return TRUE;
-}
-
-static Bool RADEONInit(ScrnInfoPtr pScrn, DisplayModePtr mode,
- RADEONSavePtr save)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
-
- if (info->IsSecondary) {
- return RADEONInit2(pScrn, NULL, mode, 2, save);
- } else if (info->MergedFB) {
- return RADEONInit2(pScrn, ((RADEONMergedDisplayModePtr)mode->Private)->CRT1,
- ((RADEONMergedDisplayModePtr)mode->Private)->CRT2, 3, save);
- } else {
- return RADEONInit2(pScrn, mode, NULL, 1, save);
- }
-}
-
-/* Initialize a new mode */
-static Bool RADEONModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
-
- RADEONTRACE(("RADEONModeInit()\n"));
-
- if (!RADEONInit(pScrn, mode, &info->ModeReg)) return FALSE;
-
- pScrn->vtSema = TRUE;
- RADEONBlank(pScrn);
- RADEONRestoreMode(pScrn, &info->ModeReg);
- RADEONUnblank(pScrn);
-
- info->CurrentLayout.mode = mode;
-
- if (info->DispPriority)
- RADEONInitDispBandwidth(pScrn);
-
- return TRUE;
-}
-
static Bool RADEONSaveScreen(ScreenPtr pScreen, int mode)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
Bool unblank;
- RADEONTRACE(("RADEONSaveScreen(%d)\n", mode));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "RADEONSaveScreen(%d)\n", mode);
unblank = xf86IsUnblank(mode);
if (unblank) SetTimeSinceLastInputEvent();
if ((pScrn != NULL) && pScrn->vtSema) {
- if (unblank) RADEONUnblank(pScrn);
- else RADEONBlank(pScrn);
+ if (unblank)
+ RADEONUnblank(pScrn);
+ else
+ RADEONBlank(pScrn);
}
return TRUE;
}
@@ -6520,7 +5451,7 @@ RADEONResetDPI(ScrnInfoPtr pScrn, Bool force)
}
}
-_X_EXPORT Bool RADEONSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
+Bool RADEONSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
RADEONInfoPtr info = RADEONPTR(pScrn);
@@ -6535,20 +5466,11 @@ _X_EXPORT Bool RADEONSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
}
#endif
- RADEONTRACE(("RADEONSwitchMode() !n"));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "RADEONSwitchMode() !n");
if (info->allowColorTiling) {
- if (info->MergedFB) {
- if ((((RADEONMergedDisplayModePtr)mode->Private)->CRT1->Flags &
- (V_DBLSCAN | V_INTERLACE)) ||
- (((RADEONMergedDisplayModePtr)mode->Private)->CRT2->Flags &
- (V_DBLSCAN | V_INTERLACE)))
- info->tilingEnabled = FALSE;
- else info->tilingEnabled = TRUE;
- }
- else {
- info->tilingEnabled = (mode->Flags & (V_DBLSCAN | V_INTERLACE)) ? FALSE : TRUE;
- }
+ info->tilingEnabled = (mode->Flags & (V_DBLSCAN | V_INTERLACE)) ? FALSE : TRUE;
#ifdef XF86DRI
if (info->directRenderingEnabled && (info->tilingEnabled != tilingOld)) {
RADEONSAREAPrivPtr pSAREAPriv;
@@ -6564,19 +5486,7 @@ _X_EXPORT Bool RADEONSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
if (info->accelOn)
RADEON_SYNC(info, pScrn);
- if (info->FBDev) {
- RADEONSaveFBDevRegisters(pScrn, &info->ModeReg);
-
- ret = fbdevHWSwitchMode(scrnIndex, mode, flags);
- pScrn->displayWidth = fbdevHWGetLineLength(pScrn)
- / info->CurrentLayout.pixel_bytes;
-
- RADEONRestoreFBDevRegisters(pScrn, &info->ModeReg);
- } else {
- info->IsSwitching = TRUE;
- ret = RADEONModeInit(xf86Screens[scrnIndex], mode);
- info->IsSwitching = FALSE;
- }
+ ret = xf86SetSingleMode (pScrn, mode, RR_Rotate_0);
if (info->tilingEnabled != tilingOld) {
/* need to redraw front buffer, I guess this can be considered a hack ? */
@@ -6601,10 +5511,7 @@ _X_EXPORT Bool RADEONSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
/* Since RandR (indirectly) uses SwitchMode(), we need to
* update our Xinerama info here, too, in case of resizing
*/
- if (info->MergedFB) {
- RADEONMergedFBResetDpi(pScrn, FALSE);
- RADEONUpdateXineramaScreenInfo(pScrn);
- } else if(info->constantDPI) {
+ if(info->constantDPI) {
RADEONResetDPI(pScrn, FALSE);
}
@@ -6614,7 +5521,7 @@ _X_EXPORT Bool RADEONSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
}
#ifdef X_XF86MiscPassMessage
-_X_EXPORT Bool RADEONHandleMessage(int scrnIndex, const char* msgtype,
+Bool RADEONHandleMessage(int scrnIndex, const char* msgtype,
const char* msgval, char** retmsg)
{
ErrorF("RADEONHandleMessage(%d, \"%s\", \"%s\", retmsg)\n", scrnIndex,
@@ -6625,7 +5532,7 @@ _X_EXPORT Bool RADEONHandleMessage(int scrnIndex, const char* msgtype,
#endif
/* Used to disallow modes that are not supported by the hardware */
-_X_EXPORT ModeStatus RADEONValidMode(int scrnIndex, DisplayModePtr mode,
+ModeStatus RADEONValidMode(int scrnIndex, DisplayModePtr mode,
Bool verbose, int flag)
{
/* There are problems with double scan mode at high clocks
@@ -6642,18 +5549,19 @@ _X_EXPORT ModeStatus RADEONValidMode(int scrnIndex, DisplayModePtr mode,
/* Adjust viewport into virtual desktop such that (0,0) in viewport
* space is (x,y) in virtual space.
*/
-void RADEONDoAdjustFrame(ScrnInfoPtr pScrn, int x, int y, int clone)
+void RADEONDoAdjustFrame(ScrnInfoPtr pScrn, int x, int y, Bool crtc2)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
unsigned char *RADEONMMIO = info->MMIO;
- int reg, Base, regcntl, crtcoffsetcntl, xytilereg, crtcxytile = 0;
+ int Base, reg, regcntl, crtcoffsetcntl, xytilereg, crtcxytile = 0;
#ifdef XF86DRI
RADEONSAREAPrivPtr pSAREAPriv;
XF86DRISAREAPtr pSAREA;
#endif
#if 0 /* Verbose */
- RADEONTRACE(("RADEONDoAdjustFrame(%d,%d,%d)\n", x, y, clone));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "RADEONDoAdjustFrame(%d,%d,%d)\n", x, y, clone);
#endif
if (info->showCache && y) {
@@ -6673,12 +5581,12 @@ void RADEONDoAdjustFrame(ScrnInfoPtr pScrn, int x, int y, int clone)
pick up the new offset value at the end of each scanline, but the new offset_cntl value
only after a vsync. We'd probably need to wait (in drm) for vsync and only then update
OFFSET and OFFSET_CNTL, if the y coord has changed. Seems hard to fix. */
- if (clone || info->IsSecondary) {
- reg = RADEON_CRTC2_OFFSET;
+ if (crtc2) {
+ reg = RADEON_CRTC2_OFFSET;
regcntl = RADEON_CRTC2_OFFSET_CNTL;
xytilereg = R300_CRTC2_TILE_X0_Y0;
} else {
- reg = RADEON_CRTC_OFFSET;
+ reg = RADEON_CRTC_OFFSET;
regcntl = RADEON_CRTC_OFFSET_CNTL;
xytilereg = R300_CRTC_TILE_X0_Y0;
}
@@ -6730,7 +5638,7 @@ void RADEONDoAdjustFrame(ScrnInfoPtr pScrn, int x, int y, int clone)
/* can't get at sarea in a semi-sane way? */
pSAREA = (void *)((char*)pSAREAPriv - sizeof(XF86DRISAREARec));
- if (clone || info->IsSecondary) {
+ if (crtc2) {
pSAREAPriv->crtc2_base = Base;
}
else {
@@ -6748,20 +5656,23 @@ void RADEONDoAdjustFrame(ScrnInfoPtr pScrn, int x, int y, int clone)
}
#endif
- OUTREG(reg, Base);
-
if (IS_R300_VARIANT) {
- OUTREG(xytilereg, crtcxytile);
+ OUTREG(xytilereg, crtcxytile);
} else {
- OUTREG(regcntl, crtcoffsetcntl);
+ OUTREG(regcntl, crtcoffsetcntl);
}
+ OUTREG(reg, Base);
}
-_X_EXPORT void RADEONAdjustFrame(int scrnIndex, int x, int y, int flags)
+void RADEONAdjustFrame(int scrnIndex, int x, int y, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+ xf86OutputPtr output = config->output[config->compat_output];
+ xf86CrtcPtr crtc = output->crtc;
#ifdef XF86DRI
if (info->CPStarted && pScrn->pScreen) DRILock(pScrn->pScreen, 0);
@@ -6770,14 +5681,16 @@ _X_EXPORT void RADEONAdjustFrame(int scrnIndex, int x, int y, int flags)
if (info->accelOn)
RADEON_SYNC(info, pScrn);
- if(info->MergedFB) {
- RADEONAdjustFrameMerged(scrnIndex, x, y, flags);
- } else if (info->FBDev) {
- fbdevHWAdjustFrame(scrnIndex, x, y, flags);
- } else {
- RADEONDoAdjustFrame(pScrn, x, y, FALSE);
+ if (crtc && crtc->enabled) {
+ if (crtc == pRADEONEnt->pCrtc[0])
+ RADEONDoAdjustFrame(pScrn, crtc->desiredX + x, crtc->desiredY + y, FALSE);
+ else
+ RADEONDoAdjustFrame(pScrn, crtc->desiredX + x, crtc->desiredY + y, TRUE);
+ crtc->x = output->initial_x + x;
+ crtc->y = output->initial_y + y;
}
+
#ifdef XF86DRI
if (info->CPStarted && pScrn->pScreen) DRIUnlock(pScrn->pScreen);
#endif
@@ -6786,15 +5699,18 @@ _X_EXPORT void RADEONAdjustFrame(int scrnIndex, int x, int y, int flags)
/* Called when VT switching back to the X server. Reinitialize the
* video mode.
*/
-_X_EXPORT Bool RADEONEnterVT(int scrnIndex, int flags)
+Bool RADEONEnterVT(int scrnIndex, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
RADEONInfoPtr info = RADEONPTR(pScrn);
unsigned char *RADEONMMIO = info->MMIO;
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ int i;
- RADEONTRACE(("RADEONEnterVT\n"));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "RADEONEnterVT\n");
- if (INREG(RADEON_CONFIG_MEMSIZE) == 0) { /* Softboot V_BIOS */
+ if ((INREG(RADEON_CONFIG_MEMSIZE)) == 0) { /* Softboot V_BIOS */
xf86Int10InfoPtr pInt;
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"zero MEMSIZE, probably at D3cold. Re-POSTing via int10.\n");
@@ -6809,18 +5725,25 @@ _X_EXPORT Bool RADEONEnterVT(int scrnIndex, int flags)
/* Makes sure the engine is idle before doing anything */
RADEONWaitForIdleMMIO(pScrn);
- if (info->FBDev) {
- unsigned char *RADEONMMIO = info->MMIO;
- if (!fbdevHWEnterVT(scrnIndex,flags)) return FALSE;
- info->PaletteSavedOnVT = FALSE;
- info->ModeReg.surface_cntl = INREG(RADEON_SURFACE_CNTL);
+ pScrn->vtSema = TRUE;
+ for (i = 0; i < xf86_config->num_crtc; i++) {
+ xf86CrtcPtr crtc = xf86_config->crtc[i];
+ /* Mark that we'll need to re-set the mode for sure */
+ memset(&crtc->mode, 0, sizeof(crtc->mode));
+ if (!crtc->desiredMode.CrtcHDisplay) {
+ crtc->desiredMode = *RADEONCrtcFindClosestMode (crtc, pScrn->currentMode);
+ crtc->desiredRotation = RR_Rotate_0;
+ crtc->desiredX = 0;
+ crtc->desiredY = 0;
+ }
- RADEONRestoreFBDevRegisters(pScrn, &info->ModeReg);
- } else
- if (!RADEONModeInit(pScrn, pScrn->currentMode)) return FALSE;
+ if (!xf86CrtcSetMode (crtc, &crtc->desiredMode, crtc->desiredRotation,
+ crtc->desiredX, crtc->desiredY))
+ return FALSE;
- if (!info->IsSecondary)
- RADEONRestoreSurfaces(pScrn, &info->ModeReg);
+ }
+
+ RADEONRestoreSurfaces(pScrn, &info->ModeReg);
#ifdef XF86DRI
if (info->directRenderingEnabled) {
if (info->cardType == CARD_PCIE && info->pKernelDRMVersion->version_minor >= 19 && info->FbSecureSize)
@@ -6830,8 +5753,10 @@ _X_EXPORT Bool RADEONEnterVT(int scrnIndex, int flags)
}
/* get the DRI back into shape after resume */
+ RADEONDRISetVBlankInterrupt (pScrn, TRUE);
RADEONDRIResume(pScrn->pScreen);
RADEONAdjustMemMapRegisters(pScrn, &info->ModeReg);
+
}
#endif
/* this will get XVideo going again, but only if XVideo was initialised
@@ -6849,7 +5774,7 @@ _X_EXPORT Bool RADEONEnterVT(int scrnIndex, int flags)
}
#endif
- pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+ // pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
return TRUE;
}
@@ -6857,15 +5782,17 @@ _X_EXPORT Bool RADEONEnterVT(int scrnIndex, int flags)
/* Called when VT switching away from the X server. Restore the
* original text mode.
*/
-_X_EXPORT void RADEONLeaveVT(int scrnIndex, int flags)
+void RADEONLeaveVT(int scrnIndex, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONSavePtr save = &info->ModeReg;
- RADEONTRACE(("RADEONLeaveVT\n"));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "RADEONLeaveVT\n");
#ifdef XF86DRI
if (RADEONPTR(pScrn)->directRenderingInited) {
+
+ RADEONDRISetVBlankInterrupt (pScrn, FALSE);
DRILock(pScrn->pScreen, 0);
RADEONCP_STOP(pScrn, info);
@@ -6874,21 +5801,26 @@ _X_EXPORT void RADEONLeaveVT(int scrnIndex, int flags)
/* we need to backup the PCIE GART TABLE from fb memory */
memcpy(info->pciGartBackup, (info->FB + info->pciGartOffset), info->pciGartSize);
}
- }
-#endif
-
- if (info->FBDev) {
- RADEONSavePalette(pScrn, save);
- info->PaletteSavedOnVT = TRUE;
- RADEONSaveFBDevRegisters(pScrn, &info->ModeReg);
-
- fbdevHWLeaveVT(scrnIndex,flags);
+ /* Make sure 3D clients will re-upload textures to video RAM */
+ if (info->textureSize) {
+ RADEONSAREAPrivPtr pSAREAPriv =
+ (RADEONSAREAPrivPtr)DRIGetSAREAPrivate(pScrn->pScreen);
+ drmTextureRegionPtr list = pSAREAPriv->texList[0];
+ int age = ++pSAREAPriv->texAge[0], i = 0;
+
+ do {
+ list[i].age = age;
+ i = list[i].next;
+ } while (i != 0);
+ }
}
+#endif
RADEONRestore(pScrn);
- RADEONTRACE(("Ok, leaving now...\n"));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "Ok, leaving now...\n");
}
/* Called at the end of each server generation. Restore the original
@@ -6900,7 +5832,8 @@ static Bool RADEONCloseScreen(int scrnIndex, ScreenPtr pScreen)
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONTRACE(("RADEONCloseScreen\n"));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "RADEONCloseScreen\n");
/* Mark acceleration as stopped or we might try to access the engine at
* wrong times, especially if we had DRI, after DRI has been stopped
@@ -6929,11 +5862,11 @@ static Bool RADEONCloseScreen(int scrnIndex, ScreenPtr pScreen)
#endif /* USE_XAA */
if (pScrn->vtSema) {
- RADEONDisplayPowerManagementSet(pScrn, DPMSModeOn, 0);
RADEONRestore(pScrn);
}
- RADEONTRACE(("Disposing accel...\n"));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "Disposing accel...\n");
#ifdef USE_EXA
if (info->exa) {
exaDriverFini(pScreen);
@@ -6953,14 +5886,17 @@ static Bool RADEONCloseScreen(int scrnIndex, ScreenPtr pScreen)
}
#endif /* USE_XAA */
- RADEONTRACE(("Disposing cusor info\n"));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "Disposing cusor info\n");
if (info->cursor) xf86DestroyCursorInfoRec(info->cursor);
info->cursor = NULL;
- RADEONTRACE(("Disposing DGA\n"));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "Disposing DGA\n");
if (info->DGAModes) xfree(info->DGAModes);
info->DGAModes = NULL;
- RADEONTRACE(("Unmapping memory\n"));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "Unmapping memory\n");
RADEONUnmapMem(pScrn);
pScrn->vtSema = FALSE;
@@ -6972,50 +5908,17 @@ static Bool RADEONCloseScreen(int scrnIndex, ScreenPtr pScreen)
return (*pScreen->CloseScreen)(scrnIndex, pScreen);
}
-_X_EXPORT void RADEONFreeScreen(int scrnIndex, int flags)
+void RADEONFreeScreen(int scrnIndex, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONTRACE(("RADEONFreeScreen\n"));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "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;
- do {
- DisplayModePtr p = pScrn->currentMode->next;
- if(pScrn->currentMode->Private)
- xfree(pScrn->currentMode->Private);
- xfree(pScrn->currentMode);
- pScrn->currentMode = p;
- } while(pScrn->currentMode != pScrn->modes);
- }
- pScrn->currentMode = info->CRT1CurrentMode;
- pScrn->modes = info->CRT1Modes;
- info->CRT1CurrentMode = NULL;
- info->CRT1Modes = NULL;
-
- if(info->CRT2pScrn) {
- if(info->CRT2pScrn->modes) {
- while(info->CRT2pScrn->modes)
- xf86DeleteMode(&info->CRT2pScrn->modes, info->CRT2pScrn->modes);
- }
- if(info->CRT2pScrn->monitor) {
- if(info->CRT2pScrn->monitor->Modes) {
- while(info->CRT2pScrn->monitor->Modes)
- xf86DeleteMode(&info->CRT2pScrn->monitor->Modes, info->CRT2pScrn->monitor->Modes);
- }
- if(info->CRT2pScrn->monitor->DDC) xfree(info->CRT2pScrn->monitor->DDC);
- xfree(info->CRT2pScrn->monitor);
- }
- xfree(info->CRT2pScrn);
- info->CRT2pScrn = NULL;
- }
- }
-
#ifdef WITH_VGAHW
if (info->VGAAccess && xf86LoaderCheckSymbol("vgaHWFreeHWRec"))
vgaHWFreeHWRec(pScrn);
@@ -7023,235 +5926,6 @@ _X_EXPORT void RADEONFreeScreen(int scrnIndex, int flags)
RADEONFreeRec(pScrn);
}
-static void
-RADEONGetMergedFBOptions(ScrnInfoPtr pScrn)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONConnector *connector;
- char *strptr;
- char *default_hsync = "28-33";
- char *default_vrefresh = "43-72";
- Bool val;
- Bool default_range = FALSE;
- static const char *mybadparm = "\"%s\" is is not a valid parameter for option \"%s\"\n";
-
- if (info->FBDev == TRUE) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "MergedFB does not work with Option UseFBDev, MergedFB mode is disabled\n");
- info->MergedFB = FALSE;
- return;
- }
-
- /* collect MergedFB options */
- info->MergedFB = TRUE;
- info->UseRADEONXinerama = TRUE;
- info->CRT2IsScrn0 = FALSE;
- info->CRT2Position = radeonClone;
- info->MergedFBXDPI = info->MergedFBYDPI = 0;
- info->CRT1XOffs = info->CRT1YOffs = info->CRT2XOffs = info->CRT2YOffs = 0;
- info->NonRect = info->HaveNonRect = info->HaveOffsRegions = FALSE;
- info->MBXNR1XMAX = info->MBXNR1YMAX = info->MBXNR2XMAX = info->MBXNR2YMAX = 65536;
- info->MouseRestrictions = TRUE;
-
- if (info->MergeType == MT_NONE) {
- info->MergedFB = FALSE;
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Failed to detect secondary monitor, MergedFB/Clone mode disabled\n");
- } else if ((connector = RADEONGetCrtcConnector(pScrn, 2))) {
- if (!connector->MonInfo) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Failed to detect secondary monitor DDC, default HSync and VRefresh used\n");
- default_range = TRUE;
- }
- }
-
- if (xf86GetOptValBool(info->Options, OPTION_MERGEDFB, &val)) {
- if (val) {
- info->MergedFB = TRUE;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "MergedFB mode forced on.\n");
- } else {
- info->MergedFB = FALSE;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "MergedFB mode forced off.\n");
- }
- }
-
- /* Do some MergedFB mode initialisation */
- if(info->MergedFB) {
- info->CRT2pScrn = xalloc(sizeof(ScrnInfoRec));
- if(!info->CRT2pScrn) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Failed to allocate memory for merged pScrn, MergedFB mode is disabled\n");
- info->MergedFB = FALSE;
- } else {
- memcpy(info->CRT2pScrn, pScrn, sizeof(ScrnInfoRec));
- }
- }
- if(info->MergedFB) {
- int result, ival;
- Bool valid = FALSE;
- char *tempstr;
- strptr = (char *)xf86GetOptValString(info->Options, OPTION_CRT2POS);
- if (strptr) {
- tempstr = xalloc(strlen(strptr) + 1);
- result = sscanf(strptr, "%s %d", tempstr, &ival);
- } else { /* Not specified - default is "Clone" */
- tempstr = NULL;
- result = 0;
- info->CRT2Position = radeonClone;
- valid = TRUE;
- }
- if(result >= 1) {
- if(!xf86NameCmp(tempstr,"LeftOf")) {
- info->CRT2Position = radeonLeftOf;
- valid = TRUE;
- if(result == 2) {
- if(ival < 0) info->CRT1YOffs = -ival;
- else info->CRT2YOffs = ival;
- }
- info->CRT2IsScrn0 = TRUE;
- } else if(!xf86NameCmp(tempstr,"RightOf")) {
- info->CRT2Position = radeonRightOf;
- valid = TRUE;
- if(result == 2) {
- if(ival < 0) info->CRT1YOffs = -ival;
- else info->CRT2YOffs = ival;
- }
- info->CRT2IsScrn0 = FALSE;
- } else if(!xf86NameCmp(tempstr,"Above")) {
- info->CRT2Position = radeonAbove;
- valid = TRUE;
- if(result == 2) {
- if(ival < 0) info->CRT1XOffs = -ival;
- else info->CRT2XOffs = ival;
- }
- info->CRT2IsScrn0 = FALSE;
- } else if(!xf86NameCmp(tempstr,"Below")) {
- info->CRT2Position = radeonBelow;
- valid = TRUE;
- if(result == 2) {
- if(ival < 0) info->CRT1XOffs = -ival;
- else info->CRT2XOffs = ival;
- }
- info->CRT2IsScrn0 = TRUE;
- } else if(!xf86NameCmp(tempstr,"Clone")) {
- info->CRT2Position = radeonClone;
- if(result == 1) valid = TRUE;
- /*info->CRT2IsScrn0 = TRUE;*/
- }
- }
- if(!valid) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "\"%s\" is not a valid parameter for Option \"CRT2Position\"\n", strptr);
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Valid parameters are \"RightOf\", \"LeftOf\", \"Above\", \"Below\", or \"Clone\"\n");
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Except for \"Clone\", the parameter may be followed by an integer.\n");
- }
- xfree(tempstr);
-
- strptr = (char *)xf86GetOptValString(info->Options, OPTION_METAMODES);
- if(strptr) {
- info->MetaModes = xalloc(strlen(strptr) + 1);
- if(info->MetaModes) memcpy(info->MetaModes, strptr, strlen(strptr) + 1);
- }
- strptr = (char *)xf86GetOptValString(info->Options, OPTION_CRT2HSYNC);
- if(strptr) {
- info->CRT2HSync = xalloc(strlen(strptr) + 1);
- if(info->CRT2HSync) memcpy(info->CRT2HSync, strptr, strlen(strptr) + 1);
- }
- strptr = (char *)xf86GetOptValString(info->Options, OPTION_CRT2VREFRESH);
- if(strptr) {
- info->CRT2VRefresh = xalloc(strlen(strptr) + 1);
- if(info->CRT2VRefresh) memcpy(info->CRT2VRefresh, strptr, strlen(strptr) + 1);
- }
-
- if(xf86GetOptValBool(info->Options, OPTION_RADEONXINERAMA, &val)) {
- if (!val)
- info->UseRADEONXinerama = FALSE;
- }
- if(info->UseRADEONXinerama) {
- if(xf86GetOptValBool(info->Options, OPTION_CRT2ISSCRN0, &val)) {
- if(val) info->CRT2IsScrn0 = TRUE;
- else info->CRT2IsScrn0 = FALSE;
- }
- if(xf86GetOptValBool(info->Options, OPTION_MERGEDFBNONRECT, &val)) {
- info->NonRect = val ? TRUE : FALSE;
- }
- if(xf86GetOptValBool(info->Options, OPTION_MERGEDFBMOUSER, &val)) {
- info->MouseRestrictions = val ? TRUE : FALSE;
- }
- }
- strptr = (char *)xf86GetOptValString(info->Options, OPTION_MERGEDDPI);
- if(strptr) {
- int val1 = 0, val2 = 0;
- sscanf(strptr, "%d %d", &val1, &val2);
- if(val1 && val2) {
- info->MergedFBXDPI = val1;
- info->MergedFBYDPI = val2;
- } else {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING, mybadparm, strptr, "MergedDPI");
- }
- }
- }
-
- if(info->MergedFB) {
- /* fill in monitor */
- info->CRT2pScrn->monitor = xalloc(sizeof(MonRec));
- if(info->CRT2pScrn->monitor) {
- DisplayModePtr tempm = NULL, currentm = NULL, newm = NULL;
- memcpy(info->CRT2pScrn->monitor, pScrn->monitor, sizeof(MonRec));
- info->CRT2pScrn->monitor->DDC = NULL;
- info->CRT2pScrn->monitor->Modes = NULL;
- info->CRT2pScrn->monitor->id = "CRT2 Monitor";
- tempm = pScrn->monitor->Modes;
- while(tempm) {
- if(!(newm = xalloc(sizeof(DisplayModeRec)))) break;
- memcpy(newm, tempm, sizeof(DisplayModeRec));
- if(!(newm->name = xalloc(strlen(tempm->name) + 1))) {
- xfree(newm);
- break;
- }
- strcpy(newm->name, tempm->name);
- if(!info->CRT2pScrn->monitor->Modes)
- info->CRT2pScrn->monitor->Modes = newm;
- if(currentm) {
- currentm->next = newm;
- newm->prev = currentm;
- }
- currentm = newm;
- tempm = tempm->next;
- }
-
- /* xf86SetDDCproperties(info->CRT2pScrn, pRADEONEnt->MonInfo2); */
-
- connector = RADEONGetCrtcConnector(pScrn, 2);
- info->CRT2pScrn->monitor->DDC = connector ? connector->MonInfo : NULL;
-
- if (default_range) {
- RADEONStrToRanges(info->CRT2pScrn->monitor->hsync, default_hsync, MAX_HSYNC);
- RADEONStrToRanges(info->CRT2pScrn->monitor->vrefresh, default_vrefresh, MAX_VREFRESH);
- }
- if(info->CRT2HSync) {
- info->CRT2pScrn->monitor->nHsync =
- RADEONStrToRanges(info->CRT2pScrn->monitor->hsync, info->CRT2HSync, MAX_HSYNC);
- }
- if(info->CRT2VRefresh) {
- info->CRT2pScrn->monitor->nVrefresh =
- RADEONStrToRanges(info->CRT2pScrn->monitor->vrefresh, info->CRT2VRefresh, MAX_VREFRESH);
- }
-
- } else {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Failed to allocate memory for CRT2 monitor, MergedFB mode disabled.\n");
- if(info->CRT2pScrn) xfree(info->CRT2pScrn);
- info->CRT2pScrn = NULL;
- info->MergedFB = FALSE;
- }
- }
-}
-
static void RADEONForceSomeClocks(ScrnInfoPtr pScrn)
{
/* It appears from r300 and rv100 may need some clocks forced-on */
@@ -7610,21 +6284,3 @@ static void RADEONSetDynamicClock(ScrnInfoPtr pScrn, int mode)
break;
}
}
-
-_X_EXPORT void RADEONFillInScreenInfo(ScrnInfoPtr pScrn)
-{
- pScrn->driverVersion = RADEON_VERSION_CURRENT;
- pScrn->driverName = RADEON_DRIVER_NAME;
- pScrn->name = RADEON_NAME;
- pScrn->PreInit = RADEONPreInit;
- pScrn->ScreenInit = RADEONScreenInit;
- pScrn->SwitchMode = RADEONSwitchMode;
-#ifdef X_XF86MiscPassMessage
- pScrn->HandleMessage = RADEONHandleMessage;
-#endif
- pScrn->AdjustFrame = RADEONAdjustFrame;
- pScrn->EnterVT = RADEONEnterVT;
- pScrn->LeaveVT = RADEONLeaveVT;
- pScrn->FreeScreen = RADEONFreeScreen;
- pScrn->ValidMode = RADEONValidMode;
-}
diff --git a/src/radeon_exa.c b/src/radeon_exa.c
index f9bcaceb..d074f08a 100644
--- a/src/radeon_exa.c
+++ b/src/radeon_exa.c
@@ -496,3 +496,20 @@ Bool RADEONSetupMemEXA (ScreenPtr pScreen)
return TRUE;
}
+
+#ifdef XF86DRI
+
+#ifndef ExaOffscreenMarkUsed
+extern void ExaOffscreenMarkUsed(PixmapPtr);
+#endif
+
+unsigned long long
+RADEONTexOffsetStart(PixmapPtr pPix)
+{
+ exaMoveInPixmap(pPix);
+ ExaOffscreenMarkUsed(pPix);
+
+ return RADEONPTR(xf86Screens[pPix->drawable.pScreen->myNum])->fbLocation +
+ exaGetPixmapOffset(pPix);
+}
+#endif
diff --git a/src/radeon_exa_funcs.c b/src/radeon_exa_funcs.c
index 0d847d1c..c356de7c 100644
--- a/src/radeon_exa_funcs.c
+++ b/src/radeon_exa_funcs.c
@@ -59,14 +59,30 @@
#include "exa.h"
+static int
+FUNC_NAME(RADEONMarkSync)(ScreenPtr pScreen)
+{
+ RINFO_FROM_SCREEN(pScreen);
+
+ TRACE;
+
+ return ++info->exaSyncMarker;
+}
+
static void
FUNC_NAME(RADEONSync)(ScreenPtr pScreen, int marker)
{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+
TRACE;
- FUNC_NAME(RADEONWaitForIdle)(xf86Screens[pScreen->myNum]);
+ if (info->exaMarkerSynced != marker) {
+ FUNC_NAME(RADEONWaitForIdle)(pScrn);
+ info->exaMarkerSynced = marker;
+ }
- RADEONPTR(xf86Screens[pScreen->myNum])->engineMode = EXA_ENGINEMODE_UNKNOWN;
+ RADEONPTR(pScrn)->engineMode = EXA_ENGINEMODE_UNKNOWN;
}
static Bool
@@ -444,6 +460,8 @@ FUNC_NAME(RADEONDownloadFromScreen)(PixmapPtr pSrc, int x, int y, int w, int h,
drmCommandWriteRead(info->drmFD, DRM_RADEON_INDIRECT,
&indirect, sizeof(drmRadeonIndirect));
+ info->exaMarkerSynced = info->exaSyncMarker;
+
return TRUE;
}
#endif
@@ -504,6 +522,7 @@ Bool FUNC_NAME(RADEONDrawInit)(ScreenPtr pScreen)
info->exa->Copy = FUNC_NAME(RADEONCopy);
info->exa->DoneCopy = FUNC_NAME(RADEONDoneCopy);
+ info->exa->MarkSync = FUNC_NAME(RADEONMarkSync);
info->exa->WaitMarker = FUNC_NAME(RADEONSync);
info->exa->UploadToScreen = FUNC_NAME(RADEONUploadToScreen);
info->exa->DownloadFromScreen = FUNC_NAME(RADEONDownloadFromScreen);
diff --git a/src/radeon_mergedfb.c b/src/radeon_mergedfb.c
deleted file mode 100644
index 820ba4ba..00000000
--- a/src/radeon_mergedfb.c
+++ /dev/null
@@ -1,2089 +0,0 @@
-/*
- * Copyright 2003 Alex Deucher.
- *
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation on the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial
- * portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NON-INFRINGEMENT. IN NO EVENT SHALL ALEX DEUCHER, OR ANY OTHER
- * CONTRIBUTORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-/*
- * Authors:
- * Alex Deucher <agd5f@yahoo.com>
- * Based, in large part, on the sis driver by Thomas Winischhofer.
- */
-
-#include <string.h>
-#include <stdio.h>
-
-#include "xf86.h"
-#include "xf86Priv.h"
-#include "xf86Resources.h"
-#include "xf86_OSproc.h"
-#include "extnsionst.h" /* required */
-#include <X11/extensions/panoramiXproto.h> /* required */
-#include "dixstruct.h"
-#include "vbe.h"
-
-
-#include "radeon.h"
-#include "radeon_reg.h"
-#include "radeon_macros.h"
-#include "radeon_mergedfb.h"
-
-/* psuedo xinerama support */
-static unsigned char RADEONXineramaReqCode = 0;
-int RADEONXineramaPixWidth = 0;
-int RADEONXineramaPixHeight = 0;
-int RADEONXineramaNumScreens = 0;
-RADEONXineramaData *RADEONXineramadataPtr = NULL;
-static int RADEONXineramaGeneration;
-Bool RADEONnoPanoramiXExtension = TRUE;
-
-int RADEONProcXineramaQueryVersion(ClientPtr client);
-int RADEONProcXineramaGetState(ClientPtr client);
-int RADEONProcXineramaGetScreenCount(ClientPtr client);
-int RADEONProcXineramaGetScreenSize(ClientPtr client);
-int RADEONProcXineramaIsActive(ClientPtr client);
-int RADEONProcXineramaQueryScreens(ClientPtr client);
-int RADEONSProcXineramaDispatch(ClientPtr client);
-
-static void
-RADEONChooseCursorCRTC(ScrnInfoPtr pScrn1, int x, int y);
-
-/* mergedfb functions */
-/* Helper function for CRT2 monitor vrefresh/hsync options
- * (Taken from mga, sis drivers)
- */
-int
-RADEONStrToRanges(range *r, char *s, int max)
-{
- float num = 0.0;
- int rangenum = 0;
- Bool gotdash = FALSE;
- Bool nextdash = FALSE;
- char* strnum = NULL;
- do {
- switch(*s) {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- case '.':
- if(strnum == NULL) {
- strnum = s;
- gotdash = nextdash;
- nextdash = FALSE;
- }
- break;
- case '-':
- case ' ':
- case 0:
- if(strnum == NULL) break;
- sscanf(strnum, "%f", &num);
- strnum = NULL;
- if(gotdash)
- r[rangenum - 1].hi = num;
- else {
- r[rangenum].lo = num;
- r[rangenum].hi = num;
- rangenum++;
- }
- if(*s == '-') nextdash = (rangenum != 0);
- else if(rangenum >= max) return rangenum;
- break;
- default :
- return 0;
- }
- } while(*(s++) != 0);
-
- return rangenum;
-}
-
-/* Copy and link two modes (i, j) for merged-fb mode
- * (Taken from mga, sis drivers)
- * Copys mode i, merges j to copy of i, links the result to dest, and returns it.
- * Links i and j in Private record.
- * If dest is NULL, return value is copy of i linked to itself.
- * For mergedfb auto-config, we only check the dimension
- * against virtualX/Y, if they were user-provided.
- */
-static DisplayModePtr
-RADEONCopyModeNLink(ScrnInfoPtr pScrn, DisplayModePtr dest,
- DisplayModePtr i, DisplayModePtr j,
- RADEONScrn2Rel srel)
-{
- DisplayModePtr mode;
- int dx = 0,dy = 0;
- RADEONInfoPtr info = RADEONPTR(pScrn);
-
- if(!((mode = xalloc(sizeof(DisplayModeRec))))) return dest;
- memcpy(mode, i, sizeof(DisplayModeRec));
- if(!((mode->Private = xalloc(sizeof(RADEONMergedDisplayModeRec))))) {
- xfree(mode);
- return dest;
- }
- ((RADEONMergedDisplayModePtr)mode->Private)->CRT1 = i;
- ((RADEONMergedDisplayModePtr)mode->Private)->CRT2 = j;
- ((RADEONMergedDisplayModePtr)mode->Private)->CRT2Position = srel;
- mode->PrivSize = 0;
-
- switch(srel) {
- case radeonLeftOf:
- case radeonRightOf:
- if(!(pScrn->display->virtualX)) {
- dx = i->HDisplay + j->HDisplay;
- } else {
- dx = min(pScrn->virtualX, i->HDisplay + j->HDisplay);
- }
- dx -= mode->HDisplay;
- if(!(pScrn->display->virtualY)) {
- dy = max(i->VDisplay, j->VDisplay);
- } else {
- dy = min(pScrn->virtualY, max(i->VDisplay, j->VDisplay));
- }
- dy -= mode->VDisplay;
- break;
- case radeonAbove:
- case radeonBelow:
- if(!(pScrn->display->virtualY)) {
- dy = i->VDisplay + j->VDisplay;
- } else {
- dy = min(pScrn->virtualY, i->VDisplay + j->VDisplay);
- }
- dy -= mode->VDisplay;
- if(!(pScrn->display->virtualX)) {
- dx = max(i->HDisplay, j->HDisplay);
- } else {
- dx = min(pScrn->virtualX, max(i->HDisplay, j->HDisplay));
- }
- dx -= mode->HDisplay;
- break;
- case radeonClone:
- if(!(pScrn->display->virtualX)) {
- dx = max(i->HDisplay, j->HDisplay);
- } else {
- dx = min(pScrn->virtualX, max(i->HDisplay, j->HDisplay));
- }
- dx -= mode->HDisplay;
- if(!(pScrn->display->virtualY)) {
- dy = max(i->VDisplay, j->VDisplay);
- } else {
- dy = min(pScrn->virtualY, max(i->VDisplay, j->VDisplay));
- }
- dy -= mode->VDisplay;
- break;
- }
- mode->HDisplay += dx;
- mode->HSyncStart += dx;
- mode->HSyncEnd += dx;
- mode->HTotal += dx;
- mode->VDisplay += dy;
- mode->VSyncStart += dy;
- mode->VSyncEnd += dy;
- mode->VTotal += dy;
-
- /* Provide a fake VRefresh/DotClock in order to trick the vidmode
- * extension to allow selecting among a number of modes whose merged result
- * looks identical but consists of different modes for CRT1 and CRT2
- */
- mode->VRefresh = (float)((i->Clock * 1000.0 / i->HTotal / i->VTotal) * 100 +
- (j->Clock * 1000.0 / j->HTotal / j->VTotal));
-
- mode->Clock = (int)(mode->VRefresh * 0.001 * mode->HTotal * mode->VTotal);
-
- if( ((mode->HDisplay * ((pScrn->bitsPerPixel + 7) / 8) * mode->VDisplay) >
- (pScrn->videoRam * 1024)) ||
- (mode->HDisplay > 8191) ||
- (mode->VDisplay > 8191) ) {
-
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Skipped \"%s\" (%dx%d), not enough video RAM or beyond hardware specs\n",
- mode->name, mode->HDisplay, mode->VDisplay);
- xfree(mode->Private);
- xfree(mode);
-
- return dest;
- }
-
- if(srel != radeonClone) {
- info->AtLeastOneNonClone = TRUE;
- }
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Merged \"%s\" (%dx%d) and \"%s\" (%dx%d) to %dx%d%s\n",
- i->name, i->HDisplay, i->VDisplay, j->name, j->HDisplay, j->VDisplay,
- mode->HDisplay, mode->VDisplay, (srel == radeonClone) ? " (Clone)" : "");
-
- mode->next = mode;
- mode->prev = mode;
-
- if(dest) {
- mode->next = dest->next; /* Insert node after "dest" */
- dest->next->prev = mode;
- mode->prev = dest;
- dest->next = mode;
- }
-
- return mode;
-}
-
-/* Helper function to find a mode from a given name
- * (Taken from mga, sis drivers)
- */
-static DisplayModePtr
-RADEONGetModeFromName(char* str, DisplayModePtr i)
-{
- DisplayModePtr c = i;
- if(!i) return NULL;
- do {
- if(strcmp(str, c->name) == 0) return c;
- c = c->next;
- } while(c != i);
- return NULL;
-}
-
-static DisplayModePtr
-RADEONFindWidestTallestMode(DisplayModePtr i, Bool tallest)
-{
- DisplayModePtr c = i, d = NULL;
- int max = 0;
- if(!i) return NULL;
- do {
- if(tallest) {
- if(c->VDisplay > max) {
- max = c->VDisplay;
- d = c;
- }
- } else {
- if(c->HDisplay > max) {
- max = c->HDisplay;
- d = c;
- }
- }
- c = c->next;
- } while(c != i);
- return d;
-}
-
-static void
-RADEONFindWidestTallestCommonMode(DisplayModePtr i, DisplayModePtr j, Bool tallest,
- DisplayModePtr *a, DisplayModePtr *b)
-{
- DisplayModePtr c = i, d;
- int max = 0;
- Bool foundone;
-
- (*a) = (*b) = NULL;
-
- if(!i || !j) return;
-
- do {
- d = j;
- foundone = FALSE;
- do {
- if( (c->HDisplay == d->HDisplay) &&
- (c->VDisplay == d->VDisplay) ) {
- foundone = TRUE;
- break;
- }
- d = d->next;
- } while(d != j);
- if(foundone) {
- if(tallest) {
- if(c->VDisplay > max) {
- max = c->VDisplay;
- (*a) = c;
- (*b) = d;
- }
- } else {
- if(c->HDisplay > max) {
- max = c->HDisplay;
- (*a) = c;
- (*b) = d;
- }
- }
- }
- c = c->next;
- } while(c != i);
-}
-
-static DisplayModePtr
-RADEONGenerateModeListFromLargestModes(ScrnInfoPtr pScrn,
- DisplayModePtr i, DisplayModePtr j,
- RADEONScrn2Rel srel)
-{
-
- RADEONInfoPtr info = RADEONPTR(pScrn);
- DisplayModePtr mode1 = NULL;
- DisplayModePtr mode2 = NULL;
- DisplayModePtr mode3 = NULL;
- DisplayModePtr mode4 = NULL;
- DisplayModePtr result = NULL;
-
- info->AtLeastOneNonClone = FALSE;
-
- /* Now build a default list of MetaModes.
- * - Non-clone: If the user enabled NonRectangular, we use the
- * largest mode for each CRT1 and CRT2. If not, we use the largest
- * common mode for CRT1 and CRT2 (if available). Additionally, and
- * regardless if the above, we produce a clone mode consisting of
- * the largest common mode (if available) in order to use DGA.
- * - Clone: If the (global) CRT2Position is Clone, we use the
- * largest common mode if available, otherwise the first two modes
- * in each list.
- */
-
- switch(srel) {
- case radeonLeftOf:
- case radeonRightOf:
- mode1 = RADEONFindWidestTallestMode(i, FALSE);
- mode2 = RADEONFindWidestTallestMode(j, FALSE);
- RADEONFindWidestTallestCommonMode(i, j, FALSE, &mode3, &mode4);
- break;
- case radeonAbove:
- case radeonBelow:
- mode1 = RADEONFindWidestTallestMode(i, TRUE);
- mode2 = RADEONFindWidestTallestMode(j, TRUE);
- RADEONFindWidestTallestCommonMode(i, j, TRUE, &mode3, &mode4);
- break;
- case radeonClone:
- RADEONFindWidestTallestCommonMode(i, j, FALSE, &mode3, &mode4);
- if(mode3 && mode4) {
- mode1 = mode3;
- mode2 = mode4;
- } else {
- mode1 = i;
- mode2 = j;
- }
- }
-
- if(srel != radeonClone) {
- if(mode3 && mode4 && !info->NonRect) {
- mode1 = mode3;
- mode2 = mode2;
- }
- }
-
- if(mode1 && mode2) {
- result = RADEONCopyModeNLink(pScrn, result, mode1, mode2, srel);
- }
-
- if(srel != radeonClone) {
- if(mode3 && mode4) {
- result = RADEONCopyModeNLink(pScrn, result, mode3, mode4, radeonClone);
- }
- }
- return result;
-}
-
-/* Generate the merged-fb mode modelist
- * (Taken from mga, sis drivers)
- */
-static DisplayModePtr
-RADEONGenerateModeListFromMetaModes(ScrnInfoPtr pScrn, char* str,
- DisplayModePtr i, DisplayModePtr j,
- RADEONScrn2Rel srel)
-{
- char* strmode = str;
- char modename[256];
- Bool gotdash = FALSE;
- char gotsep = 0;
- RADEONScrn2Rel sr;
- DisplayModePtr mode1 = NULL;
- DisplayModePtr mode2 = NULL;
- DisplayModePtr result = NULL;
- int myslen;
- RADEONInfoPtr info = RADEONPTR(pScrn);
-
- info->AtLeastOneNonClone = FALSE;
-
- do {
- switch(*str) {
- case 0:
- case '-':
- case '+':
- case ' ':
- case ',':
- case ';':
- if(strmode != str) {
-
- myslen = str - strmode;
- if(myslen > 255) myslen = 255;
- strncpy(modename, strmode, myslen);
- modename[myslen] = 0;
-
- if(gotdash) {
- if(mode1 == NULL) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Error parsing MetaModes parameter\n");
- return NULL;
- }
- mode2 = RADEONGetModeFromName(modename, j);
- if(!mode2) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Mode \"%s\" is not a supported mode for CRT2\n", modename);
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "\t(Skipping metamode \"%s%c%s\")\n", mode1->name, gotsep, modename);
- mode1 = NULL;
- gotsep = 0;
- }
- } else {
- mode1 = RADEONGetModeFromName(modename, i);
- if(!mode1) {
- char* tmps = str;
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Mode \"%s\" is not a supported mode for CRT1\n", modename);
- while(*tmps == ' ' || *tmps == ';') tmps++;
- /* skip the next mode */
- if(*tmps == '-' || *tmps == '+' || *tmps == ',') {
- tmps++;
- /* skip spaces */
- while(*tmps == ' ' || *tmps == ';') tmps++;
- /* skip modename */
- while(*tmps && *tmps != ' ' && *tmps != ';' && *tmps != '-' && *tmps != '+' && *tmps != ',') tmps++;
- myslen = tmps - strmode;
- if(myslen > 255) myslen = 255;
- strncpy(modename,strmode,myslen);
- modename[myslen] = 0;
- str = tmps-1;
- }
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "\t(Skipping metamode \"%s\")\n", modename);
- mode1 = NULL;
- gotsep = 0;
- }
- }
- gotdash = FALSE;
- }
- strmode = str + 1;
- gotdash |= (*str == '-' || *str == '+' || *str == ',');
- if (*str == '-' || *str == '+' || *str == ',')
- gotsep = *str;
-
- if(*str != 0) break;
- /* Fall through otherwise */
-
- default:
- if(!gotdash && mode1) {
- sr = srel;
- if(gotsep == '+') sr = radeonClone;
- if(!mode2) {
- mode2 = RADEONGetModeFromName(mode1->name, j);
- sr = radeonClone;
- }
- if(!mode2) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Mode \"%s\" is not a supported mode for CRT2\n", mode1->name);
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "\t(Skipping metamode \"%s\")\n", modename);
- mode1 = NULL;
- } else {
- result = RADEONCopyModeNLink(pScrn, result, mode1, mode2, sr);
- mode1 = NULL;
- mode2 = NULL;
- }
- gotsep = 0;
- }
- break;
-
- }
-
- } while(*(str++) != 0);
-
- return result;
-}
-
-DisplayModePtr
-RADEONGenerateModeList(ScrnInfoPtr pScrn, char* str,
- DisplayModePtr i, DisplayModePtr j,
- RADEONScrn2Rel srel)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
-
- if(str != NULL) {
- return(RADEONGenerateModeListFromMetaModes(pScrn, str, i, j, srel));
- } else {
- if (srel == radeonClone ) {
- DisplayModePtr p, q, result = NULL;
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Clone mode, list all common modes\n");
- for (p = i; p->next != i; p = p->next)
- for (q = j; q->next != j; q = q->next)
- if ((p->HDisplay == q->HDisplay) &&
- (p->VDisplay == q->VDisplay))
- result = RADEONCopyModeNLink(pScrn, result, p, q, srel);
- return result;
- } else {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "No MetaModes given, linking %s modes by default\n",
- (info->NonRect ?
- (((srel == radeonLeftOf) || (srel == radeonRightOf)) ? "widest" : "tallest")
- :
- (((srel == radeonLeftOf) || (srel == radeonRightOf)) ? "widest common" : "tallest common")) );
- return(RADEONGenerateModeListFromLargestModes(pScrn, i, j, srel));
- }
- }
-}
-
-void
-RADEONRecalcDefaultVirtualSize(ScrnInfoPtr pScrn)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- DisplayModePtr mode, bmode;
- int maxh, maxv;
- static const char *str = "MergedFB: Virtual %s %d\n";
- static const char *errstr = "Virtual %s to small for given CRT2Position offset\n";
-
- mode = bmode = pScrn->modes;
- maxh = maxv = 0;
- do {
- if(mode->HDisplay > maxh) maxh = mode->HDisplay;
- if(mode->VDisplay > maxv) maxv = mode->VDisplay;
- mode = mode->next;
- } while(mode != bmode);
- maxh += info->CRT1XOffs + info->CRT2XOffs;
- maxv += info->CRT1YOffs + info->CRT2YOffs;
-
- if(!(pScrn->display->virtualX)) {
- if(maxh > 8191) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Virtual width with CRT2Position offset beyond hardware specs\n");
- info->CRT1XOffs = info->CRT2XOffs = 0;
- maxh -= (info->CRT1XOffs + info->CRT2XOffs);
- }
- pScrn->virtualX = maxh;
- pScrn->displayWidth = maxh;
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED, str, "width", maxh);
- } else {
- if(maxh < pScrn->display->virtualX) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, errstr, "width");
- info->CRT1XOffs = info->CRT2XOffs = 0;
- }
- }
-
- if(!(pScrn->display->virtualY)) {
- pScrn->virtualY = maxv;
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED, str, "height", maxv);
- } else {
- if(maxv < pScrn->display->virtualY) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, errstr, "height");
- info->CRT1YOffs = info->CRT2YOffs = 0;
- }
- }
-}
-
-/* Pseudo-Xinerama extension for MergedFB mode */
-void
-RADEONUpdateXineramaScreenInfo(ScrnInfoPtr pScrn1)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn1);
- ScrnInfoPtr pScrn2 = NULL;
- int crt1scrnnum = 0, crt2scrnnum = 1;
- int x1=0, x2=0, y1=0, y2=0, h1=0, h2=0, w1=0, w2=0;
- int realvirtX, realvirtY;
- DisplayModePtr currentMode, firstMode;
- Bool infochanged = FALSE;
- Bool usenonrect = info->NonRect;
- const char *rectxine = "\t... setting up rectangular Xinerama layout\n";
-
- info->MBXNR1XMAX = info->MBXNR1YMAX = info->MBXNR2XMAX = info->MBXNR2YMAX = 65536;
- info->HaveNonRect = info->HaveOffsRegions = FALSE;
-
- if(!info->MergedFB) return;
-
- if(RADEONnoPanoramiXExtension) return;
-
- if(!RADEONXineramadataPtr) return;
-
- if(info->CRT2IsScrn0) {
- crt1scrnnum = 1;
- crt2scrnnum = 0;
- }
-
- pScrn2 = info->CRT2pScrn;
-
- /* Attention: Usage of RandR may lead into virtual X and Y values
- * actually smaller than our MetaModes! To avoid this, we calculate
- * the maxCRT fields here (and not somewhere else, like in CopyNLink)
- */
-
- /* "Real" virtual: Virtual without the Offset */
- realvirtX = pScrn1->virtualX - info->CRT1XOffs - info->CRT2XOffs;
- realvirtY = pScrn1->virtualY - info->CRT1YOffs - info->CRT2YOffs;
-
- if((info->RADEONXineramaVX != pScrn1->virtualX) || (info->RADEONXineramaVY != pScrn1->virtualY)) {
-
- if(!(pScrn1->modes)) {
- xf86DrvMsg(pScrn1->scrnIndex, X_ERROR,
- "Internal error: RADEONUpdateXineramaScreenInfo(): pScrn->modes is NULL\n");
- return;
- }
-
- info->maxCRT1_X1 = info->maxCRT1_X2 = 0;
- info->maxCRT1_Y1 = info->maxCRT1_Y2 = 0;
- info->maxCRT2_X1 = info->maxCRT2_X2 = 0;
- info->maxCRT2_Y1 = info->maxCRT2_Y2 = 0;
- info->maxClone_X1 = info->maxClone_X2 = 0;
- info->maxClone_Y1 = info->maxClone_Y2 = 0;
-
- currentMode = firstMode = pScrn1->modes;
-
- do {
-
- DisplayModePtr p = currentMode->next;
- DisplayModePtr i = ((RADEONMergedDisplayModePtr)currentMode->Private)->CRT1;
- DisplayModePtr j = ((RADEONMergedDisplayModePtr)currentMode->Private)->CRT2;
- RADEONScrn2Rel srel = ((RADEONMergedDisplayModePtr)currentMode->Private)->CRT2Position;
-
- if((currentMode->HDisplay <= realvirtX) && (currentMode->VDisplay <= realvirtY) &&
- (i->HDisplay <= realvirtX) && (j->HDisplay <= realvirtX) &&
- (i->VDisplay <= realvirtY) && (j->VDisplay <= realvirtY)) {
-
- if(srel != radeonClone) {
- if(info->maxCRT1_X1 == i->HDisplay) {
- if(info->maxCRT1_X2 < j->HDisplay) {
- info->maxCRT1_X2 = j->HDisplay; /* Widest CRT2 mode displayed with widest CRT1 mode */
- }
- } else if(info->maxCRT1_X1 < i->HDisplay) {
- info->maxCRT1_X1 = i->HDisplay; /* Widest CRT1 mode */
- info->maxCRT1_X2 = j->HDisplay;
- }
- if(info->maxCRT2_X2 == j->HDisplay) {
- if(info->maxCRT2_X1 < i->HDisplay) {
- info->maxCRT2_X1 = i->HDisplay; /* Widest CRT1 mode displayed with widest CRT2 mode */
- }
- } else if(info->maxCRT2_X2 < j->HDisplay) {
- info->maxCRT2_X2 = j->HDisplay; /* Widest CRT2 mode */
- info->maxCRT2_X1 = i->HDisplay;
- }
- if(info->maxCRT1_Y1 == i->VDisplay) { /* Same as above, but tallest instead of widest */
- if(info->maxCRT1_Y2 < j->VDisplay) {
- info->maxCRT1_Y2 = j->VDisplay;
- }
- } else if(info->maxCRT1_Y1 < i->VDisplay) {
- info->maxCRT1_Y1 = i->VDisplay;
- info->maxCRT1_Y2 = j->VDisplay;
- }
- if(info->maxCRT2_Y2 == j->VDisplay) {
- if(info->maxCRT2_Y1 < i->VDisplay) {
- info->maxCRT2_Y1 = i->VDisplay;
- }
- } else if(info->maxCRT2_Y2 < j->VDisplay) {
- info->maxCRT2_Y2 = j->VDisplay;
- info->maxCRT2_Y1 = i->VDisplay;
- }
- } else {
- if(info->maxClone_X1 < i->HDisplay) {
- info->maxClone_X1 = i->HDisplay;
- }
- if(info->maxClone_X2 < j->HDisplay) {
- info->maxClone_X2 = j->HDisplay;
- }
- if(info->maxClone_Y1 < i->VDisplay) {
- info->maxClone_Y1 = i->VDisplay;
- }
- if(info->maxClone_Y2 < j->VDisplay) {
- info->maxClone_Y2 = j->VDisplay;
- }
- }
- }
- currentMode = p;
-
- } while((currentMode) && (currentMode != firstMode));
-
- info->RADEONXineramaVX = pScrn1->virtualX;
- info->RADEONXineramaVY = pScrn1->virtualY;
- infochanged = TRUE;
-
- }
-
- if((usenonrect) && (info->CRT2Position != radeonClone) && info->maxCRT1_X1) {
- switch(info->CRT2Position) {
- case radeonLeftOf:
- case radeonRightOf:
- if((info->maxCRT1_Y1 != realvirtY) && (info->maxCRT2_Y2 != realvirtY)) {
- usenonrect = FALSE;
- }
- break;
- case radeonAbove:
- case radeonBelow:
- if((info->maxCRT1_X1 != realvirtX) && (info->maxCRT2_X2 != realvirtX)) {
- usenonrect = FALSE;
- }
- break;
- case radeonClone:
- break;
- }
-
- if(infochanged && !usenonrect) {
- xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
- "Virtual screen size does not match maximum display modes...\n");
- xf86DrvMsg(pScrn1->scrnIndex, X_INFO, rectxine);
-
- }
- } else if(infochanged && usenonrect) {
- usenonrect = FALSE;
- xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
- "Only clone modes available for this virtual screen size...\n");
- xf86DrvMsg(pScrn1->scrnIndex, X_INFO, rectxine);
- }
-
- if(info->maxCRT1_X1) { /* Means we have at least one non-clone mode */
- switch(info->CRT2Position) {
- case radeonLeftOf:
- x1 = min(info->maxCRT1_X2, pScrn1->virtualX - info->maxCRT1_X1);
- if(x1 < 0) x1 = 0;
- y1 = info->CRT1YOffs;
- w1 = pScrn1->virtualX - x1;
- h1 = realvirtY;
- if((usenonrect) && (info->maxCRT1_Y1 != realvirtY)) {
- h1 = info->MBXNR1YMAX = info->maxCRT1_Y1;
- info->NonRectDead.x0 = x1;
- info->NonRectDead.x1 = x1 + w1 - 1;
- info->NonRectDead.y0 = y1 + h1;
- info->NonRectDead.y1 = pScrn1->virtualY - 1;
- info->HaveNonRect = TRUE;
- }
- x2 = 0;
- y2 = info->CRT2YOffs;
- w2 = max(info->maxCRT2_X2, pScrn1->virtualX - info->maxCRT2_X1);
- if(w2 > pScrn1->virtualX) w2 = pScrn1->virtualX;
- h2 = realvirtY;
- if((usenonrect) && (info->maxCRT2_Y2 != realvirtY)) {
- h2 = info->MBXNR2YMAX = info->maxCRT2_Y2;
- info->NonRectDead.x0 = x2;
- info->NonRectDead.x1 = x2 + w2 - 1;
- info->NonRectDead.y0 = y2 + h2;
- info->NonRectDead.y1 = pScrn1->virtualY - 1;
- info->HaveNonRect = TRUE;
- }
- break;
- case radeonRightOf:
- x1 = 0;
- y1 = info->CRT1YOffs;
- w1 = max(info->maxCRT1_X1, pScrn1->virtualX - info->maxCRT1_X2);
- if(w1 > pScrn1->virtualX) w1 = pScrn1->virtualX;
- h1 = realvirtY;
- if((usenonrect) && (info->maxCRT1_Y1 != realvirtY)) {
- h1 = info->MBXNR1YMAX = info->maxCRT1_Y1;
- info->NonRectDead.x0 = x1;
- info->NonRectDead.x1 = x1 + w1 - 1;
- info->NonRectDead.y0 = y1 + h1;
- info->NonRectDead.y1 = pScrn1->virtualY - 1;
- info->HaveNonRect = TRUE;
- }
- x2 = min(info->maxCRT2_X1, pScrn1->virtualX - info->maxCRT2_X2);
- if(x2 < 0) x2 = 0;
- y2 = info->CRT2YOffs;
- w2 = pScrn1->virtualX - x2;
- h2 = realvirtY;
- if((usenonrect) && (info->maxCRT2_Y2 != realvirtY)) {
- h2 = info->MBXNR2YMAX = info->maxCRT2_Y2;
- info->NonRectDead.x0 = x2;
- info->NonRectDead.x1 = x2 + w2 - 1;
- info->NonRectDead.y0 = y2 + h2;
- info->NonRectDead.y1 = pScrn1->virtualY - 1;
- info->HaveNonRect = TRUE;
- }
- break;
- case radeonAbove:
- x1 = info->CRT1XOffs;
- y1 = min(info->maxCRT1_Y2, pScrn1->virtualY - info->maxCRT1_Y1);
- if(y1 < 0) y1 = 0;
- w1 = realvirtX;
- h1 = pScrn1->virtualY - y1;
- if((usenonrect) && (info->maxCRT1_X1 != realvirtX)) {
- w1 = info->MBXNR1XMAX = info->maxCRT1_X1;
- info->NonRectDead.x0 = x1 + w1;
- info->NonRectDead.x1 = pScrn1->virtualX - 1;
- info->NonRectDead.y0 = y1;
- info->NonRectDead.y1 = y1 + h1 - 1;
- info->HaveNonRect = TRUE;
- }
- x2 = info->CRT2XOffs;
- y2 = 0;
- w2 = realvirtX;
- h2 = max(info->maxCRT2_Y2, pScrn1->virtualY - info->maxCRT2_Y1);
- if(h2 > pScrn1->virtualY) h2 = pScrn1->virtualY;
- if((usenonrect) && (info->maxCRT2_X2 != realvirtX)) {
- w2 = info->MBXNR2XMAX = info->maxCRT2_X2;
- info->NonRectDead.x0 = x2 + w2;
- info->NonRectDead.x1 = pScrn1->virtualX - 1;
- info->NonRectDead.y0 = y2;
- info->NonRectDead.y1 = y2 + h2 - 1;
- info->HaveNonRect = TRUE;
- }
- break;
- case radeonBelow:
- x1 = info->CRT1XOffs;
- y1 = 0;
- w1 = realvirtX;
- h1 = max(info->maxCRT1_Y1, pScrn1->virtualY - info->maxCRT1_Y2);
- if(h1 > pScrn1->virtualY) h1 = pScrn1->virtualY;
- if((usenonrect) && (info->maxCRT1_X1 != realvirtX)) {
- w1 = info->MBXNR1XMAX = info->maxCRT1_X1;
- info->NonRectDead.x0 = x1 + w1;
- info->NonRectDead.x1 = pScrn1->virtualX - 1;
- info->NonRectDead.y0 = y1;
- info->NonRectDead.y1 = y1 + h1 - 1;
- info->HaveNonRect = TRUE;
- }
- x2 = info->CRT2XOffs;
- y2 = min(info->maxCRT2_Y1, pScrn1->virtualY - info->maxCRT2_Y2);
- if(y2 < 0) y2 = 0;
- w2 = realvirtX;
- h2 = pScrn1->virtualY - y2;
- if((usenonrect) && (info->maxCRT2_X2 != realvirtX)) {
- w2 = info->MBXNR2XMAX = info->maxCRT2_X2;
- info->NonRectDead.x0 = x2 + w2;
- info->NonRectDead.x1 = pScrn1->virtualX - 1;
- info->NonRectDead.y0 = y2;
- info->NonRectDead.y1 = y2 + h2 - 1;
- info->HaveNonRect = TRUE;
- }
- default:
- break;
- }
-
- switch(info->CRT2Position) {
- case radeonLeftOf:
- case radeonRightOf:
- if(info->CRT1YOffs) {
- info->OffDead1.x0 = x1;
- info->OffDead1.x1 = x1 + w1 - 1;
- info->OffDead1.y0 = 0;
- info->OffDead1.y1 = y1 - 1;
- info->OffDead2.x0 = x2;
- info->OffDead2.x1 = x2 + w2 - 1;
- info->OffDead2.y0 = y2 + h2;
- info->OffDead2.y1 = pScrn1->virtualY - 1;
- info->HaveOffsRegions = TRUE;
- } else if(info->CRT2YOffs) {
- info->OffDead1.x0 = x2;
- info->OffDead1.x1 = x2 + w2 - 1;
- info->OffDead1.y0 = 0;
- info->OffDead1.y1 = y2 - 1;
- info->OffDead2.x0 = x1;
- info->OffDead2.x1 = x1 + w1 - 1;
- info->OffDead2.y0 = y1 + h1;
- info->OffDead2.y1 = pScrn1->virtualY - 1;
- info->HaveOffsRegions = TRUE;
- }
- break;
- case radeonAbove:
- case radeonBelow:
- if(info->CRT1XOffs) {
- info->OffDead1.x0 = x2 + w2;
- info->OffDead1.x1 = pScrn1->virtualX - 1;
- info->OffDead1.y0 = y2;
- info->OffDead1.y1 = y2 + h2 - 1;
- info->OffDead2.x0 = 0;
- info->OffDead2.x1 = x1 - 1;
- info->OffDead2.y0 = y1;
- info->OffDead2.y1 = y1 + h1 - 1;
- info->HaveOffsRegions = TRUE;
- } else if(info->CRT2XOffs) {
- info->OffDead1.x0 = x1 + w1;
- info->OffDead1.x1 = pScrn1->virtualX - 1;
- info->OffDead1.y0 = y1;
- info->OffDead1.y1 = y1 + h1 - 1;
- info->OffDead2.x0 = 0;
- info->OffDead2.x1 = x2 - 1;
- info->OffDead2.y0 = y2;
- info->OffDead2.y1 = y2 + h2 - 1;
- info->HaveOffsRegions = TRUE;
- }
- default:
- break;
- }
-
- } else { /* Only clone-modes left */
-
- x1 = x2 = 0;
- y1 = y2 = 0;
- w1 = w2 = max(info->maxClone_X1, info->maxClone_X2);
- h1 = h2 = max(info->maxClone_Y1, info->maxClone_Y2);
-
- }
-
- RADEONXineramadataPtr[crt1scrnnum].x = x1;
- RADEONXineramadataPtr[crt1scrnnum].y = y1;
- RADEONXineramadataPtr[crt1scrnnum].width = w1;
- RADEONXineramadataPtr[crt1scrnnum].height = h1;
- RADEONXineramadataPtr[crt2scrnnum].x = x2;
- RADEONXineramadataPtr[crt2scrnnum].y = y2;
- RADEONXineramadataPtr[crt2scrnnum].width = w2;
- RADEONXineramadataPtr[crt2scrnnum].height = h2;
-
- if(infochanged) {
- xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
- "Pseudo-Xinerama: CRT1 (Screen %d) (%d,%d)-(%d,%d)\n",
- crt1scrnnum, x1, y1, w1+x1-1, h1+y1-1);
- xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
- "Pseudo-Xinerama: CRT2 (Screen %d) (%d,%d)-(%d,%d)\n",
- crt2scrnnum, x2, y2, w2+x2-1, h2+y2-1);
- if(info->HaveNonRect) {
- xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
- "Pseudo-Xinerama: Inaccessible area (%d,%d)-(%d,%d)\n",
- info->NonRectDead.x0, info->NonRectDead.y0,
- info->NonRectDead.x1, info->NonRectDead.y1);
- }
- if(info->HaveOffsRegions) {
- xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
- "Pseudo-Xinerama: Inaccessible offset area (%d,%d)-(%d,%d)\n",
- info->OffDead1.x0, info->OffDead1.y0,
- info->OffDead1.x1, info->OffDead1.y1);
- xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
- "Pseudo-Xinerama: Inaccessible offset area (%d,%d)-(%d,%d)\n",
- info->OffDead2.x0, info->OffDead2.y0,
- info->OffDead2.x1, info->OffDead2.y1);
- }
- if(info->HaveNonRect || info->HaveOffsRegions) {
- xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
- "Mouse restriction for inaccessible areas is %s\n",
- info->MouseRestrictions ? "enabled" : "disabled");
- }
- }
-}
-/* Proc */
-
-int
-RADEONProcXineramaQueryVersion(ClientPtr client)
-{
- xPanoramiXQueryVersionReply rep;
- register int n;
-
- REQUEST_SIZE_MATCH(xPanoramiXQueryVersionReq);
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.majorVersion = RADEON_XINERAMA_MAJOR_VERSION;
- rep.minorVersion = RADEON_XINERAMA_MINOR_VERSION;
- if(client->swapped) {
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- swaps(&rep.majorVersion, n);
- swaps(&rep.minorVersion, n);
- }
- WriteToClient(client, sizeof(xPanoramiXQueryVersionReply), (char *)&rep);
- return (client->noClientException);
-}
-
-int
-RADEONProcXineramaGetState(ClientPtr client)
-{
- REQUEST(xPanoramiXGetStateReq);
- WindowPtr pWin;
- xPanoramiXGetStateReply rep;
- register int n;
-
- REQUEST_SIZE_MATCH(xPanoramiXGetStateReq);
- pWin = LookupWindow(stuff->window, client);
- if(!pWin) return BadWindow;
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.state = !RADEONnoPanoramiXExtension;
- if(client->swapped) {
- swaps (&rep.sequenceNumber, n);
- swapl (&rep.length, n);
- swaps (&rep.state, n);
- }
- WriteToClient(client, sizeof(xPanoramiXGetStateReply), (char *)&rep);
- return client->noClientException;
-}
-
-int
-RADEONProcXineramaGetScreenCount(ClientPtr client)
-{
- REQUEST(xPanoramiXGetScreenCountReq);
- WindowPtr pWin;
- xPanoramiXGetScreenCountReply rep;
- register int n;
-
- REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq);
- pWin = LookupWindow(stuff->window, client);
- if(!pWin) return BadWindow;
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.ScreenCount = RADEONXineramaNumScreens;
- if(client->swapped) {
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- swaps(&rep.ScreenCount, n);
- }
- WriteToClient(client, sizeof(xPanoramiXGetScreenCountReply), (char *)&rep);
- return client->noClientException;
-}
-
-int
-RADEONProcXineramaGetScreenSize(ClientPtr client)
-{
- REQUEST(xPanoramiXGetScreenSizeReq);
- WindowPtr pWin;
- xPanoramiXGetScreenSizeReply rep;
- register int n;
-
- REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
- pWin = LookupWindow (stuff->window, client);
- if(!pWin) return BadWindow;
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.width = RADEONXineramadataPtr[stuff->screen].width;
- rep.height = RADEONXineramadataPtr[stuff->screen].height;
- if(client->swapped) {
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- swaps(&rep.width, n);
- swaps(&rep.height, n);
- }
- WriteToClient(client, sizeof(xPanoramiXGetScreenSizeReply), (char *)&rep);
- return client->noClientException;
-}
-
-int
-RADEONProcXineramaIsActive(ClientPtr client)
-{
- xXineramaIsActiveReply rep;
-
- REQUEST_SIZE_MATCH(xXineramaIsActiveReq);
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.state = !RADEONnoPanoramiXExtension;
- if(client->swapped) {
- register int n;
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- swapl(&rep.state, n);
- }
- WriteToClient(client, sizeof(xXineramaIsActiveReply), (char *) &rep);
- return client->noClientException;
-}
-
-int
-RADEONProcXineramaQueryScreens(ClientPtr client)
-{
- xXineramaQueryScreensReply rep;
-
- REQUEST_SIZE_MATCH(xXineramaQueryScreensReq);
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.number = (RADEONnoPanoramiXExtension) ? 0 : RADEONXineramaNumScreens;
- rep.length = rep.number * sz_XineramaScreenInfo >> 2;
- if(client->swapped) {
- register int n;
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- swapl(&rep.number, n);
- }
- WriteToClient(client, sizeof(xXineramaQueryScreensReply), (char *)&rep);
-
- if(!RADEONnoPanoramiXExtension) {
- xXineramaScreenInfo scratch;
- int i;
-
- for(i = 0; i < RADEONXineramaNumScreens; i++) {
- scratch.x_org = RADEONXineramadataPtr[i].x;
- scratch.y_org = RADEONXineramadataPtr[i].y;
- scratch.width = RADEONXineramadataPtr[i].width;
- scratch.height = RADEONXineramadataPtr[i].height;
- if(client->swapped) {
- register int n;
- swaps(&scratch.x_org, n);
- swaps(&scratch.y_org, n);
- swaps(&scratch.width, n);
- swaps(&scratch.height, n);
- }
- WriteToClient(client, sz_XineramaScreenInfo, (char *)&scratch);
- }
- }
-
- return client->noClientException;
-}
-
-static int
-RADEONProcXineramaDispatch(ClientPtr client)
-{
- REQUEST(xReq);
- switch (stuff->data)
- {
- case X_PanoramiXQueryVersion:
- return RADEONProcXineramaQueryVersion(client);
- case X_PanoramiXGetState:
- return RADEONProcXineramaGetState(client);
- case X_PanoramiXGetScreenCount:
- return RADEONProcXineramaGetScreenCount(client);
- case X_PanoramiXGetScreenSize:
- return RADEONProcXineramaGetScreenSize(client);
- case X_XineramaIsActive:
- return RADEONProcXineramaIsActive(client);
- case X_XineramaQueryScreens:
- return RADEONProcXineramaQueryScreens(client);
- }
- return BadRequest;
-}
-
-/* SProc */
-
-static int
-RADEONSProcXineramaQueryVersion (ClientPtr client)
-{
- REQUEST(xPanoramiXQueryVersionReq);
- register int n;
- swaps(&stuff->length,n);
- REQUEST_SIZE_MATCH (xPanoramiXQueryVersionReq);
- return RADEONProcXineramaQueryVersion(client);
-}
-
-static int
-RADEONSProcXineramaGetState(ClientPtr client)
-{
- REQUEST(xPanoramiXGetStateReq);
- register int n;
- swaps (&stuff->length, n);
- REQUEST_SIZE_MATCH(xPanoramiXGetStateReq);
- return RADEONProcXineramaGetState(client);
-}
-
-static int
-RADEONSProcXineramaGetScreenCount(ClientPtr client)
-{
- REQUEST(xPanoramiXGetScreenCountReq);
- register int n;
- swaps (&stuff->length, n);
- REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq);
- return RADEONProcXineramaGetScreenCount(client);
-}
-
-static int
-RADEONSProcXineramaGetScreenSize(ClientPtr client)
-{
- REQUEST(xPanoramiXGetScreenSizeReq);
- register int n;
- swaps (&stuff->length, n);
- REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
- return RADEONProcXineramaGetScreenSize(client);
-}
-
-static int
-RADEONSProcXineramaIsActive(ClientPtr client)
-{
- REQUEST(xXineramaIsActiveReq);
- register int n;
- swaps (&stuff->length, n);
- REQUEST_SIZE_MATCH(xXineramaIsActiveReq);
- return RADEONProcXineramaIsActive(client);
-}
-
-static int
-RADEONSProcXineramaQueryScreens(ClientPtr client)
-{
- REQUEST(xXineramaQueryScreensReq);
- register int n;
- swaps (&stuff->length, n);
- REQUEST_SIZE_MATCH(xXineramaQueryScreensReq);
- return RADEONProcXineramaQueryScreens(client);
-}
-
-int
-RADEONSProcXineramaDispatch(ClientPtr client)
-{
- REQUEST(xReq);
- switch (stuff->data) {
- case X_PanoramiXQueryVersion:
- return RADEONSProcXineramaQueryVersion(client);
- case X_PanoramiXGetState:
- return RADEONSProcXineramaGetState(client);
- case X_PanoramiXGetScreenCount:
- return RADEONSProcXineramaGetScreenCount(client);
- case X_PanoramiXGetScreenSize:
- return RADEONSProcXineramaGetScreenSize(client);
- case X_XineramaIsActive:
- return RADEONSProcXineramaIsActive(client);
- case X_XineramaQueryScreens:
- return RADEONSProcXineramaQueryScreens(client);
- }
- return BadRequest;
-}
-
-static void
-RADEONXineramaResetProc(ExtensionEntry* extEntry)
-{
- if(RADEONXineramadataPtr) {
- Xfree(RADEONXineramadataPtr);
- RADEONXineramadataPtr = NULL;
- }
-}
-
-void
-RADEONXineramaExtensionInit(ScrnInfoPtr pScrn)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- Bool success = FALSE;
-
- if(!(RADEONXineramadataPtr)) {
-
- if(!info->MergedFB) {
- RADEONnoPanoramiXExtension = TRUE;
- info->MouseRestrictions = FALSE;
- return;
- }
-
-#ifdef PANORAMIX
- if(!noPanoramiXExtension) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Xinerama active, not initializing Radeon Pseudo-Xinerama\n");
- RADEONnoPanoramiXExtension = TRUE;
- info->MouseRestrictions = FALSE;
- return;
- }
-#endif
-
- if(RADEONnoPanoramiXExtension) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Radeon Pseudo-Xinerama disabled\n");
- info->MouseRestrictions = FALSE;
- return;
- }
-
- if(info->CRT2Position == radeonClone) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Running MergedFB in Clone mode, Radeon Pseudo-Xinerama disabled\n");
- RADEONnoPanoramiXExtension = TRUE;
- info->MouseRestrictions = FALSE;
- return;
- }
-
- if(!(info->AtLeastOneNonClone)) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Only Clone modes defined, Radeon Pseudo-Xinerama disabled\n");
- RADEONnoPanoramiXExtension = TRUE;
- info->MouseRestrictions = FALSE;
- return;
- }
-
- RADEONXineramaNumScreens = 2;
-
- while(RADEONXineramaGeneration != serverGeneration) {
-
- info->XineramaExtEntry = AddExtension(PANORAMIX_PROTOCOL_NAME, 0,0,
- RADEONProcXineramaDispatch,
- RADEONSProcXineramaDispatch,
- RADEONXineramaResetProc,
- StandardMinorOpcode);
-
- if(!info->XineramaExtEntry) break;
-
- RADEONXineramaReqCode = (unsigned char)info->XineramaExtEntry->base;
-
- if(!(RADEONXineramadataPtr = (RADEONXineramaData *)
- xcalloc(RADEONXineramaNumScreens, sizeof(RADEONXineramaData)))) break;
-
- RADEONXineramaGeneration = serverGeneration;
- success = TRUE;
- }
-
- if(!success) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Failed to initialize Radeon Pseudo-Xinerama extension\n");
- RADEONnoPanoramiXExtension = TRUE;
- info->MouseRestrictions = FALSE;
- return;
- }
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Initialized Radeon Pseudo-Xinerama extension\n");
-
- info->RADEONXineramaVX = 0;
- info->RADEONXineramaVY = 0;
-
- }
-
- RADEONUpdateXineramaScreenInfo(pScrn);
-
-}
-/* End of PseudoXinerama */
-
-static Bool
-InRegion(int x, int y, region r)
-{
- return (r.x0 <= x) && (x <= r.x1) && (r.y0 <= y) && (y <= r.y1);
-}
-
-void
-RADEONMergePointerMoved(int scrnIndex, int x, int y)
-{
- ScrnInfoPtr pScrn1 = xf86Screens[scrnIndex];
- RADEONInfoPtr info = RADEONPTR(pScrn1);
- ScrnInfoPtr pScrn2 = info->CRT2pScrn;
- region out, in1, in2, f2, f1;
- int deltax, deltay;
- int temp1, temp2;
- int old1x0, old1y0, old2x0, old2y0;
- int CRT1XOffs = 0, CRT1YOffs = 0, CRT2XOffs = 0, CRT2YOffs = 0;
- int HVirt = pScrn1->virtualX;
- int VVirt = pScrn1->virtualY;
- int sigstate;
- Bool doit = FALSE, HaveNonRect = FALSE, HaveOffsRegions = FALSE;
- RADEONScrn2Rel srel = ((RADEONMergedDisplayModePtr)info->CurrentLayout.mode->Private)->CRT2Position;
-
- if(info->DGAactive) {
- return;
- /* DGA: There is no cursor and no panning while DGA is active. */
- /* If it were, we would need to do: */
- /* HVirt = info->CurrentLayout.displayWidth;
- VVirt = info->CurrentLayout.displayHeight;
- BOUND(x, info->CurrentLayout.DGAViewportX, HVirt);
- BOUND(y, info->CurrentLayout.DGAViewportY, VVirt); */
- } else {
- CRT1XOffs = info->CRT1XOffs;
- CRT1YOffs = info->CRT1YOffs;
- CRT2XOffs = info->CRT2XOffs;
- CRT2YOffs = info->CRT2YOffs;
- HaveNonRect = info->HaveNonRect;
- HaveOffsRegions = info->HaveOffsRegions;
- }
-
- /* Check if the pointer is inside our dead areas */
- if((info->MouseRestrictions) && (srel != radeonClone) && !RADEONnoPanoramiXExtension) {
- if(HaveNonRect) {
- if(InRegion(x, y, info->NonRectDead)) {
- switch(srel) {
- case radeonLeftOf:
- case radeonRightOf: y = info->NonRectDead.y0 - 1;
- doit = TRUE;
- break;
- case radeonAbove:
- case radeonBelow: x = info->NonRectDead.x0 - 1;
- doit = TRUE;
- default: break;
- }
- }
- }
- if(HaveOffsRegions) {
- if(InRegion(x, y, info->OffDead1)) {
- switch(srel) {
- case radeonLeftOf:
- case radeonRightOf: y = info->OffDead1.y1;
- doit = TRUE;
- break;
- case radeonAbove:
- case radeonBelow: x = info->OffDead1.x1;
- doit = TRUE;
- default: break;
- }
- } else if(InRegion(x, y, info->OffDead2)) {
- switch(srel) {
- case radeonLeftOf:
- case radeonRightOf: y = info->OffDead2.y0 - 1;
- doit = TRUE;
- break;
- case radeonAbove:
- case radeonBelow: x = info->OffDead2.x0 - 1;
- doit = TRUE;
- default: break;
- }
- }
- }
- if(doit) {
- UpdateCurrentTime();
- sigstate = xf86BlockSIGIO();
- miPointerAbsoluteCursor(x, y, currentTime.milliseconds);
- xf86UnblockSIGIO(sigstate);
- return;
- }
- }
-
- f1.x0 = old1x0 = info->CRT1frameX0;
- f1.x1 = info->CRT1frameX1;
- f1.y0 = old1y0 = info->CRT1frameY0;
- f1.y1 = info->CRT1frameY1;
- f2.x0 = old2x0 = pScrn2->frameX0;
- f2.x1 = pScrn2->frameX1;
- f2.y0 = old2y0 = pScrn2->frameY0;
- f2.y1 = pScrn2->frameY1;
-
- /* Define the outer region. Crossing this causes all frames to move */
- out.x0 = pScrn1->frameX0;
- out.x1 = pScrn1->frameX1;
- out.y0 = pScrn1->frameY0;
- out.y1 = pScrn1->frameY1;
-
- /*
- * Define the inner sliding window. Being outsize both frames but
- * inside the outer clipping window will slide corresponding frame
- */
- in1 = out;
- in2 = out;
- switch(srel) {
- case radeonLeftOf:
- in1.x0 = f1.x0;
- in2.x1 = f2.x1;
- break;
- case radeonRightOf:
- in1.x1 = f1.x1;
- in2.x0 = f2.x0;
- break;
- case radeonBelow:
- in1.y1 = f1.y1;
- in2.y0 = f2.y0;
- break;
- case radeonAbove:
- in1.y0 = f1.y0;
- in2.y1 = f2.y1;
- break;
- case radeonClone:
- break;
- }
-
- deltay = 0;
- deltax = 0;
-
- if(InRegion(x, y, out)) { /* inside outer region */
-
- /* xf86DrvMsg(0, X_INFO, "1: %d %d | %d %d %d %d | %d %d %d %d\n",
- x, y, in1.x0, in1.x1, in1.y0, in1.y1, f1.x0, f1.x1, f1.y0, f1.y1); */
-
- if(InRegion(x, y, in1) && !InRegion(x, y, f1)) {
- REBOUND(f1.x0, f1.x1, x);
- REBOUND(f1.y0, f1.y1, y);
- deltax = 1;
- /* xf86DrvMsg(0, X_INFO, "2: %d %d | %d %d %d %d | %d %d %d %d\n",
- x, y, in1.x0, in1.x1, in1.y0, in1.y1, f1.x0, f1.x1, f1.y0, f1.y1); */
- }
- if(InRegion(x, y, in2) && !InRegion(x, y, f2)) {
- REBOUND(f2.x0, f2.x1, x);
- REBOUND(f2.y0, f2.y1, y);
- deltax = 1;
- }
-
- } else { /* outside outer region */
-
- /* xf86DrvMsg(0, X_INFO, "3: %d %d | %d %d %d %d | %d %d %d %d\n",
- x, y, in1.x0, in1.x1, in1.y0, in1.y1, f1.x0, f1.x1, f1.y0, f1.y1);
- xf86DrvMsg(0, X_INFO, "3-out: %d %d %d %d\n",
- out.x0, out.x1, out.y0, out.y1); */
-
- if(out.x0 > x) {
- deltax = x - out.x0;
- }
- if(out.x1 < x) {
- deltax = x - out.x1;
- }
- if(deltax) {
- pScrn1->frameX0 += deltax;
- pScrn1->frameX1 += deltax;
- f1.x0 += deltax;
- f1.x1 += deltax;
- f2.x0 += deltax;
- f2.x1 += deltax;
- }
-
- if(out.y0 > y) {
- deltay = y - out.y0;
- }
- if(out.y1 < y) {
- deltay = y - out.y1;
- }
- if(deltay) {
- pScrn1->frameY0 += deltay;
- pScrn1->frameY1 += deltay;
- f1.y0 += deltay;
- f1.y1 += deltay;
- f2.y0 += deltay;
- f2.y1 += deltay;
- }
-
- switch(srel) {
- case radeonLeftOf:
- if(x >= f1.x0) { REBOUND(f1.y0, f1.y1, y); }
- if(x <= f2.x1) { REBOUND(f2.y0, f2.y1, y); }
- break;
- case radeonRightOf:
- if(x <= f1.x1) { REBOUND(f1.y0, f1.y1, y); }
- if(x >= f2.x0) { REBOUND(f2.y0, f2.y1, y); }
- break;
- case radeonBelow:
- if(y <= f1.y1) { REBOUND(f1.x0, f1.x1, x); }
- if(y >= f2.y0) { REBOUND(f2.x0, f2.x1, x); }
- break;
- case radeonAbove:
- if(y >= f1.y0) { REBOUND(f1.x0, f1.x1, x); }
- if(y <= f2.y1) { REBOUND(f2.x0, f2.x1, x); }
- break;
- case radeonClone:
- break;
- }
-
- }
-
- if(deltax || deltay) {
- info->CRT1frameX0 = f1.x0;
- info->CRT1frameY0 = f1.y0;
- pScrn2->frameX0 = f2.x0;
- pScrn2->frameY0 = f2.y0;
-
- switch(((RADEONMergedDisplayModePtr)info->CurrentLayout.mode->Private)->CRT2Position) {
- case radeonLeftOf:
- case radeonRightOf:
- if(info->CRT1YOffs || info->CRT2YOffs || HaveNonRect) {
- if(info->CRT1frameY0 != old1y0) {
- if(info->CRT1frameY0 < info->CRT1YOffs)
- info->CRT1frameY0 = info->CRT1YOffs;
- temp1 = info->CRT1frameY0 + CDMPTR->CRT1->VDisplay;
- /*temp2 = pScrn1->virtualY - info->CRT2YOffs;*/
- temp2 = min((VVirt - CRT2YOffs), (CRT1YOffs + info->MBXNR1YMAX));
- if(temp1 > temp2)
- info->CRT1frameY0 -= (temp1 - temp2);
- }
- if(pScrn2->frameY0 != old2y0) {
- if(pScrn2->frameY0 < info->CRT2YOffs)
- pScrn2->frameY0 = info->CRT2YOffs;
- temp1 = pScrn2->frameY0 + CDMPTR->CRT2->VDisplay;
- /*temp2 = pScrn1->virtualY - info->CRT1YOffs;*/
- temp2 = min((VVirt - CRT1YOffs), (CRT2YOffs + info->MBXNR2YMAX));
- if(temp1 > temp2)
- pScrn2->frameY0 -= (temp1 - temp2);
- }
- }
- break;
- case radeonBelow:
- case radeonAbove:
- if(info->CRT1XOffs || info->CRT2XOffs || HaveNonRect) {
- if(info->CRT1frameX0 != old1x0) {
- if(info->CRT1frameX0 < info->CRT1XOffs)
- info->CRT1frameX0 = info->CRT1XOffs;
- temp1 = info->CRT1frameX0 + CDMPTR->CRT1->HDisplay;
- /*temp2 = pScrn1->virtualX - info->CRT2XOffs;*/
- temp2 = min((HVirt - CRT2XOffs), (CRT1XOffs + info->MBXNR1XMAX));
- if(temp1 > temp2)
- info->CRT1frameX0 -= (temp1 - temp2);
- }
- if(pScrn2->frameX0 != old2x0) {
- if(pScrn2->frameX0 < info->CRT2XOffs)
- pScrn2->frameX0 = info->CRT2XOffs;
- temp1 = pScrn2->frameX0 + CDMPTR->CRT2->HDisplay;
- /*temp2 = pScrn1->virtualX - info->CRT1XOffs;*/
- temp2 = min((HVirt - CRT1XOffs), (CRT2XOffs + info->MBXNR2XMAX));
- if(temp1 > temp2)
- pScrn2->frameX0 -= (temp1 - temp2);
- }
- }
- break;
- case radeonClone:
- break;
- }
-
- info->CRT1frameX1 = info->CRT1frameX0 + CDMPTR->CRT1->HDisplay - 1;
- info->CRT1frameY1 = info->CRT1frameY0 + CDMPTR->CRT1->VDisplay - 1;
- pScrn2->frameX1 = pScrn2->frameX0 + CDMPTR->CRT2->HDisplay - 1;
- pScrn2->frameY1 = pScrn2->frameY0 + CDMPTR->CRT2->VDisplay - 1;
-#if 0
- pScrn1->frameX1 = pScrn1->frameX0 + info->CurrentLayout.mode->HDisplay - 1;
- pScrn1->frameY1 = pScrn1->frameY0 + info->CurrentLayout.mode->VDisplay - 1;
-#endif
-
- RADEONDoAdjustFrame(pScrn1, info->CRT1frameX0, info->CRT1frameY0, FALSE);
- RADEONDoAdjustFrame(pScrn1, pScrn2->frameX0, pScrn2->frameY0, TRUE);
- }
-}
-
-static void
-RADEONAdjustFrameMergedHelper(int scrnIndex, int x, int y, int flags)
-{
- ScrnInfoPtr pScrn1 = xf86Screens[scrnIndex];
- RADEONInfoPtr info = RADEONPTR(pScrn1);
- ScrnInfoPtr pScrn2 = info->CRT2pScrn;
- int VTotal = info->CurrentLayout.mode->VDisplay;
- int HTotal = info->CurrentLayout.mode->HDisplay;
- int VMax = VTotal;
- int HMax = HTotal;
- int HVirt = pScrn1->virtualX;
- int VVirt = pScrn1->virtualY;
- int x1 = x, x2 = x;
- int y1 = y, y2 = y;
- int CRT1XOffs = 0, CRT1YOffs = 0, CRT2XOffs = 0, CRT2YOffs = 0;
- int MBXNR1XMAX = 65536, MBXNR1YMAX = 65536, MBXNR2XMAX = 65536, MBXNR2YMAX = 65536;
-
- if(info->DGAactive) {
- HVirt = info->CurrentLayout.displayWidth;
- VVirt = info->CurrentLayout.displayHeight;
- } else {
- CRT1XOffs = info->CRT1XOffs;
- CRT1YOffs = info->CRT1YOffs;
- CRT2XOffs = info->CRT2XOffs;
- CRT2YOffs = info->CRT2YOffs;
- MBXNR1XMAX = info->MBXNR1XMAX;
- MBXNR1YMAX = info->MBXNR1YMAX;
- MBXNR2XMAX = info->MBXNR2XMAX;
- MBXNR2YMAX = info->MBXNR2YMAX;
- }
-
-
- BOUND(x, 0, pScrn1->virtualX - HTotal);
- BOUND(y, 0, pScrn1->virtualY - VTotal);
- if(SDMPTR(pScrn1)->CRT2Position != radeonClone) {
-#if 0
- BOUND(x1, info->CRT1XOffs, pScrn1->virtualX - HTotal - info->CRT2XOffs);
- BOUND(y1, info->CRT1YOffs, pScrn1->virtualY - VTotal - info->CRT2YOffs);
- BOUND(x2, info->CRT2XOffs, pScrn1->virtualX - HTotal - info->CRT1XOffs);
- BOUND(y2, info->CRT2YOffs, pScrn1->virtualY - VTotal - info->CRT1YOffs);
-#endif
- BOUND(x1, CRT1XOffs, min(HVirt, MBXNR1XMAX + CRT1XOffs) - min(HTotal, MBXNR1XMAX) - CRT2XOffs);
- BOUND(y1, CRT1YOffs, min(VVirt, MBXNR1YMAX + CRT1YOffs) - min(VTotal, MBXNR1YMAX) - CRT2YOffs);
- BOUND(x2, CRT2XOffs, min(HVirt, MBXNR2XMAX + CRT2XOffs) - min(HTotal, MBXNR2XMAX) - CRT1XOffs);
- BOUND(y2, CRT2YOffs, min(VVirt, MBXNR2YMAX + CRT2YOffs) - min(VTotal, MBXNR2YMAX) - CRT1YOffs);
- }
-
- switch(SDMPTR(pScrn1)->CRT2Position) {
- case radeonLeftOf:
- pScrn2->frameX0 = x2;
- /*BOUND(pScrn2->frameY0, y2, y2 + VMax - CDMPTR->CRT2->VDisplay);*/
- BOUND(pScrn2->frameY0, y2, y2 + min(VMax, MBXNR2YMAX) - CDMPTR->CRT2->VDisplay);
- info->CRT1frameX0 = x1 + CDMPTR->CRT2->HDisplay;
- /*BOUND(info->CRT1frameY0, y1, y1 + VMax - CDMPTR->CRT1->VDisplay);*/
- BOUND(info->CRT1frameY0, y1, y1 + min(VMax, MBXNR1YMAX) - CDMPTR->CRT1->VDisplay);
- break;
- case radeonRightOf:
- info->CRT1frameX0 = x1;
- /*BOUND(info->CRT1frameY0, y1, y1 + VMax - CDMPTR->CRT1->VDisplay);*/
- BOUND(info->CRT1frameY0, y1, y1 + min(VMax, MBXNR1YMAX) - CDMPTR->CRT1->VDisplay);
- pScrn2->frameX0 = x2 + CDMPTR->CRT1->HDisplay;
- /*BOUND(pScrn2->frameY0, y2, y2 + VMax - CDMPTR->CRT2->VDisplay);*/
- BOUND(pScrn2->frameY0, y2, y2 + min(VMax, MBXNR2YMAX) - CDMPTR->CRT2->VDisplay);
- break;
- case radeonAbove:
- /*BOUND(pScrn2->frameX0, x2, x2 + HMax - CDMPTR->CRT2->HDisplay);*/
- BOUND(pScrn2->frameX0, x2, x2 + min(HMax, MBXNR2XMAX) - CDMPTR->CRT2->HDisplay);
- pScrn2->frameY0 = y2;
- /*BOUND(info->CRT1frameX0, x1, x1 + HMax - CDMPTR->CRT1->HDisplay);*/
- BOUND(info->CRT1frameX0, x1, x1 + min(HMax, MBXNR1XMAX) - CDMPTR->CRT1->HDisplay);
- info->CRT1frameY0 = y1 + CDMPTR->CRT2->VDisplay;
- break;
- case radeonBelow:
- /*BOUND(info->CRT1frameX0, x1, x1 + HMax - CDMPTR->CRT1->HDisplay);*/
- BOUND(info->CRT1frameX0, x1, x1 + min(HMax, MBXNR1XMAX) - CDMPTR->CRT1->HDisplay);
- info->CRT1frameY0 = y1;
- /*BOUND(pScrn2->frameX0, x2, x2 + HMax - CDMPTR->CRT2->HDisplay);*/
- BOUND(pScrn2->frameX0, x2, x2 + min(HMax, MBXNR2XMAX) - CDMPTR->CRT2->HDisplay);
- pScrn2->frameY0 = y2 + CDMPTR->CRT1->VDisplay;
- break;
- case radeonClone:
- BOUND(info->CRT1frameX0, x, x + HMax - CDMPTR->CRT1->HDisplay);
- BOUND(info->CRT1frameY0, y, y + VMax - CDMPTR->CRT1->VDisplay);
- BOUND(pScrn2->frameX0, x, x + HMax - CDMPTR->CRT2->HDisplay);
- BOUND(pScrn2->frameY0, y, y + VMax - CDMPTR->CRT2->VDisplay);
- break;
- }
-
- BOUND(info->CRT1frameX0, 0, pScrn1->virtualX - CDMPTR->CRT1->HDisplay);
- BOUND(info->CRT1frameY0, 0, pScrn1->virtualY - CDMPTR->CRT1->VDisplay);
- BOUND(pScrn2->frameX0, 0, pScrn1->virtualX - CDMPTR->CRT2->HDisplay);
- BOUND(pScrn2->frameY0, 0, pScrn1->virtualY - CDMPTR->CRT2->VDisplay);
-
- pScrn1->frameX0 = x;
- pScrn1->frameY0 = y;
-
- info->CRT1frameX1 = info->CRT1frameX0 + CDMPTR->CRT1->HDisplay - 1;
- info->CRT1frameY1 = info->CRT1frameY0 + CDMPTR->CRT1->VDisplay - 1;
- pScrn2->frameX1 = pScrn2->frameX0 + CDMPTR->CRT2->HDisplay - 1;
- pScrn2->frameY1 = pScrn2->frameY0 + CDMPTR->CRT2->VDisplay - 1;
- pScrn1->frameX1 = pScrn1->frameX0 + info->CurrentLayout.mode->HDisplay - 1;
- pScrn1->frameY1 = pScrn1->frameY0 + info->CurrentLayout.mode->VDisplay - 1;
-
- if(SDMPTR(pScrn1)->CRT2Position != radeonClone) {
- pScrn1->frameX1 += CRT1XOffs + CRT2XOffs;
- pScrn1->frameY1 += CRT1YOffs + CRT2YOffs;
- }
-
-/*
- RADEONDoAdjustFrame(pScrn1, info->CRT1frameX0, info->CRT1frameY0, FALSE);
- RADEONDoAdjustFrame(pScrn1, pScrn2->frameX0, pScrn2->frameY0, TRUE);
-*/
-}
-
-void
-RADEONAdjustFrameMerged(int scrnIndex, int x, int y, int flags)
-{
- ScrnInfoPtr pScrn1 = xf86Screens[scrnIndex];
- RADEONInfoPtr info = RADEONPTR(pScrn1);
- ScrnInfoPtr pScrn2 = info->CRT2pScrn;
-
- RADEONAdjustFrameMergedHelper(scrnIndex, x, y, flags);
- RADEONDoAdjustFrame(pScrn1, info->CRT1frameX0, info->CRT1frameY0, FALSE);
- RADEONDoAdjustFrame(pScrn1, pScrn2->frameX0, pScrn2->frameY0, TRUE);
-}
-
-static void
-RADEONMergedFBCalcDPI(ScrnInfoPtr pScrn1, ScrnInfoPtr pScrn2, RADEONScrn2Rel srel, Bool quiet)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn1);
- MessageType from = X_DEFAULT;
- xf86MonPtr DDC1 = (xf86MonPtr)(pScrn1->monitor->DDC);
- xf86MonPtr DDC2 = (xf86MonPtr)(pScrn2->monitor->DDC);
- int ddcWidthmm = 0, ddcHeightmm = 0;
- const char *dsstr = "MergedFB: Display dimensions: %dx%d mm\n";
-
- /* This sets the DPI for MergedFB mode. The problem is that
- * this can never be exact, because the output devices may
- * have different dimensions. This function tries to compromise
- * through a few assumptions, and it just calculates an average
- * DPI value for both monitors.
- */
-
- /* Copy user-given DisplaySize (which should regard BOTH monitors!) */
- pScrn1->widthmm = pScrn1->monitor->widthmm;
- pScrn1->heightmm = pScrn1->monitor->heightmm;
-
- if(monitorResolution > 0) {
-
- /* Set command line given values (overrules given options) */
- pScrn1->xDpi = monitorResolution;
- pScrn1->yDpi = monitorResolution;
- from = X_CMDLINE;
-
- } else if(info->MergedFBXDPI) {
-
- /* Set option-wise given values (overrules DisplaySize config option) */
- pScrn1->xDpi = info->MergedFBXDPI;
- pScrn1->yDpi = info->MergedFBYDPI;
- from = X_CONFIG;
-
- } else if(pScrn1->widthmm > 0 || pScrn1->heightmm > 0) {
-
- /* Set values calculated from given DisplaySize */
- from = X_CONFIG;
- if(pScrn1->widthmm > 0) {
- pScrn1->xDpi = (int)((double)pScrn1->virtualX * 25.4 / pScrn1->widthmm);
- }
- if(pScrn1->heightmm > 0) {
- pScrn1->yDpi = (int)((double)pScrn1->virtualY * 25.4 / pScrn1->heightmm);
- }
- if(!quiet) {
- xf86DrvMsg(pScrn1->scrnIndex, from, dsstr, pScrn1->widthmm, pScrn1->heightmm);
- }
-
- } else if(ddcWidthmm && ddcHeightmm) {
-
- /* Set values from DDC-provided display size */
-
- /* Get DDC display size; if only either CRT1 or CRT2 provided these,
- * assume equal dimensions for both, otherwise add dimensions
- */
- if( (DDC1 && (DDC1->features.hsize > 0 && DDC1->features.vsize > 0)) &&
- (DDC2 && (DDC2->features.hsize > 0 && DDC2->features.vsize > 0)) ) {
- ddcWidthmm = max(DDC1->features.hsize, DDC2->features.hsize) * 10;
- ddcHeightmm = max(DDC1->features.vsize, DDC2->features.vsize) * 10;
- switch(srel) {
- case radeonLeftOf:
- case radeonRightOf:
- ddcWidthmm = (DDC1->features.hsize + DDC2->features.hsize) * 10;
- break;
- case radeonAbove:
- case radeonBelow:
- ddcHeightmm = (DDC1->features.vsize + DDC2->features.vsize) * 10;
- default:
- break;
- }
- } else if(DDC1 && (DDC1->features.hsize > 0 && DDC1->features.vsize > 0)) {
- ddcWidthmm = DDC1->features.hsize * 10;
- ddcHeightmm = DDC1->features.vsize * 10;
- switch(srel) {
- case radeonLeftOf:
- case radeonRightOf:
- ddcWidthmm *= 2;
- break;
- case radeonAbove:
- case radeonBelow:
- ddcHeightmm *= 2;
- default:
- break;
- }
- } else if(DDC2 && (DDC2->features.hsize > 0 && DDC2->features.vsize > 0) ) {
- ddcWidthmm = DDC2->features.hsize * 10;
- ddcHeightmm = DDC2->features.vsize * 10;
- switch(srel) {
- case radeonLeftOf:
- case radeonRightOf:
- ddcWidthmm *= 2;
- break;
- case radeonAbove:
- case radeonBelow:
- ddcHeightmm *= 2;
- default:
- break;
- }
- }
-
- from = X_PROBED;
-
- if(!quiet) {
- xf86DrvMsg(pScrn1->scrnIndex, from, dsstr, ddcWidthmm, ddcHeightmm);
- }
-
- pScrn1->widthmm = ddcWidthmm;
- pScrn1->heightmm = ddcHeightmm;
- if(pScrn1->widthmm > 0) {
- pScrn1->xDpi = (int)((double)pScrn1->virtualX * 25.4 / pScrn1->widthmm);
- }
- if(pScrn1->heightmm > 0) {
- pScrn1->yDpi = (int)((double)pScrn1->virtualY * 25.4 / pScrn1->heightmm);
- }
-
- } else {
-
- pScrn1->xDpi = pScrn1->yDpi = DEFAULT_DPI;
-
- }
-
- /* Sanity check */
- if(pScrn1->xDpi > 0 && pScrn1->yDpi <= 0)
- pScrn1->yDpi = pScrn1->xDpi;
- if(pScrn1->yDpi > 0 && pScrn1->xDpi <= 0)
- pScrn1->xDpi = pScrn1->yDpi;
-
- pScrn2->xDpi = pScrn1->xDpi;
- pScrn2->yDpi = pScrn1->yDpi;
-
- if(!quiet) {
- xf86DrvMsg(pScrn1->scrnIndex, from, "MergedFB: DPI set to (%d, %d)\n",
- pScrn1->xDpi, pScrn1->yDpi);
- }
-}
-
-
-void
-RADEONMergedFBSetDpi(ScrnInfoPtr pScrn1, ScrnInfoPtr pScrn2, RADEONScrn2Rel srel)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn1);
-
- RADEONMergedFBCalcDPI(pScrn1, pScrn2, srel, FALSE);
-
- info->MergedDPISRel = srel;
- info->RADEONMergedDPIVX = pScrn1->virtualX;
- info->RADEONMergedDPIVY = pScrn1->virtualY;
-
-}
-
-void
-RADEONMergedFBResetDpi(ScrnInfoPtr pScrn, Bool force)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
- RADEONScrn2Rel srel = ((RADEONMergedDisplayModePtr)info->CurrentLayout.mode->Private)->CRT2Position;
-
- /* This does the same calculation for the DPI as
- * the initial run. This means that an eventually
- * given -dpi command line switch will lead to
- * constant dpi values, regardless of the virtual
- * screen size.
- * I consider this consequent. If this is undesired,
- * one should use the DisplaySize parameter in the
- * config file instead of the command line switch.
- * The DPI will be calculated then.
- */
-
- if(force ||
- (info->MergedDPISRel != srel) ||
- (info->RADEONMergedDPIVX != pScrn->virtualX) ||
- (info->RADEONMergedDPIVY != pScrn->virtualY)
- ) {
-
- RADEONMergedFBCalcDPI(pScrn, info->CRT2pScrn, srel, TRUE);
-
- pScreen->mmWidth = (pScrn->virtualX * 254 + pScrn->xDpi * 5) / (pScrn->xDpi * 10);
- pScreen->mmHeight = (pScrn->virtualY * 254 + pScrn->yDpi * 5) / (pScrn->yDpi * 10);
-
- info->MergedDPISRel = srel;
- info->RADEONMergedDPIVX = pScrn->virtualX;
- info->RADEONMergedDPIVY = pScrn->virtualY;
-
- }
-}
-
-/* radeon cursor helpers */
-static void
-RADEONChooseCursorCRTC(ScrnInfoPtr pScrn1, int x, int y)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn1);
- unsigned char *RADEONMMIO = info->MMIO;
- RADEONScrn2Rel srel =
- ((RADEONMergedDisplayModePtr)info->CurrentLayout.mode->Private)->CRT2Position;
- ScrnInfoPtr pScrn2 = info->CRT2pScrn;
-
- if (srel == radeonClone) {
- /* show cursor 2 */
- OUTREGP(RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_CUR_EN,
- ~RADEON_CRTC2_CUR_EN);
- /* show cursor 1 */
- OUTREGP(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_CUR_EN,
- ~RADEON_CRTC_CUR_EN);
- }
- else {
- if (((x >= pScrn1->frameX0) && (x <= pScrn1->frameX1)) &&
- ((y >= pScrn1->frameY0) && (y <= pScrn1->frameY1))) {
- /* hide cursor 2 */
- OUTREGP(RADEON_CRTC2_GEN_CNTL, 0, ~RADEON_CRTC2_CUR_EN);
- /* show cursor 1 */
- OUTREGP(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_CUR_EN,
- ~RADEON_CRTC_CUR_EN);
- }
- if (((x >= pScrn2->frameX0) && (x <= pScrn2->frameX1)) &&
- ((y >= pScrn2->frameY0) && (y <= pScrn2->frameY1))) {
- /* hide cursor 1 */
- OUTREGP(RADEON_CRTC_GEN_CNTL, 0, ~RADEON_CRTC_CUR_EN);
- /* show cursor 2 */
- OUTREGP(RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_CUR_EN,
- ~RADEON_CRTC2_CUR_EN);
- }
- }
-}
-
-void
-RADEONSetCursorPositionMerged(ScrnInfoPtr pScrn, int x, int y)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
- xf86CursorInfoPtr cursor = info->cursor;
- int xorigin = 0;
- int yorigin = 0;
- int stride = 256;
- ScrnInfoPtr pScrn2 = info->CRT2pScrn;
- DisplayModePtr mode1 = CDMPTR->CRT1;
- DisplayModePtr mode2 = CDMPTR->CRT2;
- int x1, y1, x2, y2;
- int total_y1 = pScrn->frameY1 - pScrn->frameY0;
- int total_y2 = pScrn2->frameY1 - pScrn2->frameY0;
-
- if (x < 0) xorigin = -x+1;
- if (y < 0) yorigin = -y+1;
- /* if (y > total_y) y = total_y; */
- if (xorigin >= cursor->MaxWidth) xorigin = cursor->MaxWidth - 1;
- if (yorigin >= cursor->MaxHeight) yorigin = cursor->MaxHeight - 1;
-
- x += pScrn->frameX0;
- y += pScrn->frameY0;
-
- x1 = x - info->CRT1frameX0;
- y1 = y - info->CRT1frameY0;
-
- x2 = x - pScrn2->frameX0;
- y2 = y - pScrn2->frameY0;
-
- if (y1 > total_y1)
- y1 = total_y1;
- if (y2 > total_y2)
- y2 = total_y2;
-
- if(mode1->Flags & V_INTERLACE)
- y1 /= 2;
- else if(mode1->Flags & V_DBLSCAN)
- y1 *= 2;
-
- if(mode2->Flags & V_INTERLACE)
- y2 /= 2;
- else if(mode2->Flags & V_DBLSCAN)
- y2 *= 2;
-
- if (x < 0)
- x = 0;
- if (y < 0)
- y = 0;
-
- RADEONChooseCursorCRTC(pScrn, x, y);
-
- /* cursor1 */
- OUTREG(RADEON_CUR_HORZ_VERT_OFF, (RADEON_CUR_LOCK
- | (xorigin << 16)
- | yorigin));
- OUTREG(RADEON_CUR_HORZ_VERT_POSN, (RADEON_CUR_LOCK
- | ((xorigin ? 0 : x1) << 16)
- | (yorigin ? 0 : y1)));
- OUTREG(RADEON_CUR_OFFSET, info->cursor_offset + yorigin * stride);
- /* cursor2 */
- OUTREG(RADEON_CUR2_HORZ_VERT_OFF, (RADEON_CUR2_LOCK
- | (xorigin << 16)
- | yorigin));
- OUTREG(RADEON_CUR2_HORZ_VERT_POSN, (RADEON_CUR2_LOCK
- | ((xorigin ? 0 : x2) << 16)
- | (yorigin ? 0 : y2)));
- OUTREG(RADEON_CUR2_OFFSET, info->cursor_offset + yorigin * stride);
-}
-
-/* radeon Xv helpers */
-
-/* choose the crtc for the overlay for mergedfb based on the location
- of the output window and the orientation of the crtcs */
-
-void
-RADEONChooseOverlayCRTC(
- ScrnInfoPtr pScrn,
- BoxPtr dstBox
-) {
- RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONScrn2Rel srel =
- ((RADEONMergedDisplayModePtr)info->CurrentLayout.mode->Private)->CRT2Position;
-
- if (srel == radeonLeftOf) {
- if (dstBox->x1 >= info->CRT2pScrn->frameX1)
- info->OverlayOnCRTC2 = FALSE;
- else
- info->OverlayOnCRTC2 = TRUE;
- }
- if (srel == radeonRightOf) {
- if (dstBox->x2 <= info->CRT2pScrn->frameX0)
- info->OverlayOnCRTC2 = FALSE;
- else
- info->OverlayOnCRTC2 = TRUE;
- }
- if (srel == radeonAbove) {
- if (dstBox->y1 >= info->CRT2pScrn->frameY1)
- info->OverlayOnCRTC2 = FALSE;
- else
- info->OverlayOnCRTC2 = TRUE;
- }
- if (srel == radeonBelow) {
- if (dstBox->y2 <= info->CRT2pScrn->frameY0)
- info->OverlayOnCRTC2 = FALSE;
- else
- info->OverlayOnCRTC2 = TRUE;
- }
-}
diff --git a/src/radeon_mergedfb.h b/src/radeon_mergedfb.h
deleted file mode 100644
index d9bcc03c..00000000
--- a/src/radeon_mergedfb.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright 2003 Alex Deucher.
- *
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation on the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial
- * portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NON-INFRINGEMENT. IN NO EVENT SHALL ALEX DEUCHER, OR ANY OTHER
- * CONTRIBUTORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-/*
- * Authors:
- * Alex Deucher <agd5f@yahoo.com>
- *
- */
-
-#ifndef _RADEON_MERGEDFB_H_
-#define _RADEON_MERGEDFB_H_
-
-#include "xf86.h"
-
-#include "radeon.h"
-
-#if 0
- /* Psuedo Xinerama support */
-#define NEED_REPLIES /* ? */
-#define EXTENSION_PROC_ARGS void *
-#include "extnsionst.h" /* required */
-#include <X11/extensions/panoramiXproto.h> /* required */
-#define RADEON_XINERAMA_MAJOR_VERSION 1
-#define RADEON_XINERAMA_MINOR_VERSION 1
-
-/* needed for pseudo-xinerama by radeon_driver.c */
-Bool RADEONnoPanoramiXExtension = TRUE;
-
-/* Relative merge position */
-typedef enum {
- radeonLeftOf,
- radeonRightOf,
- radeonAbove,
- radeonBelow,
- radeonClone
-} RADEONScrn2Rel;
-#endif
-
-#define SDMPTR(x) ((RADEONMergedDisplayModePtr)(x->currentMode->Private))
-#define CDMPTR ((RADEONMergedDisplayModePtr)(info->CurrentLayout.mode->Private))
-
-#define BOUND(test,low,hi) { \
- if(test < low) test = low; \
- if(test > hi) test = hi; }
-
-#define REBOUND(low,hi,test) { \
- if(test < low) { \
- hi += test-low; \
- low = test; } \
- if(test > hi) { \
- low += test-hi; \
- hi = test; } }
-
-typedef struct _MergedDisplayModeRec {
- DisplayModePtr CRT1;
- DisplayModePtr CRT2;
- RADEONScrn2Rel CRT2Position;
-} RADEONMergedDisplayModeRec, *RADEONMergedDisplayModePtr;
-
-typedef struct _RADEONXineramaData {
- int x;
- int y;
- int width;
- int height;
-} RADEONXineramaData;
-
-/* needed by radeon_driver.c */
-extern void
-RADEONAdjustFrameMerged(int scrnIndex, int x, int y, int flags);
-extern void
-RADEONMergePointerMoved(int scrnIndex, int x, int y);
-extern DisplayModePtr
-RADEONGenerateModeList(ScrnInfoPtr pScrn, char* str,
- DisplayModePtr i, DisplayModePtr j,
- RADEONScrn2Rel srel);
-extern int
-RADEONStrToRanges(range *r, char *s, int max);
-extern void
-RADEONXineramaExtensionInit(ScrnInfoPtr pScrn);
-extern void
-RADEONUpdateXineramaScreenInfo(ScrnInfoPtr pScrn1);
-extern void
-RADEONMergedFBSetDpi(ScrnInfoPtr pScrn1, ScrnInfoPtr pScrn2, RADEONScrn2Rel srel);
-extern void
-RADEONMergedFBResetDpi(ScrnInfoPtr pScrn, Bool force);
-extern void
-RADEONRecalcDefaultVirtualSize(ScrnInfoPtr pScrn);
-
-/* needed by radeon_cursor.c */
-extern void
-RADEONSetCursorPositionMerged(ScrnInfoPtr pScrn, int x, int y);
-
-/* needed by radeon_video.c */
-extern void
-RADEONChooseOverlayCRTC(ScrnInfoPtr, BoxPtr);
-
-#endif /* _RADEON_MERGEDFB_H_ */
diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index 70bf1846..687e3888 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -42,80 +42,18 @@
#include "xf86.h"
/* Driver data structures */
+#include "randrstr.h"
+#include "radeon_probe.h"
#include "radeon.h"
#include "radeon_reg.h"
#include "radeon_macros.h"
-#include "radeon_probe.h"
+
#include "radeon_version.h"
+#include "xf86Modes.h"
/* DDC support */
#include "xf86DDC.h"
-
-/* Established timings from EDID standard */
-static struct
-{
- int hsize;
- int vsize;
- int refresh;
-} est_timings[] = {
- {1280, 1024, 75},
- {1024, 768, 75},
- {1024, 768, 70},
- {1024, 768, 60},
- {1024, 768, 87},
- {832, 624, 75},
- {800, 600, 75},
- {800, 600, 72},
- {800, 600, 60},
- {800, 600, 56},
- {640, 480, 75},
- {640, 480, 72},
- {640, 480, 67},
- {640, 480, 60},
- {720, 400, 88},
- {720, 400, 70},
-};
-
-/* This function will sort all modes according to their resolution.
- * Highest resolution first.
- */
-static void RADEONSortModes(DisplayModePtr *new, DisplayModePtr *first,
- DisplayModePtr *last)
-{
- DisplayModePtr p;
-
- p = *last;
- while (p) {
- if ((((*new)->HDisplay < p->HDisplay) &&
- ((*new)->VDisplay < p->VDisplay)) ||
- (((*new)->HDisplay == p->HDisplay) &&
- ((*new)->VDisplay == p->VDisplay) &&
- ((*new)->Clock < p->Clock))) {
-
- if (p->next) p->next->prev = *new;
- (*new)->prev = p;
- (*new)->next = p->next;
- p->next = *new;
- if (!((*new)->next)) *last = *new;
- break;
- }
- if (!p->prev) {
- (*new)->prev = NULL;
- (*new)->next = p;
- p->prev = *new;
- *first = *new;
- break;
- }
- p = p->prev;
- }
-
- if (!*first) {
- *first = *new;
- (*new)->prev = NULL;
- (*new)->next = NULL;
- *last = *new;
- }
-}
+#include <randrstr.h>
void RADEONSetPitch (ScrnInfoPtr pScrn)
{
@@ -136,346 +74,61 @@ void RADEONSetPitch (ScrnInfoPtr pScrn)
break;
}
pScrn->displayWidth = dummy;
-}
-
-/* When no mode provided in config file, this will add all modes supported in
- * DDC date the pScrn->modes list
- */
-static DisplayModePtr RADEONDDCModes(ScrnInfoPtr pScrn, xf86MonPtr ddc)
-{
- DisplayModePtr p;
- DisplayModePtr last = NULL;
- DisplayModePtr new = NULL;
- DisplayModePtr first = NULL;
- int count = 0;
- int j, tmp;
- char stmp[32];
-
- /* Go thru detailed timing table first */
- for (j = 0; j < 4; j++) {
- if (ddc->det_mon[j].type == 0) {
- struct detailed_timings *d_timings =
- &ddc->det_mon[j].section.d_timings;
-
- if (d_timings->h_active == 0 || d_timings->v_active == 0) break;
-
- new = xnfcalloc(1, sizeof (DisplayModeRec));
- memset(new, 0, sizeof (DisplayModeRec));
-
- new->HDisplay = d_timings->h_active;
- new->VDisplay = d_timings->v_active;
-
- sprintf(stmp, "%dx%d", new->HDisplay, new->VDisplay);
- new->name = xnfalloc(strlen(stmp) + 1);
- strcpy(new->name, stmp);
-
- new->HTotal = new->HDisplay + d_timings->h_blanking;
- new->HSyncStart = new->HDisplay + d_timings->h_sync_off;
- new->HSyncEnd = new->HSyncStart + d_timings->h_sync_width;
- new->VTotal = new->VDisplay + d_timings->v_blanking;
- new->VSyncStart = new->VDisplay + d_timings->v_sync_off;
- new->VSyncEnd = new->VSyncStart + d_timings->v_sync_width;
- new->Clock = d_timings->clock / 1000;
- new->Flags = (d_timings->interlaced ? V_INTERLACE : 0);
- new->status = MODE_OK;
-#ifdef M_T_PREFERRED
- if (PREFERRED_TIMING_MODE(ddc->features.msc))
- new->type = M_T_PREFERRED;
- else
-#endif
- new->type = M_T_DEFAULT;
-
- if (d_timings->sync == 3) {
- switch (d_timings->misc) {
- case 0: new->Flags |= V_NHSYNC | V_NVSYNC; break;
- case 1: new->Flags |= V_PHSYNC | V_NVSYNC; break;
- case 2: new->Flags |= V_NHSYNC | V_PVSYNC; break;
- case 3: new->Flags |= V_PHSYNC | V_PVSYNC; break;
- }
- }
- count++;
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Valid Mode from Detailed timing table: %s\n",
- new->name);
+ info->CurrentLayout.displayWidth = pScrn->displayWidth;
- RADEONSortModes(&new, &first, &last);
- }
- }
-
- /* Search thru standard VESA modes from EDID */
- for (j = 0; j < 8; j++) {
- if (ddc->timings2[j].hsize == 0 || ddc->timings2[j].vsize == 0)
- continue;
- for (p = pScrn->monitor->Modes; p && p->next; p = p->next->next) {
- /* Ignore all double scan modes */
- if ((ddc->timings2[j].hsize == p->HDisplay) &&
- (ddc->timings2[j].vsize == p->VDisplay)) {
- float refresh =
- (float)p->Clock * 1000.0 / p->HTotal / p->VTotal;
-
- if (abs((float)ddc->timings2[j].refresh - refresh) < 1.0) {
- /* Is this good enough? */
- new = xnfcalloc(1, sizeof (DisplayModeRec));
- memcpy(new, p, sizeof(DisplayModeRec));
- new->name = xnfalloc(strlen(p->name) + 1);
- strcpy(new->name, p->name);
- new->status = MODE_OK;
- new->type = M_T_DEFAULT;
-
- count++;
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Valid Mode from standard timing table: %s\n",
- new->name);
-
- RADEONSortModes(&new, &first, &last);
- break;
- }
- }
- }
- }
-
- /* Search thru established modes from EDID */
- tmp = (ddc->timings1.t1 << 8) | ddc->timings1.t2;
- for (j = 0; j < 16; j++) {
- if (tmp & (1 << j)) {
- for (p = pScrn->monitor->Modes; p && p->next; p = p->next->next) {
- if ((est_timings[j].hsize == p->HDisplay) &&
- (est_timings[j].vsize == p->VDisplay)) {
- float refresh =
- (float)p->Clock * 1000.0 / p->HTotal / p->VTotal;
-
- if (abs((float)est_timings[j].refresh - refresh) < 1.0) {
- /* Is this good enough? */
- new = xnfcalloc(1, sizeof (DisplayModeRec));
- memcpy(new, p, sizeof(DisplayModeRec));
- new->name = xnfalloc(strlen(p->name) + 1);
- strcpy(new->name, p->name);
- new->status = MODE_OK;
- new->type = M_T_DEFAULT;
-
- count++;
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Valid Mode from established timing "
- "table: %s\n", new->name);
-
- RADEONSortModes(&new, &first, &last);
- break;
- }
- }
- }
- }
- }
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Total of %d mode(s) found.\n", count);
-
- return first;
}
-/* XFree86's xf86ValidateModes routine doesn't work well with DDC modes,
- * so here is our own validation routine.
- */
-int RADEONValidateDDCModes(ScrnInfoPtr pScrn1, char **ppModeName,
- RADEONMonitorType DisplayType, int crtc2)
+static DisplayModePtr RADEONTVModes(xf86OutputPtr output)
{
- RADEONInfoPtr info = RADEONPTR(pScrn1);
- DisplayModePtr p;
- DisplayModePtr last = NULL;
- DisplayModePtr first = NULL;
- DisplayModePtr ddcModes = NULL;
- int count = 0;
- int i, width, height;
- ScrnInfoPtr pScrn = pScrn1;
-
- if (crtc2)
- pScrn = info->CRT2pScrn;
-
- pScrn->virtualX = pScrn1->display->virtualX;
- pScrn->virtualY = pScrn1->display->virtualY;
-
- if (pScrn->monitor->DDC) {
- int maxVirtX = pScrn->virtualX;
- int maxVirtY = pScrn->virtualY;
-
- /* Collect all of the DDC modes */
- first = last = ddcModes = RADEONDDCModes(pScrn, pScrn->monitor->DDC);
+ DisplayModePtr new = NULL;
- for (p = ddcModes; p; p = p->next) {
+ /* just a place holder */
+ new = xf86CVTMode(800, 600, 60.00, FALSE, FALSE);
+ new->type = M_T_DRIVER | M_T_PREFERRED;
- /* If primary head is a flat panel, use RMX by default */
- if ((!info->IsSecondary && DisplayType != MT_CRT) &&
- (!info->ddc_mode) && (!crtc2)) {
- /* These values are effective values after expansion.
- * They are not really used to set CRTC registers.
- */
- p->HTotal = info->PanelXRes + info->HBlank;
- p->HSyncStart = info->PanelXRes + info->HOverPlus;
- p->HSyncEnd = p->HSyncStart + info->HSyncWidth;
- p->VTotal = info->PanelYRes + info->VBlank;
- p->VSyncStart = info->PanelYRes + info->VOverPlus;
- p->VSyncEnd = p->VSyncStart + info->VSyncWidth;
- p->Clock = info->DotClock;
-
- p->Flags |= RADEON_USE_RMX;
- }
-
- maxVirtX = MAX(maxVirtX, p->HDisplay);
- maxVirtY = MAX(maxVirtY, p->VDisplay);
- count++;
-
- last = p;
- }
-
- /* Match up modes that are specified in the XF86Config file */
- if (ppModeName[0]) {
- DisplayModePtr next;
-
- /* Reset the max virtual dimensions */
- maxVirtX = pScrn->virtualX;
- maxVirtY = pScrn->virtualY;
-
- /* Reset list */
- first = last = NULL;
-
- for (i = 0; ppModeName[i]; i++) {
- /* FIXME: Use HDisplay and VDisplay instead of mode string */
- if (sscanf(ppModeName[i], "%dx%d", &width, &height) == 2) {
- for (p = ddcModes; p; p = next) {
- next = p->next;
-
- if (p->HDisplay == width && p->VDisplay == height) {
- /* We found a DDC mode that matches the one
- requested in the XF86Config file */
- p->type |= M_T_USERDEF;
-
- /* Update the max virtual setttings */
- maxVirtX = MAX(maxVirtX, width);
- maxVirtY = MAX(maxVirtY, height);
-
- /* Unhook from DDC modes */
- if (p->prev) p->prev->next = p->next;
- if (p->next) p->next->prev = p->prev;
- if (p == ddcModes) ddcModes = p->next;
-
- /* Add to used modes */
- if (last) {
- last->next = p;
- p->prev = last;
- } else {
- first = p;
- p->prev = NULL;
- }
- p->next = NULL;
- last = p;
-
- break;
- }
- }
- }
- }
-
- /*
- * Add remaining DDC modes if they're smaller than the user
- * specified modes
- */
- for (p = ddcModes; p; p = next) {
- next = p->next;
- if (p->HDisplay <= maxVirtX && p->VDisplay <= maxVirtY) {
- /* Unhook from DDC modes */
- if (p->prev) p->prev->next = p->next;
- if (p->next) p->next->prev = p->prev;
- if (p == ddcModes) ddcModes = p->next;
-
- /* Add to used modes */
- if (last) {
- last->next = p;
- p->prev = last;
- } else {
- first = p;
- p->prev = NULL;
- }
- p->next = NULL;
- last = p;
- }
- }
-
- /* Delete unused modes */
- while (ddcModes)
- xf86DeleteMode(&ddcModes, ddcModes);
- } else {
- /*
- * No modes were configured, so we make the DDC modes
- * available for the user to cycle through.
- */
- for (p = ddcModes; p; p = p->next)
- p->type |= M_T_USERDEF;
- }
-
- if (crtc2) {
- pScrn->virtualX = maxVirtX;
- pScrn->virtualY = maxVirtY;
- } else {
- pScrn->virtualX = pScrn->display->virtualX = maxVirtX;
- pScrn->virtualY = pScrn->display->virtualY = maxVirtY;
- }
- }
-
- /* Close the doubly-linked mode list, if we found any usable modes */
- if (last) {
- last->next = first;
- first->prev = last;
- pScrn->modes = first;
- RADEONSetPitch(pScrn);
- }
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Total number of valid DDC mode(s) found: %d\n", count);
-
- return count;
+ return new;
}
/* This is used only when no mode is specified for FP and no ddc is
* available. We force it to native mode, if possible.
*/
-static DisplayModePtr RADEONFPNativeMode(ScrnInfoPtr pScrn)
+static DisplayModePtr RADEONFPNativeMode(xf86OutputPtr output)
{
- RADEONInfoPtr info = RADEONPTR(pScrn);
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
DisplayModePtr new = NULL;
char stmp[32];
- if (info->PanelXRes != 0 &&
- info->PanelYRes != 0 &&
- info->DotClock != 0) {
+ if (radeon_output->PanelXRes != 0 &&
+ radeon_output->PanelYRes != 0 &&
+ radeon_output->DotClock != 0) {
/* Add native panel size */
new = xnfcalloc(1, sizeof (DisplayModeRec));
- sprintf(stmp, "%dx%d", info->PanelXRes, info->PanelYRes);
+ sprintf(stmp, "%dx%d", radeon_output->PanelXRes, radeon_output->PanelYRes);
new->name = xnfalloc(strlen(stmp) + 1);
strcpy(new->name, stmp);
- new->HDisplay = info->PanelXRes;
- new->VDisplay = info->PanelYRes;
+ new->HDisplay = radeon_output->PanelXRes;
+ new->VDisplay = radeon_output->PanelYRes;
- new->HTotal = new->HDisplay + info->HBlank;
- new->HSyncStart = new->HDisplay + info->HOverPlus;
- new->HSyncEnd = new->HSyncStart + info->HSyncWidth;
- new->VTotal = new->VDisplay + info->VBlank;
- new->VSyncStart = new->VDisplay + info->VOverPlus;
- new->VSyncEnd = new->VSyncStart + info->VSyncWidth;
+ new->HTotal = new->HDisplay + radeon_output->HBlank;
+ new->HSyncStart = new->HDisplay + radeon_output->HOverPlus;
+ new->HSyncEnd = new->HSyncStart + radeon_output->HSyncWidth;
+ new->VTotal = new->VDisplay + radeon_output->VBlank;
+ new->VSyncStart = new->VDisplay + radeon_output->VOverPlus;
+ new->VSyncEnd = new->VSyncStart + radeon_output->VSyncWidth;
- new->Clock = info->DotClock;
+ new->Clock = radeon_output->DotClock;
new->Flags = 0;
- new->type = M_T_USERDEF;
+ new->type = M_T_USERDEF | M_T_PREFERRED;
new->next = NULL;
new->prev = NULL;
pScrn->display->virtualX =
- pScrn->virtualX = MAX(pScrn->virtualX, info->PanelXRes);
+ pScrn->virtualX = MAX(pScrn->virtualX, radeon_output->PanelXRes);
pScrn->display->virtualY =
- pScrn->virtualY = MAX(pScrn->virtualY, info->PanelYRes);
+ pScrn->virtualY = MAX(pScrn->virtualY, radeon_output->PanelYRes);
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"No valid mode specified, force to native mode\n");
@@ -486,9 +139,10 @@ static DisplayModePtr RADEONFPNativeMode(ScrnInfoPtr pScrn)
/* FP mode initialization routine for using on-chip RMX to scale
*/
-int RADEONValidateFPModes(ScrnInfoPtr pScrn, char **ppModeName)
+int RADEONValidateFPModes(xf86OutputPtr output, char **ppModeName, DisplayModePtr *modeList)
{
- RADEONInfoPtr info = RADEONPTR(pScrn);
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
DisplayModePtr last = NULL;
DisplayModePtr new = NULL;
DisplayModePtr first = NULL;
@@ -511,13 +165,13 @@ int RADEONValidateFPModes(ScrnInfoPtr pScrn, char **ppModeName)
* need the internal RMX unit in the video chips (and there is
* only one per card), this will only apply to the primary head.
*/
- if (width < 320 || width > info->PanelXRes ||
- height < 200 || height > info->PanelYRes) {
+ if (width < 320 || width > radeon_output->PanelXRes ||
+ height < 200 || height > radeon_output->PanelYRes) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Mode %s is out of range.\n", ppModeName[i]);
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Valid modes must be between 320x200-%dx%d\n",
- info->PanelXRes, info->PanelYRes);
+ radeon_output->PanelXRes, radeon_output->PanelYRes);
continue;
}
@@ -530,17 +184,17 @@ int RADEONValidateFPModes(ScrnInfoPtr pScrn, char **ppModeName)
/* These values are effective values after expansion They are
* not really used to set CRTC registers.
*/
- new->HTotal = info->PanelXRes + info->HBlank;
- new->HSyncStart = info->PanelXRes + info->HOverPlus;
- new->HSyncEnd = new->HSyncStart + info->HSyncWidth;
- new->VTotal = info->PanelYRes + info->VBlank;
- new->VSyncStart = info->PanelYRes + info->VOverPlus;
- new->VSyncEnd = new->VSyncStart + info->VSyncWidth;
- new->Clock = info->DotClock;
+ new->HTotal = radeon_output->PanelXRes + radeon_output->HBlank;
+ new->HSyncStart = radeon_output->PanelXRes + radeon_output->HOverPlus;
+ new->HSyncEnd = new->HSyncStart + radeon_output->HSyncWidth;
+ new->VTotal = radeon_output->PanelYRes + radeon_output->VBlank;
+ new->VSyncStart = radeon_output->PanelYRes + radeon_output->VOverPlus;
+ new->VSyncEnd = new->VSyncStart + radeon_output->VSyncWidth;
+ new->Clock = radeon_output->DotClock;
new->Flags |= RADEON_USE_RMX;
#ifdef M_T_PREFERRED
- if (width == info->PanelXRes && height == info->PanelYRes)
+ if (width == radeon_output->PanelXRes && height == radeon_output->PanelYRes)
new->type |= M_T_PREFERRED;
#endif
@@ -551,7 +205,7 @@ int RADEONValidateFPModes(ScrnInfoPtr pScrn, char **ppModeName)
if (last) last->next = new;
last = new;
- if (!first) first = new;
+ if (!first) first = new;
pScrn->display->virtualX =
pScrn->virtualX = MAX(pScrn->virtualX, width);
@@ -564,13 +218,13 @@ int RADEONValidateFPModes(ScrnInfoPtr pScrn, char **ppModeName)
/* If all else fails, add the native mode */
if (!count) {
- first = last = RADEONFPNativeMode(pScrn);
+ first = last = RADEONFPNativeMode(output);
if (first) count = 1;
}
/* add in all default vesa modes smaller than panel size, used for randr*/
- for (p = pScrn->monitor->Modes; p && p->next; p = p->next->next) {
- if ((p->HDisplay <= info->PanelXRes) && (p->VDisplay <= info->PanelYRes)) {
+ for (p = *modeList; p && p->next; p = p->next->next) {
+ if ((p->HDisplay <= radeon_output->PanelXRes) && (p->VDisplay <= radeon_output->PanelYRes)) {
tmp = first;
while (tmp) {
if ((p->HDisplay == tmp->HDisplay) && (p->VDisplay == tmp->VDisplay)) break;
@@ -586,22 +240,19 @@ int RADEONValidateFPModes(ScrnInfoPtr pScrn, char **ppModeName)
/* These values are effective values after expansion They are
* not really used to set CRTC registers.
*/
- new->HTotal = info->PanelXRes + info->HBlank;
- new->HSyncStart = info->PanelXRes + info->HOverPlus;
- new->HSyncEnd = new->HSyncStart + info->HSyncWidth;
- new->VTotal = info->PanelYRes + info->VBlank;
- new->VSyncStart = info->PanelYRes + info->VOverPlus;
- new->VSyncEnd = new->VSyncStart + info->VSyncWidth;
- new->Clock = info->DotClock;
+ new->HTotal = radeon_output->PanelXRes + radeon_output->HBlank;
+ new->HSyncStart = radeon_output->PanelXRes + radeon_output->HOverPlus;
+ new->HSyncEnd = new->HSyncStart + radeon_output->HSyncWidth;
+ new->VTotal = radeon_output->PanelYRes + radeon_output->VBlank;
+ new->VSyncStart = radeon_output->PanelYRes + radeon_output->VOverPlus;
+ new->VSyncEnd = new->VSyncStart + radeon_output->VSyncWidth;
+ new->Clock = radeon_output->DotClock;
new->Flags |= RADEON_USE_RMX;
new->type |= M_T_DEFAULT;
- new->next = NULL;
- new->prev = last;
-
if (last) last->next = new;
- last = new;
+ last = new;
if (!first) first = new;
}
}
@@ -609,10 +260,10 @@ int RADEONValidateFPModes(ScrnInfoPtr pScrn, char **ppModeName)
/* Close the doubly-linked mode list, if we found any usable modes */
if (last) {
- last->next = first;
- first->prev = last;
- pScrn->modes = first;
- RADEONSetPitch(pScrn);
+ last->next = NULL; //first;
+ first->prev = NULL; //last;
+ *modeList = first;
+ //RADEONSetPitch(pScrn);
}
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
@@ -621,164 +272,66 @@ int RADEONValidateFPModes(ScrnInfoPtr pScrn, char **ppModeName)
return count;
}
-
-int RADEONValidateMergeModes(ScrnInfoPtr pScrn1)
+DisplayModePtr
+RADEONProbeOutputModes(xf86OutputPtr output)
{
- RADEONInfoPtr info = RADEONPTR(pScrn1);
- ClockRangePtr clockRanges;
- int modesFound;
- ScrnInfoPtr pScrn = info->CRT2pScrn;
-
- /* fill in pScrn2 */
- pScrn->videoRam = pScrn1->videoRam;
- pScrn->depth = pScrn1->depth;
- pScrn->numClocks = pScrn1->numClocks;
- pScrn->progClock = pScrn1->progClock;
- pScrn->fbFormat = pScrn1->fbFormat;
- pScrn->videoRam = pScrn1->videoRam;
- pScrn->maxHValue = pScrn1->maxHValue;
- pScrn->maxVValue = pScrn1->maxVValue;
- pScrn->xInc = pScrn1->xInc;
-
- if (info->NoVirtual) {
- pScrn1->display->virtualX = 0;
- pScrn1->display->virtualY = 0;
- }
-
- if (pScrn->monitor->DDC) {
- /* If we still don't know sync range yet, let's try EDID.
- *
- * Note that, since we can have dual heads, Xconfigurator
- * may not be able to probe both monitors correctly through
- * vbe probe function (RADEONProbeDDC). Here we provide an
- * additional way to auto-detect sync ranges if they haven't
- * been added to XF86Config manually.
- */
- if (pScrn->monitor->nHsync <= 0)
- RADEONSetSyncRangeFromEdid(pScrn, 1);
- if (pScrn->monitor->nVrefresh <= 0)
- RADEONSetSyncRangeFromEdid(pScrn, 0);
- }
-
- /* Get mode information */
- pScrn->progClock = TRUE;
- clockRanges = xnfcalloc(sizeof(*clockRanges), 1);
- clockRanges->next = NULL;
- clockRanges->minClock = info->pll.min_pll_freq;
- clockRanges->maxClock = info->pll.max_pll_freq * 10;
- clockRanges->clockIndex = -1;
- clockRanges->interlaceAllowed = (info->MergeType == MT_CRT);
- clockRanges->doubleScanAllowed = (info->MergeType == MT_CRT);
-
- /* We'll use our own mode validation routine for DFP/LCD, since
- * xf86ValidateModes does not work correctly with the DFP/LCD modes
- * 'stretched' from their native mode.
- */
- if (info->MergeType == MT_CRT && !info->ddc_mode) {
-
- modesFound =
- xf86ValidateModes(pScrn,
- pScrn->monitor->Modes,
- pScrn1->display->modes,
- clockRanges,
- NULL, /* linePitches */
- 8 * 64, /* minPitch */
- 8 * 1024, /* maxPitch */
- info->allowColorTiling ? 2048 :
- 64 * pScrn1->bitsPerPixel, /* pitchInc */
- 128, /* minHeight */
- info->MaxLines, /* maxHeight */
- pScrn1->display->virtualX ? pScrn1->virtualX : 0,
- pScrn1->display->virtualY ? pScrn1->virtualY : 0,
- info->FbMapSize,
- LOOKUP_BEST_REFRESH);
-
- if (modesFound == -1) return 0;
-
- xf86PruneDriverModes(pScrn);
- if (!modesFound || !pScrn->modes) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
- return 0;
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+ DisplayModePtr mode;
+ xf86MonPtr edid_mon;
+ DisplayModePtr modes = NULL;
+
+#if 0
+ /* force reprobe */
+ radeon_output->MonType = MT_UNKNOWN;
+
+ RADEONConnectorFindMonitor(pScrn, output);
+#endif
+ ErrorF("in RADEONProbeOutputModes\n");
+
+ if (output->status == XF86OutputStatusConnected) {
+ if (radeon_output->type == OUTPUT_DVI || radeon_output->type == OUTPUT_VGA) {
+ edid_mon = xf86OutputGetEDID (output, radeon_output->pI2CBus);
+ xf86OutputSetEDID (output, edid_mon);
+
+ modes = xf86OutputGetEDIDModes (output);
+ return modes;
}
-
- } else {
- /* First, free any allocated modes during configuration, since
- * we don't need them
- */
- while (pScrn->modes)
- xf86DeleteMode(&pScrn->modes, pScrn->modes);
- while (pScrn->modePool)
- xf86DeleteMode(&pScrn->modePool, pScrn->modePool);
-
- /* Next try to add DDC modes */
- modesFound = RADEONValidateDDCModes(pScrn, pScrn1->display->modes,
- info->MergeType, 1);
-
- /* If that fails and we're connect to a flat panel, then try to
- * add the flat panel modes
- */
- if (info->MergeType != MT_CRT) {
-
- /* some panels have DDC, but don't have internal scaler.
- * in this case, we need to validate additional modes
- * by using on-chip RMX.
- */
- int user_modes_asked = 0, user_modes_found = 0, i;
- DisplayModePtr tmp_mode = pScrn->modes;
- while (pScrn1->display->modes[user_modes_asked]) user_modes_asked++;
- if (tmp_mode) {
- for (i = 0; i < modesFound; i++) {
- if (tmp_mode->type & M_T_USERDEF) user_modes_found++;
- tmp_mode = tmp_mode->next;
+ if (radeon_output->type == OUTPUT_STV || radeon_output->type == OUTPUT_CTV) {
+ modes = RADEONTVModes(output);
+ return modes;
+ }
+ if (radeon_output->type == OUTPUT_LVDS) {
+ /* okay we got DDC info */
+ if (output->MonInfo) {
+ /* Debug info for now, at least */
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID for output %d\n", radeon_output->num);
+ xf86PrintEDID(output->MonInfo);
+
+ modes = xf86DDCGetModes(pScrn->scrnIndex, output->MonInfo);
+
+ for (mode = modes; mode != NULL; mode = mode->next) {
+ if (mode->Flags & V_DBLSCAN) {
+ if ((mode->CrtcHDisplay >= 1024) || (mode->CrtcVDisplay >= 768))
+ mode->status = MODE_CLOCK_RANGE;
+ }
}
+ xf86PruneInvalidModes(pScrn, &modes, TRUE);
+
+ /* do some physcial size stuff */
}
-
- if ((modesFound <= 1) || (user_modes_found < user_modes_asked)) {
- /* when panel size is not valid, try to validate
- * mode using xf86ValidateModes routine
- * This can happen when DDC is disabled.
- */
- /* if (info->PanelXRes < 320 || info->PanelYRes < 200) */
- modesFound =
- xf86ValidateModes(pScrn,
- pScrn->monitor->Modes,
- pScrn1->display->modes,
- clockRanges,
- NULL, /* linePitches */
- 8 * 64, /* minPitch */
- 8 * 1024, /* maxPitch */
- info->allowColorTiling ? 2048 :
- 64 * pScrn1->bitsPerPixel, /* pitchInc */
- 128, /* minHeight */
- info->MaxLines, /* maxHeight */
- pScrn1->display->virtualX,
- pScrn1->display->virtualY,
- info->FbMapSize,
- LOOKUP_BEST_REFRESH);
-
- }
- }
-
- /* Setup the screen's clockRanges for the VidMode extension */
- if (!pScrn->clockRanges) {
- pScrn->clockRanges = xnfcalloc(sizeof(*(pScrn->clockRanges)), 1);
- memcpy(pScrn->clockRanges, clockRanges, sizeof(*clockRanges));
- pScrn->clockRanges->strategy = LOOKUP_BEST_REFRESH;
- }
-
- /* Fail if we still don't have any valid modes */
- if (modesFound < 1) {
- if (info->MergeType == MT_CRT) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "No valid DDC modes found for this CRT\n");
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Try turning off the \"DDCMode\" option\n");
- } else {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "No valid mode found for this DFP/LCD\n");
+
+ if (modes == NULL) {
+ RADEONValidateFPModes(output, pScrn->display->modes, &modes);
}
- return 0;
}
}
- return modesFound;
+
+ if (modes) {
+ xf86ValidateModesUserConfig(pScrn, modes);
+ xf86PruneInvalidModes(pScrn, &modes, FALSE);
+ }
+
+ return modes;
}
+
diff --git a/src/radeon_output.c b/src/radeon_output.c
new file mode 100644
index 00000000..4df25972
--- /dev/null
+++ b/src/radeon_output.c
@@ -0,0 +1,2756 @@
+/*
+ * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
+ * VA Linux Systems Inc., Fremont, California.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+#include <stdio.h>
+
+/* X and server generic header files */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "vgaHW.h"
+#include "xf86Modes.h"
+
+/* Driver data structures */
+#include "radeon.h"
+#include "radeon_reg.h"
+#include "radeon_macros.h"
+#include "radeon_probe.h"
+#include "radeon_version.h"
+#include "radeon_tv.h"
+
+
+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[4] = {
+ "Unknown",
+ "Internal",
+ "External",
+ "None"
+};
+
+const char *DDCTypeName[6] = {
+ "None",
+ "MONID",
+ "DVI_DDC",
+ "VGA_DDC",
+ "CRT2_DDC",
+ "LCD_DDC"
+};
+
+const char *DACTypeName[4] = {
+ "Unknown",
+ "Primary",
+ "TVDAC/ExtDAC",
+ "None"
+};
+
+const char *ConnectorTypeName[8] = {
+ "None",
+ "Proprietary/LVDS",
+ "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"
+};
+
+const char *OutputType[10] = {
+ "None",
+ "VGA",
+ "DVI",
+ "LVDS",
+ "S-video",
+ "Composite",
+};
+
+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*/
+ {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RADEON*/
+ {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RV100*/
+ {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RS100*/
+ {{15000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RV200*/
+ {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RS200*/
+ {{15000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_R200*/
+ {{15500, 0x81b}, {0xffffffff, 0x83f}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RV250*/
+ {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RS300*/
+ {{13000, 0x400f4}, {15000, 0x400f7}, {0xffffffff, 0x40111}, {0, 0}}, /*CHIP_FAMILY_RV280*/
+ {{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*/
+ {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RV410*/ /* FIXME: just values from r420 used... */
+ {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RS400*/ /* FIXME: just values from rv380 used... */
+};
+
+static RADEONMonitorType RADEONPortCheckNonDDC(ScrnInfoPtr pScrn, xf86OutputPtr output);
+static void RADEONUpdatePanelSize(xf86OutputPtr output);
+static RADEONMonitorType radeon_detect_tv(ScrnInfoPtr pScrn);
+static RADEONMonitorType radeon_detect_primary_dac(ScrnInfoPtr pScrn, Bool color);
+static RADEONMonitorType radeon_detect_tv_dac(ScrnInfoPtr pScrn, Bool color);
+static RADEONMonitorType radeon_detect_ext_dac(ScrnInfoPtr pScrn);
+static void RADEONGetTMDSInfoFromTable(xf86OutputPtr output);
+
+void RADEONPrintPortMap(ScrnInfoPtr pScrn)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ RADEONOutputPrivatePtr radeon_output;
+ xf86OutputPtr output;
+ int o;
+
+ for (o = 0; o < xf86_config->num_output; o++) {
+ output = xf86_config->output[o];
+ radeon_output = output->driver_private;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Port%d:\n Monitor -- %s\n Connector -- %s\n DAC Type -- %s\n TMDS Type -- %s\n DDC Type -- %s\n",
+ o,
+ MonTypeName[radeon_output->MonType+1],
+ info->IsAtomBios ?
+ ConnectorTypeNameATOM[radeon_output->ConnectorType]:
+ ConnectorTypeName[radeon_output->ConnectorType],
+ DACTypeName[radeon_output->DACType+1],
+ TMDSTypeName[radeon_output->TMDSType+1],
+ DDCTypeName[radeon_output->DDCType]);
+ }
+
+}
+
+static RADEONMonitorType
+RADEONDisplayDDCConnected(ScrnInfoPtr pScrn, xf86OutputPtr output)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ unsigned long DDCReg;
+ RADEONMonitorType MonType = MT_NONE;
+ xf86MonPtr* MonInfo = &output->MonInfo;
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+ RADEONDDCType DDCType = radeon_output->DDCType;
+ int i, j;
+
+ DDCReg = radeon_output->DDCReg;
+
+ /* Read and output monitor info using DDC2 over I2C bus */
+ if (radeon_output->pI2CBus && info->ddc2 && (DDCReg != RADEON_LCD_GPIO_MASK)) {
+ OUTREG(DDCReg, INREG(DDCReg) &
+ (CARD32)~(RADEON_GPIO_A_0 | RADEON_GPIO_A_1));
+
+ /* For some old monitors (like Compaq Presario FP500), we need
+ * following process to initialize/stop DDC
+ */
+ OUTREG(DDCReg, INREG(DDCReg) & ~(RADEON_GPIO_EN_1));
+ for (j = 0; j < 3; j++) {
+ OUTREG(DDCReg,
+ INREG(DDCReg) & ~(RADEON_GPIO_EN_0));
+ usleep(13000);
+
+ OUTREG(DDCReg,
+ INREG(DDCReg) & ~(RADEON_GPIO_EN_1));
+ for (i = 0; i < 10; i++) {
+ usleep(15000);
+ if (INREG(DDCReg) & RADEON_GPIO_Y_1)
+ break;
+ }
+ if (i == 10) continue;
+
+ usleep(15000);
+
+ OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_0);
+ usleep(15000);
+
+ OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_1);
+ usleep(15000);
+ OUTREG(DDCReg,
+ INREG(DDCReg) & ~(RADEON_GPIO_EN_0));
+ usleep(15000);
+ *MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex, radeon_output->pI2CBus);
+
+ OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_1);
+ OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_0);
+ usleep(15000);
+ OUTREG(DDCReg,
+ INREG(DDCReg) & ~(RADEON_GPIO_EN_1));
+ for (i = 0; i < 5; i++) {
+ usleep(15000);
+ if (INREG(DDCReg) & RADEON_GPIO_Y_1)
+ break;
+ }
+ usleep(15000);
+ OUTREG(DDCReg,
+ INREG(DDCReg) & ~(RADEON_GPIO_EN_0));
+ usleep(15000);
+
+ OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_1);
+ OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_0);
+ usleep(15000);
+ if(*MonInfo) break;
+ }
+ } else if (radeon_output->pI2CBus && info->ddc2 && DDCReg == RADEON_LCD_GPIO_MASK) {
+ *MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex, radeon_output->pI2CBus);
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "DDC2/I2C is not properly initialized\n");
+ MonType = MT_NONE;
+ }
+
+ OUTREG(DDCReg, INREG(DDCReg) &
+ ~(RADEON_GPIO_EN_0 | RADEON_GPIO_EN_1));
+
+ if (*MonInfo) {
+ if ((info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_LVDS_ATOM) ||
+ (!info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_PROPRIETARY)) {
+ MonType = MT_LCD;
+ } else if ((info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_DVI_D_ATOM) ||
+ (!info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_DVI_D)) {
+ MonType = MT_DFP;
+ } else if ((*MonInfo)->rawData[0x14] & 0x80) { /* if it's digital */
+ MonType = MT_DFP;
+ } else {
+ MonType = MT_CRT;
+ }
+ } else MonType = MT_NONE;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "DDC Type: %d, Detected Monitor Type: %d\n", DDCType, MonType);
+
+ return MonType;
+}
+
+#if 0
+static RADEONMonitorType
+RADEONCrtIsPhysicallyConnected(ScrnInfoPtr pScrn, int IsCrtDac)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ int bConnected = 0;
+
+ /* the monitor either wasn't connected or it is a non-DDC CRT.
+ * try to probe it
+ */
+ if(IsCrtDac) {
+ unsigned long ulOrigVCLK_ECP_CNTL;
+ unsigned long ulOrigDAC_CNTL;
+ unsigned long ulOrigDAC_MACRO_CNTL;
+ unsigned long ulOrigDAC_EXT_CNTL;
+ unsigned long ulOrigCRTC_EXT_CNTL;
+ unsigned long ulData;
+ unsigned long ulMask;
+
+ ulOrigVCLK_ECP_CNTL = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
+
+ ulData = ulOrigVCLK_ECP_CNTL;
+ ulData &= ~(RADEON_PIXCLK_ALWAYS_ONb
+ | RADEON_PIXCLK_DAC_ALWAYS_ONb);
+ ulMask = ~(RADEON_PIXCLK_ALWAYS_ONb
+ |RADEON_PIXCLK_DAC_ALWAYS_ONb);
+ OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL, ulData, ulMask);
+
+ ulOrigCRTC_EXT_CNTL = INREG(RADEON_CRTC_EXT_CNTL);
+ ulData = ulOrigCRTC_EXT_CNTL;
+ ulData |= RADEON_CRTC_CRT_ON;
+ OUTREG(RADEON_CRTC_EXT_CNTL, ulData);
+
+ ulOrigDAC_EXT_CNTL = INREG(RADEON_DAC_EXT_CNTL);
+ ulData = ulOrigDAC_EXT_CNTL;
+ ulData &= ~RADEON_DAC_FORCE_DATA_MASK;
+ ulData |= (RADEON_DAC_FORCE_BLANK_OFF_EN
+ |RADEON_DAC_FORCE_DATA_EN
+ |RADEON_DAC_FORCE_DATA_SEL_MASK);
+ if ((info->ChipFamily == CHIP_FAMILY_RV250) ||
+ (info->ChipFamily == CHIP_FAMILY_RV280))
+ ulData |= (0x01b6 << RADEON_DAC_FORCE_DATA_SHIFT);
+ else
+ ulData |= (0x01ac << RADEON_DAC_FORCE_DATA_SHIFT);
+
+ OUTREG(RADEON_DAC_EXT_CNTL, ulData);
+
+ /* turn on power so testing can go through */
+ ulOrigDAC_CNTL = INREG(RADEON_DAC_CNTL);
+ ulOrigDAC_CNTL &= ~RADEON_DAC_PDWN;
+ OUTREG(RADEON_DAC_CNTL, ulOrigDAC_CNTL);
+
+ ulOrigDAC_MACRO_CNTL = INREG(RADEON_DAC_MACRO_CNTL);
+ ulOrigDAC_MACRO_CNTL &= ~(RADEON_DAC_PDWN_R | RADEON_DAC_PDWN_G |
+ RADEON_DAC_PDWN_B);
+ OUTREG(RADEON_DAC_MACRO_CNTL, ulOrigDAC_MACRO_CNTL);
+
+ /* Enable comparators and set DAC range to PS2 (VGA) output level */
+ ulData = ulOrigDAC_CNTL;
+ ulData |= RADEON_DAC_CMP_EN;
+ ulData &= ~RADEON_DAC_RANGE_CNTL_MASK;
+ ulData |= 0x2;
+ OUTREG(RADEON_DAC_CNTL, ulData);
+
+ /* Settle down */
+ usleep(10000);
+
+ /* Read comparators */
+ ulData = INREG(RADEON_DAC_CNTL);
+ bConnected = (RADEON_DAC_CMP_OUTPUT & ulData)?1:0;
+
+ /* Restore things */
+ ulData = ulOrigVCLK_ECP_CNTL;
+ ulMask = 0xFFFFFFFFL;
+ OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL, ulData, ulMask);
+
+ OUTREG(RADEON_DAC_CNTL, ulOrigDAC_CNTL );
+ OUTREG(RADEON_DAC_EXT_CNTL, ulOrigDAC_EXT_CNTL );
+ OUTREG(RADEON_CRTC_EXT_CNTL, ulOrigCRTC_EXT_CNTL);
+
+ if (!bConnected) {
+ /* Power DAC down if CRT is not connected */
+ ulOrigDAC_MACRO_CNTL = INREG(RADEON_DAC_MACRO_CNTL);
+ ulOrigDAC_MACRO_CNTL |= (RADEON_DAC_PDWN_R | RADEON_DAC_PDWN_G |
+ RADEON_DAC_PDWN_B);
+ OUTREG(RADEON_DAC_MACRO_CNTL, ulOrigDAC_MACRO_CNTL);
+
+ ulData = INREG(RADEON_DAC_CNTL);
+ ulData |= RADEON_DAC_PDWN;
+ OUTREG(RADEON_DAC_CNTL, ulData);
+ }
+ } else { /* TV DAC */
+
+ /* This doesn't seem to work reliably (maybe worse on some OEM cards),
+ for now we always return false. If one wants to connected a
+ non-DDC monitor on the DVI port when CRT port is also connected,
+ he will need to explicitly tell the driver in the config file
+ with Option MonitorLayout.
+ */
+ bConnected = FALSE;
+
+#if 0
+ if (info->ChipFamily == CHIP_FAMILY_R200) {
+ unsigned long ulOrigGPIO_MONID;
+ unsigned long ulOrigFP2_GEN_CNTL;
+ unsigned long ulOrigDISP_OUTPUT_CNTL;
+ unsigned long ulOrigCRTC2_GEN_CNTL;
+ unsigned long ulOrigDISP_LIN_TRANS_GRPH_A;
+ unsigned long ulOrigDISP_LIN_TRANS_GRPH_B;
+ unsigned long ulOrigDISP_LIN_TRANS_GRPH_C;
+ unsigned long ulOrigDISP_LIN_TRANS_GRPH_D;
+ unsigned long ulOrigDISP_LIN_TRANS_GRPH_E;
+ unsigned long ulOrigDISP_LIN_TRANS_GRPH_F;
+ unsigned long ulOrigCRTC2_H_TOTAL_DISP;
+ unsigned long ulOrigCRTC2_V_TOTAL_DISP;
+ unsigned long ulOrigCRTC2_H_SYNC_STRT_WID;
+ unsigned long ulOrigCRTC2_V_SYNC_STRT_WID;
+ unsigned long ulData, i;
+
+ ulOrigGPIO_MONID = INREG(RADEON_GPIO_MONID);
+ ulOrigFP2_GEN_CNTL = INREG(RADEON_FP2_GEN_CNTL);
+ ulOrigDISP_OUTPUT_CNTL = INREG(RADEON_DISP_OUTPUT_CNTL);
+ ulOrigCRTC2_GEN_CNTL = INREG(RADEON_CRTC2_GEN_CNTL);
+ ulOrigDISP_LIN_TRANS_GRPH_A = INREG(RADEON_DISP_LIN_TRANS_GRPH_A);
+ ulOrigDISP_LIN_TRANS_GRPH_B = INREG(RADEON_DISP_LIN_TRANS_GRPH_B);
+ ulOrigDISP_LIN_TRANS_GRPH_C = INREG(RADEON_DISP_LIN_TRANS_GRPH_C);
+ ulOrigDISP_LIN_TRANS_GRPH_D = INREG(RADEON_DISP_LIN_TRANS_GRPH_D);
+ ulOrigDISP_LIN_TRANS_GRPH_E = INREG(RADEON_DISP_LIN_TRANS_GRPH_E);
+ ulOrigDISP_LIN_TRANS_GRPH_F = INREG(RADEON_DISP_LIN_TRANS_GRPH_F);
+
+ ulOrigCRTC2_H_TOTAL_DISP = INREG(RADEON_CRTC2_H_TOTAL_DISP);
+ ulOrigCRTC2_V_TOTAL_DISP = INREG(RADEON_CRTC2_V_TOTAL_DISP);
+ ulOrigCRTC2_H_SYNC_STRT_WID = INREG(RADEON_CRTC2_H_SYNC_STRT_WID);
+ ulOrigCRTC2_V_SYNC_STRT_WID = INREG(RADEON_CRTC2_V_SYNC_STRT_WID);
+
+ ulData = INREG(RADEON_GPIO_MONID);
+ ulData &= ~RADEON_GPIO_A_0;
+ OUTREG(RADEON_GPIO_MONID, ulData);
+
+ OUTREG(RADEON_FP2_GEN_CNTL, 0x0a000c0c);
+
+ OUTREG(RADEON_DISP_OUTPUT_CNTL, 0x00000012);
+
+ OUTREG(RADEON_CRTC2_GEN_CNTL, 0x06000000);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_A, 0x00000000);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_B, 0x000003f0);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_C, 0x00000000);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_D, 0x000003f0);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_E, 0x00000000);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_F, 0x000003f0);
+ OUTREG(RADEON_CRTC2_H_TOTAL_DISP, 0x01000008);
+ OUTREG(RADEON_CRTC2_H_SYNC_STRT_WID, 0x00000800);
+ OUTREG(RADEON_CRTC2_V_TOTAL_DISP, 0x00080001);
+ OUTREG(RADEON_CRTC2_V_SYNC_STRT_WID, 0x00000080);
+
+ for (i = 0; i < 200; i++) {
+ ulData = INREG(RADEON_GPIO_MONID);
+ bConnected = (ulData & RADEON_GPIO_Y_0)?1:0;
+ if (!bConnected) break;
+
+ usleep(1000);
+ }
+
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_A, ulOrigDISP_LIN_TRANS_GRPH_A);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_B, ulOrigDISP_LIN_TRANS_GRPH_B);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_C, ulOrigDISP_LIN_TRANS_GRPH_C);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_D, ulOrigDISP_LIN_TRANS_GRPH_D);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_E, ulOrigDISP_LIN_TRANS_GRPH_E);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_F, ulOrigDISP_LIN_TRANS_GRPH_F);
+ OUTREG(RADEON_CRTC2_H_TOTAL_DISP, ulOrigCRTC2_H_TOTAL_DISP);
+ OUTREG(RADEON_CRTC2_V_TOTAL_DISP, ulOrigCRTC2_V_TOTAL_DISP);
+ OUTREG(RADEON_CRTC2_H_SYNC_STRT_WID, ulOrigCRTC2_H_SYNC_STRT_WID);
+ OUTREG(RADEON_CRTC2_V_SYNC_STRT_WID, ulOrigCRTC2_V_SYNC_STRT_WID);
+ OUTREG(RADEON_CRTC2_GEN_CNTL, ulOrigCRTC2_GEN_CNTL);
+ OUTREG(RADEON_DISP_OUTPUT_CNTL, ulOrigDISP_OUTPUT_CNTL);
+ OUTREG(RADEON_FP2_GEN_CNTL, ulOrigFP2_GEN_CNTL);
+ OUTREG(RADEON_GPIO_MONID, ulOrigGPIO_MONID);
+ } else {
+ unsigned long ulOrigPIXCLKSDATA;
+ unsigned long ulOrigTV_MASTER_CNTL;
+ unsigned long ulOrigTV_DAC_CNTL;
+ unsigned long ulOrigTV_PRE_DAC_MUX_CNTL;
+ unsigned long ulOrigDAC_CNTL2;
+ unsigned long ulData;
+ unsigned long ulMask;
+
+ ulOrigPIXCLKSDATA = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
+
+ ulData = ulOrigPIXCLKSDATA;
+ ulData &= ~(RADEON_PIX2CLK_ALWAYS_ONb
+ | RADEON_PIX2CLK_DAC_ALWAYS_ONb);
+ ulMask = ~(RADEON_PIX2CLK_ALWAYS_ONb
+ | RADEON_PIX2CLK_DAC_ALWAYS_ONb);
+ OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, ulData, ulMask);
+
+ ulOrigTV_MASTER_CNTL = INREG(RADEON_TV_MASTER_CNTL);
+ ulData = ulOrigTV_MASTER_CNTL;
+ ulData &= ~RADEON_TVCLK_ALWAYS_ONb;
+ OUTREG(RADEON_TV_MASTER_CNTL, ulData);
+
+ ulOrigDAC_CNTL2 = INREG(RADEON_DAC_CNTL2);
+ ulData = ulOrigDAC_CNTL2;
+ ulData &= ~RADEON_DAC2_DAC2_CLK_SEL;
+ OUTREG(RADEON_DAC_CNTL2, ulData);
+
+ ulOrigTV_DAC_CNTL = INREG(RADEON_TV_DAC_CNTL);
+
+ ulData = 0x00880213;
+ OUTREG(RADEON_TV_DAC_CNTL, ulData);
+
+ ulOrigTV_PRE_DAC_MUX_CNTL = INREG(RADEON_TV_PRE_DAC_MUX_CNTL);
+
+ ulData = (RADEON_Y_RED_EN
+ | RADEON_C_GRN_EN
+ | RADEON_CMP_BLU_EN
+ | RADEON_RED_MX_FORCE_DAC_DATA
+ | RADEON_GRN_MX_FORCE_DAC_DATA
+ | RADEON_BLU_MX_FORCE_DAC_DATA);
+ 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(10000);
+
+ ulData = INREG(RADEON_TV_DAC_CNTL);
+ bConnected = (ulData & RADEON_TV_DAC_CMPOUT)?1:0;
+
+ ulData = ulOrigPIXCLKSDATA;
+ ulMask = 0xFFFFFFFFL;
+ OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, ulData, ulMask);
+
+ OUTREG(RADEON_TV_MASTER_CNTL, ulOrigTV_MASTER_CNTL);
+ OUTREG(RADEON_DAC_CNTL2, ulOrigDAC_CNTL2);
+ OUTREG(RADEON_TV_DAC_CNTL, ulOrigTV_DAC_CNTL);
+ OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, ulOrigTV_PRE_DAC_MUX_CNTL);
+ }
+#endif
+ return MT_UNKNOWN;
+ }
+
+ return(bConnected ? MT_CRT : MT_NONE);
+}
+#endif
+
+/* Primary Head (DVI or Laptop Int. panel)*/
+/* A ddc capable display connected on DVI port */
+/* Secondary Head (mostly VGA, can be DVI on some OEM boards)*/
+void RADEONConnectorFindMonitor(ScrnInfoPtr pScrn, xf86OutputPtr output)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+
+ if (radeon_output->MonType == MT_UNKNOWN) {
+ if (radeon_output->type == OUTPUT_STV || radeon_output->type == OUTPUT_CTV) {
+ if (info->InternalTVOut) {
+ if (radeon_output->load_detection)
+ radeon_output->MonType = radeon_detect_tv(pScrn);
+ else
+ radeon_output->MonType = MT_NONE;
+ }
+ } else {
+ radeon_output->MonType = RADEONDisplayDDCConnected(pScrn, output);
+ if (!radeon_output->MonType) {
+ if (radeon_output->type == OUTPUT_LVDS || radeon_output->type == OUTPUT_DVI)
+ radeon_output->MonType = RADEONPortCheckNonDDC(pScrn, output);
+ if (!radeon_output->MonType) {
+ if (radeon_output->DACType == DAC_PRIMARY) {
+ if (radeon_output->load_detection)
+ radeon_output->MonType = radeon_detect_primary_dac(pScrn, TRUE);
+ } else if (radeon_output->DACType == DAC_TVDAC) {
+ if (radeon_output->load_detection) {
+ if (info->ChipFamily == CHIP_FAMILY_R200)
+ radeon_output->MonType = radeon_detect_ext_dac(pScrn);
+ else
+ radeon_output->MonType = radeon_detect_tv_dac(pScrn, TRUE);
+ } else
+ radeon_output->MonType = MT_NONE;
+ }
+ }
+ }
+ }
+ }
+
+ /* update panel info for RMX */
+ if (radeon_output->MonType == MT_LCD || radeon_output->MonType == MT_DFP)
+ RADEONUpdatePanelSize(output);
+
+ if (output->MonInfo) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID data from the display on connector: %s ----------------------\n",
+ info->IsAtomBios ?
+ ConnectorTypeNameATOM[radeon_output->ConnectorType]:
+ ConnectorTypeName[radeon_output->ConnectorType]
+ );
+ xf86PrintEDID( output->MonInfo );
+ }
+}
+
+static RADEONMonitorType RADEONPortCheckNonDDC(ScrnInfoPtr pScrn, xf86OutputPtr output)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+ RADEONMonitorType MonType = MT_NONE;
+
+
+ if (radeon_output->type == OUTPUT_LVDS) {
+ MonType = MT_LCD;
+ } else if (radeon_output->type == OUTPUT_DVI) {
+ if (radeon_output->TMDSType == TMDS_INT) {
+ if (INREG(RADEON_FP_GEN_CNTL) & RADEON_FP_DETECT_SENSE)
+ MonType = MT_DFP;
+ } else if (radeon_output->TMDSType == TMDS_EXT) {
+ if (INREG(RADEON_FP2_GEN_CNTL) & RADEON_FP2_DETECT_SENSE)
+ MonType = MT_DFP;
+ }
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Detected Monitor Type: %d\n", MonType);
+
+ return MonType;
+
+}
+
+static void
+radeon_dpms(xf86OutputPtr output, int mode)
+{
+ switch(mode) {
+ case DPMSModeOn:
+ RADEONEnableDisplay(output, TRUE);
+ break;
+ case DPMSModeOff:
+ case DPMSModeSuspend:
+ case DPMSModeStandby:
+ RADEONEnableDisplay(output, FALSE);
+ break;
+ }
+}
+
+static void
+radeon_save(xf86OutputPtr output)
+{
+
+}
+
+static void
+radeon_restore(xf86OutputPtr restore)
+{
+
+}
+
+static int
+radeon_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
+{
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+
+ if (radeon_output->type == OUTPUT_STV ||
+ radeon_output->type == OUTPUT_CTV) {
+ /* FIXME: Update when more modes are added */
+ if (pMode->HDisplay == 800 && pMode->VDisplay == 600)
+ return MODE_OK;
+ else
+ return MODE_CLOCK_RANGE;
+ }
+
+ if (radeon_output->type != OUTPUT_LVDS)
+ return MODE_OK;
+
+ if (pMode->HDisplay > radeon_output->PanelXRes ||
+ pMode->VDisplay > radeon_output->PanelYRes)
+ return MODE_PANEL;
+
+ return MODE_OK;
+}
+
+static Bool
+radeon_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
+ DisplayModePtr adjusted_mode)
+{
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+
+ if (radeon_output->MonType == MT_LCD || radeon_output->MonType == MT_DFP) {
+ xf86CrtcPtr crtc = output->crtc;
+ RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+
+ if ((mode->HDisplay < radeon_output->PanelXRes ||
+ mode->VDisplay < radeon_output->PanelYRes) &&
+ radeon_crtc->crtc_id == 0)
+ adjusted_mode->Flags |= RADEON_USE_RMX;
+
+ if (adjusted_mode->Flags & RADEON_USE_RMX) {
+ adjusted_mode->CrtcHTotal = mode->CrtcHDisplay + radeon_output->HBlank;
+ adjusted_mode->CrtcHSyncStart = mode->CrtcHDisplay + radeon_output->HOverPlus;
+ adjusted_mode->CrtcHSyncEnd = mode->CrtcHSyncStart + radeon_output->HSyncWidth;
+ adjusted_mode->CrtcVTotal = mode->CrtcVDisplay + radeon_output->VBlank;
+ adjusted_mode->CrtcVSyncStart = mode->CrtcVDisplay + radeon_output->VOverPlus;
+ adjusted_mode->CrtcVSyncEnd = mode->CrtcVSyncStart + radeon_output->VSyncWidth;
+ adjusted_mode->Clock = radeon_output->DotClock;
+ radeon_output->Flags |= RADEON_USE_RMX;
+ adjusted_mode->Flags = radeon_output->Flags;
+ } else
+ radeon_output->Flags &= ~RADEON_USE_RMX;
+
+ }
+
+ return TRUE;
+}
+
+static void
+radeon_mode_prepare(xf86OutputPtr output)
+{
+}
+
+static void RADEONInitFPRegisters(xf86OutputPtr output, RADEONSavePtr save,
+ DisplayModePtr mode, BOOL IsPrimary)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+ int i;
+ CARD32 tmp = info->SavedReg.tmds_pll_cntl & 0xfffff;
+
+ for (i=0; i<4; i++) {
+ if (radeon_output->tmds_pll[i].freq == 0) break;
+ if ((CARD32)(mode->Clock/10) < radeon_output->tmds_pll[i].freq) {
+ tmp = radeon_output->tmds_pll[i].value ;
+ break;
+ }
+ }
+
+ if (IS_R300_VARIANT || (info->ChipFamily == CHIP_FAMILY_RV280)) {
+ if (tmp & 0xfff00000)
+ save->tmds_pll_cntl = tmp;
+ else {
+ save->tmds_pll_cntl = info->SavedReg.tmds_pll_cntl & 0xfff00000;
+ save->tmds_pll_cntl |= tmp;
+ }
+ } else save->tmds_pll_cntl = tmp;
+
+ save->tmds_transmitter_cntl = info->SavedReg.tmds_transmitter_cntl &
+ ~(RADEON_TMDS_TRANSMITTER_PLLRST);
+
+ if (IS_R300_VARIANT || (info->ChipFamily == CHIP_FAMILY_R200) || !pRADEONEnt->HasCRTC2)
+ save->tmds_transmitter_cntl &= ~(RADEON_TMDS_TRANSMITTER_PLLEN);
+ else /* weird, RV chips got this bit reversed? */
+ save->tmds_transmitter_cntl |= (RADEON_TMDS_TRANSMITTER_PLLEN);
+
+ save->fp_gen_cntl = info->SavedReg.fp_gen_cntl |
+ (RADEON_FP_CRTC_DONT_SHADOW_VPAR |
+ RADEON_FP_CRTC_DONT_SHADOW_HEND );
+
+ save->fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN);
+
+ if (pScrn->rgbBits == 8)
+ save->fp_gen_cntl |= RADEON_FP_PANEL_FORMAT; /* 24 bit format */
+ else
+ save->fp_gen_cntl &= ~RADEON_FP_PANEL_FORMAT;/* 18 bit format */
+
+
+ if (IsPrimary) {
+ 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;
+ } else {
+ if ((IS_R300_VARIANT) || (info->ChipFamily == CHIP_FAMILY_R200)) {
+ save->fp_gen_cntl &= ~R200_FP_SOURCE_SEL_MASK;
+ save->fp_gen_cntl |= R200_FP_SOURCE_SEL_CRTC2;
+ } else
+ save->fp_gen_cntl |= RADEON_FP_SEL_CRTC2;
+ }
+
+}
+
+static void RADEONInitFP2Registers(xf86OutputPtr output, RADEONSavePtr save,
+ DisplayModePtr mode, BOOL IsPrimary)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+
+
+ if (pScrn->rgbBits == 8)
+ save->fp2_gen_cntl = info->SavedReg.fp2_gen_cntl |
+ RADEON_FP2_PANEL_FORMAT; /* 24 bit format, */
+ else
+ save->fp2_gen_cntl = info->SavedReg.fp2_gen_cntl &
+ ~RADEON_FP2_PANEL_FORMAT;/* 18 bit format, */
+
+ save->fp2_gen_cntl &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
+
+ if (IsPrimary) {
+ if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) {
+ save->fp2_gen_cntl &= ~(R200_FP2_SOURCE_SEL_MASK |
+ RADEON_FP2_DVO_EN |
+ RADEON_FP2_DVO_RATE_SEL_SDR);
+ if (mode->Flags & RADEON_USE_RMX)
+ save->fp2_gen_cntl |= R200_FP2_SOURCE_SEL_RMX;
+ } else {
+ save->fp2_gen_cntl &= ~(RADEON_FP2_SRC_SEL_CRTC2 |
+ RADEON_FP2_DVO_RATE_SEL_SDR);
+ }
+ } else {
+ if ((info->ChipFamily == CHIP_FAMILY_R200) || 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;
+ } else {
+ save->fp2_gen_cntl &= ~(RADEON_FP2_DVO_RATE_SEL_SDR);
+ save->fp2_gen_cntl |= RADEON_FP2_SRC_SEL_CRTC2;
+ }
+ }
+
+}
+
+static void RADEONInitLVDSRegisters(xf86OutputPtr output, RADEONSavePtr save,
+ DisplayModePtr mode, BOOL IsPrimary)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+
+ save->lvds_pll_cntl = info->SavedReg.lvds_pll_cntl;
+
+ save->lvds_gen_cntl = info->SavedReg.lvds_gen_cntl;
+ save->lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS;
+ save->lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON);
+
+ if (IsPrimary)
+ save->lvds_gen_cntl &= ~RADEON_LVDS_SEL_CRTC2;
+ else
+ save->lvds_gen_cntl |= RADEON_LVDS_SEL_CRTC2;
+
+}
+
+static void RADEONInitRMXRegisters(xf86OutputPtr output, RADEONSavePtr save,
+ DisplayModePtr mode)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+ int xres = mode->HDisplay;
+ int yres = mode->VDisplay;
+ float Hratio, Vratio;
+
+ save->fp_vert_stretch = info->SavedReg.fp_vert_stretch &
+ RADEON_VERT_STRETCH_RESERVED;
+ save->fp_horz_stretch = info->SavedReg.fp_horz_stretch &
+ (RADEON_HORZ_FP_LOOP_STRETCH |
+ RADEON_HORZ_AUTO_RATIO_INC);
+
+ if (radeon_output->MonType != MT_LCD && radeon_output->MonType != MT_DFP)
+ return;
+
+ if (radeon_output->PanelXRes == 0 || radeon_output->PanelYRes == 0) {
+ Hratio = 1.0;
+ Vratio = 1.0;
+ } else {
+ if (xres > radeon_output->PanelXRes) xres = radeon_output->PanelXRes;
+ if (yres > radeon_output->PanelYRes) yres = radeon_output->PanelYRes;
+
+ Hratio = (float)xres/(float)radeon_output->PanelXRes;
+ Vratio = (float)yres/(float)radeon_output->PanelYRes;
+ }
+
+ if (Hratio == 1.0 || !(mode->Flags & RADEON_USE_RMX)) {
+ save->fp_horz_stretch |= ((xres/8-1)<<16);
+ } else {
+ save->fp_horz_stretch |= ((((unsigned long)
+ (Hratio * RADEON_HORZ_STRETCH_RATIO_MAX)) &
+ RADEON_HORZ_STRETCH_RATIO_MASK) |
+ RADEON_HORZ_STRETCH_BLEND |
+ RADEON_HORZ_STRETCH_ENABLE |
+ ((radeon_output->PanelXRes/8-1)<<16));
+ }
+
+ if (Vratio == 1.0 || !(mode->Flags & RADEON_USE_RMX)) {
+ save->fp_vert_stretch |= ((yres-1)<<12);
+ } else {
+ save->fp_vert_stretch |= ((((unsigned long)(Vratio * RADEON_VERT_STRETCH_RATIO_MAX)) &
+ RADEON_VERT_STRETCH_RATIO_MASK) |
+ RADEON_VERT_STRETCH_ENABLE |
+ RADEON_VERT_STRETCH_BLEND |
+ ((radeon_output->PanelYRes-1)<<12));
+ }
+
+}
+
+static void RADEONInitDACRegisters(xf86OutputPtr output, RADEONSavePtr save,
+ DisplayModePtr mode, BOOL IsPrimary)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+
+ if (IsPrimary) {
+ if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) {
+ save->disp_output_cntl = info->SavedReg.disp_output_cntl &
+ ~RADEON_DISP_DAC_SOURCE_MASK;
+ } else {
+ save->dac2_cntl = info->SavedReg.dac2_cntl & ~(RADEON_DAC2_DAC_CLK_SEL);
+ }
+ } else {
+ if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) {
+ save->disp_output_cntl = info->SavedReg.disp_output_cntl &
+ ~RADEON_DISP_DAC_SOURCE_MASK;
+ save->disp_output_cntl |= RADEON_DISP_DAC_SOURCE_CRTC2;
+ } else {
+ save->dac2_cntl = info->SavedReg.dac2_cntl | RADEON_DAC2_DAC_CLK_SEL;
+ }
+ }
+ save->dac_cntl = (RADEON_DAC_MASK_ALL
+ | RADEON_DAC_VGA_ADR_EN
+ | (info->dac6bits ? 0 : RADEON_DAC_8BIT_EN));
+
+ save->dac_macro_cntl = info->SavedReg.dac_macro_cntl;
+}
+
+/* XXX: fix me */
+static void
+RADEONInitTvDacCntl(ScrnInfoPtr pScrn, RADEONSavePtr save)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+
+ if (info->ChipFamily == CHIP_FAMILY_R420 ||
+ info->ChipFamily == CHIP_FAMILY_RV410) {
+ save->tv_dac_cntl = info->SavedReg.tv_dac_cntl &
+ ~(RADEON_TV_DAC_STD_MASK |
+ RADEON_TV_DAC_BGADJ_MASK |
+ R420_TV_DAC_DACADJ_MASK |
+ R420_TV_DAC_RDACPD |
+ R420_TV_DAC_GDACPD |
+ R420_TV_DAC_GDACPD |
+ R420_TV_DAC_TVENABLE);
+ } else {
+ save->tv_dac_cntl = info->SavedReg.tv_dac_cntl &
+ ~(RADEON_TV_DAC_STD_MASK |
+ RADEON_TV_DAC_BGADJ_MASK |
+ RADEON_TV_DAC_DACADJ_MASK |
+ RADEON_TV_DAC_RDACPD |
+ RADEON_TV_DAC_GDACPD |
+ RADEON_TV_DAC_GDACPD);
+ }
+ /* FIXME: doesn't make sense, this just replaces the previous value... */
+ save->tv_dac_cntl |= (RADEON_TV_DAC_NBLANK |
+ RADEON_TV_DAC_NHOLD |
+ RADEON_TV_DAC_STD_PS2);
+
+}
+
+static void RADEONInitDAC2Registers(xf86OutputPtr output, RADEONSavePtr save,
+ DisplayModePtr mode, BOOL IsPrimary)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+
+ /*0x0028023;*/
+ RADEONInitTvDacCntl(pScrn, save);
+
+ if (IS_R300_VARIANT)
+ save->gpiopad_a = info->SavedReg.gpiopad_a | 1;
+
+ save->dac2_cntl = info->SavedReg.dac2_cntl | RADEON_DAC2_DAC2_CLK_SEL;
+
+ if (IsPrimary) {
+ if (IS_R300_VARIANT) {
+ save->disp_output_cntl = info->SavedReg.disp_output_cntl &
+ ~RADEON_DISP_TVDAC_SOURCE_MASK;
+ save->disp_output_cntl |= RADEON_DISP_TVDAC_SOURCE_CRTC;
+ } else if (info->ChipFamily == CHIP_FAMILY_R200) {
+ save->fp2_gen_cntl = info->SavedReg.fp2_gen_cntl &
+ ~(R200_FP2_SOURCE_SEL_MASK |
+ RADEON_FP2_DVO_RATE_SEL_SDR);
+ } else {
+ save->disp_hw_debug = info->SavedReg.disp_hw_debug | RADEON_CRT2_DISP1_SEL;
+ }
+ } else {
+ if (IS_R300_VARIANT) {
+ save->disp_output_cntl = info->SavedReg.disp_output_cntl &
+ ~RADEON_DISP_TVDAC_SOURCE_MASK;
+ save->disp_output_cntl |= RADEON_DISP_TVDAC_SOURCE_CRTC2;
+ } else if (info->ChipFamily == CHIP_FAMILY_R200) {
+ save->fp2_gen_cntl = info->SavedReg.fp2_gen_cntl &
+ ~(R200_FP2_SOURCE_SEL_MASK |
+ RADEON_FP2_DVO_RATE_SEL_SDR);
+ save->fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC2;
+ } else {
+ save->disp_hw_debug = info->SavedReg.disp_hw_debug &
+ ~RADEON_CRT2_DISP1_SEL;
+ }
+ }
+}
+
+static void
+RADEONInitOutputRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save,
+ DisplayModePtr mode, xf86OutputPtr output,
+ int crtc_num)
+{
+ Bool IsPrimary = crtc_num == 0 ? TRUE : FALSE;
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+
+ if (crtc_num == 0)
+ RADEONInitRMXRegisters(output, save, mode);
+
+ if (radeon_output->MonType == MT_CRT) {
+ if (radeon_output->DACType == DAC_PRIMARY) {
+ RADEONInitDACRegisters(output, save, mode, IsPrimary);
+ } else {
+ RADEONInitDAC2Registers(output, save, mode, IsPrimary);
+ }
+ } else if (radeon_output->MonType == MT_LCD) {
+ RADEONInitLVDSRegisters(output, save, mode, IsPrimary);
+ } else if (radeon_output->MonType == MT_DFP) {
+ if (radeon_output->TMDSType == TMDS_INT) {
+ RADEONInitFPRegisters(output, save, mode, IsPrimary);
+ } else {
+ RADEONInitFP2Registers(output, save, mode, IsPrimary);
+ }
+ } else if (radeon_output->MonType == MT_STV ||
+ radeon_output->MonType == MT_CTV) {
+ RADEONInitTVRegisters(output, save, mode, IsPrimary);
+ }
+}
+
+static void
+radeon_mode_set(xf86OutputPtr output, DisplayModePtr mode,
+ DisplayModePtr adjusted_mode)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+ xf86CrtcPtr crtc = output->crtc;
+ RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+
+ if (radeon_output->type == OUTPUT_DVI &&
+ radeon_output->TMDSType == TMDS_INT) {
+ if (radeon_output->tmds_pll_table == TMDS_PLL_BIOS) {
+ if (!RADEONGetTMDSInfoFromBIOS(output))
+ RADEONGetTMDSInfoFromTable(output);
+ } else
+ RADEONGetTMDSInfoFromTable(output);
+ }
+
+ RADEONInitOutputRegisters(pScrn, &info->ModeReg, adjusted_mode, output, radeon_crtc->crtc_id);
+
+ if (radeon_crtc->crtc_id == 0)
+ RADEONRestoreRMXRegisters(pScrn, &info->ModeReg);
+
+ switch(radeon_output->MonType) {
+ case MT_LCD:
+ ErrorF("restore LVDS\n");
+ RADEONRestoreLVDSRegisters(pScrn, &info->ModeReg);
+ break;
+ case MT_DFP:
+ if (radeon_output->TMDSType == TMDS_INT) {
+ ErrorF("restore FP\n");
+ RADEONRestoreFPRegisters(pScrn, &info->ModeReg);
+ } else {
+ ErrorF("restore FP2\n");
+ RADEONRestoreFP2Registers(pScrn, &info->ModeReg);
+ }
+ break;
+ case MT_STV:
+ case MT_CTV:
+ ErrorF("restore tv\n");
+ RADEONRestoreDACRegisters(pScrn, &info->ModeReg);
+ RADEONRestoreTVRegisters(pScrn, &info->ModeReg);
+ break;
+ default:
+ ErrorF("restore dac\n");
+ RADEONRestoreDACRegisters(pScrn, &info->ModeReg);
+ }
+
+}
+
+static void
+radeon_mode_commit(xf86OutputPtr output)
+{
+ RADEONEnableDisplay(output, TRUE);
+}
+
+/* the following functions are based on the load detection code
+ * in the beos radeon driver by Thomas Kurschel and the existing
+ * load detection code in this driver.
+ */
+static RADEONMonitorType
+radeon_detect_primary_dac(ScrnInfoPtr pScrn, Bool color)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ CARD32 vclk_ecp_cntl, crtc_ext_cntl;
+ CARD32 dac_ext_cntl, dac_cntl, dac_macro_cntl, tmp;
+ RADEONMonitorType found = MT_NONE;
+
+ /* save the regs we need */
+ vclk_ecp_cntl = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
+ crtc_ext_cntl = INREG(RADEON_CRTC_EXT_CNTL);
+ dac_ext_cntl = INREG(RADEON_DAC_EXT_CNTL);
+ dac_cntl = INREG(RADEON_DAC_CNTL);
+ dac_macro_cntl = INREG(RADEON_DAC_MACRO_CNTL);
+
+ tmp = vclk_ecp_cntl &
+ ~(RADEON_PIXCLK_ALWAYS_ONb | RADEON_PIXCLK_DAC_ALWAYS_ONb);
+ OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, tmp);
+
+ tmp = crtc_ext_cntl | RADEON_CRTC_CRT_ON;
+ OUTREG(RADEON_CRTC_EXT_CNTL, tmp);
+
+ tmp = RADEON_DAC_FORCE_BLANK_OFF_EN |
+ RADEON_DAC_FORCE_DATA_EN;
+
+ if (color)
+ tmp |= RADEON_DAC_FORCE_DATA_SEL_RGB;
+ else
+ tmp |= RADEON_DAC_FORCE_DATA_SEL_G;
+
+ if (IS_R300_VARIANT)
+ tmp |= (0x1b6 << RADEON_DAC_FORCE_DATA_SHIFT);
+ else
+ tmp |= (0x180 << RADEON_DAC_FORCE_DATA_SHIFT);
+
+ OUTREG(RADEON_DAC_EXT_CNTL, tmp);
+
+ tmp = dac_cntl & ~(RADEON_DAC_RANGE_CNTL_MASK | RADEON_DAC_PDWN);
+ tmp |= RADEON_DAC_RANGE_CNTL_PS2 | RADEON_DAC_CMP_EN;
+ OUTREG(RADEON_DAC_CNTL, tmp);
+
+ tmp &= ~(RADEON_DAC_PDWN_R |
+ RADEON_DAC_PDWN_G |
+ RADEON_DAC_PDWN_B);
+
+ OUTREG(RADEON_DAC_MACRO_CNTL, tmp);
+
+ usleep(2000);
+
+ if (INREG(RADEON_DAC_CNTL) & RADEON_DAC_CMP_OUTPUT) {
+ found = MT_CRT;
+ xf86DrvMsg (pScrn->scrnIndex, X_INFO,
+ "Found %s CRT connected to primary DAC\n",
+ color ? "color" : "bw");
+ }
+
+ /* restore the regs we used */
+ OUTREG(RADEON_DAC_CNTL, dac_cntl);
+ OUTREG(RADEON_DAC_MACRO_CNTL, dac_macro_cntl);
+ OUTREG(RADEON_DAC_EXT_CNTL, dac_ext_cntl);
+ OUTREG(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl);
+ OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, vclk_ecp_cntl);
+
+ return found;
+}
+
+static RADEONMonitorType
+radeon_detect_ext_dac(ScrnInfoPtr pScrn)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ CARD32 gpio_monid, fp2_gen_cntl, disp_output_cntl, crtc2_gen_cntl;
+ CARD32 disp_lin_trans_grph_a, disp_lin_trans_grph_b, disp_lin_trans_grph_c;
+ CARD32 disp_lin_trans_grph_d, disp_lin_trans_grph_e, disp_lin_trans_grph_f;
+ CARD32 tmp, crtc2_h_total_disp, crtc2_v_total_disp;
+ CARD32 crtc2_h_sync_strt_wid, crtc2_v_sync_strt_wid;
+ RADEONMonitorType found = MT_NONE;
+ int connected = 0;
+ int i = 0;
+
+ /* save the regs we need */
+ gpio_monid = INREG(RADEON_GPIO_MONID);
+ fp2_gen_cntl = INREG(RADEON_FP2_GEN_CNTL);
+ disp_output_cntl = INREG(RADEON_DISP_OUTPUT_CNTL);
+ crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL);
+ disp_lin_trans_grph_a = INREG(RADEON_DISP_LIN_TRANS_GRPH_A);
+ disp_lin_trans_grph_b = INREG(RADEON_DISP_LIN_TRANS_GRPH_B);
+ disp_lin_trans_grph_c = INREG(RADEON_DISP_LIN_TRANS_GRPH_C);
+ disp_lin_trans_grph_d = INREG(RADEON_DISP_LIN_TRANS_GRPH_D);
+ disp_lin_trans_grph_e = INREG(RADEON_DISP_LIN_TRANS_GRPH_E);
+ disp_lin_trans_grph_f = INREG(RADEON_DISP_LIN_TRANS_GRPH_F);
+ crtc2_h_total_disp = INREG(RADEON_CRTC2_H_TOTAL_DISP);
+ crtc2_v_total_disp = INREG(RADEON_CRTC2_V_TOTAL_DISP);
+ crtc2_h_sync_strt_wid = INREG(RADEON_CRTC2_H_SYNC_STRT_WID);
+ crtc2_v_sync_strt_wid = INREG(RADEON_CRTC2_V_SYNC_STRT_WID);
+
+ tmp = INREG(RADEON_GPIO_MONID);
+ tmp &= ~RADEON_GPIO_A_0;
+ OUTREG(RADEON_GPIO_MONID, tmp);
+
+ OUTREG(RADEON_FP2_GEN_CNTL,
+ RADEON_FP2_ON |
+ RADEON_FP2_PANEL_FORMAT |
+ R200_FP2_SOURCE_SEL_TRANS_UNIT |
+ RADEON_FP2_DVO_EN |
+ R200_FP2_DVO_RATE_SEL_SDR);
+
+ OUTREG(RADEON_DISP_OUTPUT_CNTL,
+ RADEON_DISP_DAC_SOURCE_RMX |
+ RADEON_DISP_TRANS_MATRIX_GRAPHICS);
+
+ OUTREG(RADEON_CRTC2_GEN_CNTL,
+ RADEON_CRTC2_EN |
+ RADEON_CRTC2_DISP_REQ_EN_B);
+
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_A, 0x00000000);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_B, 0x000003f0);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_C, 0x00000000);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_D, 0x000003f0);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_E, 0x00000000);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_F, 0x000003f0);
+
+ OUTREG(RADEON_CRTC2_H_TOTAL_DISP, 0x01000008);
+ OUTREG(RADEON_CRTC2_H_SYNC_STRT_WID, 0x00000800);
+ OUTREG(RADEON_CRTC2_V_TOTAL_DISP, 0x00080001);
+ OUTREG(RADEON_CRTC2_V_SYNC_STRT_WID, 0x00000080);
+
+ for (i = 0; i < 200; i++) {
+ tmp = INREG(RADEON_GPIO_MONID);
+ if (tmp & RADEON_GPIO_Y_0)
+ connected = 1;
+ else
+ connected = 0;
+
+ if (!connected)
+ break;
+
+ usleep(1000);
+ }
+
+ if (connected)
+ found = MT_CRT;
+
+ /* restore the regs we used */
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_A, disp_lin_trans_grph_a);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_B, disp_lin_trans_grph_b);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_C, disp_lin_trans_grph_c);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_D, disp_lin_trans_grph_d);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_E, disp_lin_trans_grph_e);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_F, disp_lin_trans_grph_f);
+ OUTREG(RADEON_CRTC2_H_TOTAL_DISP, crtc2_h_total_disp);
+ OUTREG(RADEON_CRTC2_V_TOTAL_DISP, crtc2_v_total_disp);
+ OUTREG(RADEON_CRTC2_H_SYNC_STRT_WID, crtc2_h_sync_strt_wid);
+ OUTREG(RADEON_CRTC2_V_SYNC_STRT_WID, crtc2_v_sync_strt_wid);
+ OUTREG(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
+ OUTREG(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl);
+ OUTREG(RADEON_FP2_GEN_CNTL, fp2_gen_cntl);
+ OUTREG(RADEON_GPIO_MONID, gpio_monid);
+
+ return found;
+}
+
+static RADEONMonitorType
+radeon_detect_tv_dac(ScrnInfoPtr pScrn, Bool color)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ CARD32 crtc2_gen_cntl, tv_dac_cntl, dac_cntl2, dac_ext_cntl;
+ CARD32 disp_hw_debug, disp_output_cntl, gpiopad_a, pixclks_cntl, tmp;
+ RADEONMonitorType found = MT_NONE;
+
+ /* save the regs we need */
+ pixclks_cntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
+ gpiopad_a = IS_R300_VARIANT ? INREG(RADEON_GPIOPAD_A) : 0;
+ disp_output_cntl = IS_R300_VARIANT ? INREG(RADEON_DISP_OUTPUT_CNTL) : 0;
+ disp_hw_debug = !IS_R300_VARIANT ? INREG(RADEON_DISP_HW_DEBUG) : 0;
+ crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL);
+ tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
+ dac_ext_cntl = INREG(RADEON_DAC_EXT_CNTL);
+ dac_cntl2 = INREG(RADEON_DAC_CNTL2);
+
+ tmp = pixclks_cntl & ~(RADEON_PIX2CLK_ALWAYS_ONb
+ | RADEON_PIX2CLK_DAC_ALWAYS_ONb);
+ OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmp);
+
+ if (IS_R300_VARIANT) {
+ OUTREGP(RADEON_GPIOPAD_A, 1, ~1 );
+ }
+
+ tmp = crtc2_gen_cntl & ~RADEON_CRTC2_PIX_WIDTH_MASK;
+ tmp |= RADEON_CRTC2_CRT2_ON |
+ (2 << RADEON_CRTC2_PIX_WIDTH_SHIFT);
+
+ OUTREG(RADEON_CRTC2_GEN_CNTL, tmp);
+
+ if (IS_R300_VARIANT) {
+ tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK;
+ tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2;
+ OUTREG(RADEON_DISP_OUTPUT_CNTL, tmp);
+ } else {
+ tmp = disp_hw_debug & ~RADEON_CRT2_DISP1_SEL;
+ OUTREG(RADEON_DISP_HW_DEBUG, tmp);
+ }
+
+ tmp = RADEON_TV_DAC_NBLANK |
+ RADEON_TV_DAC_NHOLD |
+ RADEON_TV_MONITOR_DETECT_EN |
+ RADEON_TV_DAC_STD_PS2;
+
+ OUTREG(RADEON_TV_DAC_CNTL, tmp);
+
+ tmp = RADEON_DAC2_FORCE_BLANK_OFF_EN |
+ RADEON_DAC2_FORCE_DATA_EN;
+
+ if (color)
+ tmp |= RADEON_DAC_FORCE_DATA_SEL_RGB;
+ else
+ tmp |= RADEON_DAC_FORCE_DATA_SEL_G;
+
+ if (IS_R300_VARIANT)
+ tmp |= (0x1b6 << RADEON_DAC_FORCE_DATA_SHIFT);
+ else
+ tmp |= (0x180 << RADEON_DAC_FORCE_DATA_SHIFT);
+
+ OUTREG(RADEON_DAC_EXT_CNTL, tmp);
+
+ tmp = dac_cntl2 | RADEON_DAC2_DAC2_CLK_SEL | RADEON_DAC2_CMP_EN;
+ OUTREG(RADEON_DAC_CNTL2, tmp);
+
+ usleep(10000);
+
+ if (IS_R300_VARIANT) {
+ if (INREG(RADEON_DAC_CNTL2) & RADEON_DAC2_CMP_OUT_B) {
+ found = MT_CRT;
+ xf86DrvMsg (pScrn->scrnIndex, X_INFO,
+ "Found %s CRT connected to TV DAC\n",
+ color ? "color" : "bw");
+ }
+ } else {
+ if (INREG(RADEON_DAC_CNTL2) & RADEON_DAC2_CMP_OUTPUT) {
+ found = MT_CRT;
+ xf86DrvMsg (pScrn->scrnIndex, X_INFO,
+ "Found %s CRT connected to TV DAC\n",
+ color ? "color" : "bw");
+ }
+ }
+
+ /* restore regs we used */
+ OUTREG(RADEON_DAC_CNTL2, dac_cntl2);
+ OUTREG(RADEON_DAC_EXT_CNTL, dac_ext_cntl);
+ OUTREG(RADEON_TV_DAC_CNTL, tv_dac_cntl);
+ OUTREG(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
+
+ if (IS_R300_VARIANT) {
+ OUTREG(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl);
+ OUTREGP(RADEON_GPIOPAD_A, gpiopad_a, ~1 );
+ } else {
+ OUTREG(RADEON_DISP_HW_DEBUG, disp_hw_debug);
+ }
+ OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, pixclks_cntl);
+
+ return found;
+}
+
+static RADEONMonitorType
+r300_detect_tv(ScrnInfoPtr pScrn)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ CARD32 tmp, dac_cntl2, crtc2_gen_cntl, dac_ext_cntl, tv_dac_cntl;
+ CARD32 gpiopad_a, disp_output_cntl;
+ RADEONMonitorType found = MT_NONE;
+
+ /* save the regs we need */
+ gpiopad_a = INREG(RADEON_GPIOPAD_A);
+ dac_cntl2 = INREG(RADEON_DAC_CNTL2);
+ crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL);
+ dac_ext_cntl = INREG(RADEON_DAC_EXT_CNTL);
+ tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
+ disp_output_cntl = INREG(RADEON_DISP_OUTPUT_CNTL);
+
+ OUTREGP(RADEON_GPIOPAD_A, 0, ~1 );
+
+ OUTREG(RADEON_DAC_CNTL2, RADEON_DAC2_DAC2_CLK_SEL );
+
+ OUTREG(RADEON_CRTC2_GEN_CNTL,
+ RADEON_CRTC2_CRT2_ON | RADEON_CRTC2_VSYNC_TRISTAT );
+
+ tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK;
+ tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2;
+ OUTREG(RADEON_DISP_OUTPUT_CNTL, tmp);
+
+ OUTREG(RADEON_DAC_EXT_CNTL,
+ RADEON_DAC2_FORCE_BLANK_OFF_EN |
+ RADEON_DAC2_FORCE_DATA_EN |
+ RADEON_DAC_FORCE_DATA_SEL_RGB |
+ (0xec << RADEON_DAC_FORCE_DATA_SHIFT ));
+
+ OUTREG(RADEON_TV_DAC_CNTL,
+ RADEON_TV_DAC_STD_NTSC |
+ (8 << RADEON_TV_DAC_BGADJ_SHIFT) |
+ (6 << RADEON_TV_DAC_DACADJ_SHIFT ));
+
+ INREG(RADEON_TV_DAC_CNTL);
+
+ usleep(4000);
+
+ OUTREG(RADEON_TV_DAC_CNTL,
+ RADEON_TV_DAC_NBLANK |
+ RADEON_TV_DAC_NHOLD |
+ RADEON_TV_MONITOR_DETECT_EN |
+ RADEON_TV_DAC_STD_NTSC |
+ (8 << RADEON_TV_DAC_BGADJ_SHIFT) |
+ (6 << RADEON_TV_DAC_DACADJ_SHIFT ));
+
+ INREG(RADEON_TV_DAC_CNTL);
+
+ usleep(6000);
+
+ tmp = INREG(RADEON_TV_DAC_CNTL);
+ if ( (tmp & RADEON_TV_DAC_GDACDET) != 0 ) {
+ found = MT_STV;
+ xf86DrvMsg (pScrn->scrnIndex, X_INFO,
+ "S-Video TV connection detected\n");
+ } else if ( (tmp & RADEON_TV_DAC_BDACDET) != 0 ) {
+ found = MT_CTV;
+ xf86DrvMsg (pScrn->scrnIndex, X_INFO,
+ "Composite TV connection detected\n" );
+ }
+
+ OUTREG(RADEON_TV_DAC_CNTL, tv_dac_cntl );
+ OUTREG(RADEON_DAC_EXT_CNTL, dac_ext_cntl);
+ OUTREG(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
+ OUTREG(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl);
+ OUTREG(RADEON_DAC_CNTL2, dac_cntl2);
+ OUTREGP(RADEON_GPIOPAD_A, gpiopad_a, ~1);
+
+ return found;
+}
+
+static RADEONMonitorType
+radeon_detect_tv(ScrnInfoPtr pScrn)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ CARD32 tmp, dac_cntl2, tv_master_cntl;
+ CARD32 tv_dac_cntl, tv_pre_dac_mux_cntl, config_cntl;
+ RADEONMonitorType found = MT_NONE;
+
+ if (IS_R300_VARIANT)
+ return r300_detect_tv(pScrn);
+
+ /* save the regs we need */
+ dac_cntl2 = INREG(RADEON_DAC_CNTL2);
+ tv_master_cntl = INREG(RADEON_TV_MASTER_CNTL);
+ tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
+ config_cntl = INREG(RADEON_CONFIG_CNTL);
+ tv_pre_dac_mux_cntl = INREG(RADEON_TV_PRE_DAC_MUX_CNTL);
+
+ tmp = dac_cntl2 & ~RADEON_DAC2_DAC2_CLK_SEL;
+ OUTREG(RADEON_DAC_CNTL2, tmp);
+
+ tmp = tv_master_cntl | RADEON_TV_ON;
+ tmp &= ~(RADEON_TV_ASYNC_RST |
+ RADEON_RESTART_PHASE_FIX |
+ RADEON_CRT_FIFO_CE_EN |
+ RADEON_TV_FIFO_CE_EN |
+ RADEON_RE_SYNC_NOW_SEL_MASK);
+ tmp |= RADEON_TV_FIFO_ASYNC_RST | RADEON_CRT_ASYNC_RST;
+
+ OUTREG(RADEON_TV_MASTER_CNTL, tmp);
+
+ tmp = RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD |
+ RADEON_TV_MONITOR_DETECT_EN | RADEON_TV_DAC_STD_NTSC |
+ (8 << RADEON_TV_DAC_BGADJ_SHIFT);
+
+ if (config_cntl & RADEON_CFG_ATI_REV_ID_MASK)
+ tmp |= (4 << RADEON_TV_DAC_DACADJ_SHIFT);
+ else
+ tmp |= (8 << RADEON_TV_DAC_DACADJ_SHIFT);
+
+ OUTREG(RADEON_TV_DAC_CNTL, tmp);
+
+ tmp = RADEON_C_GRN_EN | RADEON_CMP_BLU_EN |
+ RADEON_RED_MX_FORCE_DAC_DATA |
+ RADEON_GRN_MX_FORCE_DAC_DATA |
+ RADEON_BLU_MX_FORCE_DAC_DATA |
+ (0x109 << RADEON_TV_FORCE_DAC_DATA_SHIFT);
+
+ OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, tmp);
+
+ usleep(3000);
+
+ tmp = INREG(RADEON_TV_DAC_CNTL);
+ if (tmp & RADEON_TV_DAC_GDACDET) {
+ found = MT_STV;
+ xf86DrvMsg (pScrn->scrnIndex, X_INFO,
+ "S-Video TV connection detected\n");
+ } else if (tmp & RADEON_TV_DAC_BDACDET) {
+ found = MT_CTV;
+ xf86DrvMsg (pScrn->scrnIndex, X_INFO,
+ "Composite TV connection detected\n" );
+ }
+
+ OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, tv_pre_dac_mux_cntl);
+ OUTREG(RADEON_TV_DAC_CNTL, tv_dac_cntl);
+ OUTREG(RADEON_TV_MASTER_CNTL, tv_master_cntl);
+ OUTREG(RADEON_DAC_CNTL2, dac_cntl2);
+
+ return found;
+}
+
+static xf86OutputStatus
+radeon_detect(xf86OutputPtr output)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+ Bool connected = TRUE;
+
+ radeon_output->MonType = MT_UNKNOWN;
+ RADEONConnectorFindMonitor(pScrn, output);
+
+ /* force montype based on output property */
+ if (radeon_output->type == OUTPUT_DVI) {
+ if (radeon_output->MonType == MT_NONE)
+ connected = FALSE;
+ if ((info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_DVI_I_ATOM) ||
+ (!info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_DVI_I)) {
+ if (radeon_output->DVIType == DVI_ANALOG)
+ radeon_output->MonType = MT_CRT;
+ else if (radeon_output->DVIType == DVI_DIGITAL)
+ radeon_output->MonType = MT_DFP;
+ }
+ }
+
+ /* set montype so users can force outputs on even if detection fails */
+ if (radeon_output->MonType == MT_NONE) {
+ connected = FALSE;
+ if (radeon_output->type == OUTPUT_LVDS)
+ radeon_output->MonType = MT_LCD;
+ else if (radeon_output->type == OUTPUT_VGA)
+ radeon_output->MonType = MT_CRT;
+ else if (radeon_output->type == OUTPUT_STV)
+ radeon_output->MonType = MT_STV;
+ else if (radeon_output->type == OUTPUT_CTV)
+ radeon_output->MonType = MT_CTV;
+ else if ((info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_DVI_D_ATOM) ||
+ (!info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_DVI_D))
+ radeon_output->MonType = MT_DFP;
+ }
+
+ if (radeon_output->MonType == MT_UNKNOWN) {
+ output->subpixel_order = SubPixelUnknown;
+ return XF86OutputStatusUnknown;
+ } else {
+
+ switch(radeon_output->MonType) {
+ case MT_LCD:
+ case MT_DFP:
+ output->subpixel_order = SubPixelHorizontalRGB;
+ break;
+ default:
+ output->subpixel_order = SubPixelNone;
+ break;
+ }
+
+ if (connected)
+ return XF86OutputStatusConnected;
+ else
+ return XF86OutputStatusDisconnected;
+ }
+
+}
+
+static DisplayModePtr
+radeon_get_modes(xf86OutputPtr output)
+{
+ DisplayModePtr modes;
+ modes = RADEONProbeOutputModes(output);
+ return modes;
+}
+
+static void
+radeon_destroy (xf86OutputPtr output)
+{
+ if(output->driver_private)
+ xfree(output->driver_private);
+}
+
+static void
+radeon_set_backlight_level(xf86OutputPtr output, int level)
+{
+#if 0
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char * RADEONMMIO = info->MMIO;
+ CARD32 lvds_gen_cntl;
+
+ lvds_gen_cntl = INREG(RADEON_LVDS_GEN_CNTL);
+ lvds_gen_cntl |= RADEON_LVDS_BL_MOD_EN;
+ lvds_gen_cntl &= ~RADEON_LVDS_BL_MOD_LEVEL_MASK;
+ lvds_gen_cntl |= (level << RADEON_LVDS_BL_MOD_LEVEL_SHIFT) & RADEON_LVDS_BL_MOD_LEVEL_MASK;
+ //usleep (radeon_output->PanelPwrDly * 1000);
+ OUTREG(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl);
+ lvds_gen_cntl &= ~RADEON_LVDS_BL_MOD_EN;
+ //usleep (radeon_output->PanelPwrDly * 1000);
+ OUTREG(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl);
+#endif
+}
+
+static Atom backlight_atom;
+static Atom tmds_pll_atom;
+static Atom rmx_atom;
+static Atom monitor_type_atom;
+static Atom load_detection_atom;
+static Atom tv_hsize_atom;
+static Atom tv_hpos_atom;
+static Atom tv_vpos_atom;
+static Atom tv_std_atom;
+#define RADEON_MAX_BACKLIGHT_LEVEL 255
+
+static void
+radeon_create_resources(xf86OutputPtr output)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+ INT32 range[2];
+ int data, err;
+ const char *s;
+
+ /* backlight control */
+ if (radeon_output->type == OUTPUT_LVDS) {
+ backlight_atom = MAKE_ATOM("backlight");
+
+ range[0] = 0;
+ range[1] = RADEON_MAX_BACKLIGHT_LEVEL;
+ err = RRConfigureOutputProperty(output->randr_output, backlight_atom,
+ FALSE, TRUE, FALSE, 2, range);
+ if (err != 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "RRConfigureOutputProperty error, %d\n", err);
+ }
+ /* Set the current value of the backlight property */
+ //data = (info->SavedReg.lvds_gen_cntl & RADEON_LVDS_BL_MOD_LEVEL_MASK) >> RADEON_LVDS_BL_MOD_LEVEL_SHIFT;
+ data = RADEON_MAX_BACKLIGHT_LEVEL;
+ err = RRChangeOutputProperty(output->randr_output, backlight_atom,
+ XA_INTEGER, 32, PropModeReplace, 1, &data,
+ FALSE, TRUE);
+ if (err != 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "RRChangeOutputProperty error, %d\n", err);
+ }
+ }
+
+ if (radeon_output->DACType == DAC_PRIMARY ||
+ radeon_output->DACType == DAC_TVDAC) {
+ load_detection_atom = MAKE_ATOM("load_detection");
+
+ range[0] = 0; /* off */
+ range[1] = 1; /* on */
+ err = RRConfigureOutputProperty(output->randr_output, load_detection_atom,
+ FALSE, TRUE, FALSE, 2, range);
+ if (err != 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "RRConfigureOutputProperty error, %d\n", err);
+ }
+
+ if (radeon_output->DACType == DAC_PRIMARY)
+ data = 1; /* primary dac, only drives vga */
+ else if (radeon_output->DACType == DAC_TVDAC &&
+ info->tvdac_use_count < 2)
+ data = 1; /* only one output with tvdac */
+ else
+ data = 0; /* shared tvdac between vga/dvi/tv */
+
+ err = RRChangeOutputProperty(output->randr_output, load_detection_atom,
+ XA_INTEGER, 32, PropModeReplace, 1, &data,
+ FALSE, TRUE);
+ if (err != 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "RRChangeOutputProperty error, %d\n", err);
+ }
+ }
+
+ if (radeon_output->type == OUTPUT_DVI &&
+ radeon_output->TMDSType == TMDS_INT) {
+ tmds_pll_atom = MAKE_ATOM("tmds_pll");
+
+ err = RRConfigureOutputProperty(output->randr_output, tmds_pll_atom,
+ FALSE, FALSE, FALSE, 0, NULL);
+ if (err != 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "RRConfigureOutputProperty error, %d\n", err);
+ }
+ /* Set the current value of the property */
+#if defined(__powerpc__)
+ s = "driver";
+#else
+ s = "bios";
+#endif
+ err = RRChangeOutputProperty(output->randr_output, tmds_pll_atom,
+ XA_STRING, 8, PropModeReplace, strlen(s), (pointer)s,
+ FALSE, FALSE);
+ if (err != 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "RRChangeOutputProperty error, %d\n", err);
+ }
+
+ }
+
+ /* RMX control - fullscreen, centered, keep ratio */
+ /* actually more of a crtc property as only crtc1 has rmx */
+ if (radeon_output->type == OUTPUT_LVDS ||
+ radeon_output->type == OUTPUT_DVI) {
+ rmx_atom = MAKE_ATOM("scaler");
+
+ err = RRConfigureOutputProperty(output->randr_output, rmx_atom,
+ FALSE, FALSE, FALSE, 0, NULL);
+ if (err != 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "RRConfigureOutputProperty error, %d\n", err);
+ }
+ /* Set the current value of the property */
+ s = "full";
+ err = RRChangeOutputProperty(output->randr_output, rmx_atom,
+ XA_STRING, 8, PropModeReplace, strlen(s), (pointer)s,
+ FALSE, FALSE);
+ if (err != 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "RRChangeOutputProperty error, %d\n", err);
+ }
+ }
+
+ /* force auto/analog/digital for DVI-I ports */
+ if (radeon_output->type == OUTPUT_DVI) {
+ if ((info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_DVI_I_ATOM) ||
+ (!info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_DVI_I)) {
+ monitor_type_atom = MAKE_ATOM("dvi_monitor_type");
+
+ err = RRConfigureOutputProperty(output->randr_output, monitor_type_atom,
+ FALSE, FALSE, FALSE, 0, NULL);
+ if (err != 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "RRConfigureOutputProperty error, %d\n", err);
+ }
+ /* Set the current value of the backlight property */
+ s = "auto";
+ err = RRChangeOutputProperty(output->randr_output, monitor_type_atom,
+ XA_STRING, 8, PropModeReplace, strlen(s), (pointer)s,
+ FALSE, FALSE);
+ if (err != 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "RRChangeOutputProperty error, %d\n", err);
+ }
+ }
+ }
+
+ if (radeon_output->type == OUTPUT_STV ||
+ radeon_output->type == OUTPUT_CTV) {
+ tv_hsize_atom = MAKE_ATOM("tv_horizontal_size");
+
+ range[0] = -MAX_H_SIZE;
+ range[1] = MAX_H_SIZE;
+ err = RRConfigureOutputProperty(output->randr_output, tv_hsize_atom,
+ FALSE, TRUE, FALSE, 2, range);
+ if (err != 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "RRConfigureOutputProperty error, %d\n", err);
+ }
+ data = 0;
+ err = RRChangeOutputProperty(output->randr_output, tv_hsize_atom,
+ XA_INTEGER, 32, PropModeReplace, 1, &data,
+ FALSE, TRUE);
+ if (err != 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "RRChangeOutputProperty error, %d\n", err);
+ }
+ }
+
+ if (radeon_output->type == OUTPUT_STV ||
+ radeon_output->type == OUTPUT_CTV) {
+ tv_hpos_atom = MAKE_ATOM("tv_horizontal_position");
+
+ range[0] = -MAX_H_POSITION;
+ range[1] = MAX_H_POSITION;
+ err = RRConfigureOutputProperty(output->randr_output, tv_hpos_atom,
+ FALSE, TRUE, FALSE, 2, range);
+ if (err != 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "RRConfigureOutputProperty error, %d\n", err);
+ }
+ data = 0;
+ err = RRChangeOutputProperty(output->randr_output, tv_hpos_atom,
+ XA_INTEGER, 32, PropModeReplace, 1, &data,
+ FALSE, TRUE);
+ if (err != 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "RRChangeOutputProperty error, %d\n", err);
+ }
+ }
+
+ if (radeon_output->type == OUTPUT_STV ||
+ radeon_output->type == OUTPUT_CTV) {
+ tv_vpos_atom = MAKE_ATOM("tv_vertical_position");
+
+ range[0] = -MAX_V_POSITION;
+ range[1] = MAX_V_POSITION;
+ err = RRConfigureOutputProperty(output->randr_output, tv_vpos_atom,
+ FALSE, TRUE, FALSE, 2, range);
+ if (err != 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "RRConfigureOutputProperty error, %d\n", err);
+ }
+ data = 0;
+ err = RRChangeOutputProperty(output->randr_output, tv_vpos_atom,
+ XA_INTEGER, 32, PropModeReplace, 1, &data,
+ FALSE, TRUE);
+ if (err != 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "RRChangeOutputProperty error, %d\n", err);
+ }
+ }
+
+ if (radeon_output->type == OUTPUT_STV ||
+ radeon_output->type == OUTPUT_CTV) {
+ tv_std_atom = MAKE_ATOM("tv_standard");
+
+ err = RRConfigureOutputProperty(output->randr_output, tv_std_atom,
+ FALSE, FALSE, FALSE, 0, NULL);
+ if (err != 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "RRConfigureOutputProperty error, %d\n", err);
+ }
+ /* Set the current value of the backlight property */
+ switch (radeon_output->default_tvStd) {
+ case TV_STD_PAL:
+ s = "pal";
+ break;
+ case TV_STD_PAL_M:
+ s = "pal-m";
+ break;
+ case TV_STD_PAL_60:
+ s = "pal-60";
+ break;
+ case TV_STD_NTSC_J:
+ s = "ntsc-j";
+ break;
+ case TV_STD_SCART_PAL:
+ s = "scart-pal";
+ break;
+ case TV_STD_NTSC:
+ default:
+ s = "ntsc";
+ break;
+ }
+ err = RRChangeOutputProperty(output->randr_output, tv_std_atom,
+ XA_STRING, 8, PropModeReplace, strlen(s), (pointer)s,
+ FALSE, FALSE);
+ if (err != 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "RRChangeOutputProperty error, %d\n", err);
+ }
+ }
+}
+
+static Bool
+radeon_set_property(xf86OutputPtr output, Atom property,
+ RRPropertyValuePtr value)
+{
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+ INT32 val;
+
+
+ if (property == backlight_atom) {
+ if (value->type != XA_INTEGER ||
+ value->format != 32 ||
+ value->size != 1) {
+ return FALSE;
+ }
+
+ val = *(INT32 *)value->data;
+ if (val < 0 || val > RADEON_MAX_BACKLIGHT_LEVEL)
+ return FALSE;
+
+#if defined(__powerpc__)
+ val = RADEON_MAX_BACKLIGHT_LEVEL - val;
+#endif
+
+ radeon_set_backlight_level(output, val);
+
+ } else if (property == load_detection_atom) {
+ if (value->type != XA_INTEGER ||
+ value->format != 32 ||
+ value->size != 1) {
+ return FALSE;
+ }
+
+ val = *(INT32 *)value->data;
+ if (val < 0 || val > 1)
+ return FALSE;
+
+ radeon_output->load_detection = val;
+
+ } else if (property == rmx_atom) {
+ xf86CrtcPtr crtc = output->crtc;
+ RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+ if (radeon_crtc->crtc_id == 0) {
+ const char *s;
+ if (value->type != XA_STRING || value->format != 8)
+ return FALSE;
+ s = (char*)value->data;
+ if (value->size == strlen("full") && !strncmp("full", s, strlen("full"))) {
+ return TRUE;
+ } else if (value->size == strlen("aspect") && !strncmp("aspect", s, strlen("aspect"))) {
+ return TRUE;
+ } else if (value->size == strlen("center") && !strncmp("center", s, strlen("center"))) {
+ return TRUE;
+ }
+ return FALSE;
+ } else {
+ return FALSE;
+ }
+ } else if (property == tmds_pll_atom) {
+ const char *s;
+ if (value->type != XA_STRING || value->format != 8)
+ return FALSE;
+ s = (char*)value->data;
+ if (value->size == strlen("bios") && !strncmp("bios", s, strlen("bios"))) {
+ radeon_output->tmds_pll_table = TMDS_PLL_BIOS;
+ return TRUE;
+ } else if (value->size == strlen("driver") && !strncmp("driver", s, strlen("driver"))) {
+ radeon_output->tmds_pll_table = TMDS_PLL_DRIVER;
+ return TRUE;
+ }
+ return FALSE;
+ } else if (property == monitor_type_atom) {
+ const char *s;
+ if (value->type != XA_STRING || value->format != 8)
+ return FALSE;
+ s = (char*)value->data;
+ if (value->size == strlen("auto") && !strncmp("auto", s, strlen("auto"))) {
+ radeon_output->DVIType = DVI_AUTO;
+ return TRUE;
+ } else if (value->size == strlen("analog") && !strncmp("analog", s, strlen("analog"))) {
+ radeon_output->DVIType = DVI_ANALOG;
+ return TRUE;
+ } else if (value->size == strlen("digital") && !strncmp("digital", s, strlen("digital"))) {
+ radeon_output->DVIType = DVI_DIGITAL;
+ return TRUE;
+ }
+ return FALSE;
+ } else if (property == tv_hsize_atom) {
+ if (value->type != XA_INTEGER ||
+ value->format != 32 ||
+ value->size != 1) {
+ return FALSE;
+ }
+
+ val = *(INT32 *)value->data;
+ if (val < -MAX_H_SIZE || val > MAX_H_SIZE)
+ return FALSE;
+
+ radeon_output->hSize = val;
+ if (radeon_output->tv_on)
+ RADEONUpdateHVPosition(output, &output->crtc->mode);
+ return TRUE;
+ } else if (property == tv_hpos_atom) {
+ if (value->type != XA_INTEGER ||
+ value->format != 32 ||
+ value->size != 1) {
+ return FALSE;
+ }
+
+ val = *(INT32 *)value->data;
+ if (val < -MAX_H_POSITION || val > MAX_H_POSITION)
+ return FALSE;
+
+ radeon_output->hPos = val;
+ if (radeon_output->tv_on)
+ RADEONUpdateHVPosition(output, &output->crtc->mode);
+ return TRUE;
+ } else if (property == tv_vpos_atom) {
+ if (value->type != XA_INTEGER ||
+ value->format != 32 ||
+ value->size != 1) {
+ return FALSE;
+ }
+
+ val = *(INT32 *)value->data;
+ if (val < -MAX_H_POSITION || val > MAX_H_POSITION)
+ return FALSE;
+
+ radeon_output->vPos = val;
+ if (radeon_output->tv_on)
+ RADEONUpdateHVPosition(output, &output->crtc->mode);
+ return TRUE;
+ } else if (property == tv_std_atom) {
+ const char *s;
+ if (value->type != XA_STRING || value->format != 8)
+ return FALSE;
+ s = (char*)value->data;
+ if (value->size == strlen("default") && !strncmp("default", s, strlen("default"))) {
+ radeon_output->tvStd = radeon_output->default_tvStd;
+ return TRUE;
+ } else if (value->size == strlen("ntsc") && !strncmp("ntsc", s, strlen("ntsc"))) {
+ if (radeon_output->SupportedTVStds & TV_STD_NTSC) {
+ radeon_output->tvStd = TV_STD_NTSC;
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+ } else if (value->size == strlen("pal") && !strncmp("pal", s, strlen("pal"))) {
+ if (radeon_output->SupportedTVStds & TV_STD_PAL) {
+ radeon_output->tvStd = TV_STD_PAL;
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+ } else if (value->size == strlen("pal-m") && !strncmp("pal-m", s, strlen("pal-m"))) {
+ if (radeon_output->SupportedTVStds & TV_STD_PAL_M) {
+ radeon_output->tvStd = TV_STD_PAL_M;
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+ } else if (value->size == strlen("pal-60") && !strncmp("pal-60", s, strlen("pal-60"))) {
+ if (radeon_output->SupportedTVStds & TV_STD_PAL_60) {
+ radeon_output->tvStd = TV_STD_PAL_60;
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+ } else if (value->size == strlen("ntsc-j") && !strncmp("ntsc-j", s, strlen("ntsc-j"))) {
+ if (radeon_output->SupportedTVStds & TV_STD_NTSC_J) {
+ radeon_output->tvStd = TV_STD_NTSC_J;
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+ } else if (value->size == strlen("scart-pal") && !strncmp("scart-pal", s, strlen("scart-pal"))) {
+ if (radeon_output->SupportedTVStds & TV_STD_SCART_PAL) {
+ radeon_output->tvStd = TV_STD_SCART_PAL;
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+ }
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static const xf86OutputFuncsRec radeon_output_funcs = {
+ .create_resources = radeon_create_resources,
+ .dpms = radeon_dpms,
+ .save = radeon_save,
+ .restore = radeon_restore,
+ .mode_valid = radeon_mode_valid,
+ .mode_fixup = radeon_mode_fixup,
+ .prepare = radeon_mode_prepare,
+ .mode_set = radeon_mode_set,
+ .commit = radeon_mode_commit,
+ .detect = radeon_detect,
+ .get_modes = radeon_get_modes,
+ .set_property = radeon_set_property,
+ .destroy = radeon_destroy
+};
+
+void RADEONSetOutputType(ScrnInfoPtr pScrn, RADEONOutputPrivatePtr radeon_output)
+{
+ RADEONInfoPtr info = RADEONPTR (pScrn);
+ RADEONOutputType output;
+
+ if (info->IsAtomBios) {
+ switch(radeon_output->ConnectorType) {
+ case CONNECTOR_VGA_ATOM:
+ output = OUTPUT_VGA; break;
+ case CONNECTOR_DVI_I_ATOM:
+ case CONNECTOR_DVI_D_ATOM:
+ case CONNECTOR_DVI_A_ATOM:
+ output = OUTPUT_DVI; break;
+ case CONNECTOR_STV_ATOM:
+ output = OUTPUT_STV; break;
+ case CONNECTOR_CTV_ATOM:
+ output = OUTPUT_CTV; break;
+ case CONNECTOR_LVDS_ATOM:
+ case CONNECTOR_DIGITAL_ATOM:
+ output = OUTPUT_LVDS; break;
+ case CONNECTOR_NONE_ATOM:
+ case CONNECTOR_UNSUPPORTED_ATOM:
+ default:
+ output = OUTPUT_NONE; break;
+ }
+ }
+ else {
+ switch(radeon_output->ConnectorType) {
+ case CONNECTOR_PROPRIETARY:
+ output = OUTPUT_LVDS; break;
+ case CONNECTOR_CRT:
+ output = OUTPUT_VGA; break;
+ case CONNECTOR_DVI_I:
+ case CONNECTOR_DVI_D:
+ output = OUTPUT_DVI; break;
+ case CONNECTOR_CTV:
+ output = OUTPUT_CTV; break;
+ case CONNECTOR_STV:
+ output = OUTPUT_STV; break;
+ case CONNECTOR_NONE:
+ case CONNECTOR_UNSUPPORTED:
+ default:
+ output = OUTPUT_NONE; break;
+ }
+ }
+ radeon_output->type = output;
+}
+
+static void RADEONI2CGetBits(I2CBusPtr b, int *Clock, int *data)
+{
+ ScrnInfoPtr pScrn = xf86Screens[b->scrnIndex];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned long val;
+ unsigned char *RADEONMMIO = info->MMIO;
+
+ /* Get the result */
+
+ if (b->DriverPrivate.uval == RADEON_LCD_GPIO_MASK) {
+ val = INREG(b->DriverPrivate.uval+4);
+ *Clock = (val & (1<<13)) != 0;
+ *data = (val & (1<<12)) != 0;
+ } else {
+ val = INREG(b->DriverPrivate.uval);
+ *Clock = (val & RADEON_GPIO_Y_1) != 0;
+ *data = (val & RADEON_GPIO_Y_0) != 0;
+ }
+}
+
+static void RADEONI2CPutBits(I2CBusPtr b, int Clock, int data)
+{
+ ScrnInfoPtr pScrn = xf86Screens[b->scrnIndex];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned long val;
+ unsigned char *RADEONMMIO = info->MMIO;
+
+ if (b->DriverPrivate.uval == RADEON_LCD_GPIO_MASK) {
+ val = INREG(b->DriverPrivate.uval) & (CARD32)~((1<<12) | (1<<13));
+ val |= (Clock ? 0:(1<<13));
+ val |= (data ? 0:(1<<12));
+ OUTREG(b->DriverPrivate.uval, val);
+ } else {
+ val = INREG(b->DriverPrivate.uval) & (CARD32)~(RADEON_GPIO_EN_0 | RADEON_GPIO_EN_1);
+ val |= (Clock ? 0:RADEON_GPIO_EN_1);
+ val |= (data ? 0:RADEON_GPIO_EN_0);
+ OUTREG(b->DriverPrivate.uval, val);
+ }
+ /* read back to improve reliability on some cards. */
+ val = INREG(b->DriverPrivate.uval);
+}
+
+static Bool
+RADEONI2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, int i2c_reg, char *name)
+{
+ I2CBusPtr pI2CBus;
+
+ pI2CBus = xf86CreateI2CBusRec();
+ if (!pI2CBus) return FALSE;
+
+ pI2CBus->BusName = name;
+ pI2CBus->scrnIndex = pScrn->scrnIndex;
+ pI2CBus->I2CPutBits = RADEONI2CPutBits;
+ pI2CBus->I2CGetBits = RADEONI2CGetBits;
+ pI2CBus->AcknTimeout = 5;
+ pI2CBus->DriverPrivate.uval = i2c_reg;
+
+ if (!xf86I2CBusInit(pI2CBus)) return FALSE;
+
+ *bus_ptr = pI2CBus;
+ return TRUE;
+}
+
+static void
+RADEONGetPanelInfoFromReg (xf86OutputPtr output)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+ unsigned char *RADEONMMIO = info->MMIO;
+ CARD32 fp_vert_stretch = INREG(RADEON_FP_VERT_STRETCH);
+ CARD32 fp_horz_stretch = INREG(RADEON_FP_HORZ_STRETCH);
+
+ radeon_output->PanelPwrDly = 200;
+ if (fp_vert_stretch & RADEON_VERT_STRETCH_ENABLE) {
+ radeon_output->PanelYRes = ((fp_vert_stretch & RADEON_VERT_PANEL_SIZE) >>
+ RADEON_VERT_PANEL_SHIFT) + 1;
+ } else {
+ radeon_output->PanelYRes = (INREG(RADEON_CRTC_V_TOTAL_DISP)>>16) + 1;
+ }
+ if (fp_horz_stretch & RADEON_HORZ_STRETCH_ENABLE) {
+ radeon_output->PanelXRes = (((fp_horz_stretch & RADEON_HORZ_PANEL_SIZE) >>
+ RADEON_HORZ_PANEL_SHIFT) + 1) * 8;
+ } else {
+ radeon_output->PanelXRes = ((INREG(RADEON_CRTC_H_TOTAL_DISP)>>16) + 1) * 8;
+ }
+
+ if ((radeon_output->PanelXRes < 640) || (radeon_output->PanelYRes < 480)) {
+ radeon_output->PanelXRes = 640;
+ radeon_output->PanelYRes = 480;
+ }
+
+ // move this to crtc function
+ if (xf86ReturnOptValBool(info->Options, OPTION_LVDS_PROBE_PLL, TRUE)) {
+ CARD32 ppll_div_sel, ppll_val;
+
+ ppll_div_sel = INREG8(RADEON_CLOCK_CNTL_INDEX + 1) & 0x3;
+ RADEONPllErrataAfterIndex(info);
+ ppll_val = INPLL(pScrn, RADEON_PPLL_DIV_0 + ppll_div_sel);
+ if ((ppll_val & 0x000707ff) == 0x1bb)
+ goto noprobe;
+ info->FeedbackDivider = ppll_val & 0x7ff;
+ info->PostDivider = (ppll_val >> 16) & 0x7;
+ info->RefDivider = info->pll.reference_div;
+ info->UseBiosDividers = TRUE;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Existing panel PLL dividers will be used.\n");
+ }
+ noprobe:
+
+ 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",
+ radeon_output->PanelXRes, radeon_output->PanelYRes);
+}
+
+/* BIOS may not have right panel size, we search through all supported
+ * DDC modes looking for the maximum panel size.
+ */
+static void
+RADEONUpdatePanelSize(xf86OutputPtr output)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+ int j;
+ /* XXX: fixme */
+ //xf86MonPtr ddc = pScrn->monitor->DDC;
+ xf86MonPtr ddc = output->MonInfo;
+ DisplayModePtr p;
+
+ // crtc should handle?
+ if ((info->UseBiosDividers && radeon_output->DotClock != 0) || (ddc == NULL))
+ return;
+
+ /* Go thru detailed timing table first */
+ for (j = 0; j < 4; j++) {
+ if (ddc->det_mon[j].type == 0) {
+ struct detailed_timings *d_timings =
+ &ddc->det_mon[j].section.d_timings;
+ int match = 0;
+
+ /* If we didn't get a panel clock or guessed one, try to match the
+ * mode with the panel size. We do that because we _need_ a panel
+ * clock, or ValidateFPModes will fail, even when UseBiosDividers
+ * is set.
+ */
+ if (radeon_output->DotClock == 0 &&
+ radeon_output->PanelXRes == d_timings->h_active &&
+ radeon_output->PanelYRes == d_timings->v_active)
+ match = 1;
+
+ /* If we don't have a BIOS provided panel data with fixed dividers,
+ * check for a larger panel size
+ */
+ if (radeon_output->PanelXRes < d_timings->h_active &&
+ radeon_output->PanelYRes < d_timings->v_active &&
+ !info->UseBiosDividers)
+ match = 1;
+
+ if (match) {
+ radeon_output->PanelXRes = d_timings->h_active;
+ radeon_output->PanelYRes = d_timings->v_active;
+ radeon_output->DotClock = d_timings->clock / 1000;
+ radeon_output->HOverPlus = d_timings->h_sync_off;
+ radeon_output->HSyncWidth = d_timings->h_sync_width;
+ radeon_output->HBlank = d_timings->h_blanking;
+ radeon_output->VOverPlus = d_timings->v_sync_off;
+ radeon_output->VSyncWidth = d_timings->v_sync_width;
+ radeon_output->VBlank = d_timings->v_blanking;
+ radeon_output->Flags = (d_timings->interlaced ? V_INTERLACE : 0);
+ switch (d_timings->misc) {
+ case 0: radeon_output->Flags |= V_NHSYNC | V_NVSYNC; break;
+ case 1: radeon_output->Flags |= V_PHSYNC | V_NVSYNC; break;
+ case 2: radeon_output->Flags |= V_NHSYNC | V_PVSYNC; break;
+ case 3: radeon_output->Flags |= V_PHSYNC | V_PVSYNC; break;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel infos found from DDC detailed: %dx%d\n",
+ radeon_output->PanelXRes, radeon_output->PanelYRes);
+ }
+ }
+ }
+
+ if (info->UseBiosDividers && radeon_output->DotClock != 0)
+ return;
+
+ /* Search thru standard VESA modes from EDID */
+ for (j = 0; j < 8; j++) {
+ if ((radeon_output->PanelXRes < ddc->timings2[j].hsize) &&
+ (radeon_output->PanelYRes < ddc->timings2[j].vsize)) {
+ for (p = pScrn->monitor->Modes; p; p = p->next) {
+ if ((ddc->timings2[j].hsize == p->HDisplay) &&
+ (ddc->timings2[j].vsize == p->VDisplay)) {
+ float refresh =
+ (float)p->Clock * 1000.0 / p->HTotal / p->VTotal;
+
+ if (abs((float)ddc->timings2[j].refresh - refresh) < 1.0) {
+ /* Is this good enough? */
+ radeon_output->PanelXRes = ddc->timings2[j].hsize;
+ radeon_output->PanelYRes = ddc->timings2[j].vsize;
+ radeon_output->HBlank = p->HTotal - p->HDisplay;
+ radeon_output->HOverPlus = p->HSyncStart - p->HDisplay;
+ radeon_output->HSyncWidth = p->HSyncEnd - p->HSyncStart;
+ radeon_output->VBlank = p->VTotal - p->VDisplay;
+ radeon_output->VOverPlus = p->VSyncStart - p->VDisplay;
+ radeon_output->VSyncWidth = p->VSyncEnd - p->VSyncStart;
+ radeon_output->DotClock = p->Clock;
+ radeon_output->Flags = p->Flags;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel infos found from DDC VESA/EDID: %dx%d\n",
+ radeon_output->PanelXRes, radeon_output->PanelYRes);
+ }
+ }
+ }
+ }
+ }
+}
+
+static Bool
+RADEONGetLVDSInfo (xf86OutputPtr output)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+ char* s;
+
+ if (!RADEONGetLVDSInfoFromBIOS(output))
+ RADEONGetPanelInfoFromReg(output);
+
+ if ((s = xf86GetOptValString(info->Options, OPTION_PANEL_SIZE))) {
+ radeon_output->PanelPwrDly = 200;
+ if (sscanf (s, "%dx%d", &radeon_output->PanelXRes, &radeon_output->PanelYRes) != 2) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Invalid PanelSize option: %s\n", s);
+ RADEONGetPanelInfoFromReg(output);
+ }
+ }
+
+ /* The panel size we collected from BIOS may not be the
+ * maximum size supported by the panel. If not, we update
+ * it now. These will be used if no matching mode can be
+ * found from EDID data.
+ */
+ RADEONUpdatePanelSize(output);
+
+ if (radeon_output->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 == radeon_output->PanelXRes) &&
+ (tmp_mode->VDisplay == radeon_output->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)) {
+ radeon_output->HBlank = tmp_mode->HTotal - tmp_mode->HDisplay;
+ radeon_output->HOverPlus = tmp_mode->HSyncStart - tmp_mode->HDisplay;
+ radeon_output->HSyncWidth = tmp_mode->HSyncEnd - tmp_mode->HSyncStart;
+ radeon_output->VBlank = tmp_mode->VTotal - tmp_mode->VDisplay;
+ radeon_output->VOverPlus = tmp_mode->VSyncStart - tmp_mode->VDisplay;
+ radeon_output->VSyncWidth = tmp_mode->VSyncEnd - tmp_mode->VSyncStart;
+ radeon_output->DotClock = tmp_mode->Clock;
+ radeon_output->Flags = 0;
+ break;
+ }
+ }
+
+ tmp_mode = tmp_mode->next;
+
+ if (tmp_mode == pScrn->monitor->Modes)
+ break;
+ }
+ if ((radeon_output->DotClock == 0) && !output->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;
+}
+
+static void
+RADEONGetTMDSInfoFromTable(xf86OutputPtr output)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+ int i;
+
+ for (i=0; i<4; i++) {
+ radeon_output->tmds_pll[i].value = default_tmds_pll[info->ChipFamily][i].value;
+ radeon_output->tmds_pll[i].freq = default_tmds_pll[info->ChipFamily][i].freq;
+ }
+}
+
+static void
+RADEONGetTMDSInfo(xf86OutputPtr output)
+{
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+ int i;
+
+ for (i=0; i<4; i++) {
+ radeon_output->tmds_pll[i].value = 0;
+ radeon_output->tmds_pll[i].freq = 0;
+ }
+
+ if (RADEONGetTMDSInfoFromBIOS(output)) return;
+
+ RADEONGetTMDSInfoFromTable(output);
+
+}
+
+static void
+RADEONGetTVInfo(xf86OutputPtr output)
+{
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+
+ radeon_output->hPos = 0;
+ radeon_output->vPos = 0;
+ radeon_output->hSize = 0;
+
+ if (RADEONGetTVInfoFromBIOS(output)) return;
+
+ /* set some reasonable defaults */
+ radeon_output->default_tvStd = TV_STD_NTSC;
+ radeon_output->tvStd = TV_STD_NTSC;
+ radeon_output->TVRefClk = 27.000000000;
+ radeon_output->SupportedTVStds = TV_STD_NTSC | TV_STD_PAL;
+
+}
+
+void RADEONInitConnector(xf86OutputPtr output)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+ int DDCReg = 0;
+ char* name = (char*) DDCTypeName[radeon_output->DDCType];
+
+ switch(radeon_output->DDCType) {
+ case DDC_MONID: DDCReg = RADEON_GPIO_MONID; break;
+ case DDC_DVI : DDCReg = RADEON_GPIO_DVI_DDC; break;
+ case DDC_VGA : DDCReg = RADEON_GPIO_VGA_DDC; break;
+ case DDC_CRT2 : DDCReg = RADEON_GPIO_CRT2_DDC; break;
+ case DDC_LCD : DDCReg = RADEON_LCD_GPIO_MASK; break;
+ default: break;
+ }
+
+ if (radeon_output->DACType == DAC_PRIMARY)
+ radeon_output->load_detection = 1; /* primary dac, only drives vga */
+ else if (radeon_output->DACType == DAC_TVDAC &&
+ info->tvdac_use_count < 2)
+ radeon_output->load_detection = 1; /* only one output with tvdac */
+ else
+ radeon_output->load_detection = 0; /* shared tvdac between vga/dvi/tv */
+
+ if (DDCReg) {
+ radeon_output->DDCReg = DDCReg;
+ RADEONI2CInit(pScrn, &radeon_output->pI2CBus, DDCReg, name);
+ }
+
+ if (radeon_output->type == OUTPUT_LVDS) {
+ RADEONGetLVDSInfo(output);
+ }
+
+ if (radeon_output->type == OUTPUT_DVI) {
+ RADEONGetTMDSInfo(output);
+ }
+
+ if (radeon_output->type == OUTPUT_STV ||
+ radeon_output->type == OUTPUT_CTV) {
+ RADEONGetTVInfo(output);
+ }
+
+ if (radeon_output->DACType == DAC_TVDAC) {
+ radeon_output->tv_on = FALSE;
+ RADEONGetTVDacAdjInfo(output);
+ }
+
+}
+
+static void RADEONSetupGenericConnectors(ScrnInfoPtr pScrn)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+
+ if (info->IsMobility) {
+ /* Below is the most common setting, but may not be true */
+ if (info->IsIGP) {
+ info->BiosConnector[0].DDCType = DDC_LCD;
+ info->BiosConnector[0].DACType = DAC_UNKNOWN;
+ info->BiosConnector[0].TMDSType = TMDS_UNKNOWN;
+ info->BiosConnector[0].ConnectorType = CONNECTOR_PROPRIETARY;
+ info->BiosConnector[0].valid = TRUE;
+
+ /* IGP only has TVDAC */
+ if (info->ChipFamily == CHIP_FAMILY_RS400)
+ info->BiosConnector[1].DDCType = DDC_CRT2;
+ else
+ info->BiosConnector[1].DDCType = DDC_VGA;
+ info->BiosConnector[1].DACType = DAC_TVDAC;
+ info->BiosConnector[1].TMDSType = TMDS_UNKNOWN;
+ info->BiosConnector[1].ConnectorType = CONNECTOR_CRT;
+ info->BiosConnector[1].valid = TRUE;
+ } else {
+#if defined(__powerpc__)
+ info->BiosConnector[0].DDCType = DDC_DVI;
+#else
+ info->BiosConnector[0].DDCType = DDC_LCD;
+#endif
+ info->BiosConnector[0].DACType = DAC_UNKNOWN;
+ info->BiosConnector[0].TMDSType = TMDS_UNKNOWN;
+ info->BiosConnector[0].ConnectorType = CONNECTOR_PROPRIETARY;
+ info->BiosConnector[0].valid = TRUE;
+
+ info->BiosConnector[1].DDCType = DDC_VGA;
+ info->BiosConnector[1].DACType = DAC_PRIMARY;
+ info->BiosConnector[1].TMDSType = TMDS_EXT;
+ info->BiosConnector[1].ConnectorType = CONNECTOR_CRT;
+ info->BiosConnector[1].valid = TRUE;
+ }
+ } else {
+ /* Below is the most common setting, but may not be true */
+ if (info->IsIGP) {
+ if (info->ChipFamily == CHIP_FAMILY_RS400)
+ info->BiosConnector[0].DDCType = DDC_CRT2;
+ else
+ info->BiosConnector[0].DDCType = DDC_VGA;
+ info->BiosConnector[0].DACType = DAC_TVDAC;
+ info->BiosConnector[0].TMDSType = TMDS_UNKNOWN;
+ info->BiosConnector[0].ConnectorType = CONNECTOR_CRT;
+ info->BiosConnector[0].valid = TRUE;
+
+ /* not sure what a good default DDCType for DVI on
+ * IGP desktop chips is
+ */
+ info->BiosConnector[1].DDCType = DDC_MONID; /* DDC_DVI? */
+ info->BiosConnector[1].DACType = DAC_UNKNOWN;
+ info->BiosConnector[1].TMDSType = TMDS_EXT;
+ info->BiosConnector[1].ConnectorType = CONNECTOR_DVI_D;
+ info->BiosConnector[1].valid = TRUE;
+ } else {
+ info->BiosConnector[0].DDCType = DDC_DVI;
+ info->BiosConnector[0].DACType = DAC_TVDAC;
+ info->BiosConnector[0].TMDSType = TMDS_INT;
+ info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_I;
+ info->BiosConnector[0].valid = TRUE;
+
+ info->BiosConnector[1].DDCType = DDC_VGA;
+ info->BiosConnector[1].DACType = DAC_PRIMARY;
+ info->BiosConnector[1].TMDSType = TMDS_EXT;
+ info->BiosConnector[1].ConnectorType = CONNECTOR_CRT;
+ info->BiosConnector[1].valid = TRUE;
+ }
+ }
+
+ if (info->InternalTVOut) {
+ info->BiosConnector[2].ConnectorType = CONNECTOR_STV;
+ info->BiosConnector[2].DACType = DAC_TVDAC;
+ info->BiosConnector[2].TMDSType = TMDS_NONE;
+ info->BiosConnector[2].DDCType = DDC_NONE_DETECTED;
+ info->BiosConnector[2].valid = TRUE;
+ }
+
+ /* Some cards have the DDC lines swapped and we have no way to
+ * detect it yet (Mac cards)
+ */
+ if (xf86ReturnOptValBool(info->Options, OPTION_REVERSE_DDC, FALSE)) {
+ info->BiosConnector[0].DDCType = DDC_VGA;
+ info->BiosConnector[1].DDCType = DDC_DVI;
+ }
+
+}
+
+/*
+ * initialise the static data sos we don't have to re-do at randr change */
+Bool RADEONSetupConnectors(ScrnInfoPtr pScrn)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
+ xf86OutputPtr output;
+ char *optstr;
+ int i = 0;
+ int num_vga = 0;
+ int num_dvi = 0;
+
+ /* 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.
+ */
+ for (i = 0; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
+ info->BiosConnector[i].valid = FALSE;
+ info->BiosConnector[i].DDCType = DDC_NONE_DETECTED;
+ info->BiosConnector[i].DACType = DAC_UNKNOWN;
+ info->BiosConnector[i].TMDSType = TMDS_UNKNOWN;
+ info->BiosConnector[i].ConnectorType = CONNECTOR_NONE;
+ }
+
+ if (xf86ReturnOptValBool(info->Options, OPTION_DEFAULT_CONNECTOR_TABLE, FALSE)) {
+ RADEONSetupGenericConnectors(pScrn);
+ } else {
+ if (!RADEONGetConnectorInfoFromBIOS(pScrn))
+ RADEONSetupGenericConnectors(pScrn);
+ }
+
+ if (info->HasSingleDAC) {
+ /* For RS300/RS350/RS400 chips, there is no primary DAC. Force VGA port to use TVDAC*/
+ for (i = 0; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
+ if (info->BiosConnector[i].ConnectorType == CONNECTOR_CRT)
+ info->BiosConnector[i].DACType = DAC_TVDAC;
+ }
+ } else if (!pRADEONEnt->HasCRTC2) {
+ for (i = 0; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
+ if (info->BiosConnector[i].ConnectorType == CONNECTOR_CRT)
+ info->BiosConnector[i].DACType = DAC_PRIMARY;
+ }
+ }
+
+ /* parse connector table option */
+ optstr = (char *)xf86GetOptValString(info->Options, OPTION_CONNECTORTABLE);
+
+ if (optstr) {
+ for (i = 2; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
+ info->BiosConnector[i].valid = FALSE;
+ }
+ info->BiosConnector[0].valid = TRUE;
+ info->BiosConnector[1].valid = TRUE;
+ if (sscanf(optstr, "%u,%d,%d,%u,%u,%d,%d,%u",
+ &info->BiosConnector[0].DDCType,
+ &info->BiosConnector[0].DACType,
+ &info->BiosConnector[0].TMDSType,
+ &info->BiosConnector[0].ConnectorType,
+ &info->BiosConnector[1].DDCType,
+ &info->BiosConnector[1].DACType,
+ &info->BiosConnector[1].TMDSType,
+ &info->BiosConnector[1].ConnectorType) != 8) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Invalid ConnectorTable option: %s\n", optstr);
+ return FALSE;
+ }
+ }
+
+ info->tvdac_use_count = 0;
+ for (i = 0; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
+ if (info->BiosConnector[i].valid) {
+ if (info->BiosConnector[i].DACType == DAC_TVDAC)
+ info->tvdac_use_count++;
+
+ if (info->IsAtomBios) {
+ if ((info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_D_ATOM) ||
+ (info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_I_ATOM) ||
+ (info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_A_ATOM)) {
+ num_dvi++;
+ } else if (info->BiosConnector[i].ConnectorType == CONNECTOR_VGA_ATOM) {
+ num_vga++;
+ }
+ } else {
+ if ((info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_D) ||
+ (info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_I)) {
+ num_dvi++;
+ } else if (info->BiosConnector[i].ConnectorType == CONNECTOR_CRT) {
+ num_vga++;
+ }
+ }
+ }
+ }
+
+ for (i = 0 ; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
+ if (info->BiosConnector[i].valid) {
+ RADEONOutputPrivatePtr radeon_output = xnfcalloc(sizeof(RADEONOutputPrivateRec), 1);
+ if (!radeon_output) {
+ return FALSE;
+ }
+ radeon_output->MonType = MT_UNKNOWN;
+ radeon_output->ConnectorType = info->BiosConnector[i].ConnectorType;
+ radeon_output->DDCType = info->BiosConnector[i].DDCType;
+ if (info->IsAtomBios) {
+ if (radeon_output->ConnectorType == CONNECTOR_DVI_D_ATOM)
+ radeon_output->DACType = DAC_NONE;
+ else
+ radeon_output->DACType = info->BiosConnector[i].DACType;
+
+ if (radeon_output->ConnectorType == CONNECTOR_VGA_ATOM)
+ radeon_output->TMDSType = TMDS_NONE;
+ else
+ radeon_output->TMDSType = info->BiosConnector[i].TMDSType;
+ } else {
+ if (radeon_output->ConnectorType == CONNECTOR_DVI_D)
+ radeon_output->DACType = DAC_NONE;
+ else
+ radeon_output->DACType = info->BiosConnector[i].DACType;
+
+ if (radeon_output->ConnectorType == CONNECTOR_CRT)
+ radeon_output->TMDSType = TMDS_NONE;
+ else
+ radeon_output->TMDSType = info->BiosConnector[i].TMDSType;
+ }
+ RADEONSetOutputType(pScrn, radeon_output);
+ if (info->IsAtomBios) {
+ if ((info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_D_ATOM) ||
+ (info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_I_ATOM) ||
+ (info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_A_ATOM)) {
+ if (num_dvi > 1) {
+ output = xf86OutputCreate(pScrn, &radeon_output_funcs, "DVI-1");
+ num_dvi--;
+ } else {
+ output = xf86OutputCreate(pScrn, &radeon_output_funcs, "DVI-0");
+ }
+ } else if (info->BiosConnector[i].ConnectorType == CONNECTOR_VGA_ATOM) {
+ if (num_vga > 1) {
+ output = xf86OutputCreate(pScrn, &radeon_output_funcs, "VGA-1");
+ num_vga--;
+ } else {
+ output = xf86OutputCreate(pScrn, &radeon_output_funcs, "VGA-0");
+ }
+ } else
+ output = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[radeon_output->type]);
+ } else {
+ if ((info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_D) ||
+ (info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_I)) {
+ if (num_dvi > 1) {
+ output = xf86OutputCreate(pScrn, &radeon_output_funcs, "DVI-1");
+ num_dvi--;
+ } else {
+ output = xf86OutputCreate(pScrn, &radeon_output_funcs, "DVI-0");
+ }
+ } else if (info->BiosConnector[i].ConnectorType == CONNECTOR_CRT) {
+ if (num_vga > 1) {
+ output = xf86OutputCreate(pScrn, &radeon_output_funcs, "VGA-1");
+ num_vga--;
+ } else {
+ output = xf86OutputCreate(pScrn, &radeon_output_funcs, "VGA-0");
+ }
+ } else
+ output = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[radeon_output->type]);
+ }
+
+ if (!output) {
+ return FALSE;
+ }
+ output->driver_private = radeon_output;
+ output->possible_crtcs = 1;
+ /* crtc2 can drive LVDS, it just doesn't have RMX */
+ if (radeon_output->type != OUTPUT_LVDS)
+ output->possible_crtcs |= 2;
+
+ /* we can clone the DACs, and probably TV-out,
+ but I'm not sure it's worth the trouble */
+ output->possible_clones = 0;
+
+ RADEONInitConnector(output);
+ }
+ }
+
+ return TRUE;
+}
+
diff --git a/src/radeon_probe.c b/src/radeon_probe.c
index 98b35aa6..c697f65c 100644
--- a/src/radeon_probe.c
+++ b/src/radeon_probe.c
@@ -40,7 +40,6 @@
* Modified by Marc Aurele La France <tsi@xfree86.org> for ATI driver merge.
*/
-#include "atimodule.h"
#include "ativersion.h"
#include "radeon_probe.h"
@@ -200,7 +199,7 @@ PciChipsets RADEONPciChipsets[] = {
int gRADEONEntityIndex = -1;
/* Return the options for supported chipset 'n'; NULL otherwise */
-const OptionInfoRec *
+_X_EXPORT const OptionInfoRec *
RADEONAvailableOptions(int chipid, int busid)
{
int i;
@@ -219,7 +218,7 @@ RADEONAvailableOptions(int chipid, int busid)
}
/* Return the string name for supported chipset 'n'; NULL otherwise. */
-void
+_X_EXPORT void
RADEONIdentify(int flags)
{
xf86PrintChipsets(RADEON_NAME,
@@ -228,7 +227,7 @@ RADEONIdentify(int flags)
}
/* Return TRUE if chipset is present; FALSE otherwise. */
-Bool
+_X_EXPORT Bool
RADEONProbe(DriverPtr drv, int flags)
{
int numUsed;
@@ -285,22 +284,26 @@ RADEONProbe(DriverPtr drv, int flags)
if ((pScrn = xf86ConfigPciEntity(pScrn, 0, usedChips[i],
RADEONPciChipsets, 0, 0, 0,
0, 0))) {
-#ifdef XFree86LOADER
- if (!xf86LoadSubModule(pScrn, "radeon")) {
- xf86Msg(X_ERROR, RADEON_NAME
- ": Failed to load \"radeon\" module.\n");
- xf86DeleteScreen(pScrn->scrnIndex, 0);
- continue;
- }
-
- xf86LoaderReqSymLists(RADEONSymbols, NULL);
+ pScrn->driverVersion = RADEON_VERSION_CURRENT;
+ pScrn->driverName = RADEON_DRIVER_NAME;
+ pScrn->name = RADEON_NAME;
+ pScrn->Probe = RADEONProbe;
+ pScrn->PreInit = RADEONPreInit;
+ pScrn->ScreenInit = RADEONScreenInit;
+ pScrn->SwitchMode = RADEONSwitchMode;
+#ifdef X_XF86MiscPassMessage
+ pScrn->HandleMessage = RADEONHandleMessage;
#endif
+ pScrn->AdjustFrame = RADEONAdjustFrame;
+ pScrn->EnterVT = RADEONEnterVT;
+ pScrn->LeaveVT = RADEONLeaveVT;
+ pScrn->FreeScreen = RADEONFreeScreen;
+ pScrn->ValidMode = RADEONValidMode;
- pScrn->Probe = RADEONProbe;
- RADEONFillInScreenInfo(pScrn);
foundScreen = TRUE;
}
+ xfree(pEnt);
pEnt = xf86GetEntityInfo(usedChips[i]);
/* create a RADEONEntity for all chips, even with
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index b651e7d0..b6ef59dd 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -38,17 +38,28 @@
#include "xf86str.h"
#include "xf86DDC.h"
+#include "randrstr.h"
#define _XF86MISC_SERVER_
#include <X11/extensions/xf86misc.h>
+#include "xf86Crtc.h"
+
+#ifdef USE_EXA
+#include "exa.h"
+#endif
+#ifdef USE_XAA
+#include "xaa.h"
+#endif
+
typedef enum
{
DDC_NONE_DETECTED,
DDC_MONID,
DDC_DVI,
DDC_VGA,
- DDC_CRT2
+ DDC_CRT2,
+ DDC_LCD,
} RADEONDDCType;
typedef enum
@@ -92,41 +103,120 @@ typedef enum
{
DAC_UNKNOWN = -1,
DAC_PRIMARY = 0,
- DAC_TVDAC = 1
+ DAC_TVDAC = 1,
+ DAC_NONE = 2
} RADEONDacType;
typedef enum
{
TMDS_UNKNOWN = -1,
TMDS_INT = 0,
- TMDS_EXT = 1
+ TMDS_EXT = 1,
+ TMDS_NONE = 2
} RADEONTmdsType;
-typedef struct
+typedef enum
{
- Bool IsUsed;
- Bool IsActive;
- int binding; // which instance of the driver "owns" this controller
- DisplayModePtr pCurMode;
-} RADEONController;
+ DVI_AUTO,
+ DVI_DIGITAL,
+ DVI_ANALOG
+} RADEONDviType;
-typedef struct
+typedef enum
+{
+ TMDS_PLL_BIOS,
+ TMDS_PLL_DRIVER
+} RADEONTMDSPllType;
+
+typedef struct {
+ CARD32 freq;
+ CARD32 value;
+}RADEONTMDSPll;
+
+typedef enum
+{
+ OUTPUT_NONE,
+ OUTPUT_VGA,
+ OUTPUT_DVI,
+ OUTPUT_LVDS,
+ OUTPUT_STV,
+ OUTPUT_CTV,
+} RADEONOutputType;
+
+/* standards */
+typedef enum
{
+ TV_STD_NTSC = 1,
+ TV_STD_PAL = 2,
+ TV_STD_PAL_M = 4,
+ TV_STD_PAL_60 = 8,
+ TV_STD_NTSC_J = 16,
+ TV_STD_SCART_PAL = 32,
+} TVStd;
+
+typedef struct _RADEONCrtcPrivateRec {
+#ifdef USE_XAA
+ FBLinearPtr rotate_mem_xaa;
+#endif
+#ifdef USE_EXA
+ ExaOffscreenArea *rotate_mem_exa;
+#endif
+ int crtc_id;
+ int binding;
+ /* Lookup table values to be set when the CRTC is enabled */
+ CARD8 lut_r[256], lut_g[256], lut_b[256];
+} RADEONCrtcPrivateRec, *RADEONCrtcPrivatePtr;
+
+typedef struct {
RADEONDDCType DDCType;
RADEONDacType DACType;
RADEONTmdsType TMDSType;
RADEONConnectorType ConnectorType;
- RADEONMonitorType MonType;
- xf86MonPtr MonInfo;
+ Bool valid;
+} RADEONBIOSConnector;
- /* one connector can be bound to one CRTC */
+typedef struct _RADEONOutputPrivateRec {
+ int num;
+ RADEONOutputType type;
+ void *dev_priv;
+ RADEONDDCType DDCType;
+ RADEONDacType DACType;
+ RADEONDviType DVIType;
+ RADEONTmdsType TMDSType;
+ RADEONConnectorType ConnectorType;
+ RADEONMonitorType MonType;
int crtc_num;
-} RADEONConnector;
-
-
+ int DDCReg;
+ I2CBusPtr pI2CBus;
+ CARD32 tv_dac_adj;
+ /* panel stuff */
+ int PanelXRes;
+ int PanelYRes;
+ int HOverPlus;
+ int HSyncWidth;
+ int HBlank;
+ int VOverPlus;
+ int VSyncWidth;
+ int VBlank;
+ int Flags; /* Saved copy of mode flags */
+ int PanelPwrDly;
+ int DotClock;
+ RADEONTMDSPll tmds_pll[4];
+ RADEONTMDSPllType tmds_pll_table;
+ /* TV out */
+ TVStd default_tvStd;
+ TVStd tvStd;
+ int hPos;
+ int vPos;
+ int hSize;
+ float TVRefClk;
+ int SupportedTVStds;
+ Bool tv_on;
+ int load_detection;
+} RADEONOutputPrivateRec, *RADEONOutputPrivatePtr;
-#define RADEON_MAX_CONNECTOR 2
#define RADEON_MAX_CRTC 2
+#define RADEON_MAX_BIOS_CONNECTOR 8
typedef struct
{
@@ -139,13 +229,11 @@ typedef struct
Bool IsSecondaryRestored;
Bool RestorePrimary;
- ScrnInfoPtr pSecondaryScrn;
- ScrnInfoPtr pPrimaryScrn;
-
Bool ReversedDAC; /* TVDAC used as primary dac */
Bool ReversedTMDS; /* DDC_DVI is used for external TMDS */
- RADEONConnector *PortInfo[RADEON_MAX_CONNECTOR];
- RADEONController *Controller[RADEON_MAX_CRTC]; /* pointer to a controller */
+ xf86CrtcPtr pCrtc[RADEON_MAX_CRTC];
+ RADEONCrtcPrivatePtr Controller[RADEON_MAX_CRTC];
+
} RADEONEntRec, *RADEONEntPtr;
/* radeon_probe.c */
@@ -172,6 +260,4 @@ extern ModeStatus RADEONValidMode(int, DisplayModePtr, Bool, int);
extern const OptionInfoRec *RADEONOptionsWeak(void);
-extern void RADEONFillInScreenInfo(ScrnInfoPtr);
-
#endif /* _RADEON_PROBE_H_ */
diff --git a/src/radeon_reg.h b/src/radeon_reg.h
index b50fcf0a..af62a692 100644
--- a/src/radeon_reg.h
+++ b/src/radeon_reg.h
@@ -231,7 +231,13 @@
# define RADEON_ACTIVE_HILO_LAT_MASK (3 << 13)
# define RADEON_ACTIVE_HILO_LAT_SHIFT 13
# define RADEON_DISP_DYN_STOP_LAT_MASK (1 << 12)
+# define RADEON_MC_BUSY (1 << 16)
+# define RADEON_DLL_READY (1 << 19)
+# define RADEON_CG_NO1_DEBUG_0 (1 << 24)
+# define RADEON_CG_NO1_DEBUG_MASK (0x1f << 24)
# define RADEON_DYN_STOP_MODE_MASK (7 << 21)
+# define RADEON_TVPLL_PWRMGT_OFF (1 << 30)
+# define RADEON_TVCLK_TURNOFF (1 << 31)
#define RADEON_PLL_PWRMGT_CNTL 0x0015
# define RADEON_TCL_BYPASS_DISABLE (1 << 20)
#define RADEON_CLR_CMP_CLR_3D 0x1a24
@@ -308,7 +314,7 @@
# define RADEON_CRTC_CSYNC_EN (1 << 4)
# define RADEON_CRTC_ICON_EN (1 << 15)
# define RADEON_CRTC_CUR_EN (1 << 16)
-# define RADEON_CRTC_CUR_MODE_MASK (7 << 17)
+# define RADEON_CRTC_CUR_MODE_MASK (7 << 20)
# define RADEON_CRTC_EXT_DISP_EN (1 << 24)
# define RADEON_CRTC_EN (1 << 25)
# define RADEON_CRTC_DISP_REQ_EN_B (1 << 26)
@@ -319,6 +325,8 @@
# define RADEON_CRTC2_HSYNC_TRISTAT (1 << 5)
# define RADEON_CRTC2_VSYNC_TRISTAT (1 << 6)
# define RADEON_CRTC2_CRT2_ON (1 << 7)
+# define RADEON_CRTC2_PIX_WIDTH_SHIFT 8
+# define RADEON_CRTC2_PIX_WIDTH_MASK (0xf << 8)
# define RADEON_CRTC2_ICON_EN (1 << 15)
# define RADEON_CRTC2_CUR_EN (1 << 16)
# define RADEON_CRTC2_CUR_MODE_MASK (7 << 20)
@@ -329,8 +337,8 @@
# define RADEON_CRTC2_HSYNC_DIS (1 << 28)
# define RADEON_CRTC2_VSYNC_DIS (1 << 29)
#define RADEON_CRTC_MORE_CNTL 0x27c
-# define RADEON_CRTC_H_CUTOFF_ACTIVE_EN (1<<4)
-# define RADEON_CRTC_V_CUTOFF_ACTIVE_EN (1<<5)
+# define RADEON_CRTC_H_CUTOFF_ACTIVE_EN (1<<4)
+# define RADEON_CRTC_V_CUTOFF_ACTIVE_EN (1<<5)
#define RADEON_CRTC_GUI_TRIG_VLINE 0x0218
#define RADEON_CRTC_H_SYNC_STRT_WID 0x0204
# define RADEON_CRTC_H_SYNC_STRT_PIX (0x07 << 0)
@@ -451,6 +459,7 @@
#define RADEON_DAC_CNTL 0x0058
# define RADEON_DAC_RANGE_CNTL (3 << 0)
+# define RADEON_DAC_RANGE_CNTL_PS2 (2 << 0)
# define RADEON_DAC_RANGE_CNTL_MASK 0x03
# define RADEON_DAC_BLANKING (1 << 2)
# define RADEON_DAC_CMP_EN (1 << 3)
@@ -461,13 +470,25 @@
# define RADEON_DAC_PDWN (1 << 15)
# define RADEON_DAC_MASK_ALL (0xff << 24)
#define RADEON_DAC_CNTL2 0x007c
+# define RADEON_DAC2_TV_CLK_SEL (0 << 1)
# define RADEON_DAC2_DAC_CLK_SEL (1 << 0)
# define RADEON_DAC2_DAC2_CLK_SEL (1 << 1)
# define RADEON_DAC2_PALETTE_ACC_CTL (1 << 5)
+# define RADEON_DAC2_CMP_EN (1 << 7)
+# define RADEON_DAC2_CMP_OUT_R (1 << 8)
+# define RADEON_DAC2_CMP_OUT_G (1 << 9)
+# define RADEON_DAC2_CMP_OUT_B (1 << 10)
+# define RADEON_DAC2_CMP_OUTPUT (1 << 11)
#define RADEON_DAC_EXT_CNTL 0x0280
-# define RADEON_DAC_FORCE_BLANK_OFF_EN (1 << 4)
-# define RADEON_DAC_FORCE_DATA_EN (1 << 5)
+# define RADEON_DAC2_FORCE_BLANK_OFF_EN (1 << 0)
+# define RADEON_DAC2_FORCE_DATA_EN (1 << 1)
+# define RADEON_DAC_FORCE_BLANK_OFF_EN (1 << 4)
+# define RADEON_DAC_FORCE_DATA_EN (1 << 5)
# define RADEON_DAC_FORCE_DATA_SEL_MASK (3 << 6)
+# define RADEON_DAC_FORCE_DATA_SEL_R (0 << 6)
+# define RADEON_DAC_FORCE_DATA_SEL_G (1 << 6)
+# define RADEON_DAC_FORCE_DATA_SEL_B (2 << 6)
+# define RADEON_DAC_FORCE_DATA_SEL_RGB (3 << 6)
# define RADEON_DAC_FORCE_DATA_MASK 0x0003ff00
# define RADEON_DAC_FORCE_DATA_SHIFT 8
#define RADEON_DAC_MACRO_CNTL 0x0d04
@@ -480,15 +501,22 @@
# define RADEON_TV_DAC_PEDESTAL (1 << 2)
# define RADEON_TV_MONITOR_DETECT_EN (1 << 4)
# define RADEON_TV_DAC_CMPOUT (1 << 5)
+# define RADEON_TV_DAC_STD_MASK (3 << 8)
+# define RADEON_TV_DAC_STD_PAL (0 << 8)
# define RADEON_TV_DAC_STD_NTSC (1 << 8)
-# define RADEON_TV_DAC_STD_MASK 0x0300
-# define RADEON_TV_DAC_STD_PS2 0x0200
+# define RADEON_TV_DAC_STD_PS2 (2 << 8)
+# define RADEON_TV_DAC_STD_RS343 (3 << 8)
# define RADEON_TV_DAC_BGSLEEP (1 << 6)
# define RADEON_TV_DAC_BGADJ_MASK (0xf << 16)
+# define RADEON_TV_DAC_BGADJ_SHIFT 16
# define RADEON_TV_DAC_DACADJ_MASK (0xf << 20)
+# define RADEON_TV_DAC_DACADJ_SHIFT 20
# define RADEON_TV_DAC_RDACPD (1 << 24)
# define RADEON_TV_DAC_GDACPD (1 << 25)
# define RADEON_TV_DAC_BDACPD (1 << 26)
+# define RADEON_TV_DAC_RDACDET (1 << 29)
+# define RADEON_TV_DAC_GDACDET (1 << 30)
+# define RADEON_TV_DAC_BDACDET (1 << 31)
# define R420_TV_DAC_DACADJ_MASK (0x1f << 20)
# define R420_TV_DAC_RDACPD (1 << 25)
# define R420_TV_DAC_GDACPD (1 << 26)
@@ -500,10 +528,18 @@
# define RADEON_DISP_DAC_SOURCE_MASK 0x03
# define RADEON_DISP_DAC2_SOURCE_MASK 0x0c
# define RADEON_DISP_DAC_SOURCE_CRTC2 0x01
+# define RADEON_DISP_DAC_SOURCE_RMX 0x02
+# define RADEON_DISP_DAC_SOURCE_LTU 0x03
# define RADEON_DISP_DAC2_SOURCE_CRTC2 0x04
-# define RADEON_DISP_TVDAC_SOURCE_MASK (0x03<<2)
+# define RADEON_DISP_TVDAC_SOURCE_MASK (0x03 << 2)
# define RADEON_DISP_TVDAC_SOURCE_CRTC 0x0
-# define RADEON_DISP_TVDAC_SOURCE_CRTC2 (0x01<<2)
+# define RADEON_DISP_TVDAC_SOURCE_CRTC2 (0x01 << 2)
+# define RADEON_DISP_TVDAC_SOURCE_RMX (0x02 << 2)
+# define RADEON_DISP_TVDAC_SOURCE_LTU (0x03 << 2)
+# define RADEON_DISP_TRANS_MATRIX_MASK (0x03 << 4)
+# define RADEON_DISP_TRANS_MATRIX_ALPHA_MSB (0x00 << 4)
+# define RADEON_DISP_TRANS_MATRIX_GRAPHICS (0x01 << 4)
+# define RADEON_DISP_TRANS_MATRIX_VIDEO (0x02 << 4)
# define RADEON_DISP_TV_SOURCE_CRTC (1 << 16) /* crtc1 or crtc2 */
# define RADEON_DISP_TV_SOURCE_LTU (0 << 16) /* linear transform unit */
#define RADEON_DISP_TV_OUT_CNTL 0x0d6c
@@ -531,12 +567,12 @@
# define RADEON_DISP_ALPHA_MODE_KEY 0
# define RADEON_DISP_ALPHA_MODE_PER_PIXEL 1
# define RADEON_DISP_ALPHA_MODE_GLOBAL 2
-# define RADEON_DISP_RGB_OFFSET_EN (1<<8)
+# define RADEON_DISP_RGB_OFFSET_EN (1 << 8)
# define RADEON_DISP_GRPH_ALPHA_MASK (0xff << 16)
# define RADEON_DISP_OV0_ALPHA_MASK (0xff << 24)
# define RADEON_DISP_LIN_TRANS_BYPASS (0x01 << 9)
#define RADEON_DISP2_MERGE_CNTL 0x0d68
-# define RADEON_DISP2_RGB_OFFSET_EN (1<<8)
+# define RADEON_DISP2_RGB_OFFSET_EN (1 << 8)
#define RADEON_DISP_LIN_TRANS_GRPH_A 0x0d80
#define RADEON_DISP_LIN_TRANS_GRPH_B 0x0d84
#define RADEON_DISP_LIN_TRANS_GRPH_C 0x0d88
@@ -742,10 +778,12 @@
# define RADEON_FP2_BLANK_EN (1 << 1)
# define RADEON_FP2_ON (1 << 2)
# define RADEON_FP2_PANEL_FORMAT (1 << 3)
+# define RADEON_FP2_DETECT_SENSE (1 << 8)
# 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 R200_FP2_SOURCE_SEL_TRANS_UNIT (3 << 10)
# define RADEON_FP2_SRC_SEL_MASK (3 << 13)
# define RADEON_FP2_SRC_SEL_CRTC2 (1 << 13)
# define RADEON_FP2_FP_POL (1 << 16)
@@ -757,6 +795,7 @@
# define RADEON_FP2_CRC_READ_EN (1 << 24)
# define RADEON_FP2_DVO_EN (1 << 25)
# define RADEON_FP2_DVO_RATE_SEL_SDR (1 << 26)
+# define R200_FP2_DVO_RATE_SEL_SDR (1 << 27)
#define RADEON_FP_H_SYNC_STRT_WID 0x02c4
#define RADEON_FP_H2_SYNC_STRT_WID 0x03c4
#define RADEON_FP_HORZ_STRETCH 0x028c
@@ -837,6 +876,7 @@
# define RADEON_HDP_SOFT_RESET (1 << 26)
# define RADEON_HDP_APER_CNTL (1 << 23)
#define RADEON_HTOTAL_CNTL 0x0009 /* PLL */
+# define RADEON_HTOT_CNTL_VGA_EN (1 << 28)
#define RADEON_HTOTAL2_CNTL 0x002e /* PLL */
/* Multimedia I2C bus */
@@ -875,6 +915,9 @@
# define RADEON_LVDS_PANEL_TYPE (1 << 2)
# define RADEON_LVDS_PANEL_FORMAT (1 << 3)
# define RADEON_LVDS_EN (1 << 7)
+# define RADEON_LVDS_BL_MOD_LEVEL_SHIFT 8
+# define RADEON_LVDS_BL_MOD_LEVEL_MASK (0xff << 8)
+# define RADEON_LVDS_BL_MOD_EN (1 << 16)
# define RADEON_LVDS_DIGON (1 << 18)
# define RADEON_LVDS_BLON (1 << 19)
# define RADEON_LVDS_SEL_CRTC2 (1 << 23)
@@ -885,9 +928,6 @@
#define RADEON_MAX_LATENCY 0x0f3f /* PCI */
#define RADEON_MC_AGP_LOCATION 0x014c
#define RADEON_MC_FB_LOCATION 0x0148
-#define RADEON_MC_STATUS 0x0150
-# define RADEON_MC_IDLE (1 << 2)
-# define R300_MC_IDLE (1 << 4)
#define RADEON_DISPLAY_BASE_ADDR 0x23c
#define RADEON_DISPLAY2_BASE_ADDR 0x33c
#define RADEON_OV0_BASE_ADDR 0x43c
@@ -903,27 +943,41 @@
# define R300_DISABLE_MC_MCLKA (1 << 21)
# define R300_DISABLE_MC_MCLKB (1 << 21)
#define RADEON_MCLK_MISC 0x001f /* PLL */
-# define RADEON_MC_MCLK_MAX_DYN_STOP_LAT (1<<12)
-# define RADEON_IO_MCLK_MAX_DYN_STOP_LAT (1<<13)
+# define RADEON_MC_MCLK_MAX_DYN_STOP_LAT (1 << 12)
+# define RADEON_IO_MCLK_MAX_DYN_STOP_LAT (1 << 13)
# define RADEON_MC_MCLK_DYN_ENABLE (1 << 14)
# define RADEON_IO_MCLK_DYN_ENABLE (1 << 15)
+#define RADEON_LCD_GPIO_MASK 0x01a0
+#define RADEON_LCD_GPIO_Y_REG 0x01a4
#define RADEON_MDGPIO_A_REG 0x01ac
#define RADEON_MDGPIO_EN_REG 0x01b0
#define RADEON_MDGPIO_MASK 0x0198
+#define RADEON_GPIOPAD_A 0x019c
#define RADEON_MDGPIO_Y_REG 0x01b4
#define RADEON_MEM_ADDR_CONFIG 0x0148
#define RADEON_MEM_BASE 0x0f10 /* PCI */
#define RADEON_MEM_CNTL 0x0140
# define RADEON_MEM_NUM_CHANNELS_MASK 0x01
-# define RADEON_MEM_USE_B_CH_ONLY (1<<1)
-# define RV100_HALF_MODE (1<<3)
+# define RADEON_MEM_USE_B_CH_ONLY (1 << 1)
+# define RV100_HALF_MODE (1 << 3)
# define R300_MEM_NUM_CHANNELS_MASK 0x03
-# define R300_MEM_USE_CD_CH_ONLY (1<<2)
+# define R300_MEM_USE_CD_CH_ONLY (1 << 2)
#define RADEON_MEM_TIMING_CNTL 0x0144 /* EXT_MEM_CNTL */
#define RADEON_MEM_INIT_LAT_TIMER 0x0154
#define RADEON_MEM_INTF_CNTL 0x014c
#define RADEON_MEM_SDRAM_MODE_REG 0x0158
+# define RADEON_SDRAM_MODE_MASK 0xffff0000
+# define RADEON_B3MEM_RESET_MASK 0x6fffffff
#define RADEON_MEM_STR_CNTL 0x0150
+# define RADEON_MEM_PWRUP_COMPL_A (1 << 0)
+# define RADEON_MEM_PWRUP_COMPL_B (1 << 1)
+# define R300_MEM_PWRUP_COMPL_C (1 << 2)
+# define R300_MEM_PWRUP_COMPL_D (1 << 3)
+# define RADEON_MEM_PWRUP_COMPLETE 0x03
+# define R300_MEM_PWRUP_COMPLETE 0x0f
+#define RADEON_MC_STATUS 0x0150
+# define RADEON_MC_IDLE (1 << 2)
+# define R300_MC_IDLE (1 << 4)
#define RADEON_MEM_VGA_RP_SEL 0x003c
#define RADEON_MEM_VGA_WP_SEL 0x0038
#define RADEON_MIN_GRANT 0x0f3e /* PCI */
@@ -1040,6 +1094,7 @@
# define RADEON_REG_LD_CTL_VBLANK_DURING_LOCK 0x00000002L
# define RADEON_REG_LD_CTL_STALL_GUI_UNTIL_FLIP 0x00000004L
# define RADEON_REG_LD_CTL_LOCK_READBACK 0x00000008L
+# define RADEON_REG_LD_CTL_FLIP_READBACK 0x00000010L
#define RADEON_OV0_SCALE_CNTL 0x0420
# define RADEON_SCALER_HORZ_PICK_NEAREST 0x00000004L
# define RADEON_SCALER_VERT_PICK_NEAREST 0x00000008L
@@ -1205,6 +1260,8 @@
#define RADEON_P2PLL_CNTL 0x002a /* P2PLL */
# define RADEON_P2PLL_RESET (1 << 0)
# define RADEON_P2PLL_SLEEP (1 << 1)
+# define RADEON_P2PLL_PVG_MASK (7 << 11)
+# define RADEON_P2PLL_PVG_SHIFT 11
# define RADEON_P2PLL_ATOMIC_UPDATE_EN (1 << 16)
# define RADEON_P2PLL_VGA_ATOMIC_UPDATE_EN (1 << 17)
# define RADEON_P2PLL_ATOMIC_UPDATE_VSYNC (1 << 18)
@@ -1245,6 +1302,7 @@
# define R300_DISP_DAC_PIXCLK_DAC2_BLANK_OFF (1 << 23)
#define RADEON_PLANE_3D_MASK_C 0x1d44
#define RADEON_PLL_TEST_CNTL 0x0013 /* PLL */
+# define RADEON_PLL_MASK_READ_B (1 << 9)
#define RADEON_PMI_CAP_ID 0x0f5c /* PCI */
#define RADEON_PMI_DATA 0x0f63 /* PCI */
#define RADEON_PMI_NXT_CAP_PTR 0x0f5d /* PCI */
@@ -1254,6 +1312,8 @@
#define RADEON_PPLL_CNTL 0x0002 /* PLL */
# define RADEON_PPLL_RESET (1 << 0)
# define RADEON_PPLL_SLEEP (1 << 1)
+# define RADEON_PPLL_PVG_MASK (7 << 11)
+# define RADEON_PPLL_PVG_SHIFT 11
# define RADEON_PPLL_ATOMIC_UPDATE_EN (1 << 16)
# define RADEON_PPLL_VGA_ATOMIC_UPDATE_EN (1 << 17)
# define RADEON_PPLL_ATOMIC_UPDATE_VSYNC (1 << 18)
@@ -3056,9 +3116,15 @@
# define RADEON_TV_ASYNC_RST (1 << 0)
# define RADEON_CRT_ASYNC_RST (1 << 1)
# define RADEON_RESTART_PHASE_FIX (1 << 3)
+# define RADEON_TV_FIFO_ASYNC_RST (1 << 4)
+# define RADEON_VIN_ASYNC_RST (1 << 5)
+# define RADEON_AUD_ASYNC_RST (1 << 6)
+# define RADEON_DVS_ASYNC_RST (1 << 7)
# define RADEON_CRT_FIFO_CE_EN (1 << 9)
# define RADEON_TV_FIFO_CE_EN (1 << 10)
+# define RADEON_RE_SYNC_NOW_SEL_MASK (3 << 14)
# define RADEON_TVCLK_ALWAYS_ONb (1 << 30)
+# define RADEON_TV_ON (1 << 31)
#define RADEON_TV_PRE_DAC_MUX_CNTL 0x0888
# define RADEON_Y_RED_EN (1 << 0)
# define RADEON_C_GRN_EN (1 << 1)
@@ -3076,7 +3142,16 @@
# define RADEON_RGB_SRC_SEL_RMX (1 << 8)
# define RADEON_RGB_SRC_SEL_CRTC2 (2 << 8)
# define RADEON_RGB_CONVERT_BY_PASS (1 << 10)
+# define RADEON_UVRAM_READ_MARGIN_SHIFT 16
+# define RADEON_FIFORAM_FFMACRO_READ_MARGIN_SHIFT 20
+# define RADEON_TVOUT_SCALE_EN (1 << 26)
#define RADEON_TV_SYNC_CNTL 0x0808
+# define RADEON_SYNC_OE (1 << 0)
+# define RADEON_SYNC_OUT (1 << 1)
+# define RADEON_SYNC_IN (1 << 2)
+# define RADEON_SYNC_PUB (1 << 3)
+# define RADEON_SYNC_PD (1 << 4)
+# define RADEON_TV_SYNC_IO_DRIVE (1 << 5)
#define RADEON_TV_HTOTAL 0x080c
#define RADEON_TV_HDISP 0x0810
#define RADEON_TV_HSTART 0x0818
@@ -3092,10 +3167,23 @@
#define RADEON_TV_HOST_READ_DATA 0x0840
#define RADEON_TV_HOST_WRITE_DATA 0x0844
#define RADEON_TV_HOST_RD_WT_CNTL 0x0848
+# define RADEON_HOST_FIFO_RD (1 << 12)
+# define RADEON_HOST_FIFO_RD_ACK (1 << 13)
+# define RADEON_HOST_FIFO_WT (1 << 14)
+# define RADEON_HOST_FIFO_WT_ACK (1 << 15)
#define RADEON_TV_VSCALER_CNTL1 0x084c
+# define RADEON_UV_INC_MASK 0xffff
+# define RADEON_UV_INC_SHIFT 0
+# define RADEON_Y_W_EN (1 << 24)
# define RADEON_RESTART_FIELD (1 << 29) /* restart on field 0 */
# define RADEON_Y_DEL_W_SIG_SHIFT 26
#define RADEON_TV_TIMING_CNTL 0x0850
+# define RADEON_H_INC_MASK 0xfff
+# define RADEON_H_INC_SHIFT 0
+# define RADEON_REQ_Y_FIRST (1 << 19)
+# define RADEON_FORCE_BURST_ALWAYS (1 << 21)
+# define RADEON_UV_POST_SCALE_BYPASS (1 << 23)
+# define RADEON_UV_OUTPUT_POST_SCALE_SHIFT 24
#define RADEON_TV_VSCALER_CNTL2 0x0854
# define RADEON_DITHER_MODE (1 << 0)
# define RADEON_Y_OUTPUT_DITHER_EN (1 << 1)
@@ -3103,25 +3191,75 @@
# define RADEON_UV_TO_BUF_DITHER_EN (1 << 3)
#define RADEON_TV_Y_FALL_CNTL 0x0858
# define RADEON_Y_FALL_PING_PONG (1 << 16)
+# define RADEON_Y_COEF_EN (1 << 17)
#define RADEON_TV_Y_RISE_CNTL 0x085c
# define RADEON_Y_RISE_PING_PONG (1 << 16)
#define RADEON_TV_Y_SAW_TOOTH_CNTL 0x0860
#define RADEON_TV_UPSAMP_AND_GAIN_CNTL 0x0864
+# define RADEON_YUPSAMP_EN (1 << 0)
+# define RADEON_UVUPSAMP_EN (1 << 2)
#define RADEON_TV_GAIN_LIMIT_SETTINGS 0x0868
+# define RADEON_Y_GAIN_LIMIT_SHIFT 0
+# define RADEON_UV_GAIN_LIMIT_SHIFT 16
#define RADEON_TV_LINEAR_GAIN_SETTINGS 0x086c
+# define RADEON_Y_GAIN_SHIFT 0
+# define RADEON_UV_GAIN_SHIFT 16
#define RADEON_TV_MODULATOR_CNTL1 0x0870
+# define RADEON_YFLT_EN (1 << 2)
+# define RADEON_UVFLT_EN (1 << 3)
# define RADEON_ALT_PHASE_EN (1 << 6)
# define RADEON_SYNC_TIP_LEVEL (1 << 7)
+# define RADEON_BLANK_LEVEL_SHIFT 8
+# define RADEON_SET_UP_LEVEL_SHIFT 16
+# define RADEON_SLEW_RATE_LIMIT (1 << 23)
+# define RADEON_CY_FILT_BLEND_SHIFT 28
#define RADEON_TV_MODULATOR_CNTL2 0x0874
+# define RADEON_TV_U_BURST_LEVEL_MASK 0x1ff
+# define RADEON_TV_V_BURST_LEVEL_MASK 0x1ff
+# define RADEON_TV_V_BURST_LEVEL_SHIFT 16
#define RADEON_TV_CRC_CNTL 0x0890
#define RADEON_TV_UV_ADR 0x08ac
+# define RADEON_MAX_UV_ADR_MASK 0x000000ff
+# define RADEON_MAX_UV_ADR_SHIFT 0
+# define RADEON_TABLE1_BOT_ADR_MASK 0x0000ff00
+# define RADEON_TABLE1_BOT_ADR_SHIFT 8
+# define RADEON_TABLE3_TOP_ADR_MASK 0x00ff0000
+# define RADEON_TABLE3_TOP_ADR_SHIFT 16
+# define RADEON_HCODE_TABLE_SEL_MASK 0x06000000
+# define RADEON_HCODE_TABLE_SEL_SHIFT 25
+# define RADEON_VCODE_TABLE_SEL_MASK 0x18000000
+# define RADEON_VCODE_TABLE_SEL_SHIFT 27
+# define RADEON_TV_MAX_FIFO_ADDR 0x1a7
+# define RADEON_TV_MAX_FIFO_ADDR_INTERNAL 0x1ff
#define RADEON_TV_PLL_FINE_CNTL 0x0020 /* PLL */
#define RADEON_TV_PLL_CNTL 0x0021 /* PLL */
+# define RADEON_TV_M0LO_MASK 0xff
+# define RADEON_TV_M0HI_MASK 0x3
+# define RADEON_TV_M0HI_SHIFT 18
+# define RADEON_TV_N0LO_MASK 0xff
+# define RADEON_TV_N0LO_SHIFT 8
+# define RADEON_TV_N0HI_MASK 0x3
+# define RADEON_TV_N0HI_SHIFT 21
+# define RADEON_TV_P_MASK 0xf
+# define RADEON_TV_P_SHIFT 24
# define RADEON_TV_SLIP_EN (1 << 23)
# define RADEON_TV_DTO_EN (1 << 28)
#define RADEON_TV_PLL_CNTL1 0x0022 /* PLL */
-# define RADEON_TVPLL_TEST_DIS (1 << 31)
-# define RADEON_TVCLK_SRC_SEL_TVPLL (1 << 30)
+# define RADEON_TVPLL_RESET (1 << 1)
# define RADEON_TVPLL_SLEEP (1 << 3)
# define RADEON_TVPLL_REFCLK_SEL (1 << 4)
+# define RADEON_TVPCP_SHIFT 8
+# define RADEON_TVPCP_MASK (7 << 8)
+# define RADEON_TVPVG_SHIFT 11
+# define RADEON_TVPVG_MASK (7 << 11)
+# define RADEON_TVPDC_SHIFT 14
+# define RADEON_TVPDC_MASK (3 << 14)
+# define RADEON_TVPLL_TEST_DIS (1 << 31)
+# define RADEON_TVCLK_SRC_SEL_TVPLL (1 << 30)
+
+#define RADEON_RS480_UNK_e30 0xe30
+#define RADEON_RS480_UNK_e34 0xe34
+#define RADEON_RS480_UNK_e38 0xe38
+#define RADEON_RS480_UNK_e3c 0xe3c
+
#endif
diff --git a/src/radeon_tv.c b/src/radeon_tv.c
new file mode 100644
index 00000000..3a26a0a7
--- /dev/null
+++ b/src/radeon_tv.c
@@ -0,0 +1,759 @@
+/*
+ * Integrated TV out support based on the GATOS code by
+ * Federico Ulivi <fulivi@lycos.com>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+#include <stdio.h>
+
+/* X and server generic header files */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "vgaHW.h"
+#include "xf86Modes.h"
+
+/* Driver data structures */
+#include "radeon.h"
+#include "radeon_reg.h"
+#include "radeon_macros.h"
+#include "radeon_probe.h"
+#include "radeon_version.h"
+#include "radeon_tv.h"
+
+/**********************************************************************
+ *
+ * ModeConstants
+ *
+ * Storage of constants related to a single video mode
+ *
+ **********************************************************************/
+
+typedef struct
+{
+ CARD16 horResolution;
+ CARD16 verResolution;
+ TVStd standard;
+ CARD16 horTotal;
+ CARD16 verTotal;
+ CARD16 horStart;
+ CARD16 horSyncStart;
+ CARD16 verSyncStart;
+ unsigned defRestart;
+ CARD16 crtcPLL_N;
+ CARD8 crtcPLL_M;
+ CARD8 crtcPLL_postDiv;
+ unsigned pixToTV;
+} TVModeConstants;
+
+static const CARD16 hor_timing_NTSC[] =
+{
+ 0x0007,
+ 0x003f,
+ 0x0263,
+ 0x0a24,
+ 0x2a6b,
+ 0x0a36,
+ 0x126d, /* H_TABLE_POS1 */
+ 0x1bfe,
+ 0x1a8f, /* H_TABLE_POS2 */
+ 0x1ec7,
+ 0x3863,
+ 0x1bfe,
+ 0x1bfe,
+ 0x1a2a,
+ 0x1e95,
+ 0x0e31,
+ 0x201b,
+ 0
+};
+
+static const CARD16 vert_timing_NTSC[] =
+{
+ 0x2001,
+ 0x200d,
+ 0x1006,
+ 0x0c06,
+ 0x1006,
+ 0x1818,
+ 0x21e3,
+ 0x1006,
+ 0x0c06,
+ 0x1006,
+ 0x1817,
+ 0x21d4,
+ 0x0002,
+ 0
+};
+
+static const CARD16 hor_timing_PAL[] =
+{
+ 0x0007,
+ 0x0058,
+ 0x027c,
+ 0x0a31,
+ 0x2a77,
+ 0x0a95,
+ 0x124f, /* H_TABLE_POS1 */
+ 0x1bfe,
+ 0x1b22, /* H_TABLE_POS2 */
+ 0x1ef9,
+ 0x387c,
+ 0x1bfe,
+ 0x1bfe,
+ 0x1b31,
+ 0x1eb5,
+ 0x0e43,
+ 0x201b,
+ 0
+};
+
+static const CARD16 vert_timing_PAL[] =
+{
+ 0x2001,
+ 0x200c,
+ 0x1005,
+ 0x0c05,
+ 0x1005,
+ 0x1401,
+ 0x1821,
+ 0x2240,
+ 0x1005,
+ 0x0c05,
+ 0x1005,
+ 0x1401,
+ 0x1822,
+ 0x2230,
+ 0x0002,
+ 0
+};
+
+/**********************************************************************
+ *
+ * availableModes
+ *
+ * Table of all allowed modes for tv output
+ *
+ **********************************************************************/
+static const TVModeConstants availableTVModes[] =
+{
+ {
+ 800, /* horResolution */
+ 600, /* verResolution */
+ TV_STD_NTSC, /* standard */
+ 990, /* horTotal */
+ 740, /* verTotal */
+ 813, /* horStart */
+ 824, /* horSyncStart */
+ 632, /* verSyncStart */
+ 625592, /* defRestart */
+ 592, /* crtcPLL_N */
+ 91, /* crtcPLL_M */
+ 4, /* crtcPLL_postDiv */
+ 1022, /* pixToTV */
+ },
+ {
+ 800, /* horResolution */
+ 600, /* verResolution */
+ TV_STD_PAL, /* standard */
+ 1144, /* horTotal */
+ 706, /* verTotal */
+ 812, /* horStart */
+ 824, /* horSyncStart */
+ 669, /* verSyncStart */
+ 696700, /* defRestart */
+ 1382, /* crtcPLL_N */
+ 231, /* crtcPLL_M */
+ 4, /* crtcPLL_postDiv */
+ 759, /* pixToTV */
+ }
+};
+
+#define N_AVAILABLE_MODES (sizeof(availableModes) / sizeof(availableModes[ 0 ]))
+
+static long YCOEF_value[5] = { 2, 2, 0, 4, 0 };
+static long YCOEF_EN_value[5] = { 1, 1, 0, 1, 0 };
+static long SLOPE_value[5] = { 1, 2, 2, 4, 8 };
+static long SLOPE_limit[5] = { 6, 5, 4, 3, 2 };
+
+
+/* Compute F,V,H restarts from default restart position and hPos & vPos
+ * Return TRUE when code timing table was changed
+ */
+static Bool RADEONInitTVRestarts(xf86OutputPtr output, RADEONSavePtr save,
+ DisplayModePtr mode)
+{
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+ int restart;
+ unsigned hTotal;
+ unsigned vTotal;
+ unsigned fTotal;
+ int vOffset;
+ int hOffset;
+ CARD16 p1;
+ CARD16 p2;
+ Bool hChanged;
+ CARD16 hInc;
+ const TVModeConstants *constPtr;
+
+ /* FIXME: need to revisit this when we add more modes */
+ if (radeon_output->tvStd == TV_STD_NTSC ||
+ radeon_output->tvStd == TV_STD_NTSC_J ||
+ radeon_output->tvStd == TV_STD_PAL_M)
+ constPtr = &availableTVModes[0];
+ else
+ constPtr = &availableTVModes[1];
+
+ hTotal = constPtr->horTotal;
+ vTotal = constPtr->verTotal;
+
+ if (radeon_output->tvStd == TV_STD_NTSC ||
+ radeon_output->tvStd == TV_STD_NTSC_J ||
+ radeon_output->tvStd == TV_STD_PAL_M ||
+ radeon_output->tvStd == TV_STD_PAL_60)
+ fTotal = NTSC_TV_VFTOTAL + 1;
+ else
+ fTotal = PAL_TV_VFTOTAL + 1;
+
+ /* Adjust positions 1&2 in hor. code timing table */
+ hOffset = radeon_output->hPos * H_POS_UNIT;
+
+ if (radeon_output->tvStd == TV_STD_NTSC ||
+ radeon_output->tvStd == TV_STD_NTSC_J ||
+ radeon_output->tvStd == TV_STD_PAL_M) {
+ p1 = hor_timing_NTSC[ H_TABLE_POS1 ];
+ p2 = hor_timing_NTSC[ H_TABLE_POS2 ];
+ } else {
+ p1 = hor_timing_PAL[ H_TABLE_POS1 ];
+ p2 = hor_timing_PAL[ H_TABLE_POS2 ];
+ }
+
+
+ p1 = (CARD16)((int)p1 + hOffset);
+ p2 = (CARD16)((int)p2 - hOffset);
+
+ hChanged = (p1 != save->h_code_timing[ H_TABLE_POS1 ] ||
+ p2 != save->h_code_timing[ H_TABLE_POS2 ]);
+
+ save->h_code_timing[ H_TABLE_POS1 ] = p1;
+ save->h_code_timing[ H_TABLE_POS2 ] = p2;
+
+ /* Convert hOffset from n. of TV clock periods to n. of CRTC clock periods (CRTC pixels) */
+ hOffset = (hOffset * (int)(constPtr->pixToTV)) / 1000;
+
+ /* Adjust restart */
+ restart = constPtr->defRestart;
+
+ /*
+ * Convert vPos TV lines to n. of CRTC pixels
+ * Be verrrrry careful when mixing signed & unsigned values in C..
+ */
+ if (radeon_output->tvStd == TV_STD_NTSC ||
+ radeon_output->tvStd == TV_STD_NTSC_J ||
+ radeon_output->tvStd == TV_STD_PAL_M ||
+ radeon_output->tvStd == TV_STD_PAL_60)
+ vOffset = ((int)(vTotal * hTotal) * 2 * radeon_output->vPos) / (int)(NTSC_TV_LINES_PER_FRAME);
+ else
+ vOffset = ((int)(vTotal * hTotal) * 2 * radeon_output->vPos) / (int)(PAL_TV_LINES_PER_FRAME);
+
+ restart -= vOffset + hOffset;
+
+ ErrorF("computeRestarts: def = %u, h = %d, v = %d, p1=%04x, p2=%04x, restart = %d\n",
+ constPtr->defRestart , radeon_output->hPos , radeon_output->vPos , p1 , p2 , restart);
+
+ save->tv_hrestart = restart % hTotal;
+ restart /= hTotal;
+ save->tv_vrestart = restart % vTotal;
+ restart /= vTotal;
+ save->tv_frestart = restart % fTotal;
+
+ ErrorF("computeRestarts: F/H/V=%u,%u,%u\n",
+ (unsigned)save->tv_frestart, (unsigned)save->tv_vrestart,
+ (unsigned)save->tv_hrestart);
+
+ /* Compute H_INC from hSize */
+ if (radeon_output->tvStd == TV_STD_NTSC ||
+ radeon_output->tvStd == TV_STD_NTSC_J ||
+ radeon_output->tvStd == TV_STD_PAL_M)
+ hInc = (CARD16)((int)(constPtr->horResolution * 4096 * NTSC_TV_CLOCK_T) /
+ (radeon_output->hSize * (int)(NTSC_TV_H_SIZE_UNIT) + (int)(NTSC_TV_ZERO_H_SIZE)));
+ else
+ hInc = (CARD16)((int)(constPtr->horResolution * 4096 * PAL_TV_CLOCK_T) /
+ (radeon_output->hSize * (int)(PAL_TV_H_SIZE_UNIT) + (int)(PAL_TV_ZERO_H_SIZE)));
+
+ save->tv_timing_cntl = (save->tv_timing_cntl & ~RADEON_H_INC_MASK) |
+ ((CARD32)hInc << RADEON_H_INC_SHIFT);
+
+ ErrorF("computeRestarts: hSize=%d,hInc=%u\n" , radeon_output->hSize , hInc);
+
+ return hChanged;
+}
+
+/* intit TV-out regs */
+void RADEONInitTVRegisters(xf86OutputPtr output, RADEONSavePtr save,
+ DisplayModePtr mode, BOOL IsPrimary)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned i;
+ unsigned long vert_space, flicker_removal;
+ CARD32 tmp;
+ const TVModeConstants *constPtr;
+ const CARD16 *hor_timing;
+ const CARD16 *vert_timing;
+
+
+ /* FIXME: need to revisit this when we add more modes */
+ if (radeon_output->tvStd == TV_STD_NTSC ||
+ radeon_output->tvStd == TV_STD_NTSC_J ||
+ radeon_output->tvStd == TV_STD_PAL_M)
+ constPtr = &availableTVModes[0];
+ else
+ constPtr = &availableTVModes[1];
+
+ save->tv_crc_cntl = 0;
+
+ save->tv_gain_limit_settings = (0x17f << RADEON_UV_GAIN_LIMIT_SHIFT) |
+ (0x5ff << RADEON_Y_GAIN_LIMIT_SHIFT);
+
+ save->tv_hdisp = constPtr->horResolution - 1;
+ save->tv_hstart = constPtr->horStart;
+ save->tv_htotal = constPtr->horTotal - 1;
+
+ save->tv_linear_gain_settings = (0x100 << RADEON_UV_GAIN_SHIFT) |
+ (0x100 << RADEON_Y_GAIN_SHIFT);
+
+ save->tv_master_cntl = (RADEON_VIN_ASYNC_RST
+ | RADEON_CRT_FIFO_CE_EN
+ | RADEON_TV_FIFO_CE_EN
+ | RADEON_TV_ON);
+
+ if (!IS_R300_VARIANT)
+ save->tv_master_cntl |= RADEON_TVCLK_ALWAYS_ONb;
+
+ if (radeon_output->tvStd == TV_STD_NTSC ||
+ radeon_output->tvStd == TV_STD_NTSC_J)
+ save->tv_master_cntl |= RADEON_RESTART_PHASE_FIX;
+
+ save->tv_modulator_cntl1 = RADEON_SLEW_RATE_LIMIT
+ | RADEON_SYNC_TIP_LEVEL
+ | RADEON_YFLT_EN
+ | RADEON_UVFLT_EN
+ | (6 << RADEON_CY_FILT_BLEND_SHIFT);
+
+ if (radeon_output->tvStd == TV_STD_NTSC ||
+ radeon_output->tvStd == TV_STD_NTSC_J) {
+ save->tv_modulator_cntl1 |= (0x46 << RADEON_SET_UP_LEVEL_SHIFT)
+ | (0x3b << RADEON_BLANK_LEVEL_SHIFT);
+ save->tv_modulator_cntl2 = (-111 & RADEON_TV_U_BURST_LEVEL_MASK) |
+ ((0 & RADEON_TV_V_BURST_LEVEL_MASK) << RADEON_TV_V_BURST_LEVEL_SHIFT);
+ } else if (radeon_output->tvStd == TV_STD_SCART_PAL) {
+ save->tv_modulator_cntl1 |= RADEON_ALT_PHASE_EN;
+ save->tv_modulator_cntl2 = (0 & RADEON_TV_U_BURST_LEVEL_MASK) |
+ ((0 & RADEON_TV_V_BURST_LEVEL_MASK) << RADEON_TV_V_BURST_LEVEL_SHIFT);
+ } else {
+ save->tv_modulator_cntl1 |= RADEON_ALT_PHASE_EN
+ | (0x3b << RADEON_SET_UP_LEVEL_SHIFT)
+ | (0x3b << RADEON_BLANK_LEVEL_SHIFT);
+ save->tv_modulator_cntl2 = (-78 & RADEON_TV_U_BURST_LEVEL_MASK) |
+ ((62 & RADEON_TV_V_BURST_LEVEL_MASK) << RADEON_TV_V_BURST_LEVEL_SHIFT);
+ }
+
+ save->pll_test_cntl = 0;
+
+ save->tv_pre_dac_mux_cntl = (RADEON_Y_RED_EN
+ | RADEON_C_GRN_EN
+ | RADEON_CMP_BLU_EN
+ | RADEON_DAC_DITHER_EN);
+
+ save->tv_rgb_cntl = (RADEON_RGB_DITHER_EN
+ | RADEON_TVOUT_SCALE_EN
+ | (0x0b << RADEON_UVRAM_READ_MARGIN_SHIFT)
+ | (0x07 << RADEON_FIFORAM_FFMACRO_READ_MARGIN_SHIFT));
+
+ if (IsPrimary) {
+ if (radeon_output->Flags & RADEON_USE_RMX)
+ save->tv_rgb_cntl |= RADEON_RGB_SRC_SEL_RMX;
+ else
+ save->tv_rgb_cntl |= RADEON_RGB_SRC_SEL_CRTC1;
+ } else {
+ save->tv_rgb_cntl |= RADEON_RGB_SRC_SEL_CRTC2;
+ }
+
+ save->tv_sync_cntl = RADEON_SYNC_PUB | RADEON_TV_SYNC_IO_DRIVE;
+
+ save->tv_sync_size = constPtr->horResolution + 8;
+
+ if (radeon_output->tvStd == TV_STD_NTSC ||
+ radeon_output->tvStd == TV_STD_NTSC_J ||
+ radeon_output->tvStd == TV_STD_PAL_M ||
+ radeon_output->tvStd == TV_STD_PAL_60)
+ vert_space = constPtr->verTotal * 2 * 10000 / NTSC_TV_LINES_PER_FRAME;
+ else
+ vert_space = constPtr->verTotal * 2 * 10000 / PAL_TV_LINES_PER_FRAME;
+
+ save->tv_vscaler_cntl1 = RADEON_Y_W_EN;
+ save->tv_vscaler_cntl1 =
+ (save->tv_vscaler_cntl1 & 0xe3ff0000) | (vert_space * (1 << FRAC_BITS) / 10000);
+ save->tv_vscaler_cntl1 |= RADEON_RESTART_FIELD;
+ if (constPtr->horResolution == 1024)
+ save->tv_vscaler_cntl1 |= (4 << RADEON_Y_DEL_W_SIG_SHIFT);
+ else
+ save->tv_vscaler_cntl1 |= (2 << RADEON_Y_DEL_W_SIG_SHIFT);
+
+ if (radeon_output->tvStd == TV_STD_NTSC ||
+ radeon_output->tvStd == TV_STD_NTSC_J ||
+ radeon_output->tvStd == TV_STD_PAL_M ||
+ radeon_output->tvStd == TV_STD_PAL_60)
+ flicker_removal =
+ (float) constPtr->verTotal * 2.0 / NTSC_TV_LINES_PER_FRAME + 0.5;
+ else
+ flicker_removal =
+ (float) constPtr->verTotal * 2.0 / PAL_TV_LINES_PER_FRAME + 0.5;
+
+ if (flicker_removal < 3)
+ flicker_removal = 3;
+ for (i = 0; i < 6; ++i) {
+ if (flicker_removal == SLOPE_limit[i])
+ break;
+ }
+ save->tv_y_saw_tooth_cntl =
+ (vert_space * SLOPE_value[i] * (1 << (FRAC_BITS - 1)) + 5001) / 10000 / 8
+ | ((SLOPE_value[i] * (1 << (FRAC_BITS - 1)) / 8) << 16);
+ save->tv_y_fall_cntl =
+ (YCOEF_EN_value[i] << 17) | ((YCOEF_value[i] * (1 << 8) / 8) << 24) |
+ RADEON_Y_FALL_PING_PONG | (272 * SLOPE_value[i] / 8) * (1 << (FRAC_BITS - 1)) /
+ 1024;
+ save->tv_y_rise_cntl =
+ RADEON_Y_RISE_PING_PONG
+ | (flicker_removal * 1024 - 272) * SLOPE_value[i] / 8 * (1 << (FRAC_BITS - 1)) / 1024;
+
+ save->tv_vscaler_cntl2 = ((save->tv_vscaler_cntl2 & 0x00fffff0)
+ | (0x10 << 24)
+ | RADEON_DITHER_MODE
+ | RADEON_Y_OUTPUT_DITHER_EN
+ | RADEON_UV_OUTPUT_DITHER_EN
+ | RADEON_UV_TO_BUF_DITHER_EN);
+
+ tmp = (save->tv_vscaler_cntl1 >> RADEON_UV_INC_SHIFT) & RADEON_UV_INC_MASK;
+ tmp = ((16384 * 256 * 10) / tmp + 5) / 10;
+ tmp = (tmp << RADEON_UV_OUTPUT_POST_SCALE_SHIFT) | 0x000b0000;
+ save->tv_timing_cntl = tmp;
+
+ save->tv_dac_cntl = RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD | (8 << 16) | (6 << 20);
+
+ if (radeon_output->tvStd == TV_STD_NTSC ||
+ radeon_output->tvStd == TV_STD_NTSC_J)
+ save->tv_dac_cntl |= RADEON_TV_DAC_STD_NTSC;
+ else
+ save->tv_dac_cntl |= RADEON_TV_DAC_STD_PAL;
+
+#if 0
+ /* needs fixes for r4xx */
+ save->tv_dac_cntl |= (RADEON_TV_DAC_RDACPD | RADEON_TV_DAC_GDACPD
+ | RADEON_TV_DAC_BDACPD);
+
+ if (radeon_output->MonType == MT_CTV) {
+ save->tv_dac_cntl &= ~RADEON_TV_DAC_BDACPD;
+ }
+
+ if (radeon_output->MonType == MT_STV) {
+ save->tv_dac_cntl &= ~(RADEON_TV_DAC_RDACPD |
+ RADEON_TV_DAC_GDACPD);
+ }
+#endif
+
+ if (radeon_output->tvStd == TV_STD_NTSC ||
+ radeon_output->tvStd == TV_STD_NTSC_J)
+ save->tv_pll_cntl = (NTSC_TV_PLL_M & RADEON_TV_M0LO_MASK) |
+ (((NTSC_TV_PLL_M >> 8) & RADEON_TV_M0HI_MASK) << RADEON_TV_M0HI_SHIFT) |
+ ((NTSC_TV_PLL_N & RADEON_TV_N0LO_MASK) << RADEON_TV_N0LO_SHIFT) |
+ (((NTSC_TV_PLL_N >> 8) & RADEON_TV_N0HI_MASK) << RADEON_TV_N0HI_SHIFT) |
+ ((NTSC_TV_PLL_P & RADEON_TV_P_MASK) << RADEON_TV_P_SHIFT);
+ else
+ save->tv_pll_cntl = (PAL_TV_PLL_M & RADEON_TV_M0LO_MASK) |
+ (((PAL_TV_PLL_M >> 8) & RADEON_TV_M0HI_MASK) << RADEON_TV_M0HI_SHIFT) |
+ ((PAL_TV_PLL_N & RADEON_TV_N0LO_MASK) << RADEON_TV_N0LO_SHIFT) |
+ (((PAL_TV_PLL_N >> 8) & RADEON_TV_N0HI_MASK) << RADEON_TV_N0HI_SHIFT) |
+ ((PAL_TV_PLL_P & RADEON_TV_P_MASK) << RADEON_TV_P_SHIFT);
+
+ save->tv_pll_cntl1 = (((4 & RADEON_TVPCP_MASK)<< RADEON_TVPCP_SHIFT) |
+ ((4 & RADEON_TVPVG_MASK) << RADEON_TVPVG_SHIFT) |
+ ((1 & RADEON_TVPDC_MASK)<< RADEON_TVPDC_SHIFT) |
+ RADEON_TVCLK_SRC_SEL_TVPLL |
+ RADEON_TVPLL_TEST_DIS);
+
+ save->tv_upsamp_and_gain_cntl = RADEON_YUPSAMP_EN | RADEON_UVUPSAMP_EN;
+
+ save->tv_uv_adr = 0xc8;
+
+ save->tv_vdisp = constPtr->verResolution - 1;
+
+ if (radeon_output->tvStd == TV_STD_NTSC ||
+ radeon_output->tvStd == TV_STD_NTSC_J ||
+ radeon_output->tvStd == TV_STD_PAL_M ||
+ radeon_output->tvStd == TV_STD_PAL_60)
+ save->tv_ftotal = NTSC_TV_VFTOTAL;
+ else
+ save->tv_ftotal = PAL_TV_VFTOTAL;
+
+ save->tv_vtotal = constPtr->verTotal - 1;
+
+ if (radeon_output->tvStd == TV_STD_NTSC ||
+ radeon_output->tvStd == TV_STD_NTSC_J ||
+ radeon_output->tvStd == TV_STD_PAL_M) {
+ hor_timing = hor_timing_NTSC;
+ } else {
+ hor_timing = hor_timing_PAL;
+ }
+
+ if (radeon_output->tvStd == TV_STD_NTSC ||
+ radeon_output->tvStd == TV_STD_NTSC_J ||
+ radeon_output->tvStd == TV_STD_PAL_M ||
+ radeon_output->tvStd == TV_STD_PAL_60) {
+ vert_timing = vert_timing_NTSC;
+ } else {
+ vert_timing = vert_timing_PAL;
+ }
+
+ for (i = 0; i < MAX_H_CODE_TIMING_LEN; i++) {
+ if ((save->h_code_timing[ i ] = hor_timing[ i ]) == 0)
+ break;
+ }
+
+ for (i = 0; i < MAX_V_CODE_TIMING_LEN; i++) {
+ if ((save->v_code_timing[ i ] = vert_timing[ i ]) == 0)
+ break;
+ }
+
+ /*
+ * This must be called AFTER loading timing tables as they are modified by this function
+ */
+ RADEONInitTVRestarts(output, save, mode);
+
+ save->dac_cntl &= ~RADEON_DAC_TVO_EN;
+
+ if (IS_R300_VARIANT)
+ save->gpiopad_a = info->SavedReg.gpiopad_a & ~1;
+
+ if (IsPrimary) {
+ save->disp_output_cntl &= ~RADEON_DISP_TVDAC_SOURCE_MASK;
+ save->disp_output_cntl |= (RADEON_DISP_TVDAC_SOURCE_CRTC
+ | RADEON_DISP_TV_SOURCE_CRTC);
+ if (info->ChipFamily >= CHIP_FAMILY_R200) {
+ save->disp_tv_out_cntl &= ~RADEON_DISP_TV_PATH_SRC_CRTC2;
+ } else {
+ save->disp_hw_debug |= RADEON_CRT2_DISP1_SEL;
+ }
+ } else {
+ save->disp_output_cntl &= ~RADEON_DISP_DAC_SOURCE_MASK;
+ save->disp_output_cntl |= RADEON_DISP_TV_SOURCE_CRTC;
+
+ if (info->ChipFamily >= CHIP_FAMILY_R200) {
+ save->disp_tv_out_cntl |= RADEON_DISP_TV_PATH_SRC_CRTC2;
+ } else {
+ save->disp_hw_debug &= ~RADEON_CRT2_DISP1_SEL;
+ }
+ }
+}
+
+
+/* Set hw registers for a new h/v position & h size */
+void RADEONUpdateHVPosition(xf86OutputPtr output, DisplayModePtr mode)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ Bool reloadTable;
+ RADEONSavePtr restore = &info->ModeReg;
+
+ reloadTable = RADEONInitTVRestarts(output, restore, mode);
+
+ RADEONRestoreTVRestarts(pScrn, restore);
+
+ OUTREG(RADEON_TV_TIMING_CNTL, restore->tv_timing_cntl);
+
+ if (reloadTable) {
+ OUTREG(RADEON_TV_MASTER_CNTL, restore->tv_master_cntl
+ | RADEON_TV_ASYNC_RST
+ | RADEON_CRT_ASYNC_RST
+ | RADEON_RESTART_PHASE_FIX);
+
+ RADEONRestoreTVTimingTables(pScrn, restore);
+
+ OUTREG(RADEON_TV_MASTER_CNTL, restore->tv_master_cntl);
+ }
+}
+
+void RADEONAdjustCrtcRegistersForTV(ScrnInfoPtr pScrn, RADEONSavePtr save,
+ DisplayModePtr mode, xf86OutputPtr output)
+{
+ const TVModeConstants *constPtr;
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+
+ /* FIXME: need to revisit this when we add more modes */
+ if (radeon_output->tvStd == TV_STD_NTSC ||
+ radeon_output->tvStd == TV_STD_NTSC_J ||
+ radeon_output->tvStd == TV_STD_PAL_M)
+ constPtr = &availableTVModes[0];
+ else
+ constPtr = &availableTVModes[1];
+
+ save->crtc_h_total_disp = (((constPtr->horResolution / 8) - 1) << RADEON_CRTC_H_DISP_SHIFT) |
+ (((constPtr->horTotal / 8) - 1) << RADEON_CRTC_H_TOTAL_SHIFT);
+
+ save->crtc_h_sync_strt_wid = (save->crtc_h_sync_strt_wid
+ & ~(RADEON_CRTC_H_SYNC_STRT_PIX | RADEON_CRTC_H_SYNC_STRT_CHAR)) |
+ (((constPtr->horSyncStart / 8) - 1) << RADEON_CRTC_H_SYNC_STRT_CHAR_SHIFT) |
+ (constPtr->horSyncStart & 7);
+
+ save->crtc_v_total_disp = ((constPtr->verResolution - 1) << RADEON_CRTC_V_DISP_SHIFT) |
+ ((constPtr->verTotal - 1) << RADEON_CRTC_V_TOTAL_SHIFT);
+
+ save->crtc_v_sync_strt_wid = (save->crtc_v_sync_strt_wid & ~RADEON_CRTC_V_SYNC_STRT) |
+ ((constPtr->verSyncStart - 1) << RADEON_CRTC_V_SYNC_STRT_SHIFT);
+
+}
+
+void RADEONAdjustPLLRegistersForTV(ScrnInfoPtr pScrn, RADEONSavePtr save,
+ DisplayModePtr mode, xf86OutputPtr output)
+{
+ unsigned postDiv;
+ const TVModeConstants *constPtr;
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+
+ /* FIXME: need to revisit this when we add more modes */
+ if (radeon_output->tvStd == TV_STD_NTSC ||
+ radeon_output->tvStd == TV_STD_NTSC_J ||
+ radeon_output->tvStd == TV_STD_PAL_M)
+ constPtr = &availableTVModes[0];
+ else
+ constPtr = &availableTVModes[1];
+
+ save->htotal_cntl = (constPtr->horTotal & 0x7 /*0xf*/) | RADEON_HTOT_CNTL_VGA_EN;
+
+ save->ppll_ref_div = constPtr->crtcPLL_M;
+
+ switch (constPtr->crtcPLL_postDiv) {
+ case 1:
+ postDiv = 0;
+ break;
+ case 2:
+ postDiv = 1;
+ break;
+ case 3:
+ postDiv = 4;
+ break;
+ case 4:
+ postDiv = 2;
+ break;
+ case 6:
+ postDiv = 6;
+ break;
+ case 8:
+ postDiv = 3;
+ break;
+ case 12:
+ postDiv = 7;
+ break;
+ case 16:
+ default:
+ postDiv = 5;
+ break;
+ }
+
+ save->ppll_div_3 = (constPtr->crtcPLL_N & 0x7ff) | (postDiv << 16);
+
+ save->pixclks_cntl &= ~(RADEON_PIX2CLK_SRC_SEL_MASK | RADEON_PIXCLK_TV_SRC_SEL);
+ save->pixclks_cntl |= RADEON_PIX2CLK_SRC_SEL_P2PLLCLK;
+
+}
+
+void RADEONAdjustCrtc2RegistersForTV(ScrnInfoPtr pScrn, RADEONSavePtr save,
+ DisplayModePtr mode, xf86OutputPtr output)
+{
+ const TVModeConstants *constPtr;
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+
+ /* FIXME: need to revisit this when we add more modes */
+ if (radeon_output->tvStd == TV_STD_NTSC ||
+ radeon_output->tvStd == TV_STD_NTSC_J ||
+ radeon_output->tvStd == TV_STD_PAL_M)
+ constPtr = &availableTVModes[0];
+ else
+ constPtr = &availableTVModes[1];
+
+ save->crtc2_h_total_disp = (((constPtr->horResolution / 8) - 1) << RADEON_CRTC_H_DISP_SHIFT) |
+ (((constPtr->horTotal / 8) - 1) << RADEON_CRTC_H_TOTAL_SHIFT);
+
+ save->crtc2_h_sync_strt_wid = (save->crtc2_h_sync_strt_wid
+ & ~(RADEON_CRTC_H_SYNC_STRT_PIX | RADEON_CRTC_H_SYNC_STRT_CHAR)) |
+ (((constPtr->horSyncStart / 8) - 1) << RADEON_CRTC_H_SYNC_STRT_CHAR_SHIFT) |
+ (constPtr->horSyncStart & 7);
+
+ save->crtc2_v_total_disp = ((constPtr->verResolution - 1) << RADEON_CRTC_V_DISP_SHIFT) |
+ ((constPtr->verTotal - 1) << RADEON_CRTC_V_TOTAL_SHIFT);
+
+ save->crtc_v_sync_strt_wid = (save->crtc_v_sync_strt_wid & ~RADEON_CRTC_V_SYNC_STRT) |
+ ((constPtr->verSyncStart - 1) << RADEON_CRTC_V_SYNC_STRT_SHIFT);
+
+}
+
+void RADEONAdjustPLL2RegistersForTV(ScrnInfoPtr pScrn, RADEONSavePtr save,
+ DisplayModePtr mode, xf86OutputPtr output)
+{
+ unsigned postDiv;
+ const TVModeConstants *constPtr;
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+
+ /* FIXME: need to revisit this when we add more modes */
+ if (radeon_output->tvStd == TV_STD_NTSC ||
+ radeon_output->tvStd == TV_STD_NTSC_J ||
+ radeon_output->tvStd == TV_STD_PAL_M)
+ constPtr = &availableTVModes[0];
+ else
+ constPtr = &availableTVModes[1];
+
+ save->htotal_cntl2 = (constPtr->horTotal & 0x7); /* 0xf */
+
+ save->p2pll_ref_div = constPtr->crtcPLL_M;
+
+ switch (constPtr->crtcPLL_postDiv) {
+ case 1:
+ postDiv = 0;
+ break;
+ case 2:
+ postDiv = 1;
+ break;
+ case 3:
+ postDiv = 4;
+ break;
+ case 4:
+ postDiv = 2;
+ break;
+ case 6:
+ postDiv = 6;
+ break;
+ case 8:
+ postDiv = 3;
+ break;
+ case 12:
+ postDiv = 7;
+ break;
+ case 16:
+ default:
+ postDiv = 5;
+ break;
+ }
+
+ save->p2pll_div_0 = (constPtr->crtcPLL_N & 0x7ff) | (postDiv << 16);
+
+ save->pixclks_cntl &= ~RADEON_PIX2CLK_SRC_SEL_MASK;
+ save->pixclks_cntl |= (RADEON_PIX2CLK_SRC_SEL_P2PLLCLK
+ | RADEON_PIXCLK_TV_SRC_SEL);
+
+}
diff --git a/src/radeon_tv.h b/src/radeon_tv.h
new file mode 100644
index 00000000..5c8c8c97
--- /dev/null
+++ b/src/radeon_tv.h
@@ -0,0 +1,56 @@
+/*
+ * Integrated TV out support based on the GATOS code by
+ * Federico Ulivi <fulivi@lycos.com>
+ */
+
+/*
+ * Maximum length of horizontal/vertical code timing tables for state storage
+ */
+#define MAX_H_CODE_TIMING_LEN 32
+#define MAX_V_CODE_TIMING_LEN 32
+
+/*
+ * Limits of h/v positions (hPos & vPos)
+ */
+#define MAX_H_POSITION 5 /* Range: [-5..5], negative is on the left, 0 is default, positive is on the right */
+#define MAX_V_POSITION 5 /* Range: [-5..5], negative is up, 0 is default, positive is down */
+
+/*
+ * Unit for hPos (in TV clock periods)
+ */
+#define H_POS_UNIT 10
+
+/*
+ * Indexes in h. code timing table for horizontal line position adjustment
+ */
+#define H_TABLE_POS1 6
+#define H_TABLE_POS2 8
+
+/*
+ * Limits of hor. size (hSize)
+ */
+#define MAX_H_SIZE 5 /* Range: [-5..5], negative is smaller, positive is larger */
+
+/* tv standard constants */
+#define NTSC_TV_PLL_M 22
+#define NTSC_TV_PLL_N 175
+#define NTSC_TV_PLL_P 5
+#define NTSC_TV_CLOCK_T 233
+#define NTSC_TV_VFTOTAL 1
+#define NTSC_TV_LINES_PER_FRAME 525
+#define NTSC_TV_ZERO_H_SIZE 479166
+#define NTSC_TV_H_SIZE_UNIT 9478
+
+#define PAL_TV_PLL_M 113
+#define PAL_TV_PLL_N 668
+#define PAL_TV_PLL_P 3
+#define PAL_TV_CLOCK_T 188
+#define PAL_TV_VFTOTAL 3
+#define PAL_TV_LINES_PER_FRAME 625
+#define PAL_TV_ZERO_H_SIZE 473200
+#define PAL_TV_H_SIZE_UNIT 9360
+
+
+#define VERT_LEAD_IN_LINES 2
+#define FRAC_BITS 0xe
+#define FRAC_MASK 0x3fff
diff --git a/src/radeon_version.h b/src/radeon_version.h
index a1b24590..ccc1367a 100644
--- a/src/radeon_version.h
+++ b/src/radeon_version.h
@@ -41,7 +41,7 @@
#define RADEON_VERSION_MAJOR 4
#define RADEON_VERSION_MAJOR_TILED 5
-#define RADEON_VERSION_MINOR 2
+#define RADEON_VERSION_MINOR 3
#define RADEON_VERSION_PATCH 0
#ifndef RADEON_VERSION_EXTRA
diff --git a/src/radeon_video.c b/src/radeon_video.c
index 390df892..271f7fe8 100644
--- a/src/radeon_video.c
+++ b/src/radeon_video.c
@@ -12,7 +12,6 @@
#include "radeon_reg.h"
#include "radeon_macros.h"
#include "radeon_probe.h"
-#include "radeon_mergedfb.h"
#include "radeon_video.h"
#include "xf86.h"
@@ -100,14 +99,14 @@ static void RADEON_TDA9885_SetEncoding(RADEONPortPrivPtr pPriv);
static void RADEON_FI1236_SetEncoding(RADEONPortPrivPtr pPriv);
-#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
+
#define ClipValue(v,min,max) ((v) < (min) ? (min) : (v) > (max) ? (max) : (v))
static Atom xvBrightness, xvColorKey, xvSaturation, xvDoubleBuffer;
static Atom xvRedIntensity, xvGreenIntensity, xvBlueIntensity;
static Atom xvContrast, xvHue, xvColor, xvAutopaintColorkey, xvSetDefaults;
static Atom xvGamma, xvColorspace;
-static Atom xvSwitchCRT;
+static Atom xvCRTC;
static Atom xvEncoding, xvFrequency, xvVolume, xvMute,
xvDecBrightness, xvDecContrast, xvDecHue, xvDecColor, xvDecSaturation,
xvTunerStatus, xvSAP, xvOverlayDeinterlacingMethod,
@@ -120,6 +119,114 @@ static Atom xvOvAlpha, xvGrAlpha, xvAlphaMode;
#define GET_PORT_PRIVATE(pScrn) \
(RADEONPortPrivPtr)((RADEONPTR(pScrn))->adaptor->pPortPrivates[0].ptr)
+static void
+radeon_box_intersect(BoxPtr dest, BoxPtr a, BoxPtr b)
+{
+ dest->x1 = a->x1 > b->x1 ? a->x1 : b->x1;
+ dest->x2 = a->x2 < b->x2 ? a->x2 : b->x2;
+ dest->y1 = a->y1 > b->y1 ? a->y1 : b->y1;
+ dest->y2 = a->y2 < b->y2 ? a->y2 : b->y2;
+
+ if (dest->x1 >= dest->x2 || dest->y1 >= dest->y2)
+ dest->x1 = dest->x2 = dest->y1 = dest->y2 = 0;
+}
+
+static void
+radeon_crtc_box(xf86CrtcPtr crtc, BoxPtr crtc_box)
+{
+ if (crtc->enabled) {
+ crtc_box->x1 = crtc->x;
+ crtc_box->x2 = crtc->x + xf86ModeWidth(&crtc->mode, crtc->rotation);
+ crtc_box->y1 = crtc->y;
+ crtc_box->y2 = crtc->y + xf86ModeHeight(&crtc->mode, crtc->rotation);
+ } else
+ crtc_box->x1 = crtc_box->x2 = crtc_box->y1 = crtc_box->y2 = 0;
+}
+
+static int
+radeon_box_area(BoxPtr box)
+{
+ return (int) (box->x2 - box->x1) * (int) (box->y2 - box->y1);
+}
+
+static xf86CrtcPtr
+radeon_covering_crtc(ScrnInfoPtr pScrn,
+ BoxPtr box,
+ xf86CrtcPtr desired,
+ BoxPtr crtc_box_ret)
+{
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ xf86CrtcPtr crtc, best_crtc;
+ int coverage, best_coverage;
+ int c;
+ BoxRec crtc_box, cover_box;
+
+ best_crtc = NULL;
+ best_coverage = 0;
+ crtc_box_ret->x1 = 0;
+ crtc_box_ret->x2 = 0;
+ crtc_box_ret->y1 = 0;
+ crtc_box_ret->y2 = 0;
+ for (c = 0; c < xf86_config->num_crtc; c++) {
+ crtc = xf86_config->crtc[c];
+ radeon_crtc_box(crtc, &crtc_box);
+ radeon_box_intersect(&cover_box, &crtc_box, box);
+ coverage = radeon_box_area(&cover_box);
+ if (coverage && crtc == desired) {
+ *crtc_box_ret = crtc_box;
+ return crtc;
+ } else if (coverage > best_coverage) {
+ *crtc_box_ret = crtc_box;
+ best_crtc = crtc;
+ best_coverage = coverage;
+ }
+ }
+ return best_crtc;
+}
+
+static Bool
+radeon_clip_video_helper(ScrnInfoPtr pScrn,
+ xf86CrtcPtr *crtc_ret,
+ xf86CrtcPtr desired_crtc,
+ BoxPtr dst,
+ INT32 *xa,
+ INT32 *xb,
+ INT32 *ya,
+ INT32 *yb,
+ RegionPtr reg,
+ INT32 width,
+ INT32 height)
+{
+ Bool ret;
+ RegionRec crtc_region_local;
+ RegionPtr crtc_region = reg;
+
+ /*
+ * For overlay video, compute the relevant CRTC and
+ * clip video to that
+ */
+ if (crtc_ret) {
+ BoxRec crtc_box;
+ xf86CrtcPtr crtc = radeon_covering_crtc(pScrn, dst,
+ desired_crtc,
+ &crtc_box);
+
+ if (crtc) {
+ REGION_INIT (pScreen, &crtc_region_local, &crtc_box, 1);
+ crtc_region = &crtc_region_local;
+ REGION_INTERSECT (pScreen, crtc_region, crtc_region, reg);
+ }
+ *crtc_ret = crtc;
+ }
+
+ ret = xf86XVClipVideoHelper(dst, xa, xb, ya, yb,
+ crtc_region, width, height);
+
+ if (crtc_region != reg)
+ REGION_UNINIT (pScreen, &crtc_region_local);
+
+ return ret;
+}
#ifdef USE_EXA
static void
@@ -227,7 +334,7 @@ static XF86AttributeRec Attributes[NUM_ATTRIBUTES] =
{XvSettable | XvGettable, -1000, 1000, "XV_RED_INTENSITY"},
{XvSettable | XvGettable, -1000, 1000, "XV_GREEN_INTENSITY"},
{XvSettable | XvGettable, -1000, 1000, "XV_BLUE_INTENSITY"},
- {XvSettable | XvGettable, 0, 1, "XV_SWITCHCRT"},
+ {XvSettable | XvGettable, -1, 1, "XV_CRTC"},
{XvSettable | XvGettable, 100, 10000, "XV_GAMMA"},
{XvSettable | XvGettable, 0, 1, "XV_COLORSPACE"},
};
@@ -258,7 +365,7 @@ static XF86AttributeRec Attributes[NUM_DEC_ATTRIBUTES+1] =
{XvSettable | XvGettable, -1000, 1000, "XV_RED_INTENSITY"},
{XvSettable | XvGettable, -1000, 1000, "XV_GREEN_INTENSITY"},
{XvSettable | XvGettable, -1000, 1000, "XV_BLUE_INTENSITY"},
- {XvSettable | XvGettable, 0, 1, "XV_SWITCHCRT"},
+ {XvSettable | XvGettable, -1, 1, "XV_CRTC"},
{XvSettable | XvGettable, 100, 10000, "XV_GAMMA"},
{XvSettable | XvGettable, 0, 1, "XV_COLORSPACE"},
@@ -1083,7 +1190,7 @@ RADEONResetVideo(ScrnInfoPtr pScrn)
xvAutopaintColorkey = MAKE_ATOM("XV_AUTOPAINT_COLORKEY");
xvSetDefaults = MAKE_ATOM("XV_SET_DEFAULTS");
- xvSwitchCRT = MAKE_ATOM("XV_SWITCHCRT");
+ xvCRTC = MAKE_ATOM("XV_CRTC");
xvOvAlpha = MAKE_ATOM("XV_OVERLAY_ALPHA");
xvGrAlpha = MAKE_ATOM("XV_GRAPHICS_ALPHA");
@@ -1189,17 +1296,10 @@ static void RADEONSetupTheatre(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
/* Go and find Rage Theatre, if it exists */
- switch(info->Chipset){
- case PCI_CHIP_RADEON_LY:
- case PCI_CHIP_RADEON_LZ:
- xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Detected Radeon Mobility M6, not scanning for Rage Theatre\n");
- break;
- case PCI_CHIP_RADEON_LW:
- xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Detected Radeon Mobility M7, not scanning for Rage Theatre\n");
- break;
- default:
- pPriv->theatre=xf86_DetectTheatre(pPriv->VIP);
- }
+ if (info->IsMobility)
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Detected Radeon Mobility, not scanning for Rage Theatre\n");
+ else
+ pPriv->theatre=xf86_DetectTheatre(pPriv->VIP);
if(pPriv->theatre==NULL)return;
@@ -1225,21 +1325,21 @@ static void RADEONSetupTheatre(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
} else {
t->wComp0Connector=RT_COMP1;
}
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Composite connector is port %ld\n", t->wComp0Connector);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Composite connector is port %u\n", (unsigned)t->wComp0Connector);
break;
case 3: if(a & 0x4){
t->wSVideo0Connector=RT_YCR_COMP4;
} else {
t->wSVideo0Connector=RT_YCF_COMP4;
}
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "SVideo connector is port %ld\n", t->wSVideo0Connector);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "SVideo connector is port %u\n", (unsigned)t->wSVideo0Connector);
break;
default:
break;
}
}
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Rage Theatre: Connectors (detected): tuner=%ld, composite=%ld, svideo=%ld\n",
- t->wTunerConnector, t->wComp0Connector, t->wSVideo0Connector);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Rage Theatre: Connectors (detected): tuner=%u, composite=%u, svideo=%u\n",
+ (unsigned)t->wTunerConnector, (unsigned)t->wComp0Connector, (unsigned)t->wSVideo0Connector);
}
@@ -1247,8 +1347,8 @@ static void RADEONSetupTheatre(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
if(info->RageTheatreCompositePort>=0)t->wComp0Connector=info->RageTheatreCompositePort;
if(info->RageTheatreSVideoPort>=0)t->wSVideo0Connector=info->RageTheatreSVideoPort;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "RageTheatre: Connectors (using): tuner=%ld, composite=%ld, svideo=%ld\n",
- t->wTunerConnector, t->wComp0Connector, t->wSVideo0Connector);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "RageTheatre: Connectors (using): tuner=%u, composite=%u, svideo=%u\n",
+ (unsigned)t->wTunerConnector, (unsigned)t->wComp0Connector, (unsigned)t->wSVideo0Connector);
switch((info->RageTheatreCrystal>=0)?info->RageTheatreCrystal:pll->reference_freq){
case 2700:
@@ -1303,11 +1403,8 @@ RADEONAllocAdaptor(ScrnInfoPtr pScrn)
pPriv->currentBuffer = 0;
pPriv->autopaint_colorkey = TRUE;
pPriv->gamma = 1000;
- if (info->OverlayOnCRTC2)
- pPriv->crt2 = TRUE;
- else
- pPriv->crt2 = FALSE;
-
+ pPriv->desired_crtc = NULL;
+
pPriv->ov_alpha = 255;
pPriv->gr_alpha = 255;
pPriv->alpha_mode = 0;
@@ -1332,27 +1429,15 @@ RADEONAllocAdaptor(ScrnInfoPtr pScrn)
* 0 for PIXCLK < 175Mhz, and 1 (divide by 2)
* for higher clocks, sure makes life nicer
*/
+ dot_clock = info->ModeReg.dot_clock_freq;
- /* Figure out which head we are on */
- if ((info->MergedFB && info->OverlayOnCRTC2) || info->IsSecondary)
- dot_clock = info->ModeReg.dot_clock_freq_2;
- else
- dot_clock = info->ModeReg.dot_clock_freq;
-
- if(dot_clock < 17500)
+ if (dot_clock < 17500)
info->ecp_div = 0;
else
info->ecp_div = 1;
ecp = (INPLL(pScrn, RADEON_VCLK_ECP_CNTL) & 0xfffffCff) | (info->ecp_div << 8);
-#if 0
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Dotclock is %g Mhz, setting ecp_div to %d\n", info->ModeReg.dot_clock_freq/100.0, info->ecp_div);
-#endif
-
-
- if ((info->ChipFamily == CHIP_FAMILY_RS100) ||
- (info->ChipFamily == CHIP_FAMILY_RS200) ||
- (info->ChipFamily == CHIP_FAMILY_RS300)) {
+ if (info->IsIGP) {
/* Force the overlay clock on for integrated chips
*/
ecp |= (1<<18);
@@ -1361,7 +1446,6 @@ RADEONAllocAdaptor(ScrnInfoPtr pScrn)
OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, ecp);
-
/* Decide on tuner type */
if((info->tunerType<0) && (info->MM_TABLE_valid)) {
pPriv->tuner_type = info->MM_TABLE.tuner_type;
@@ -1478,7 +1562,7 @@ RADEONSetupImageVideo(ScreenPtr pScreen)
return NULL;
adapt->type = XvWindowMask | XvInputMask | XvImageMask;
- adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
+ adapt->flags = VIDEO_OVERLAID_IMAGES /*| VIDEO_CLIP_TO_VIEWPORT*/;
adapt->name = "ATI Radeon Video Overlay";
adapt->nEncodings = 1;
adapt->pEncodings = &DummyEncoding;
@@ -1665,14 +1749,15 @@ RADEONSetPortAttribute(ScrnInfoPtr pScrn,
RADEONSetColorKey (pScrn, pPriv->colorKey);
REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
}
- else if(attribute == xvSwitchCRT)
+ else if(attribute == xvCRTC)
{
- pPriv->crt2 = ClipValue (value, 0, 1);
- pPriv->crt2 = value;
- if (pPriv->crt2)
- info->OverlayOnCRTC2 = TRUE;
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ if ((value < -1) || (value > xf86_config->num_crtc))
+ return BadValue;
+ if (value < 0)
+ pPriv->desired_crtc = NULL;
else
- info->OverlayOnCRTC2 = FALSE;
+ pPriv->desired_crtc = xf86_config->crtc[value];
}
else if(attribute == xvOvAlpha)
{
@@ -1796,7 +1881,8 @@ RADEONSetPortAttribute(ScrnInfoPtr pScrn,
else if(attribute == xvAdjustment)
{
pPriv->adjustment=value;
- xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Setting pPriv->adjustment to %ld\n", pPriv->adjustment);
+ xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Setting pPriv->adjustment to %u\n",
+ (unsigned)pPriv->adjustment);
if(pPriv->tda9885!=0){
pPriv->tda9885->top_adjustment=value;
RADEON_TDA9885_SetEncoding(pPriv);
@@ -1862,8 +1948,16 @@ RADEONGetPortAttribute(ScrnInfoPtr pScrn,
*value = pPriv->doubleBuffer ? 1 : 0;
else if(attribute == xvColorKey)
*value = pPriv->colorKey;
- else if(attribute == xvSwitchCRT)
- *value = pPriv->crt2 ? 1 : 0;
+ else if(attribute == xvCRTC) {
+ int c;
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ for (c = 0; c < xf86_config->num_crtc; c++)
+ if (xf86_config->crtc[c] == pPriv->desired_crtc)
+ break;
+ if (c == xf86_config->num_crtc)
+ c = -1;
+ *value = c;
+ }
else if(attribute == xvOvAlpha)
*value = pPriv->ov_alpha;
else if(attribute == xvGrAlpha)
@@ -2396,7 +2490,8 @@ RADEONFreeMemory(
static void
RADEONDisplayVideo(
ScrnInfoPtr pScrn,
- RADEONPortPrivPtr pPriv,
+ xf86CrtcPtr crtc,
+ RADEONPortPrivPtr pPriv,
int id,
int offset1, int offset2,
int offset3, int offset4,
@@ -2410,6 +2505,7 @@ RADEONDisplayVideo(
int deinterlacing_method
){
RADEONInfoPtr info = RADEONPTR(pScrn);
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
unsigned char *RADEONMMIO = info->MMIO;
CARD32 v_inc, h_inc, h_inc_uv, step_by_y, step_by_uv, tmp;
double h_inc_d;
@@ -2423,7 +2519,6 @@ RADEONDisplayVideo(
int y_off;
CARD32 scaler_src;
CARD32 dot_clock;
- DisplayModePtr overlay_mode;
int is_rgb;
int is_planar;
int i;
@@ -2433,6 +2528,10 @@ RADEONDisplayVideo(
int predownscale=0;
int src_w_d;
int leftuv = 0;
+ DisplayModePtr mode;
+ RADEONOutputPrivatePtr radeon_output;
+ xf86OutputPtr output;
+ RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
is_rgb=0; is_planar=0;
switch(id){
@@ -2455,7 +2554,7 @@ RADEONDisplayVideo(
workarounds for chip erratas */
/* Figure out which head we are on for dot clock */
- if ((info->MergedFB && info->OverlayOnCRTC2) || info->IsSecondary)
+ if (radeon_crtc->crtc_id == 1)
dot_clock = info->ModeReg.dot_clock_freq_2;
else
dot_clock = info->ModeReg.dot_clock_freq;
@@ -2480,34 +2579,26 @@ RADEONDisplayVideo(
v_inc_shift = 20;
y_mult = 1;
- if (info->MergedFB) {
- if (info->OverlayOnCRTC2)
- overlay_mode = ((RADEONMergedDisplayModePtr)info->CurrentLayout.mode->Private)->CRT2;
- else
- overlay_mode = ((RADEONMergedDisplayModePtr)info->CurrentLayout.mode->Private)->CRT1;
- if (overlay_mode->Flags & V_INTERLACE)
- v_inc_shift++;
- if (overlay_mode->Flags & V_DBLSCAN) {
- v_inc_shift--;
- y_mult = 2;
- }
- if (overlay_mode->Flags & RADEON_USE_RMX) {
- v_inc = ((src_h * overlay_mode->CrtcVDisplay / info->PanelYRes) << v_inc_shift) / drw_h;
- } else {
- v_inc = (src_h << v_inc_shift) / drw_h;
- }
- } else {
- if (pScrn->currentMode->Flags & V_INTERLACE)
- v_inc_shift++;
- if (pScrn->currentMode->Flags & V_DBLSCAN) {
- v_inc_shift--;
- y_mult = 2;
+ mode = &crtc->mode;
+
+ if (mode->Flags & V_INTERLACE)
+ v_inc_shift++;
+ if (mode->Flags & V_DBLSCAN) {
+ v_inc_shift--;
+ y_mult = 2;
+ }
+
+ v_inc = (src_h << v_inc_shift) / drw_h;
+
+ for (i = 0; i < xf86_config->num_output; i++) {
+ output = xf86_config->output[i];
+ if (output->crtc == crtc) {
+ radeon_output = output->driver_private;
+ if (radeon_output->Flags & RADEON_USE_RMX)
+ v_inc = ((src_h * mode->CrtcVDisplay /
+ radeon_output->PanelYRes) << v_inc_shift) / drw_h;
+ break;
}
- if (pScrn->currentMode->Flags & RADEON_USE_RMX) {
- v_inc = ((src_h * pScrn->currentMode->CrtcVDisplay / info->PanelYRes) << v_inc_shift) / drw_h;
- } else {
- v_inc = (src_h << v_inc_shift) / drw_h;
- }
}
h_inc = (1 << (12 + ecp_div));
@@ -2593,14 +2684,6 @@ RADEONDisplayVideo(
offset5 += ((left >> 16) & ~7) << 1;
offset6 += ((left >> 16) & ~7) << 1;
}
- if (info->IsSecondary) {
- offset1 += info->FbMapSize;
- offset2 += info->FbMapSize;
- offset3 += info->FbMapSize;
- offset4 += info->FbMapSize;
- offset5 += info->FbMapSize;
- offset6 += info->FbMapSize;
- }
tmp = (left & 0x0003ffff) + 0x00028000 + (h_inc << 3);
p1_h_accum_init = ((tmp << 4) & 0x000f8000) |
@@ -2651,19 +2734,15 @@ RADEONDisplayVideo(
x_off = 0;
/* needed to make the overlay work on crtc1 in leftof and above modes */
- if (info->MergedFB) {
- RADEONScrn2Rel srel =
- ((RADEONMergedDisplayModePtr)info->CurrentLayout.mode->Private)->CRT2Position;
- overlay_mode = ((RADEONMergedDisplayModePtr)info->CurrentLayout.mode->Private)->CRT2;
- if (srel == radeonLeftOf) {
- x_off -= overlay_mode->CrtcHDisplay;
- /* y_off -= pScrn->frameY0; */
- }
- if (srel == radeonAbove) {
- y_off -= overlay_mode->CrtcVDisplay;
- /* x_off -= pScrn->frameX0; */
- }
+ /* XXX: may need to adjust x_off/y_off for dualhead like mergedfb -- need to test */
+ /*
+ if (srel == radeonLeftOf) {
+ x_off -= mode->CrtcHDisplay;
+ }
+ if (srel == radeonAbove) {
+ y_off -= mode->CrtcVDisplay;
}
+ */
/* Put the hardware overlay on CRTC2:
*
@@ -2672,7 +2751,7 @@ RADEONDisplayVideo(
* rendering for the second head.
*/
- if ((info->MergedFB && info->OverlayOnCRTC2) || info->IsSecondary) {
+ if (radeon_crtc->crtc_id == 1) {
x_off = 0;
OUTREG(RADEON_OV1_Y_X_START, ((dstBox->x1 + x_off) |
((dstBox->y1*y_mult) << 16)));
@@ -2750,6 +2829,7 @@ RADEONDisplayVideo(
| ((info->ChipFamily >= CHIP_FAMILY_R200) ? RADEON_SCALER_TEMPORAL_DEINT : 0);
break;
}
+
OUTREG(RADEON_OV0_SCALE_CNTL, scale_cntl);
OUTREG(RADEON_OV0_REG_LOAD_CNTL, 0);
}
@@ -2789,6 +2869,7 @@ RADEONPutImage(
int top, left, npixels, nlines, bpp;
BoxRec dstBox;
CARD32 tmp;
+ xf86CrtcPtr crtc;
/*
* s2offset, s3offset - byte offsets into U and V plane of the
@@ -2821,24 +2902,15 @@ RADEONPutImage(
dstBox.y1 = drw_y;
dstBox.y2 = drw_y + drw_h;
- if (info->MergedFB)
- RADEONChooseOverlayCRTC(pScrn, &dstBox);
-
- if(!xf86XVClipVideoHelper(&dstBox, &xa, &xb, &ya, &yb,
- clipBoxes, width, height))
- return Success;
-
- if (info->MergedFB && info->OverlayOnCRTC2) {
- dstBox.x1 -= info->CRT2pScrn->frameX0;
- dstBox.x2 -= info->CRT2pScrn->frameX0;
- dstBox.y1 -= info->CRT2pScrn->frameY0;
- dstBox.y2 -= info->CRT2pScrn->frameY0;
- } else {
- dstBox.x1 -= pScrn->frameX0;
- dstBox.x2 -= pScrn->frameX0;
- dstBox.y1 -= pScrn->frameY0;
- dstBox.y2 -= pScrn->frameY0;
- }
+ if (!radeon_clip_video_helper(pScrn, &crtc, pPriv->desired_crtc,
+ &dstBox, &xa, &xb, &ya, &yb,
+ clipBoxes, width, height))
+ return Success;
+
+ dstBox.x1 -= crtc->x;
+ dstBox.x2 -= crtc->x;
+ dstBox.y1 -= crtc->y;
+ dstBox.y2 -= crtc->y;
bpp = pScrn->bitsPerPixel >> 3;
@@ -2891,8 +2963,14 @@ RADEONPutImage(
offset = (pPriv->video_offset) + (top * dstPitch);
- if(pPriv->doubleBuffer)
+ if(pPriv->doubleBuffer) {
+ unsigned char *RADEONMMIO = info->MMIO;
+
+ /* Wait for last flip to take effect */
+ while(!(INREG(RADEON_OV0_REG_LOAD_CNTL) & RADEON_REG_LD_CTL_FLIP_READBACK));
+
offset += pPriv->currentBuffer * new_size;
+ }
dst_start = info->FB + offset;
@@ -2962,7 +3040,7 @@ RADEONPutImage(
/* FIXME: someone should look at these offsets, I don't think it makes sense how
they are handled throughout the source. */
- RADEONDisplayVideo(pScrn, pPriv, id, offset, offset + d2line, offset + d3line,
+ RADEONDisplayVideo(pScrn, crtc, pPriv, id, offset, offset + d2line, offset + d3line,
offset, offset + d2line, offset + d3line, width, height, dstPitch,
xa, xb, ya, &dstBox, src_w, src_h, drw_w, drw_h, METHOD_BOB);
@@ -3180,12 +3258,12 @@ RADEONDisplaySurface(
){
OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr;
ScrnInfoPtr pScrn = surface->pScrn;
-
RADEONInfoPtr info = RADEONPTR(pScrn);
RADEONPortPrivPtr portPriv = info->adaptor->pPortPrivates[0].ptr;
INT32 xa, ya, xb, yb;
BoxRec dstBox;
+ xf86CrtcPtr crtc;
if (src_w > (drw_w << 4))
drw_w = src_w >> 4;
@@ -3202,30 +3280,21 @@ RADEONDisplaySurface(
dstBox.y1 = drw_y;
dstBox.y2 = drw_y + drw_h;
- if (info->MergedFB)
- RADEONChooseOverlayCRTC(pScrn, &dstBox);
-
- if (!xf86XVClipVideoHelper(&dstBox, &xa, &xb, &ya, &yb, clipBoxes,
- surface->width, surface->height))
- return Success;
+ if (!radeon_clip_video_helper(pScrn, &crtc, portPriv->desired_crtc,
+ &dstBox, &xa, &xb, &ya, &yb, clipBoxes,
+ surface->width, surface->height))
+ return Success;
- if (info->MergedFB && info->OverlayOnCRTC2) {
- dstBox.x1 -= info->CRT2pScrn->frameX0;
- dstBox.x2 -= info->CRT2pScrn->frameX0;
- dstBox.y1 -= info->CRT2pScrn->frameY0;
- dstBox.y2 -= info->CRT2pScrn->frameY0;
- } else {
- dstBox.x1 -= pScrn->frameX0;
- dstBox.x2 -= pScrn->frameX0;
- dstBox.y1 -= pScrn->frameY0;
- dstBox.y2 -= pScrn->frameY0;
- }
+ dstBox.x1 -= crtc->x;
+ dstBox.x2 -= crtc->x;
+ dstBox.y1 -= crtc->y;
+ dstBox.y2 -= crtc->y;
#if 0
/* this isn't needed */
RADEONResetVideo(pScrn);
#endif
- RADEONDisplayVideo(pScrn, portPriv, surface->id,
+ RADEONDisplayVideo(pScrn, crtc, portPriv, surface->id,
surface->offsets[0], surface->offsets[0],
surface->offsets[0], surface->offsets[0],
surface->offsets[0], surface->offsets[0],
@@ -3261,8 +3330,8 @@ RADEONInitOffscreenImages(ScreenPtr pScreen)
return;
offscreenImages[0].image = &Images[0];
- offscreenImages[0].flags = VIDEO_OVERLAID_IMAGES |
- VIDEO_CLIP_TO_VIEWPORT;
+ offscreenImages[0].flags = VIDEO_OVERLAID_IMAGES /*|
+ VIDEO_CLIP_TO_VIEWPORT*/;
offscreenImages[0].alloc_surface = RADEONAllocateSurface;
offscreenImages[0].free_surface = RADEONFreeSurface;
offscreenImages[0].display = RADEONDisplaySurface;
@@ -3303,6 +3372,7 @@ RADEONPutVideo(
int width, height;
int mult;
int vbi_line_width, vbi_start, vbi_end;
+ xf86CrtcPtr crtc;
RADEON_SYNC(info, pScrn);
/*
@@ -3340,27 +3410,19 @@ RADEONPutVideo(
vbi_line_width = 798*2;
if(width<=640)
- vbi_line_width = 0x640; /* 1600 actually */
- else
- vbi_line_width = 2000; /* might need adjustment */
+ vbi_line_width = 0x640; /* 1600 actually */
+ else
+ vbi_line_width = 2000; /* might need adjustment */
- if (info->MergedFB)
- RADEONChooseOverlayCRTC(pScrn, &dstBox);
-
- if(!xf86XVClipVideoHelper(&dstBox, &xa, &xb, &ya, &yb, clipBoxes, width, height))
- return Success;
+ if (!radeon_clip_video_helper(pScrn, &crtc, pPriv->desired_crtc,
+ &dstBox, &xa, &xb, &ya, &yb,
+ clipBoxes, width, height))
+ return Success;
- if (info->MergedFB && info->OverlayOnCRTC2) {
- dstBox.x1 -= info->CRT2pScrn->frameX0;
- dstBox.x2 -= info->CRT2pScrn->frameX0;
- dstBox.y1 -= info->CRT2pScrn->frameY0;
- dstBox.y2 -= info->CRT2pScrn->frameY0;
- } else {
- dstBox.x1 -= pScrn->frameX0;
- dstBox.x2 -= pScrn->frameX0;
- dstBox.y1 -= pScrn->frameY0;
- dstBox.y2 -= pScrn->frameY0;
- }
+ dstBox.x1 -= crtc->x;
+ dstBox.x2 -= crtc->x;
+ dstBox.y1 -= crtc->y;
+ dstBox.y2 -= crtc->y;
bpp = pScrn->bitsPerPixel >> 3;
pitch = bpp * pScrn->displayWidth;
@@ -3382,7 +3444,8 @@ RADEONPutVideo(
id = FOURCC_YUY2;
top = ya>>16;
-
+#if 0
+ /* setting the ID above makes this useful - needs revisiting */
switch(id) {
case FOURCC_YV12:
case FOURCC_I420:
@@ -3400,6 +3463,10 @@ RADEONPutVideo(
srcPitch = (width<<1);
break;
}
+#else
+ dstPitch = ((width<<1) + 15) & ~15;
+ srcPitch = (width<<1);
+#endif
new_size = dstPitch * height;
new_size = new_size + 0x1f; /* for aligning */
@@ -3510,7 +3577,7 @@ RADEONPutVideo(
RADEONFillKeyHelper(pDraw, pPriv->colorKey, clipBoxes);
}
- RADEONDisplayVideo(pScrn, pPriv, id, offset1+top*srcPitch, offset2+top*srcPitch,
+ RADEONDisplayVideo(pScrn, crtc, pPriv, id, offset1+top*srcPitch, offset2+top*srcPitch,
offset3+top*srcPitch, offset4+top*srcPitch, offset1+top*srcPitch,
offset2+top*srcPitch, width, height, dstPitch*mult/2,
xa, xb, ya, &dstBox, src_w, src_h*mult/2, drw_w, drw_h, pPriv->overlay_deinterlacing_method);
diff --git a/src/radeon_video.h b/src/radeon_video.h
index b6d5d2d9..072f40e1 100644
--- a/src/radeon_video.h
+++ b/src/radeon_video.h
@@ -11,6 +11,8 @@
#include "generic_bus.h"
#include "theatre.h"
+#include "xf86Crtc.h"
+
/* Xvideo port struct */
typedef struct {
CARD32 transform_index;
@@ -40,7 +42,7 @@ typedef struct {
CARD8 tuner_type;
MSP3430Ptr msp3430;
TDA9885Ptr tda9885;
- UDA1380Ptr uda1380;
+ UDA1380Ptr uda1380;
/* VIP bus and devices */
GENERIC_BUS_Ptr VIP;
@@ -77,7 +79,7 @@ typedef struct {
Time offTime;
Time freeTime;
Bool autopaint_colorkey;
- Bool crt2; /* 0=CRT1, 1=CRT2 */
+ xf86CrtcPtr desired_crtc;
#ifdef USE_EXA
int size;
diff --git a/src/theatre.c b/src/theatre.c
index 0a635fa7..a5aadfb3 100644
--- a/src/theatre.c
+++ b/src/theatre.c
@@ -1796,7 +1796,9 @@ void RT_SetConnector (TheatrePtr t, CARD16 wConnector, int tunerFlag)
counter++;
}
dwTempContrast = ReadRT_fld (fld_LP_CONTRAST);
- if(counter>=10000)xf86DrvMsg(t->VIP->scrnIndex, X_INFO, "Rage Theatre: timeout waiting for line count (%ld)\n", ReadRT_fld (fld_VS_LINE_COUNT));
+ if(counter>=10000)xf86DrvMsg(t->VIP->scrnIndex, X_INFO,
+ "Rage Theatre: timeout waiting for line count (%u)\n",
+ (unsigned)ReadRT_fld (fld_VS_LINE_COUNT));
WriteRT_fld (fld_LP_CONTRAST, 0x0);
@@ -1851,7 +1853,9 @@ void RT_SetConnector (TheatrePtr t, CARD16 wConnector, int tunerFlag)
counter++;
}
WriteRT_fld (fld_LP_CONTRAST, dwTempContrast);
- if(counter>=10000)xf86DrvMsg(t->VIP->scrnIndex, X_INFO, "Rage Theatre: timeout waiting for line count (%ld)\n", ReadRT_fld (fld_VS_LINE_COUNT));
+ if(counter>=10000)xf86DrvMsg(t->VIP->scrnIndex, X_INFO,
+ "Rage Theatre: timeout waiting for line count (%u)\n",
+ (unsigned)ReadRT_fld (fld_VS_LINE_COUNT));
@@ -1942,7 +1946,8 @@ void DumpRageTheatreRegs(TheatrePtr t)
for(i=0;i<0x900;i+=4)
{
RT_regr(i, &data);
- xf86DrvMsg(t->VIP->scrnIndex, X_INFO, "register 0x%04x is equal to 0x%08lx\n", i, data);
+ xf86DrvMsg(t->VIP->scrnIndex, X_INFO,
+ "register 0x%04x is equal to 0x%08x\n", i, (unsigned)data);
}
}
@@ -2147,7 +2152,9 @@ void DumpRageTheatreRegsByName(TheatrePtr t)
for(i=0; rt_reg_list[i].name!=NULL;i++){
RT_regr(rt_reg_list[i].addr, &data);
- xf86DrvMsg(t->VIP->scrnIndex, X_INFO, "register (0x%04lx) %s is equal to 0x%08lx\n", rt_reg_list[i].addr, rt_reg_list[i].name, data);
+ xf86DrvMsg(t->VIP->scrnIndex, X_INFO,
+ "register (0x%04lx) %s is equal to 0x%08x\n",
+ rt_reg_list[i].addr, rt_reg_list[i].name, (unsigned)data);
}
}
diff --git a/src/theatre200.c b/src/theatre200.c
index ff863959..672f01e8 100644
--- a/src/theatre200.c
+++ b/src/theatre200.c
@@ -1799,10 +1799,12 @@ void RT_SetConnector (TheatrePtr t, CARD16 wConnector, int tunerFlag)
t->wConnector = wConnector;
theatre_read(t, VIP_GPIO_CNTL, &data);
- xf86DrvMsg(t->VIP->scrnIndex,X_INFO,"VIP_GPIO_CNTL: %lx\n", data);
+ xf86DrvMsg(t->VIP->scrnIndex,X_INFO,"VIP_GPIO_CNTL: %x\n",
+ (unsigned)data);
theatre_read(t, VIP_GPIO_INOUT, &data);
- xf86DrvMsg(t->VIP->scrnIndex,X_INFO,"VIP_GPIO_INOUT: %lx\n", data);
+ xf86DrvMsg(t->VIP->scrnIndex,X_INFO,"VIP_GPIO_INOUT: %x\n",
+ (unsigned)data);
switch (wConnector)
{
@@ -1851,10 +1853,12 @@ void RT_SetConnector (TheatrePtr t, CARD16 wConnector, int tunerFlag)
}
theatre_read(t, VIP_GPIO_CNTL, &data);
- xf86DrvMsg(t->VIP->scrnIndex,X_INFO,"VIP_GPIO_CNTL: %lx\n", data);
+ xf86DrvMsg(t->VIP->scrnIndex,X_INFO,"VIP_GPIO_CNTL: %x\n",
+ (unsigned)data);
theatre_read(t, VIP_GPIO_INOUT, &data);
- xf86DrvMsg(t->VIP->scrnIndex,X_INFO,"VIP_GPIO_INOUT: %lx\n", data);
+ xf86DrvMsg(t->VIP->scrnIndex,X_INFO,"VIP_GPIO_INOUT: %x\n",
+ (unsigned)data);
dsp_configure_i2s_port(t, 0, 0, 0);
@@ -2007,7 +2011,8 @@ void DumpRageTheatreRegs(TheatrePtr t)
for(i=0;i<0x900;i+=4)
{
RT_regr(i, &data);
- xf86DrvMsg(t->VIP->scrnIndex, X_INFO, "register 0x%04x is equal to 0x%08lx\n", i, data);
+ xf86DrvMsg(t->VIP->scrnIndex, X_INFO,
+ "register 0x%04x is equal to 0x%08x\n", i, (unsigned)data);
}
}
@@ -2212,7 +2217,9 @@ void DumpRageTheatreRegsByName(TheatrePtr t)
for(i=0; rt_reg_list[i].name!=NULL;i++){
RT_regr(rt_reg_list[i].addr, &data);
- xf86DrvMsg(t->VIP->scrnIndex, X_INFO, "register (0x%04lx) %s is equal to 0x%08lx\n", rt_reg_list[i].addr, rt_reg_list[i].name, data);
+ xf86DrvMsg(t->VIP->scrnIndex, X_INFO,
+ "register (0x%04lx) %s is equal to 0x%08x\n",
+ rt_reg_list[i].addr, rt_reg_list[i].name, (unsigned)data);
}
}
diff --git a/src/theatre_detect.c b/src/theatre_detect.c
index e7548327..87709119 100644
--- a/src/theatre_detect.c
+++ b/src/theatre_detect.c
@@ -67,7 +67,7 @@ static Bool theatre_write(TheatrePtr t,CARD32 reg, CARD32 data)
TheatrePtr DetectTheatre(GENERIC_BUS_Ptr b)
{
TheatrePtr t;
- CARD32 i;
+ int i;
CARD32 val;
char s[20];
@@ -88,7 +88,9 @@ TheatrePtr DetectTheatre(GENERIC_BUS_Ptr b)
{
if(b->read(b, ((i & 0x03)<<14) | VIP_VIP_VENDOR_DEVICE_ID, 4, (CARD8 *)&val))
{
- if(val)xf86DrvMsg(b->scrnIndex, X_INFO, "Device %ld on VIP bus ids as 0x%08lx\n",i,val);
+ if(val)xf86DrvMsg(b->scrnIndex, X_INFO,
+ "Device %d on VIP bus ids as 0x%08x\n", i,
+ (unsigned)val);
if(t->theatre_num>=0)continue; /* already found one instance */
switch(val){
case RT100_ATI_ID:
@@ -101,10 +103,12 @@ TheatrePtr DetectTheatre(GENERIC_BUS_Ptr b)
break;
}
} else {
- xf86DrvMsg(b->scrnIndex, X_INFO, "No response from device %ld on VIP bus\n",i);
+ xf86DrvMsg(b->scrnIndex, X_INFO, "No response from device %d on VIP bus\n",i);
}
}
- if(t->theatre_num>=0)xf86DrvMsg(b->scrnIndex, X_INFO, "Detected Rage Theatre as device %d on VIP bus with id 0x%08lx\n",t->theatre_num,t->theatre_id);
+ if(t->theatre_num>=0)xf86DrvMsg(b->scrnIndex, X_INFO,
+ "Detected Rage Theatre as device %d on VIP bus with id 0x%08x\n",
+ t->theatre_num, (unsigned)t->theatre_id);
if(t->theatre_num < 0)
{
@@ -113,7 +117,8 @@ TheatrePtr DetectTheatre(GENERIC_BUS_Ptr b)
}
RT_regr(VIP_VIP_REVISION_ID, &val);
- xf86DrvMsg(b->scrnIndex, X_INFO, "Detected Rage Theatre revision %8.8lX\n", val);
+ xf86DrvMsg(b->scrnIndex, X_INFO, "Detected Rage Theatre revision %8.8X\n",
+ (unsigned)val);
#if 0
DumpRageTheatreRegsByName(t);