summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortsi <tsi>2008-04-02 20:47:56 +0000
committertsi <tsi>2008-04-02 20:47:56 +0000
commit32a312b4fddbe8af2892a1d602b7c0446f9011b4 (patch)
tree7e093d44e558afd5235694eb140dd5cc2a7bae3f
parentc5ebdff80cf33d34c124a1ff71bb6c1e3d93bf7e (diff)
36. Rage 128 driver changes:
- Add support for dual head on Rage 128 Mobility's (X.Org, via OpenBSD's xenocara repository). - Don't use vgaHW if the video mode on server entry is found to be an accelerator (i.e. non-VGA) video mode (Marc La France). - Avoid hard-failed master aborts while attempting to read video BIOS (Marc La France).
-rw-r--r--programs/Xserver/hw/xfree86/CHANGELOG9
-rw-r--r--programs/Xserver/hw/xfree86/drivers/ati/r128.h57
-rw-r--r--programs/Xserver/hw/xfree86/drivers/ati/r128.man12
-rw-r--r--programs/Xserver/hw/xfree86/drivers/ati/r128_accel.c67
-rw-r--r--programs/Xserver/hw/xfree86/drivers/ati/r128_cursor.c62
-rw-r--r--programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c19
-rw-r--r--programs/Xserver/hw/xfree86/drivers/ati/r128_driver.c1771
-rw-r--r--programs/Xserver/hw/xfree86/drivers/ati/r128_probe.c52
-rw-r--r--programs/Xserver/hw/xfree86/drivers/ati/r128_probe.h17
-rw-r--r--programs/Xserver/hw/xfree86/drivers/ati/r128_reg.h91
-rw-r--r--programs/Xserver/hw/xfree86/drivers/ati/r128_version.h6
-rw-r--r--programs/Xserver/hw/xfree86/drivers/ati/r128_video.c8
12 files changed, 1629 insertions, 542 deletions
diff --git a/programs/Xserver/hw/xfree86/CHANGELOG b/programs/Xserver/hw/xfree86/CHANGELOG
index 25803d7ae..83287db9f 100644
--- a/programs/Xserver/hw/xfree86/CHANGELOG
+++ b/programs/Xserver/hw/xfree86/CHANGELOG
@@ -1,4 +1,11 @@
XFree86 4.7.99.15 (xx April 2008)
+ 36. Rage 128 driver changes:
+ - Add support for dual head on Rage 128 Mobility's (X.Org, via OpenBSD's
+ xenocara repository).
+ - Don't use vgaHW if the video mode on server entry is found to be an
+ accelerator (i.e. non-VGA) video mode (Marc La France).
+ - Avoid hard-failed master aborts while attempting to read video BIOS
+ (Marc La France).
35. Fix PCI resource relocation to avoid nullifying resources
(Marc La France).
34. In int10, do attempt to populate shadow system BIOS segments if there's
@@ -20697,4 +20704,4 @@ XFree86 3.0a (28 April 1994)
XFree86 3.0 (26 April 1994)
-$XFree86: xc/programs/Xserver/hw/xfree86/CHANGELOG,v 3.3943 2008/03/27 16:22:40 tsi Exp $
+$XFree86: xc/programs/Xserver/hw/xfree86/CHANGELOG,v 3.3944 2008/04/01 17:18:20 tsi Exp $
diff --git a/programs/Xserver/hw/xfree86/drivers/ati/r128.h b/programs/Xserver/hw/xfree86/drivers/ati/r128.h
index 955f851d7..399914005 100644
--- a/programs/Xserver/hw/xfree86/drivers/ati/r128.h
+++ b/programs/Xserver/hw/xfree86/drivers/ati/r128.h
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128.h,v 1.28tsi Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128.h,v 1.29tsi Exp $ */
/*
* Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario,
* Precision Insight, Inc., Cedar Park, Texas, and
@@ -134,6 +134,13 @@ typedef struct {
/* CRTC2 registers */
CARD32 crtc2_gen_cntl;
+ CARD32 crtc2_h_total_disp;
+ CARD32 crtc2_h_sync_strt_wid;
+ CARD32 crtc2_v_total_disp;
+ CARD32 crtc2_v_sync_strt_wid;
+ CARD32 crtc2_offset;
+ CARD32 crtc2_offset_cntl;
+ CARD32 crtc2_pitch;
/* Flat panel registers */
CARD32 fp_crtc_h_total_disp;
@@ -159,13 +166,29 @@ typedef struct {
CARD32 ppll_div_3;
CARD32 htotal_cntl;
+ /* Computed values for PLL2 */
+ CARD32 dot_clock_freq_2;
+ CARD32 pll_output_freq_2;
+ int feedback_div_2;
+ int post_div_2;
+
+ /* PLL2 registers */
+ CARD32 p2pll_ref_div;
+ CARD32 p2pll_div_0;
+ CARD32 htotal_cntl2;
+
/* DDA register */
CARD32 dda_config;
CARD32 dda_on_off;
+ /* DDA2 register */
+ CARD32 dda2_config;
+ CARD32 dda2_on_off;
+
/* Pallet */
Bool palette_valid;
CARD32 palette[256];
+ CARD32 palette2[256];
} R128SaveRec, *R128SavePtr;
typedef struct {
@@ -185,6 +208,16 @@ typedef struct {
DisplayModePtr mode;
} R128FBLayout;
+typedef enum
+{
+ MT_NONE,
+ MT_CRT,
+ MT_LCD,
+ MT_DFP,
+ MT_CTV,
+ MT_STV
+} R128MonitorType;
+
typedef struct {
EntityInfoPtr pEnt;
pciVideoPtr PciInfo;
@@ -301,7 +334,7 @@ typedef struct {
Bool IsPCI; /* Current card is a PCI card */
drmSize pciSize;
drm_handle_t pciMemHandle;
- unsigned char *PCI; /* Map */
+ drmAddress PCI; /* Map */
Bool allowPageFlip; /* Enable 3d page flipping */
Bool have3DWindows; /* Are there any 3d clients? */
@@ -310,7 +343,7 @@ typedef struct {
drmSize agpSize;
drm_handle_t agpMemHandle; /* Handle from drmAgpAlloc */
unsigned long agpOffset;
- unsigned char *AGP; /* Map */
+ drmAddress AGP; /* Map */
int agpMode;
Bool CCEInUse; /* CCE is currently active */
@@ -324,20 +357,20 @@ typedef struct {
drm_handle_t ringHandle; /* Handle from drmAddMap */
drmSize ringMapSize; /* Size of map */
int ringSize; /* Size of ring (in MB) */
- unsigned char *ring; /* Map */
+ drmAddress ring; /* Map */
int ringSizeLog2QW;
unsigned long ringReadOffset; /* Offset into AGP space */
drm_handle_t ringReadPtrHandle; /* Handle from drmAddMap */
drmSize ringReadMapSize; /* Size of map */
- unsigned char *ringReadPtr; /* Map */
+ drmAddress ringReadPtr; /* Map */
/* CCE vertex/indirect buffer data */
unsigned long bufStart; /* Offset into AGP space */
drm_handle_t bufHandle; /* Handle from drmAddMap */
drmSize bufMapSize; /* Size of map */
int bufSize; /* Size of buffers (in MB) */
- unsigned char *buf; /* Map */
+ drmAddress buf; /* Map */
int bufNumBufs; /* Number of buffers */
drmBufMapPtr buffers; /* Buffer map */
@@ -346,7 +379,7 @@ typedef struct {
drm_handle_t agpTexHandle; /* Handle from drmAddMap */
drmSize agpTexMapSize; /* Size of map */
int agpTexSize; /* Size of AGP tex space (in MB) */
- unsigned char *agpTex; /* Map */
+ drmAddress agpTex; /* Map */
int log2AGPTexGran;
/* CCE 2D accleration */
@@ -400,6 +433,16 @@ typedef struct {
I2CBusPtr pI2CBus;
CARD32 DDCReg;
+ /****** Added for dualhead support *******************/
+ Bool HasCRTC2; /* M3/M4 */
+ Bool IsSecondary; /* second Screen */
+ Bool IsPrimary; /* primary Screen */
+ Bool UseCRT; /* force use CRT port as primary */
+ Bool SwitchingMode;
+ R128MonitorType DisplayType; /* Monitor connected on */
+
+ Bool UseVGAHW;
+
} R128InfoRec, *R128InfoPtr;
#define R128WaitForFifo(pScrn, entries) \
diff --git a/programs/Xserver/hw/xfree86/drivers/ati/r128.man b/programs/Xserver/hw/xfree86/drivers/ati/r128.man
index 606b9d642..278a1b804 100644
--- a/programs/Xserver/hw/xfree86/drivers/ati/r128.man
+++ b/programs/Xserver/hw/xfree86/drivers/ati/r128.man
@@ -1,4 +1,4 @@
-.\" $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128.man,v 1.3 2001/06/01 02:10:05 dawes Exp $
+.\" $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128.man,v 1.4tsi Exp $
.\" shorthand for double quote that works everywhere.
.ds q \N'34'
.TH R128 __drivermansuffix__ __vendorversion__
@@ -19,7 +19,8 @@ full support for 8, 15, 16 and 24 bit pixel depths, hardware
acceleration of drawing primitives, hardware cursor, video modes up to
1800x1440 @ 70Hz, doublescan modes (e.g., 320x200 and 320x240), gamma
correction at all pixel depths, a fully programming dot clock and robust
-text mode restoration for VT switching.
+text mode restoration for VT switching. Dualhead is supported on M3/M4
+mobile chips.
.SH SUPPORTED HARDWARE
The
.B r128
@@ -124,6 +125,13 @@ are supported:
Enable or disable viewing offscreen cache memory. A
development debug option. Default: off.
+.PP
+.B Dualhead Note:
+The video BIOS on some laptops interacts strangely with dualhead.
+This can result in flickering and problems changing modes on crtc2.
+If you experience these problems, try toggling your laptop's video
+output switch (e.g. fn-f7, etc.) prior to starting X or switch to
+another VT and back.
.SH "SEE ALSO"
XFree86(1), XF86Config(__filemansuffix__), xf86config(1), Xserver(1), X(__miscmansuffix__)
.SH AUTHORS
diff --git a/programs/Xserver/hw/xfree86/drivers/ati/r128_accel.c b/programs/Xserver/hw/xfree86/drivers/ati/r128_accel.c
index e1026a0ab..cec9f3bd1 100644
--- a/programs/Xserver/hw/xfree86/drivers/ati/r128_accel.c
+++ b/programs/Xserver/hw/xfree86/drivers/ati/r128_accel.c
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_accel.c,v 1.20tsi Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_accel.c,v 1.21tsi Exp $ */
/*
* Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario,
* Precision Insight, Inc., Cedar Park, Texas, and
@@ -82,6 +82,7 @@
/* Driver data structures */
#include "r128.h"
#include "r128_reg.h"
+#include "r128_probe.h"
#ifdef XF86DRI
#include "r128_sarea.h"
#define _XF86DRI_SERVER_
@@ -117,6 +118,8 @@ static struct {
{ R128_ROP3_ONE, R128_ROP3_ONE } /* GXset */
};
+extern int gR128EntityIndex;
+
/* Flush all dirty data in the Pixel Cache to memory. */
void R128EngineFlush(ScrnInfoPtr pScrn)
{
@@ -240,17 +243,23 @@ void R128CCEWaitForIdle(ScrnInfoPtr pScrn)
i = 0;
do {
ret = drmCommandNone(info->drmFD, DRM_R128_CCE_IDLE);
- } while ( ret && errno == EBUSY && i++ < R128_IDLE_RETRY );
+ } while ( ret && errno == EBUSY && i++ < (R128_IDLE_RETRY * R128_IDLE_RETRY) );
if (ret && ret != -EBUSY) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"%s: CCE idle %d\n", __FUNCTION__, ret);
}
+ if (i > R128_IDLE_RETRY) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "%s: (DEBUG) CCE idle took i = %d\n", __FUNCTION__, i);
+ }
+
if (ret == 0) return;
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Idle timed out, resetting engine...\n");
+ R128CCE_STOP(pScrn, info);
R128EngineReset(pScrn);
/* Always restart the engine when doing CCE 2D acceleration */
@@ -1020,7 +1029,7 @@ void R128EngineInit(ScrnInfoPtr pScrn)
R128TRACE(("Pitch for acceleration = %d\n", info->pitch));
R128WaitForFifo(pScrn, 2);
- OUTREG(R128_DEFAULT_OFFSET, 0);
+ OUTREG(R128_DEFAULT_OFFSET, pScrn->fbOffset);
OUTREG(R128_DEFAULT_PITCH, info->pitch);
R128WaitForFifo(pScrn, 4);
@@ -1644,6 +1653,24 @@ void R128CCEReleaseIndirect( ScrnInfoPtr pScrn )
&indirect, sizeof(drmR128Indirect));
}
+/* This callback is required for multihead cards using XAA */
+static
+void R128RestoreCCEAccelState(ScrnInfoPtr pScrn)
+{
+ R128InfoPtr info = R128PTR(pScrn);
+/* unsigned char *R128MMIO = info->MMIO; needed for OUTREG below */
+ /*xf86DrvMsg(pScrn->scrnIndex, X_INFO, "===>RestoreCP\n");*/
+
+ R128WaitForFifo(pScrn, 1);
+/* is this needed on r128
+ OUTREG( R128_DEFAULT_OFFSET, info->frontPitchOffset);
+*/
+ R128WaitForIdle(pScrn);
+
+ /* FIXME: May need to restore other things,
+ like BKGD_CLK FG_CLK...*/
+}
+
static void R128CCEAccelInit(ScrnInfoPtr pScrn, XAAInfoRecPtr a)
{
R128InfoPtr info = R128PTR(pScrn);
@@ -1704,9 +1731,29 @@ static void R128CCEAccelInit(ScrnInfoPtr pScrn, XAAInfoRecPtr a)
| HARDWARE_PATTERN_PROGRAMMED_ORIGIN
| HARDWARE_PATTERN_SCREEN_ORIGIN
| BIT_ORDER_IN_BYTE_LSBFIRST);
+
+ if(!info->IsSecondary && xf86IsEntityShared(pScrn->entityList[0]))
+ a->RestoreAccelState = R128RestoreCCEAccelState;
}
#endif
+/* This callback is required for multihead cards using XAA */
+static
+void R128RestoreAccelState(ScrnInfoPtr pScrn)
+{
+ R128InfoPtr info = R128PTR(pScrn);
+ unsigned char *R128MMIO = info->MMIO;
+
+ R128WaitForFifo(pScrn, 2);
+ OUTREG(R128_DEFAULT_OFFSET, pScrn->fbOffset);
+ OUTREG(R128_DEFAULT_PITCH, info->pitch);
+
+ /* FIXME: May need to restore other things,
+ like BKGD_CLK FG_CLK...*/
+
+ R128WaitForIdle(pScrn);
+}
+
static void R128MMIOAccelInit(ScrnInfoPtr pScrn, XAAInfoRecPtr a)
{
R128InfoPtr info = R128PTR(pScrn);
@@ -1785,6 +1832,20 @@ static void R128MMIOAccelInit(ScrnInfoPtr pScrn, XAAInfoRecPtr a)
| LEFT_EDGE_CLIPPING
| LEFT_EDGE_CLIPPING_NEGATIVE_X
| SCANLINE_PAD_DWORD;
+
+ if(xf86IsEntityShared(pScrn->entityList[0]))
+ {
+ DevUnion* pPriv;
+ R128EntPtr pR128Ent;
+ pPriv = xf86GetEntityPrivate(pScrn->entityList[0], gR128EntityIndex);
+ pR128Ent = pPriv->ptr;
+
+ /*if there are more than one devices sharing this entity, we
+ have to assign this call back, otherwise the XAA will be
+ disabled */
+ if(pR128Ent->HasSecondary || pR128Ent->BypassSecondary)
+ a->RestoreAccelState = R128RestoreAccelState;
+ }
}
/* Initialize XAA for supported acceleration and also initialize the
diff --git a/programs/Xserver/hw/xfree86/drivers/ati/r128_cursor.c b/programs/Xserver/hw/xfree86/drivers/ati/r128_cursor.c
index 7527c3367..a4dc73959 100644
--- a/programs/Xserver/hw/xfree86/drivers/ati/r128_cursor.c
+++ b/programs/Xserver/hw/xfree86/drivers/ati/r128_cursor.c
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_cursor.c,v 1.5tsi Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_cursor.c,v 1.6tsi Exp $ */
/*
* Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario,
* Precision Insight, Inc., Cedar Park, Texas, and
@@ -72,8 +72,16 @@ static void R128SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
R128InfoPtr info = R128PTR(pScrn);
unsigned char *R128MMIO = info->MMIO;
- OUTREG(R128_CUR_CLR0, bg);
- OUTREG(R128_CUR_CLR1, fg);
+ if(info->IsSecondary)
+ {
+ OUTREG(R128_CUR2_CLR0, bg);
+ OUTREG(R128_CUR2_CLR1, fg);
+ }
+ else
+ {
+ OUTREG(R128_CUR_CLR0, bg);
+ OUTREG(R128_CUR_CLR1, fg);
+ }
}
/* Set cursor position to (x,y) with offset into cursor bitmap at
@@ -94,11 +102,25 @@ static void R128SetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
if (xorigin >= cursor->MaxWidth) xorigin = cursor->MaxWidth - 1;
if (yorigin >= cursor->MaxHeight) yorigin = cursor->MaxHeight - 1;
- OUTREG(R128_CUR_HORZ_VERT_OFF, R128_CUR_LOCK | (xorigin << 16) | yorigin);
- OUTREG(R128_CUR_HORZ_VERT_POSN, (R128_CUR_LOCK
+ if(!info->IsSecondary)
+ {
+ OUTREG(R128_CUR_HORZ_VERT_OFF, R128_CUR_LOCK | (xorigin << 16) | yorigin);
+ OUTREG(R128_CUR_HORZ_VERT_POSN, (R128_CUR_LOCK
| ((xorigin ? 0 : x) << 16)
| (yorigin ? 0 : y)));
- OUTREG(R128_CUR_OFFSET, info->cursor_start + yorigin * 16);
+ OUTREG(R128_CUR_OFFSET, info->cursor_start + yorigin * 16);
+ }
+ else
+ {
+ OUTREG(R128_CUR2_HORZ_VERT_OFF, (R128_CUR2_LOCK
+ | (xorigin << 16)
+ | yorigin));
+ OUTREG(R128_CUR2_HORZ_VERT_POSN, (R128_CUR2_LOCK
+ | ((xorigin ? 0 : x) << 16)
+ | (yorigin ? 0 : y)));
+ OUTREG(R128_CUR2_OFFSET,
+ info->cursor_start + pScrn->fbOffset + yorigin * 16);
+ }
}
/* Copy cursor image from `image' to video memory. R128SetCursorPosition
@@ -112,8 +134,16 @@ static void R128LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *image)
int y;
CARD32 save;
- save = INREG(R128_CRTC_GEN_CNTL);
- OUTREG(R128_CRTC_GEN_CNTL, save & (CARD32)~R128_CRTC_CUR_EN);
+ if(!info->IsSecondary)
+ {
+ save = INREG(R128_CRTC_GEN_CNTL);
+ OUTREG(R128_CRTC_GEN_CNTL, save & (CARD32)~R128_CRTC_CUR_EN);
+ }
+ else
+ {
+ save = INREG(R128_CRTC2_GEN_CNTL);
+ OUTREG(R128_CRTC2_GEN_CNTL, save & (CARD32)~R128_CRTC2_CUR_EN);
+ }
#if X_BYTE_ORDER == X_BIG_ENDIAN
switch(info->CurrentLayout.pixel_bytes) {
@@ -169,7 +199,11 @@ static void R128LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *image)
}
- OUTREG(R128_CRTC_GEN_CNTL, save);
+ if(!info->IsSecondary)
+ OUTREG(R128_CRTC_GEN_CNTL, save);
+ else
+ OUTREG(R128_CRTC2_GEN_CNTL, save);
+
}
/* Hide hardware cursor. */
@@ -178,7 +212,10 @@ static void R128HideCursor(ScrnInfoPtr pScrn)
R128InfoPtr info = R128PTR(pScrn);
unsigned char *R128MMIO = info->MMIO;
- OUTREGP(R128_CRTC_GEN_CNTL, 0, ~R128_CRTC_CUR_EN);
+ if(info->IsSecondary)
+ OUTREGP(R128_CRTC2_GEN_CNTL, 0, ~R128_CRTC2_CUR_EN);
+ else
+ OUTREGP(R128_CRTC_GEN_CNTL, 0, ~R128_CRTC_CUR_EN);
}
/* Show hardware cursor. */
@@ -187,7 +224,10 @@ static void R128ShowCursor(ScrnInfoPtr pScrn)
R128InfoPtr info = R128PTR(pScrn);
unsigned char *R128MMIO = info->MMIO;
- OUTREGP(R128_CRTC_GEN_CNTL, R128_CRTC_CUR_EN, ~R128_CRTC_CUR_EN);
+ if(info->IsSecondary)
+ OUTREGP(R128_CRTC2_GEN_CNTL, R128_CRTC2_CUR_EN, ~R128_CRTC2_CUR_EN);
+ else
+ OUTREGP(R128_CRTC_GEN_CNTL, R128_CRTC_CUR_EN, ~R128_CRTC_CUR_EN);
}
/* Determine if hardware cursor is in use. */
diff --git a/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c b/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c
index 27810b8a4..8dad7dbc0 100644
--- a/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c
+++ b/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c,v 1.33tsi Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c,v 1.34tsi Exp $ */
/*
* Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario,
* Precision Insight, Inc., Cedar Park, Texas, and
@@ -243,7 +243,7 @@ static Bool R128InitVisualConfigs(ScreenPtr pScreen)
}
pConfigs[i].auxBuffers = 0;
pConfigs[i].level = 0;
- if (accum || stencil) {
+ if (accum) {
pConfigs[i].visualRating = GLX_SLOW_CONFIG;
} else {
pConfigs[i].visualRating = GLX_NONE;
@@ -525,7 +525,7 @@ static Bool R128DRIAgpInit(R128InfoPtr info, ScreenPtr pScreen)
"[agp] ring handle = 0x%08lx\n", info->ringHandle);
if (drmMap(info->drmFD, info->ringHandle, info->ringMapSize,
- (drmAddressPtr)&info->ring) < 0) {
+ &info->ring) < 0) {
xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] Could not map ring\n");
return FALSE;
}
@@ -544,7 +544,7 @@ static Bool R128DRIAgpInit(R128InfoPtr info, ScreenPtr pScreen)
info->ringReadPtrHandle);
if (drmMap(info->drmFD, info->ringReadPtrHandle, info->ringReadMapSize,
- (drmAddressPtr)&info->ringReadPtr) < 0) {
+ &info->ringReadPtr) < 0) {
xf86DrvMsg(pScreen->myNum, X_ERROR,
"[agp] Could not map ring read ptr\n");
return FALSE;
@@ -564,7 +564,7 @@ static Bool R128DRIAgpInit(R128InfoPtr info, ScreenPtr pScreen)
info->bufHandle);
if (drmMap(info->drmFD, info->bufHandle, info->bufMapSize,
- (drmAddressPtr)&info->buf) < 0) {
+ &info->buf) < 0) {
xf86DrvMsg(pScreen->myNum, X_ERROR,
"[agp] Could not map vertex/indirect buffers\n");
return FALSE;
@@ -584,7 +584,7 @@ static Bool R128DRIAgpInit(R128InfoPtr info, ScreenPtr pScreen)
info->agpTexHandle);
if (drmMap(info->drmFD, info->agpTexHandle, info->agpTexMapSize,
- (drmAddressPtr)&info->agpTex) < 0) {
+ &info->agpTex) < 0) {
xf86DrvMsg(pScreen->myNum, X_ERROR,
"[agp] Could not map AGP texture map\n");
return FALSE;
@@ -669,7 +669,7 @@ static Bool R128DRIPciInit(R128InfoPtr info, ScreenPtr pScreen)
"[pci] ring handle = 0x%08lx\n", info->ringHandle);
if (drmMap(info->drmFD, info->ringHandle, info->ringMapSize,
- (drmAddressPtr)&info->ring) < 0) {
+ &info->ring) < 0) {
xf86DrvMsg(pScreen->myNum, X_ERROR, "[pci] Could not map ring\n");
return FALSE;
}
@@ -691,7 +691,7 @@ static Bool R128DRIPciInit(R128InfoPtr info, ScreenPtr pScreen)
info->ringReadPtrHandle);
if (drmMap(info->drmFD, info->ringReadPtrHandle, info->ringReadMapSize,
- (drmAddressPtr)&info->ringReadPtr) < 0) {
+ &info->ringReadPtr) < 0) {
xf86DrvMsg(pScreen->myNum, X_ERROR,
"[pci] Could not map ring read ptr\n");
return FALSE;
@@ -714,7 +714,7 @@ static Bool R128DRIPciInit(R128InfoPtr info, ScreenPtr pScreen)
info->bufHandle);
if (drmMap(info->drmFD, info->bufHandle, info->bufMapSize,
- (drmAddressPtr)&info->buf) < 0) {
+ &info->buf) < 0) {
xf86DrvMsg(pScreen->myNum, X_ERROR,
"[pci] Could not map vertex/indirect buffers\n");
return FALSE;
@@ -1297,6 +1297,7 @@ void R128DRICloseScreen(ScreenPtr pScreen)
if (info->irq) {
drmCtlUninstHandler(info->drmFD);
info->irq = 0;
+ info->gen_int_cntl = 0;
}
/* De-allocate vertex buffers */
diff --git a/programs/Xserver/hw/xfree86/drivers/ati/r128_driver.c b/programs/Xserver/hw/xfree86/drivers/ati/r128_driver.c
index b4768818b..842d2eb29 100644
--- a/programs/Xserver/hw/xfree86/drivers/ati/r128_driver.c
+++ b/programs/Xserver/hw/xfree86/drivers/ati/r128_driver.c
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_driver.c,v 1.97tsi Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_driver.c,v 1.98tsi Exp $ */
/*
* Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario,
* Precision Insight, Inc., Cedar Park, Texas, and
@@ -178,6 +178,7 @@ R128RAMRec R128RAM[] = { /* Memory Specifications
static const char *vgahwSymbols[] = {
"vgaHWFreeHWRec",
"vgaHWGetHWRec",
+ "vgaHWGetIOBase",
"vgaHWGetIndex",
"vgaHWLock",
"vgaHWRestore",
@@ -217,7 +218,6 @@ static const char *fbdevHWSymbols[] = {
static const char *ddcSymbols[] = {
"xf86PrintEDID",
- "xf86DoEDID_DDC1",
"xf86DoEDID_DDC2",
NULL
};
@@ -244,6 +244,7 @@ static const char *xaaSymbols[] = {
static const char *ramdacSymbols[] = {
"xf86CreateCursorInfoRec",
"xf86DestroyCursorInfoRec",
+ "xf86ForceHWCursor",
"xf86InitCursor",
NULL
};
@@ -346,6 +347,16 @@ void R128LoaderRefSymLists(ModuleDescPtr module)
NULL);
}
+extern int gR128EntityIndex;
+
+static R128EntPtr R128EntPriv(ScrnInfoPtr pScrn)
+{
+ DevUnion *pPriv;
+ R128InfoPtr info = R128PTR(pScrn);
+ pPriv = xf86GetEntityPrivate(info->pEnt->index, gR128EntityIndex);
+ return pPriv->ptr;
+}
+
/* Allocate our private R128InfoRec. */
static Bool R128GetRec(ScrnInfoPtr pScrn)
{
@@ -455,7 +466,7 @@ unsigned R128INPLL(ScrnInfoPtr pScrn, int addr)
R128InfoPtr info = R128PTR(pScrn);
unsigned char *R128MMIO = info->MMIO;
- OUTREG8(R128_CLOCK_CNTL_INDEX, addr & 0x1f);
+ OUTREG8(R128_CLOCK_CNTL_INDEX, addr & 0x3f);
return INREG(R128_CLOCK_CNTL_DATA);
}
@@ -489,10 +500,30 @@ static void R128Blank(ScrnInfoPtr pScrn)
{
R128InfoPtr info = R128PTR(pScrn);
unsigned char *R128MMIO = info->MMIO;
- if(info->isDFP)
- OUTREGP(R128_FP_GEN_CNTL, R128_FP_BLANK_DIS, ~R128_FP_BLANK_DIS);
+
+ if(!info->IsSecondary)
+ {
+ switch(info->DisplayType)
+ {
+ case MT_LCD:
+ OUTREGP(R128_LVDS_GEN_CNTL, R128_LVDS_DISPLAY_DIS,
+ ~R128_LVDS_DISPLAY_DIS);
+ break;
+ case MT_CRT:
+ OUTREGP(R128_CRTC_EXT_CNTL, R128_CRTC_DISPLAY_DIS, ~R128_CRTC_DISPLAY_DIS);
+ break;
+ case MT_DFP:
+ OUTREGP(R128_FP_GEN_CNTL, R128_FP_BLANK_DIS, ~R128_FP_BLANK_DIS);
+ break;
+ case MT_NONE:
+ default:
+ break;
+ }
+ }
else
- OUTREGP(R128_CRTC_EXT_CNTL, R128_CRTC_DISPLAY_DIS, ~R128_CRTC_DISPLAY_DIS);
+ {
+ OUTREGP(R128_CRTC2_GEN_CNTL, R128_CRTC2_DISP_DIS, ~R128_CRTC2_DISP_DIS);
+ }
}
/* Unblank screen. */
@@ -501,12 +532,39 @@ static void R128Unblank(ScrnInfoPtr pScrn)
R128InfoPtr info = R128PTR(pScrn);
unsigned char *R128MMIO = info->MMIO;
- if(info->isDFP)
- OUTREGP(R128_FP_GEN_CNTL, 0, ~R128_FP_BLANK_DIS);
+ if(!info->IsSecondary)
+ {
+ switch(info->DisplayType)
+ {
+ case MT_LCD:
+ OUTREGP(R128_LVDS_GEN_CNTL, 0,
+ ~R128_LVDS_DISPLAY_DIS);
+ break;
+ case MT_CRT:
+ OUTREGP(R128_CRTC_EXT_CNTL, 0, ~R128_CRTC_DISPLAY_DIS);
+ break;
+ case MT_DFP:
+ OUTREGP(R128_FP_GEN_CNTL, 0, ~R128_FP_BLANK_DIS);
+ break;
+ case MT_NONE:
+ default:
+ break;
+ }
+ }
else
- OUTREGP(R128_CRTC_EXT_CNTL, 0, ~(R128_CRTC_DISPLAY_DIS |
- R128_CRTC_VSYNC_DIS |
- R128_CRTC_HSYNC_DIS));
+ {
+ switch(info->DisplayType)
+ {
+ case MT_LCD:
+ case MT_DFP:
+ case MT_CRT:
+ OUTREGP(R128_CRTC2_GEN_CNTL, 0, ~R128_CRTC2_DISP_DIS);
+ break;
+ case MT_NONE:
+ default:
+ break;
+ }
+ }
}
/* Compute log base 2 of val. */
@@ -553,14 +611,23 @@ static Bool R128GetBIOSParameters(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
} else {
xf86ReadPciBIOS(0, info->PciTag, 0, info->VBIOS, R128_VBIOS_SIZE);
if (info->VBIOS[0] != 0x55 || info->VBIOS[1] != 0xaa) {
+ if (!xf86DomainHasBIOSSegments(xf86GetPciDomain(info->PciTag))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "x86 video BIOS not available\n");
+ xfree(info->VBIOS);
+ info->VBIOS = NULL;
+ return FALSE;
+ }
+
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Video BIOS not detected in PCI space!\n");
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Attempting to read Video BIOS from legacy ISA space!\n");
+ "Attempting to read Video BIOS from ISA space!\n");
info->BIOSAddr = 0x000c0000;
xf86ReadDomainMemory(info->PciTag, info->BIOSAddr, R128_VBIOS_SIZE, info->VBIOS);
}
}
+
if (info->VBIOS[0] != 0x55 || info->VBIOS[1] != 0xaa) {
info->BIOSAddr = 0x00000000;
xfree(info->VBIOS);
@@ -569,7 +636,62 @@ static Bool R128GetBIOSParameters(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
"Video BIOS not found!\n");
}
- if (info->VBIOS && info->HasPanelRegs) {
+ if (info->HasCRTC2) {
+ if (info->IsSecondary) {
+ /* there may be a way to detect this, for now, just assume
+ second head is CRT */
+ info->DisplayType = MT_CRT;
+
+ if (info->DisplayType > MT_NONE) {
+ DevUnion* pPriv;
+ R128EntPtr pR128Ent;
+ pPriv = xf86GetEntityPrivate(pScrn->entityList[0],
+ gR128EntityIndex);
+ pR128Ent = pPriv->ptr;
+ pR128Ent->HasSecondary = TRUE;
+ } else return FALSE;
+ } else {
+ /* really need some sort of detection here */
+ if (info->HasPanelRegs) {
+ info->DisplayType = MT_LCD;
+ } else if (info->isDFP) {
+ info->DisplayType = MT_DFP;
+ } else {
+ /* DVI port has no monitor connected, try CRT port.
+ If something on CRT port, treat it as primary */
+ if (xf86IsEntityShared(pScrn->entityList[0])) {
+ DevUnion* pPriv;
+ R128EntPtr pR128Ent;
+ pPriv = xf86GetEntityPrivate(pScrn->entityList[0],
+ gR128EntityIndex);
+ pR128Ent = pPriv->ptr;
+ pR128Ent->BypassSecondary = TRUE;
+ }
+
+ info->DisplayType = MT_CRT;
+#if 0
+ {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "No monitor detected!!!\n");
+ return FALSE;
+ }
+#endif
+ }
+ }
+ } else {
+ /* Regular Radeon ASIC, only one CRTC, but it could be
+ used for DFP with a DVI output, like AIW board */
+ if (info->isDFP)
+ info->DisplayType = MT_DFP;
+ else
+ info->DisplayType = MT_CRT;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%s Display == Type %d\n",
+ (info->IsSecondary ? "Secondary" : "Primary"),
+ info->DisplayType);
+
+ if (info->VBIOS && info->DisplayType == MT_LCD) {
info->FPBIOSstart = 0;
/* FIXME: There should be direct access to the start of the FP info
@@ -640,10 +762,10 @@ static Bool R128GetBIOSParameters(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
}
if (!info->PanelXRes || !info->PanelYRes) {
- info->HasPanelRegs = FALSE;
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Can't determine panel dimensions, and none specified. \
- Disabling programming of FP registers.\n");
+ info->HasPanelRegs = FALSE;
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Can't determine panel dimensions, and none specified.\n"
+ "\tDisabling programming of FP registers.\n");
}
return TRUE;
@@ -915,12 +1037,13 @@ static Bool R128PreInitConfig(ScrnInfoPtr pScrn)
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"\n\nWARNING: Forcing the driver to use/not use the flat panel registers\nmight damage your flat panel. Use at your *OWN* *RISK*.\n\n");
} else {
- info->isDFP = FALSE;
- info->isPro2 = FALSE;
+ info->isDFP = FALSE;
+ info->isPro2 = FALSE;
+ info->HasCRTC2 = FALSE;
switch (info->Chipset) {
/* R128 Pro and Pro2 can have DFP, we will deal with it.
No support for dual-head/xinerama yet.
- M3 can also have DFP, no support for now */
+ M3 can also have DFP, no support for now */
case PCI_CHIP_RAGE128TF:
case PCI_CHIP_RAGE128TL:
case PCI_CHIP_RAGE128TR:
@@ -966,7 +1089,11 @@ static Bool R128PreInitConfig(ScrnInfoPtr pScrn)
case PCI_CHIP_RAGE128LE:
case PCI_CHIP_RAGE128LF:
case PCI_CHIP_RAGE128MF:
- case PCI_CHIP_RAGE128ML: info->HasPanelRegs = TRUE; break;
+ case PCI_CHIP_RAGE128ML:
+ info->HasPanelRegs = TRUE;
+ /* which chips support dualhead? */
+ info->HasCRTC2 = TRUE;
+ break;
case PCI_CHIP_RAGE128RE:
case PCI_CHIP_RAGE128RF:
case PCI_CHIP_RAGE128RG:
@@ -1008,12 +1135,14 @@ static Bool R128PreInitConfig(ScrnInfoPtr pScrn)
config file setting. BIOS_5_SCRATCH holds the display device on flat
panel systems only. */
if (info->HasPanelRegs) {
- char *Display = xf86GetOptValString(info->Options, OPTION_DISPLAY);
+ char *Display = xf86GetOptValString(info->Options, OPTION_DISPLAY);
if (info->FBDev)
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Option \"Display\" ignored "
"(framebuffer device determines display type)\n");
+ else if (info->IsPrimary || info->IsSecondary)
+ info->BIOSDisplay = R128_DUALHEAD;
else if (!Display || !xf86NameCmp(Display, "FP"))
info->BIOSDisplay = R128_BIOS_DISPLAY_FP;
else if (!xf86NameCmp(Display, "BIOS"))
@@ -1070,13 +1199,35 @@ static Bool R128PreInitConfig(ScrnInfoPtr pScrn)
from = X_CONFIG;
pScrn->videoRam = dev->videoRam;
}
- pScrn->videoRam &= ~1023;
- info->FbMapSize = pScrn->videoRam * 1024;
+
xf86DrvMsg(pScrn->scrnIndex, from,
"VideoRAM: %d kByte (%s)\n", pScrn->videoRam, info->ram->name);
+ if (info->IsPrimary) {
+ pScrn->videoRam /= 2;
+ 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;
+
+
/* Flat panel (part 2) */
switch (info->BIOSDisplay) {
+ case R128_DUALHEAD:
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Dual display\n");
+ break;
case R128_BIOS_DISPLAY_FP:
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
"Using flat panel for display\n");
@@ -1203,7 +1354,7 @@ static Bool R128PreInitDDC(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
if (!pVbe) {
ret = FALSE;
} else {
- xf86SetDDCproperties(pScrn,xf86PrintEDID(vbeDoEDID(pVbe,pModule)));
+ xf86SetDDCproperties(pScrn,xf86PrintEDID(vbeDoEDID(pVbe,pModule)));
vbeFree(pVbe);
ret = TRUE;
}
@@ -1247,7 +1398,7 @@ R128I2CPutBits(I2CBusPtr b, int Clock, int data)
unsigned char *R128MMIO = info->MMIO;
val = INREG(info->DDCReg)
- & ~(CARD32)(R128_GPIO_MONID_EN_0 | R128_GPIO_MONID_EN_3);
+ & ~(CARD32)(R128_GPIO_MONID_EN_0 | R128_GPIO_MONID_EN_3);
val |= (Clock ? 0:R128_GPIO_MONID_EN_3);
val |= (data ? 0:R128_GPIO_MONID_EN_0);
OUTREG(info->DDCReg, val);
@@ -1260,10 +1411,10 @@ R128I2cInit(ScrnInfoPtr pScrn)
R128InfoPtr info = R128PTR(pScrn);
ModuleDescPtr pModule;
if ((pModule = xf86LoadSubModule(pScrn, "i2c")) )
- xf86LoaderModReqSymLists(pModule, i2cSymbols,NULL);
+ xf86LoaderModReqSymLists(pModule, i2cSymbols,NULL);
else{
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Failed to load i2c module\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Failed to load i2c module\n");
return FALSE;
}
@@ -1278,7 +1429,7 @@ R128I2cInit(ScrnInfoPtr pScrn)
info->pI2CBus->AcknTimeout = 5;
if (!xf86I2CBusInit(info->pI2CBus)) {
- return FALSE;
+ return FALSE;
}
return TRUE;
}
@@ -1293,47 +1444,49 @@ static Bool R128GetDFPInfo(ScrnInfoPtr pScrn)
unsigned char *R128MMIO = info->MMIO;
if(!R128I2cInit(pScrn)){
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "I2C initialization failed!\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "I2C initialization failed!\n");
}
OUTREG(info->DDCReg, (INREG(info->DDCReg)
- | R128_GPIO_MONID_MASK_0 | R128_GPIO_MONID_MASK_3));
+ | R128_GPIO_MONID_MASK_0 | R128_GPIO_MONID_MASK_3));
OUTREG(info->DDCReg, INREG(info->DDCReg)
- & ~(CARD32)(R128_GPIO_MONID_A_0 | R128_GPIO_MONID_A_3));
+ & ~(CARD32)(R128_GPIO_MONID_A_0 | R128_GPIO_MONID_A_3));
MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex, info->pI2CBus);
if(!MonInfo) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "No DFP detected\n");
- return FALSE;
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "No DFP detected\n");
+ return FALSE;
}
xf86SetDDCproperties(pScrn, MonInfo);
ddc = pScrn->monitor->DDC;
for(i=0; i<4; i++)
{
- if(ddc->det_mon[i].type == 0)
- {
- info->PanelXRes =
- ddc->det_mon[i].section.d_timings.h_active;
- info->PanelYRes =
- ddc->det_mon[i].section.d_timings.v_active;
-
- info->HOverPlus =
- ddc->det_mon[i].section.d_timings.h_sync_off;
- info->HSyncWidth =
- ddc->det_mon[i].section.d_timings.h_sync_width;
- info->HBlank =
- ddc->det_mon[i].section.d_timings.h_blanking;
- info->VOverPlus =
- ddc->det_mon[i].section.d_timings.v_sync_off;
- info->VSyncWidth =
- ddc->det_mon[i].section.d_timings.v_sync_width;
- info->VBlank =
- ddc->det_mon[i].section.d_timings.v_blanking;
- }
+ if((ddc->det_mon[i].type == 0) &&
+ (ddc->det_mon[i].section.d_timings.h_active > 0) &&
+ (ddc->det_mon[i].section.d_timings.v_active > 0))
+ {
+ info->PanelXRes =
+ ddc->det_mon[i].section.d_timings.h_active;
+ info->PanelYRes =
+ ddc->det_mon[i].section.d_timings.v_active;
+
+ info->HOverPlus =
+ ddc->det_mon[i].section.d_timings.h_sync_off;
+ info->HSyncWidth =
+ ddc->det_mon[i].section.d_timings.h_sync_width;
+ info->HBlank =
+ ddc->det_mon[i].section.d_timings.h_blanking;
+ info->VOverPlus =
+ ddc->det_mon[i].section.d_timings.v_sync_off;
+ info->VSyncWidth =
+ ddc->det_mon[i].section.d_timings.v_sync_width;
+ info->VBlank =
+ ddc->det_mon[i].section.d_timings.v_blanking;
+ }
}
return TRUE;
}
@@ -1345,120 +1498,120 @@ static void R128SetSyncRangeFromEdid(ScrnInfoPtr pScrn, int flag)
xf86MonPtr ddc = pScrn->monitor->DDC;
if(flag) /*HSync*/
{
- for(i=0; i<4; i++)
- {
- if(ddc->det_mon[i].type == DS_RANGES)
- {
- pScrn->monitor->nHsync = 1;
- pScrn->monitor->hsync[0].lo =
- ddc->det_mon[i].section.ranges.min_h;
- pScrn->monitor->hsync[0].hi =
- ddc->det_mon[i].section.ranges.max_h;
- return;
- }
- }
- /*if no sync ranges detected in detailed timing table,
- let's try to derive them from supported VESA modes
- Are we doing too much here!!!?
- **/
- i = 0;
- if(ddc->timings1.t1 & 0x02) /*800x600@56*/
- {
- pScrn->monitor->hsync[i].lo =
- pScrn->monitor->hsync[i].hi = 35.2;
- i++;
- }
- if(ddc->timings1.t1 & 0x04) /*640x480@75*/
- {
- pScrn->monitor->hsync[i].lo =
- pScrn->monitor->hsync[i].hi = 37.5;
- i++;
- }
- if((ddc->timings1.t1 & 0x08) || (ddc->timings1.t1 & 0x01))
- {
- pScrn->monitor->hsync[i].lo =
- pScrn->monitor->hsync[i].hi = 37.9;
- i++;
- }
- if(ddc->timings1.t2 & 0x40)
- {
- pScrn->monitor->hsync[i].lo =
- pScrn->monitor->hsync[i].hi = 46.9;
- i++;
- }
- if((ddc->timings1.t2 & 0x80) || (ddc->timings1.t2 & 0x08))
- {
- pScrn->monitor->hsync[i].lo =
- pScrn->monitor->hsync[i].hi = 48.1;
- i++;
- }
- if(ddc->timings1.t2 & 0x04)
- {
- pScrn->monitor->hsync[i].lo =
- pScrn->monitor->hsync[i].hi = 56.5;
- i++;
- }
- if(ddc->timings1.t2 & 0x02)
- {
- pScrn->monitor->hsync[i].lo =
- pScrn->monitor->hsync[i].hi = 60.0;
- i++;
- }
- if(ddc->timings1.t2 & 0x01)
- {
- pScrn->monitor->hsync[i].lo =
- pScrn->monitor->hsync[i].hi = 64.0;
- i++;
- }
- pScrn->monitor->nHsync = i;
+ for(i=0; i<4; i++)
+ {
+ if(ddc->det_mon[i].type == DS_RANGES)
+ {
+ pScrn->monitor->nHsync = 1;
+ pScrn->monitor->hsync[0].lo =
+ ddc->det_mon[i].section.ranges.min_h;
+ pScrn->monitor->hsync[0].hi =
+ ddc->det_mon[i].section.ranges.max_h;
+ return;
+ }
+ }
+ /*if no sync ranges detected in detailed timing table,
+ let's try to derive them from supported VESA modes
+ Are we doing too much here!!!?
+ **/
+ i = 0;
+ if(ddc->timings1.t1 & 0x02) /*800x600@56*/
+ {
+ pScrn->monitor->hsync[i].lo =
+ pScrn->monitor->hsync[i].hi = 35.2;
+ i++;
+ }
+ if(ddc->timings1.t1 & 0x04) /*640x480@75*/
+ {
+ pScrn->monitor->hsync[i].lo =
+ pScrn->monitor->hsync[i].hi = 37.5;
+ i++;
+ }
+ if((ddc->timings1.t1 & 0x08) || (ddc->timings1.t1 & 0x01))
+ {
+ pScrn->monitor->hsync[i].lo =
+ pScrn->monitor->hsync[i].hi = 37.9;
+ i++;
+ }
+ if(ddc->timings1.t2 & 0x40)
+ {
+ pScrn->monitor->hsync[i].lo =
+ pScrn->monitor->hsync[i].hi = 46.9;
+ i++;
+ }
+ if((ddc->timings1.t2 & 0x80) || (ddc->timings1.t2 & 0x08))
+ {
+ pScrn->monitor->hsync[i].lo =
+ pScrn->monitor->hsync[i].hi = 48.1;
+ i++;
+ }
+ if(ddc->timings1.t2 & 0x04)
+ {
+ pScrn->monitor->hsync[i].lo =
+ pScrn->monitor->hsync[i].hi = 56.5;
+ i++;
+ }
+ if(ddc->timings1.t2 & 0x02)
+ {
+ pScrn->monitor->hsync[i].lo =
+ pScrn->monitor->hsync[i].hi = 60.0;
+ i++;
+ }
+ if(ddc->timings1.t2 & 0x01)
+ {
+ pScrn->monitor->hsync[i].lo =
+ pScrn->monitor->hsync[i].hi = 64.0;
+ i++;
+ }
+ pScrn->monitor->nHsync = i;
}
else /*Vrefresh*/
{
- for(i=0; i<4; i++)
- {
- if(ddc->det_mon[i].type == DS_RANGES)
- {
- pScrn->monitor->nVrefresh = 1;
- pScrn->monitor->vrefresh[0].lo =
- ddc->det_mon[i].section.ranges.min_v;
- pScrn->monitor->vrefresh[0].hi =
- ddc->det_mon[i].section.ranges.max_v;
- return;
- }
- }
- i = 0;
- if(ddc->timings1.t1 & 0x02) /*800x600@56*/
- {
- pScrn->monitor->vrefresh[i].lo =
- pScrn->monitor->vrefresh[i].hi = 56;
- i++;
- }
- if((ddc->timings1.t1 & 0x01) || (ddc->timings1.t2 & 0x08))
- {
- pScrn->monitor->vrefresh[i].lo =
- pScrn->monitor->vrefresh[i].hi = 60;
- i++;
- }
- if(ddc->timings1.t2 & 0x04)
- {
- pScrn->monitor->vrefresh[i].lo =
- pScrn->monitor->vrefresh[i].hi = 70;
- i++;
- }
- if((ddc->timings1.t1 & 0x08) || (ddc->timings1.t2 & 0x80))
- {
- pScrn->monitor->vrefresh[i].lo =
- pScrn->monitor->vrefresh[i].hi = 72;
- i++;
- }
- if((ddc->timings1.t1 & 0x04) || (ddc->timings1.t2 & 0x40)
- || (ddc->timings1.t2 & 0x02) || (ddc->timings1.t2 & 0x01))
- {
- pScrn->monitor->vrefresh[i].lo =
- pScrn->monitor->vrefresh[i].hi = 75;
- i++;
- }
- pScrn->monitor->nVrefresh = i;
+ for(i=0; i<4; i++)
+ {
+ if(ddc->det_mon[i].type == DS_RANGES)
+ {
+ pScrn->monitor->nVrefresh = 1;
+ pScrn->monitor->vrefresh[0].lo =
+ ddc->det_mon[i].section.ranges.min_v;
+ pScrn->monitor->vrefresh[0].hi =
+ ddc->det_mon[i].section.ranges.max_v;
+ return;
+ }
+ }
+ i = 0;
+ if(ddc->timings1.t1 & 0x02) /*800x600@56*/
+ {
+ pScrn->monitor->vrefresh[i].lo =
+ pScrn->monitor->vrefresh[i].hi = 56;
+ i++;
+ }
+ if((ddc->timings1.t1 & 0x01) || (ddc->timings1.t2 & 0x08))
+ {
+ pScrn->monitor->vrefresh[i].lo =
+ pScrn->monitor->vrefresh[i].hi = 60;
+ i++;
+ }
+ if(ddc->timings1.t2 & 0x04)
+ {
+ pScrn->monitor->vrefresh[i].lo =
+ pScrn->monitor->vrefresh[i].hi = 70;
+ i++;
+ }
+ if((ddc->timings1.t1 & 0x08) || (ddc->timings1.t2 & 0x80))
+ {
+ pScrn->monitor->vrefresh[i].lo =
+ pScrn->monitor->vrefresh[i].hi = 72;
+ i++;
+ }
+ if((ddc->timings1.t1 & 0x04) || (ddc->timings1.t2 & 0x40)
+ || (ddc->timings1.t2 & 0x02) || (ddc->timings1.t2 & 0x01))
+ {
+ pScrn->monitor->vrefresh[i].lo =
+ pScrn->monitor->vrefresh[i].hi = 75;
+ i++;
+ }
+ pScrn->monitor->nVrefresh = i;
}
}
@@ -1467,7 +1620,7 @@ static void R128SetSyncRangeFromEdid(ScrnInfoPtr pScrn, int flag)
here is our own validation routine. All modes between
640<=XRes<=MaxRes and 480<=YRes<=MaxYRes will be permitted.
NOTE: RageProII doesn't support rmx, can only work with the
- standard modes the monitor can support (scale).
+ standard modes the monitor can support (scale).
************/
static int R128ValidateFPModes(ScrnInfoPtr pScrn)
@@ -1493,58 +1646,58 @@ static int R128ValidateFPModes(ScrnInfoPtr pScrn)
/* If no mode specified in config, we use native resolution*/
if(!pScrn->display->modes[0])
{
- pScrn->display->modes[0] = xnfalloc(16);
- sprintf(pScrn->display->modes[0], "%dx%d",
- info->PanelXRes, info->PanelYRes);
+ pScrn->display->modes[0] = xnfalloc(16);
+ sprintf(pScrn->display->modes[0], "%dx%d",
+ info->PanelXRes, info->PanelYRes);
}
for(i=0; pScrn->display->modes[i] != NULL; i++)
{
- if (sscanf(pScrn->display->modes[i], "%dx%d", &width, &height) == 2)
- {
-
- if(width < 640 || width > info->PanelXRes ||
- height < 480 || height > info->PanelYRes)
- {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Mode %s is out of range.\n"
- "Valid mode should be between 640x480-%dx%d\n",
- pScrn->display->modes[i], info->PanelXRes, info->PanelYRes);
- continue;
- }
-
- new = xnfcalloc(1, sizeof(DisplayModeRec));
- new->prev = last;
- new->name = xnfalloc(strlen(pScrn->display->modes[i]) + 1);
- strcpy(new->name, pScrn->display->modes[i]);
- new->HDisplay = new->CrtcHDisplay = width;
- new->VDisplay = new->CrtcVDisplay = height;
-
- ddc = pScrn->monitor->DDC;
- for(j=0; j<DET_TIMINGS; j++)
- {
- /*We use native mode clock only*/
- if(ddc->det_mon[j].type == 0){
- new->Clock = ddc->det_mon[j].section.d_timings.clock / 1000;
- break;
- }
- }
-
- if(new->prev) new->prev->next = new;
- last = new;
- if(!first) first = new;
- pScrn->display->virtualX =
- pScrn->virtualX = MAX(pScrn->virtualX, width);
- pScrn->display->virtualY =
- pScrn->virtualY = MAX(pScrn->virtualY, height);
- count++;
- }
- else
- {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Mode name %s is invalid\n", pScrn->display->modes[i]);
- continue;
- }
+ if (sscanf(pScrn->display->modes[i], "%dx%d", &width, &height) == 2)
+ {
+
+ if(width < 640 || width > info->PanelXRes ||
+ height < 480 || height > info->PanelYRes)
+ {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Mode %s is out of range.\n"
+ "Valid mode should be between 640x480-%dx%d\n",
+ pScrn->display->modes[i], info->PanelXRes, info->PanelYRes);
+ continue;
+ }
+
+ new = xnfcalloc(1, sizeof(DisplayModeRec));
+ new->prev = last;
+ new->name = xnfalloc(strlen(pScrn->display->modes[i]) + 1);
+ strcpy(new->name, pScrn->display->modes[i]);
+ new->HDisplay = new->CrtcHDisplay = width;
+ new->VDisplay = new->CrtcVDisplay = height;
+
+ ddc = pScrn->monitor->DDC;
+ for(j=0; j<DET_TIMINGS; j++)
+ {
+ /*We use native mode clock only*/
+ if(ddc->det_mon[j].type == 0){
+ new->Clock = ddc->det_mon[j].section.d_timings.clock / 1000;
+ break;
+ }
+ }
+
+ if(new->prev) new->prev->next = new;
+ last = new;
+ if(!first) first = new;
+ pScrn->display->virtualX =
+ pScrn->virtualX = MAX(pScrn->virtualX, width);
+ pScrn->display->virtualY =
+ pScrn->virtualY = MAX(pScrn->virtualY, height);
+ count++;
+ }
+ else
+ {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Mode name %s is invalid\n", pScrn->display->modes[i]);
+ continue;
+ }
}
if(last)
@@ -1555,20 +1708,20 @@ static int R128ValidateFPModes(ScrnInfoPtr pScrn)
/*FIXME: May need to validate line pitch here*/
{
- int dummy = 0;
- switch(pScrn->depth / 8)
- {
- case 1:
- dummy = 128 - pScrn->virtualX % 128;
- break;
- case 2:
- dummy = 32 - pScrn->virtualX % 32;
- break;
- case 3:
- case 4:
- dummy = 16 - pScrn->virtualX % 16;
- }
- pScrn->displayWidth = pScrn->virtualX + dummy;
+ int dummy = 0;
+ switch(pScrn->depth / 8)
+ {
+ case 1:
+ dummy = 128 - pScrn->virtualX % 128;
+ break;
+ case 2:
+ dummy = 32 - pScrn->virtualX % 32;
+ break;
+ case 3:
+ case 4:
+ dummy = 16 - pScrn->virtualX % 16;
+ }
+ pScrn->displayWidth = pScrn->virtualX + dummy;
}
}
@@ -1587,66 +1740,70 @@ static Bool R128PreInitModes(ScrnInfoPtr pScrn)
ModuleDescPtr pModule;
if(info->isDFP) {
- R128MapMem(pScrn);
- info->BIOSDisplay = R128_BIOS_DISPLAY_FP;
- /* validate if DFP really connected. */
- if(!R128GetDFPInfo(pScrn)) {
- info->isDFP = FALSE;
- info->BIOSDisplay = R128_BIOS_DISPLAY_CRT;
- } else if(!info->isPro2) {
- /* RageProII doesn't support rmx, we can't use native-mode
- stretching for other non-native modes. It will rely on
- whatever VESA modes monitor can support. */
- modesFound = R128ValidateFPModes(pScrn);
- if(modesFound < 1) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "No valid mode found for this DFP/LCD\n");
- R128UnmapMem(pScrn);
- return FALSE;
-
- }
- }
- R128UnmapMem(pScrn);
+ R128MapMem(pScrn);
+ info->BIOSDisplay = R128_BIOS_DISPLAY_FP;
+ /* validate if DFP really connected. */
+ if(!R128GetDFPInfo(pScrn)) {
+ info->isDFP = FALSE;
+ info->BIOSDisplay = R128_BIOS_DISPLAY_CRT;
+ } else if(!info->isPro2) {
+ /* RageProII doesn't support rmx, we can't use native-mode
+ stretching for other non-native modes. It will rely on
+ whatever VESA modes monitor can support. */
+ modesFound = R128ValidateFPModes(pScrn);
+ if(modesFound < 1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "No valid mode found for this DFP/LCD\n");
+ R128UnmapMem(pScrn);
+ return FALSE;
+
+ }
+ }
+ R128UnmapMem(pScrn);
}
if(!info->isDFP || info->isPro2) {
/* 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;
- if (info->HasPanelRegs || info->isDFP) {
- clockRanges->interlaceAllowed = FALSE;
- clockRanges->doubleScanAllowed = FALSE;
- } else {
- clockRanges->interlaceAllowed = TRUE;
- clockRanges->doubleScanAllowed = TRUE;
- }
-
- 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, the Xconfigurator
- may not be able to probe both monitors correctly through
- vbe probe function (R128ProbeDDC). 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)
- R128SetSyncRangeFromEdid(pScrn, 1);
- if(pScrn->monitor->nVrefresh <= 0)
- R128SetSyncRangeFromEdid(pScrn, 0);
- }
-
- modesFound = xf86ValidateModes(pScrn,
+ 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;
+ if (info->HasPanelRegs || info->isDFP) {
+ clockRanges->interlaceAllowed = FALSE;
+ clockRanges->doubleScanAllowed = FALSE;
+ } else {
+ clockRanges->interlaceAllowed = TRUE;
+ clockRanges->doubleScanAllowed = TRUE;
+ }
+
+ 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, the Xconfigurator
+ may not be able to probe both monitors correctly through
+ vbe probe function (R128ProbeDDC). 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)
+ R128SetSyncRangeFromEdid(pScrn, 1);
+ if(pScrn->monitor->nVrefresh <= 0)
+ R128SetSyncRangeFromEdid(pScrn, 0);
+ }
+
+ modesFound = xf86ValidateModes(pScrn,
pScrn->monitor->Modes,
pScrn->display->modes,
clockRanges,
NULL, /* linePitches */
8 * 64, /* minPitch */
8 * 1024, /* maxPitch */
- 8 * 64, /* pitchInc */
+/*
+ * ATI docs say pitchInc must be 8 * 64, but this doesn't permit a pitch of
+ * 800 bytes, which is known to work on the Rage128 LF on clamshell iBooks
+ */
+ 8 * 32, /* pitchInc */
128, /* minHeight */
2048, /* maxHeight */
pScrn->display->virtualX,
@@ -1654,19 +1811,19 @@ static Bool R128PreInitModes(ScrnInfoPtr pScrn)
info->FbMapSize,
LOOKUP_BEST_REFRESH);
- if (modesFound < 1 && info->FBDev) {
+ if (modesFound < 1 && info->FBDev) {
fbdevHWUseBuildinMode(pScrn);
pScrn->displayWidth = fbdevHWGetLineLength(pScrn)/(pScrn->bitsPerPixel/8);
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;
- }
- xf86SetCrtcForModes(pScrn, 0);
+ if (modesFound == -1) return FALSE;
+ xf86PruneDriverModes(pScrn);
+ if (!modesFound || !pScrn->modes) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
+ return FALSE;
+ }
+ xf86SetCrtcForModes(pScrn, 0);
}
/* Set DPI */
pScrn->currentMode = pScrn->modes;
@@ -1865,7 +2022,8 @@ Bool R128PreInit(ScrnInfoPtr pScrn, int flags)
{
R128InfoPtr info;
xf86Int10InfoPtr pInt10 = NULL;
- ModuleDescPtr pModule;
+ ModuleDescPtr pModule;
+ unsigned char *R128MMIO = NULL;
R128TRACE(("R128PreInit\n"));
@@ -1875,21 +2033,49 @@ Bool R128PreInit(ScrnInfoPtr pScrn, int flags)
info = R128PTR(pScrn);
+ info->IsSecondary = FALSE;
+ info->IsPrimary = FALSE;
+ info->SwitchingMode = FALSE;
+
info->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
if (info->pEnt->location.type != BUS_PCI) goto fail;
+ if(xf86IsEntityShared(pScrn->entityList[0]))
+ {
+ if(xf86IsPrimInitDone(pScrn->entityList[0]))
+ {
+ DevUnion* pPriv;
+ R128EntPtr pR128Ent;
+ info->IsSecondary = TRUE;
+ pPriv = xf86GetEntityPrivate(pScrn->entityList[0],
+ gR128EntityIndex);
+ pR128Ent = pPriv->ptr;
+ if(pR128Ent->BypassSecondary) return FALSE;
+ pR128Ent->pSecondaryScrn = pScrn;
+ }
+ else
+ {
+ DevUnion* pPriv;
+ R128EntPtr pR128Ent;
+ info->IsPrimary = TRUE;
+ xf86SetPrimInitDone(pScrn->entityList[0]);
+ pPriv = xf86GetEntityPrivate(pScrn->entityList[0],
+ gR128EntityIndex);
+ pR128Ent = pPriv->ptr;
+ pR128Ent->pPrimaryScrn = pScrn;
+ pR128Ent->IsDRIEnabled = FALSE;
+ pR128Ent->BypassSecondary = FALSE;
+ pR128Ent->HasSecondary = FALSE;
+ pR128Ent->RestorePrimary = FALSE;
+ pR128Ent->IsSecondaryRestored = FALSE;
+ }
+ }
+
if (flags & PROBE_DETECT) {
R128ProbeDDC(pScrn, info->pEnt->index);
return TRUE;
}
- if (!(pModule = xf86LoadSubModule(pScrn, "vgahw"))) return FALSE;
- xf86LoaderModReqSymLists(pModule, vgahwSymbols, NULL);
- if (!vgaHWGetHWRec(pScrn)) {
- R128FreeRec(pScrn);
- return FALSE;
- }
-
info->PciInfo = xf86GetPciInfoForEntity(info->pEnt->index);
info->PciTag = pciTag(info->PciInfo->bus,
info->PciInfo->device,
@@ -1919,15 +2105,15 @@ Bool R128PreInit(ScrnInfoPtr pScrn, int flags)
if (!R128PreInitWeight(pScrn)) goto fail;
if(xf86GetOptValInteger(info->Options, OPTION_VIDEO_KEY, &(info->videoKey))) {
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "video key set to 0x%x\n",
- info->videoKey);
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "video key set to 0x%x\n",
+ info->videoKey);
} else {
- info->videoKey = 0x1E;
+ info->videoKey = 0x1E;
}
if (xf86ReturnOptValBool(info->Options, OPTION_SHOW_CACHE, FALSE)) {
- info->showCache = TRUE;
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ShowCache enabled\n");
+ info->showCache = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ShowCache enabled\n");
}
if (xf86ReturnOptValBool(info->Options, OPTION_FBDEV, FALSE)) {
@@ -1949,6 +2135,28 @@ Bool R128PreInit(ScrnInfoPtr pScrn, int flags)
if (!info->FBDev)
if (!R128PreInitInt10(pScrn, &pInt10)) goto fail;
+ if (!R128MapMMIO(pScrn)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Memory map of MMIO region failed\n");
+ goto fail;
+ }
+
+ R128MMIO = info->MMIO;
+
+ /*
+ * Don't use vgaHW if the adapter is found to be in an accelerator video
+ * mode on entry, as vgaHW will not be able to save & restore video memory
+ * contents.
+ */
+ info->UseVGAHW = !(INREG(R128_CRTC_GEN_CNTL) & R128_CRTC_EXT_DISP_EN);
+ if (info->UseVGAHW) {
+ if (!(pModule = xf86LoadSubModule(pScrn, "vgahw"))) goto fail1;
+ xf86LoaderModReqSymLists(pModule, vgahwSymbols, NULL);
+ if (!vgaHWGetHWRec(pScrn)) goto fail1;
+
+ vgaHWGetIOBase(VGAHWPTR(pScrn));
+ }
+
if (!R128PreInitConfig(pScrn)) goto fail;
if (!R128GetBIOSParameters(pScrn, pInt10)) goto fail;
@@ -1980,9 +2188,12 @@ Bool R128PreInit(ScrnInfoPtr pScrn, int flags)
if (pInt10)
xf86FreeInt10(pInt10);
+ if (R128MMIO)
+ R128UnmapMMIO(pScrn);
+
return TRUE;
- fail:
+fail:
/* Pre-init failed. */
/* Free the video bios (if applicable) */
@@ -1991,11 +2202,17 @@ Bool R128PreInit(ScrnInfoPtr pScrn, int flags)
info->VBIOS = NULL;
}
+ if (info->UseVGAHW)
+ vgaHWFreeHWRec(pScrn);
+
+fail1:
/* Free int10 info */
if (pInt10)
xf86FreeInt10(pInt10);
- vgaHWFreeHWRec(pScrn);
+ if (R128MMIO)
+ R128UnmapMMIO(pScrn);
+
R128FreeRec(pScrn);
return FALSE;
}
@@ -2006,12 +2223,14 @@ static void R128LoadPalette(ScrnInfoPtr pScrn, int numColors,
{
R128InfoPtr info = R128PTR(pScrn);
unsigned char *R128MMIO = info->MMIO;
- int i;
+ int i, j;
int idx;
unsigned char r, g, b;
- /* Select palette 0 (main CRTC) if using FP-enabled chip */
- if (info->HasPanelRegs || info->isDFP) PAL_SELECT(0);
+ /* 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. */
@@ -2059,7 +2278,7 @@ R128BlockHandler(int i, pointer blockData, pointer pTimeout, pointer pReadmask)
#ifdef XF86DRI
if (info->directRenderingEnabled)
- FLUSH_RING();
+ FLUSH_RING();
#endif
pScreen->BlockHandler = info->BlockHandler;
@@ -2067,7 +2286,7 @@ R128BlockHandler(int i, pointer blockData, pointer pTimeout, pointer pReadmask)
pScreen->BlockHandler = R128BlockHandler;
if(info->VideoTimerCallback) {
- (*info->VideoTimerCallback)(pScrn, currentTime.milliseconds);
+ (*info->VideoTimerCallback)(pScrn, currentTime.milliseconds);
}
}
@@ -2090,6 +2309,7 @@ Bool R128ScreenInit(int scrnIndex, ScreenPtr pScreen,
if (!R128MapMem(pScrn)) return FALSE;
pScrn->fbOffset = 0;
+ if(info->IsSecondary) pScrn->fbOffset = pScrn->videoRam * 1024;
#ifdef XF86DRI
info->fbX = 0;
info->fbY = 0;
@@ -2143,7 +2363,30 @@ Bool R128ScreenInit(int scrnIndex, ScreenPtr pScreen,
info->CurrentLayout.pixel_bytes * 3 + 1023) / 1024);
info->directRenderingEnabled = FALSE;
} else {
- info->directRenderingEnabled = R128DRIScreenInit(pScreen);
+ if(info->IsSecondary)
+ info->directRenderingEnabled = FALSE;
+ else
+ {
+ /* Xinerama has sync problem with DRI, disable it for now */
+ if(xf86IsEntityShared(pScrn->entityList[0]))
+ {
+ DevUnion* pPriv;
+ R128EntPtr pR128Ent;
+ info->directRenderingEnabled = FALSE;
+ xf86DrvMsg(scrnIndex, X_WARNING,
+ "Direct Rendering Disabled -- "
+ "Dual-head configuration is not working with DRI "
+ "at present.\nPlease use only one Device/Screen "
+ "section in your XFConfig file.\n");
+ pPriv = xf86GetEntityPrivate(pScrn->entityList[0],
+ gR128EntityIndex);
+ pR128Ent = pPriv->ptr;
+ pR128Ent->IsDRIEnabled = info->directRenderingEnabled;
+ }
+ else
+ info->directRenderingEnabled =
+ R128DRIScreenInit(pScreen);
+ }
}
}
#endif
@@ -2456,14 +2699,16 @@ Bool R128ScreenInit(int scrnIndex, ScreenPtr pScreen,
/* DPMS setup - FIXME: also for mirror mode in non-fbdev case? - Michel */
if (info->FBDev)
xf86DPMSInit(pScreen, fbdevHWDPMSSet, 0);
+
else {
- if (!info->HasPanelRegs || info->BIOSDisplay == R128_BIOS_DISPLAY_CRT)
- xf86DPMSInit(pScreen, R128DisplayPowerManagementSet, 0);
- else if (info->HasPanelRegs || info->BIOSDisplay == R128_BIOS_DISPLAY_FP)
+ if (info->DisplayType == MT_LCD)
xf86DPMSInit(pScreen, R128DisplayPowerManagementSetLCD, 0);
+ else
+ xf86DPMSInit(pScreen, R128DisplayPowerManagementSet, 0);
}
- R128InitVideo(pScreen);
+ if (!info->IsSecondary)
+ R128InitVideo(pScreen);
/* Provide SaveScreen */
pScreen->SaveScreen = R128SaveScreen;
@@ -2544,6 +2789,25 @@ static void R128RestoreCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
OUTREG(R128_CRTC_PITCH, restore->crtc_pitch);
}
+/* Write CRTC2 registers. */
+static void R128RestoreCrtc2Registers(ScrnInfoPtr pScrn,
+ R128SavePtr restore)
+{
+ R128InfoPtr info = R128PTR(pScrn);
+ unsigned char *R128MMIO = info->MMIO;
+
+ OUTREGP(R128_CRTC2_GEN_CNTL, restore->crtc2_gen_cntl,
+ R128_CRTC2_DISP_DIS);
+
+ OUTREG(R128_CRTC2_H_TOTAL_DISP, restore->crtc2_h_total_disp);
+ OUTREG(R128_CRTC2_H_SYNC_STRT_WID, restore->crtc2_h_sync_strt_wid);
+ OUTREG(R128_CRTC2_V_TOTAL_DISP, restore->crtc2_v_total_disp);
+ OUTREG(R128_CRTC2_V_SYNC_STRT_WID, restore->crtc2_v_sync_strt_wid);
+ OUTREG(R128_CRTC2_OFFSET, restore->crtc2_offset);
+ OUTREG(R128_CRTC2_OFFSET_CNTL, restore->crtc2_offset_cntl);
+ OUTREG(R128_CRTC2_PITCH, restore->crtc2_pitch);
+}
+
/* Write flat panel registers */
static void R128RestoreFPRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
{
@@ -2551,8 +2815,8 @@ static void R128RestoreFPRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
unsigned char *R128MMIO = info->MMIO;
CARD32 tmp;
-
- /*OUTREG(R128_CRTC2_GEN_CNTL, restore->crtc2_gen_cntl);*/
+ if (info->BIOSDisplay != R128_DUALHEAD)
+ OUTREG(R128_CRTC2_GEN_CNTL, restore->crtc2_gen_cntl);
OUTREG(R128_FP_HORZ_STRETCH, restore->fp_horz_stretch);
OUTREG(R128_FP_VERT_STRETCH, restore->fp_vert_stretch);
OUTREG(R128_FP_CRTC_H_TOTAL_DISP, restore->fp_crtc_h_total_disp);
@@ -2593,7 +2857,28 @@ static void R128PLLWriteUpdate(ScrnInfoPtr pScrn)
R128InfoPtr info = R128PTR(pScrn);
unsigned char *R128MMIO = info->MMIO;
- OUTPLLP(pScrn, R128_PPLL_REF_DIV, R128_PPLL_ATOMIC_UPDATE_W, 0xffff);
+ while (INPLL(pScrn, R128_PPLL_REF_DIV) & R128_PPLL_ATOMIC_UPDATE_R);
+
+ OUTPLLP(pScrn, R128_PPLL_REF_DIV, R128_PPLL_ATOMIC_UPDATE_W,
+ ~R128_PPLL_ATOMIC_UPDATE_W);
+
+}
+
+static void R128PLL2WaitForReadUpdateComplete(ScrnInfoPtr pScrn)
+{
+ while (INPLL(pScrn, R128_P2PLL_REF_DIV) & R128_P2PLL_ATOMIC_UPDATE_R);
+}
+
+static void R128PLL2WriteUpdate(ScrnInfoPtr pScrn)
+{
+ R128InfoPtr info = R128PTR(pScrn);
+ unsigned char *R128MMIO = info->MMIO;
+
+ while (INPLL(pScrn, R128_P2PLL_REF_DIV) & R128_P2PLL_ATOMIC_UPDATE_R);
+
+ OUTPLLP(pScrn, R128_P2PLL_REF_DIV,
+ R128_P2PLL_ATOMIC_UPDATE_W,
+ ~(R128_P2PLL_ATOMIC_UPDATE_W));
}
/* Write PLL registers. */
@@ -2602,33 +2887,44 @@ static void R128RestorePLLRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
R128InfoPtr info = R128PTR(pScrn);
unsigned char *R128MMIO = info->MMIO;
- OUTREGP(R128_CLOCK_CNTL_INDEX, R128_PLL_DIV_SEL, 0xffff);
+
+ OUTPLLP(pScrn, R128_VCLK_ECP_CNTL,
+ R128_VCLK_SRC_SEL_CPUCLK,
+ ~(R128_VCLK_SRC_SEL_MASK));
OUTPLLP(pScrn,
R128_PPLL_CNTL,
R128_PPLL_RESET
| R128_PPLL_ATOMIC_UPDATE_EN
| R128_PPLL_VGA_ATOMIC_UPDATE_EN,
- 0xffff);
+ ~(R128_PPLL_RESET
+ | R128_PPLL_ATOMIC_UPDATE_EN
+ | R128_PPLL_VGA_ATOMIC_UPDATE_EN));
- R128PLLWaitForReadUpdateComplete(pScrn);
+ OUTREGP(R128_CLOCK_CNTL_INDEX, R128_PLL_DIV_SEL, ~(R128_PLL_DIV_SEL));
+
+/* R128PLLWaitForReadUpdateComplete(pScrn);*/
OUTPLLP(pScrn, R128_PPLL_REF_DIV,
restore->ppll_ref_div, ~R128_PPLL_REF_DIV_MASK);
- R128PLLWriteUpdate(pScrn);
+/* R128PLLWriteUpdate(pScrn);
- R128PLLWaitForReadUpdateComplete(pScrn);
+ R128PLLWaitForReadUpdateComplete(pScrn);*/
OUTPLLP(pScrn, R128_PPLL_DIV_3,
restore->ppll_div_3, ~R128_PPLL_FB3_DIV_MASK);
- R128PLLWriteUpdate(pScrn);
+/* R128PLLWriteUpdate(pScrn);*/
OUTPLLP(pScrn, R128_PPLL_DIV_3,
restore->ppll_div_3, ~R128_PPLL_POST3_DIV_MASK);
- R128PLLWriteUpdate(pScrn);
+ R128PLLWriteUpdate(pScrn);
R128PLLWaitForReadUpdateComplete(pScrn);
+
OUTPLL(R128_HTOTAL_CNTL, restore->htotal_cntl);
- R128PLLWriteUpdate(pScrn);
+/* R128PLLWriteUpdate(pScrn);*/
- OUTPLLP(pScrn, R128_PPLL_CNTL, 0, ~R128_PPLL_RESET);
+ OUTPLLP(pScrn, R128_PPLL_CNTL, 0, ~(R128_PPLL_RESET
+ | R128_PPLL_SLEEP
+ | R128_PPLL_ATOMIC_UPDATE_EN
+ | R128_PPLL_VGA_ATOMIC_UPDATE_EN));
R128TRACE(("Wrote: 0x%08x 0x%08x 0x%08x (0x%08x)\n",
restore->ppll_ref_div,
@@ -2639,6 +2935,82 @@ static void R128RestorePLLRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
restore->ppll_ref_div & R128_PPLL_REF_DIV_MASK,
restore->ppll_div_3 & R128_PPLL_FB3_DIV_MASK,
(restore->ppll_div_3 & R128_PPLL_POST3_DIV_MASK) >> 16));
+
+ usleep(5000); /* let the clock lock */
+
+ OUTPLLP(pScrn, R128_VCLK_ECP_CNTL,
+ R128_VCLK_SRC_SEL_PPLLCLK,
+ ~(R128_VCLK_SRC_SEL_MASK));
+
+}
+
+/* Write PLL2 registers. */
+static void R128RestorePLL2Registers(ScrnInfoPtr pScrn, R128SavePtr restore)
+{
+ R128InfoPtr info = R128PTR(pScrn);
+ unsigned char *R128MMIO = info->MMIO;
+
+ OUTPLLP(pScrn, R128_V2CLK_VCLKTV_CNTL,
+ R128_V2CLK_SRC_SEL_CPUCLK,
+ ~R128_V2CLK_SRC_SEL_MASK);
+
+ OUTPLLP(pScrn,
+ R128_P2PLL_CNTL,
+ R128_P2PLL_RESET
+ | R128_P2PLL_ATOMIC_UPDATE_EN
+ | R128_P2PLL_VGA_ATOMIC_UPDATE_EN,
+ ~(R128_P2PLL_RESET
+ | R128_P2PLL_ATOMIC_UPDATE_EN
+ | R128_P2PLL_VGA_ATOMIC_UPDATE_EN));
+
+#if 1
+ OUTREGP(R128_CLOCK_CNTL_INDEX, 0, R128_PLL2_DIV_SEL_MASK);
+#endif
+
+ /*R128PLL2WaitForReadUpdateComplete(pScrn);*/
+
+ OUTPLLP(pScrn, R128_P2PLL_REF_DIV, restore->p2pll_ref_div, ~R128_P2PLL_REF_DIV_MASK);
+
+/* R128PLL2WriteUpdate(pScrn);
+ R128PLL2WaitForReadUpdateComplete(pScrn);*/
+
+ OUTPLLP(pScrn, R128_P2PLL_DIV_0,
+ restore->p2pll_div_0, ~R128_P2PLL_FB0_DIV_MASK);
+
+/* R128PLL2WriteUpdate(pScrn);
+ R128PLL2WaitForReadUpdateComplete(pScrn);*/
+
+ OUTPLLP(pScrn, R128_P2PLL_DIV_0,
+ restore->p2pll_div_0, ~R128_P2PLL_POST0_DIV_MASK);
+
+ R128PLL2WriteUpdate(pScrn);
+ R128PLL2WaitForReadUpdateComplete(pScrn);
+
+ OUTPLL(R128_HTOTAL2_CNTL, restore->htotal_cntl2);
+
+/* R128PLL2WriteUpdate(pScrn);*/
+
+ OUTPLLP(pScrn, R128_P2PLL_CNTL, 0, ~(R128_P2PLL_RESET
+ | R128_P2PLL_SLEEP
+ | R128_P2PLL_ATOMIC_UPDATE_EN
+ | R128_P2PLL_VGA_ATOMIC_UPDATE_EN));
+
+ R128TRACE(("Wrote: 0x%08x 0x%08x 0x%08x (0x%08x)\n",
+ restore->p2pll_ref_div,
+ restore->p2pll_div_0,
+ restore->htotal_cntl2,
+ INPLL(pScrn, RADEON_P2PLL_CNTL)));
+ R128TRACE(("Wrote: rd=%d, fd=%d, pd=%d\n",
+ restore->p2pll_ref_div & RADEON_P2PLL_REF_DIV_MASK,
+ restore->p2pll_div_0 & RADEON_P2PLL_FB3_DIV_MASK,
+ (restore->p2pll_div_0 & RADEON_P2PLL_POST3_DIV_MASK) >>16));
+
+ usleep(5000); /* Let the clock to lock */
+
+ OUTPLLP(pScrn, R128_V2CLK_VCLKTV_CNTL,
+ R128_V2CLK_SRC_SEL_P2PLLCLK,
+ ~R128_V2CLK_SRC_SEL_MASK);
+
}
/* Write DDA registers. */
@@ -2651,6 +3023,16 @@ static void R128RestoreDDARegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
OUTREG(R128_DDA_ON_OFF, restore->dda_on_off);
}
+/* Write DDA registers. */
+static void R128RestoreDDA2Registers(ScrnInfoPtr pScrn, R128SavePtr restore)
+{
+ R128InfoPtr info = R128PTR(pScrn);
+ unsigned char *R128MMIO = info->MMIO;
+
+ OUTREG(R128_DDA2_CONFIG, restore->dda2_config);
+ OUTREG(R128_DDA2_ON_OFF, restore->dda2_on_off);
+}
+
/* Write palette data. */
static void R128RestorePalette(ScrnInfoPtr pScrn, R128SavePtr restore)
{
@@ -2660,27 +3042,113 @@ static void R128RestorePalette(ScrnInfoPtr pScrn, R128SavePtr restore)
if (!restore->palette_valid) return;
- /* Select palette 0 (main CRTC) if using FP-enabled chip */
- if (info->HasPanelRegs || info->isDFP) PAL_SELECT(0);
+ PAL_SELECT(1);
+ OUTPAL_START(0);
+ for (i = 0; i < 256; i++) {
+ R128WaitForFifo(pScrn, 32); /* delay */
+ OUTPAL_NEXT_CARD32(restore->palette2[i]);
+ }
+ PAL_SELECT(0);
OUTPAL_START(0);
- for (i = 0; i < 256; i++) OUTPAL_NEXT_CARD32(restore->palette[i]);
+ for (i = 0; i < 256; i++) {
+ R128WaitForFifo(pScrn, 32); /* delay */
+ OUTPAL_NEXT_CARD32(restore->palette[i]);
+ }
+
}
/* Write out state to define a new video mode. */
static void R128RestoreMode(ScrnInfoPtr pScrn, R128SavePtr restore)
{
R128InfoPtr info = R128PTR(pScrn);
+ DevUnion* pPriv;
+ R128EntPtr pR128Ent;
+ static R128SaveRec restore0;
R128TRACE(("R128RestoreMode(%p)\n", restore));
- R128RestoreCommonRegisters(pScrn, restore);
- R128RestoreCrtcRegisters(pScrn, restore);
- if (!(info->HasPanelRegs) || info->BIOSDisplay == R128_BIOS_DISPLAY_CRT){
- R128RestorePLLRegisters(pScrn, restore);
+ if(!info->HasCRTC2)
+ {
+ R128RestoreCommonRegisters(pScrn, restore);
+ R128RestoreDDARegisters(pScrn, restore);
+ R128RestoreCrtcRegisters(pScrn, restore);
+ if((info->DisplayType == MT_DFP) ||
+ (info->DisplayType == MT_LCD))
+ {
+ R128RestoreFPRegisters(pScrn, restore);
+ }
+ R128RestorePLLRegisters(pScrn, restore);
+ return;
+ }
+
+ pPriv = xf86GetEntityPrivate(pScrn->entityList[0],
+ gR128EntityIndex);
+ pR128Ent = pPriv->ptr;
+
+
+ /*****
+ When changing mode with Dual-head card (VE/M6), 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.
+ *****/
+
+ if(info->IsSecondary)
+ {
+ if (!pR128Ent->RestorePrimary && !info->SwitchingMode)
+ R128RestoreCommonRegisters(pScrn, restore);
+ R128RestoreDDA2Registers(pScrn, restore);
+ R128RestoreCrtc2Registers(pScrn, restore);
+ R128RestorePLL2Registers(pScrn, restore);
+
+ if(info->SwitchingMode) return;
+
+ pR128Ent->IsSecondaryRestored = TRUE;
+
+ if(pR128Ent->RestorePrimary)
+ {
+ R128InfoPtr info0 = R128PTR(pR128Ent->pPrimaryScrn);
+ pR128Ent->RestorePrimary = FALSE;
+
+ R128RestoreCrtcRegisters(pScrn, &restore0);
+ if((info0->DisplayType == MT_DFP) ||
+ (info0->DisplayType == MT_LCD))
+ {
+ R128RestoreFPRegisters(pScrn, &restore0);
+ }
+
+ R128RestorePLLRegisters(pScrn, &restore0);
+ pR128Ent->IsSecondaryRestored = FALSE;
+
+ }
+ }
+ else
+ {
+ if (!pR128Ent->IsSecondaryRestored)
+ R128RestoreCommonRegisters(pScrn, restore);
+ R128RestoreDDARegisters(pScrn, restore);
+ if(!pR128Ent->HasSecondary || pR128Ent->IsSecondaryRestored
+ || info->SwitchingMode)
+ {
+ pR128Ent->IsSecondaryRestored = FALSE;
+ R128RestoreCrtcRegisters(pScrn, restore);
+ if((info->DisplayType == MT_DFP) ||
+ (info->DisplayType == MT_LCD))
+ {
+ R128RestoreFPRegisters(pScrn, restore);
+ }
+ R128RestorePLLRegisters(pScrn, restore);
+ }
+ else
+ {
+ memcpy(&restore0, restore, sizeof(restore0));
+ pR128Ent->RestorePrimary = TRUE;
+ }
}
- R128RestoreDDARegisters(pScrn, restore);
- if (info->HasPanelRegs || info->isDFP)
- R128RestoreFPRegisters(pScrn, restore);
R128RestorePalette(pScrn, restore);
}
@@ -2731,7 +3199,8 @@ static void R128SaveFPRegisters(ScrnInfoPtr pScrn, R128SavePtr save)
R128InfoPtr info = R128PTR(pScrn);
unsigned char *R128MMIO = info->MMIO;
- save->crtc2_gen_cntl = INREG(R128_CRTC2_GEN_CNTL);
+ if (info->BIOSDisplay != R128_DUALHEAD)
+ save->crtc2_gen_cntl = INREG(R128_CRTC2_GEN_CNTL);
save->fp_crtc_h_total_disp = INREG(R128_FP_CRTC_H_TOTAL_DISP);
save->fp_crtc_v_total_disp = INREG(R128_FP_CRTC_V_TOTAL_DISP);
save->fp_gen_cntl = INREG(R128_FP_GEN_CNTL);
@@ -2745,6 +3214,22 @@ static void R128SaveFPRegisters(ScrnInfoPtr pScrn, R128SavePtr save)
save->tmds_transmitter_cntl = INREG(R128_TMDS_TRANSMITTER_CNTL);
}
+/* Read CRTC2 registers. */
+static void R128SaveCrtc2Registers(ScrnInfoPtr pScrn, R128SavePtr save)
+{
+ R128InfoPtr info = R128PTR(pScrn);
+ unsigned char *R128MMIO = info->MMIO;
+
+ save->crtc2_gen_cntl = INREG(R128_CRTC2_GEN_CNTL);
+ save->crtc2_h_total_disp = INREG(R128_CRTC2_H_TOTAL_DISP);
+ save->crtc2_h_sync_strt_wid = INREG(R128_CRTC2_H_SYNC_STRT_WID);
+ save->crtc2_v_total_disp = INREG(R128_CRTC2_V_TOTAL_DISP);
+ save->crtc2_v_sync_strt_wid = INREG(R128_CRTC2_V_SYNC_STRT_WID);
+ save->crtc2_offset = INREG(R128_CRTC2_OFFSET);
+ save->crtc2_offset_cntl = INREG(R128_CRTC2_OFFSET_CNTL);
+ save->crtc2_pitch = INREG(R128_CRTC2_PITCH);
+}
+
/* Read PLL registers. */
static void R128SavePLLRegisters(ScrnInfoPtr pScrn, R128SavePtr save)
{
@@ -2762,6 +3247,23 @@ static void R128SavePLLRegisters(ScrnInfoPtr pScrn, R128SavePtr save)
(save->ppll_div_3 & R128_PPLL_POST3_DIV_MASK) >> 16));
}
+/* Read PLL2 registers. */
+static void R128SavePLL2Registers(ScrnInfoPtr pScrn, R128SavePtr save)
+{
+ save->p2pll_ref_div = INPLL(pScrn, R128_P2PLL_REF_DIV);
+ save->p2pll_div_0 = INPLL(pScrn, R128_P2PLL_DIV_0);
+ save->htotal_cntl2 = INPLL(pScrn, R128_HTOTAL2_CNTL);
+
+ R128TRACE(("Read: 0x%08x 0x%08x 0x%08x\n",
+ save->p2pll_ref_div,
+ save->p2pll_div_0,
+ save->htotal_cntl2));
+ R128TRACE(("Read: rd=%d, fd=%d, pd=%d\n",
+ save->p2pll_ref_div & R128_P2PLL_REF_DIV_MASK,
+ save->p2pll_div_0 & R128_P2PLL_FB0_DIV_MASK,
+ (save->p2pll_div_0 & R128_P2PLL_POST0_DIV_MASK) >> 16));
+}
+
/* Read DDA registers. */
static void R128SaveDDARegisters(ScrnInfoPtr pScrn, R128SavePtr save)
{
@@ -2772,6 +3274,16 @@ static void R128SaveDDARegisters(ScrnInfoPtr pScrn, R128SavePtr save)
save->dda_on_off = INREG(R128_DDA_ON_OFF);
}
+/* Read DDA2 registers. */
+static void R128SaveDDA2Registers(ScrnInfoPtr pScrn, R128SavePtr save)
+{
+ R128InfoPtr info = R128PTR(pScrn);
+ unsigned char *R128MMIO = info->MMIO;
+
+ save->dda2_config = INREG(R128_DDA2_CONFIG);
+ save->dda2_on_off = INREG(R128_DDA2_ON_OFF);
+}
+
/* Read palette data. */
static void R128SavePalette(ScrnInfoPtr pScrn, R128SavePtr save)
{
@@ -2779,9 +3291,10 @@ static void R128SavePalette(ScrnInfoPtr pScrn, R128SavePtr save)
unsigned char *R128MMIO = info->MMIO;
int i;
- /* Select palette 0 (main CRTC) if using FP-enabled chip */
- if (info->HasPanelRegs || info->isDFP) PAL_SELECT(0);
-
+ PAL_SELECT(1);
+ INPAL_START(0);
+ for (i = 0; i < 256; i++) save->palette2[i] = INPAL_NEXT();
+ PAL_SELECT(0);
INPAL_START(0);
for (i = 0; i < 256; i++) save->palette[i] = INPAL_NEXT();
save->palette_valid = TRUE;
@@ -2790,15 +3303,29 @@ static void R128SavePalette(ScrnInfoPtr pScrn, R128SavePtr save)
/* Save state that defines current video mode. */
static void R128SaveMode(ScrnInfoPtr pScrn, R128SavePtr save)
{
+ R128InfoPtr info = R128PTR(pScrn);
+
R128TRACE(("R128SaveMode(%p)\n", save));
- R128SaveCommonRegisters(pScrn, save);
- R128SaveCrtcRegisters(pScrn, save);
- if (R128PTR(pScrn)->HasPanelRegs || R128PTR(pScrn)->isDFP)
- R128SaveFPRegisters(pScrn, save);
- R128SavePLLRegisters(pScrn, save);
- R128SaveDDARegisters(pScrn, save);
- R128SavePalette(pScrn, save);
+ if(info->IsSecondary)
+ {
+ R128SaveCrtc2Registers(pScrn, save);
+ R128SavePLL2Registers(pScrn, save);
+ R128SaveDDA2Registers(pScrn, save);
+ }
+ else
+ {
+ R128SaveCommonRegisters(pScrn, save);
+ R128SaveCrtcRegisters(pScrn, save);
+ if((info->DisplayType == MT_DFP) ||
+ (info->DisplayType == MT_LCD))
+ {
+ R128SaveFPRegisters(pScrn, save);
+ }
+ R128SavePLLRegisters(pScrn, save);
+ R128SaveDDARegisters(pScrn, save);
+ R128SavePalette(pScrn, save);
+ }
R128TRACE(("R128SaveMode returns %p\n", save));
}
@@ -2809,24 +3336,30 @@ static void R128Save(ScrnInfoPtr pScrn)
R128InfoPtr info = R128PTR(pScrn);
unsigned char *R128MMIO = info->MMIO;
R128SavePtr save = &info->SavedReg;
- vgaHWPtr hwp = VGAHWPTR(pScrn);
R128TRACE(("R128Save\n"));
if (info->FBDev) {
fbdevHWSave(pScrn);
return;
}
- vgaHWUnlock(hwp);
- vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_ALL); /* save mode, fonts, cmap */
- vgaHWLock(hwp);
- R128SaveMode(pScrn, save);
+ if (!info->IsSecondary) {
+ if (info->UseVGAHW) {
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+ vgaHWUnlock(hwp);
+ vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_ALL);
+ vgaHWLock(hwp);
+ }
+
+ save->dp_datatype = INREG(R128_DP_DATATYPE);
+ save->gen_reset_cntl = INREG(R128_GEN_RESET_CNTL);
+ save->clock_cntl_index = INREG(R128_CLOCK_CNTL_INDEX);
+ save->amcgpio_en_reg = INREG(R128_AMCGPIO_EN_REG);
+ save->amcgpio_mask = INREG(R128_AMCGPIO_MASK);
+ }
- save->dp_datatype = INREG(R128_DP_DATATYPE);
- save->gen_reset_cntl = INREG(R128_GEN_RESET_CNTL);
- save->clock_cntl_index = INREG(R128_CLOCK_CNTL_INDEX);
- save->amcgpio_en_reg = INREG(R128_AMCGPIO_EN_REG);
- save->amcgpio_mask = INREG(R128_AMCGPIO_MASK);
+ R128SaveMode(pScrn, save);
}
/* Restore the original (text) mode. */
@@ -2835,7 +3368,6 @@ static void R128Restore(ScrnInfoPtr pScrn)
R128InfoPtr info = R128PTR(pScrn);
unsigned char *R128MMIO = info->MMIO;
R128SavePtr restore = &info->SavedReg;
- vgaHWPtr hwp = VGAHWPTR(pScrn);
R128TRACE(("R128Restore\n"));
if (info->FBDev) {
@@ -2844,16 +3376,33 @@ static void R128Restore(ScrnInfoPtr pScrn)
}
R128Blank(pScrn);
- OUTREG(R128_AMCGPIO_MASK, restore->amcgpio_mask);
- OUTREG(R128_AMCGPIO_EN_REG, restore->amcgpio_en_reg);
- OUTREG(R128_CLOCK_CNTL_INDEX, restore->clock_cntl_index);
- OUTREG(R128_GEN_RESET_CNTL, restore->gen_reset_cntl);
- OUTREG(R128_DP_DATATYPE, restore->dp_datatype);
+
+ if (!info->IsSecondary) {
+ OUTREG(R128_AMCGPIO_MASK, restore->amcgpio_mask);
+ OUTREG(R128_AMCGPIO_EN_REG, restore->amcgpio_en_reg);
+ OUTREG(R128_CLOCK_CNTL_INDEX, restore->clock_cntl_index);
+ OUTREG(R128_GEN_RESET_CNTL, restore->gen_reset_cntl);
+ OUTREG(R128_DP_DATATYPE, restore->dp_datatype);
+ }
R128RestoreMode(pScrn, restore);
- vgaHWUnlock(hwp);
- vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE | VGA_SR_FONTS );
- vgaHWLock(hwp);
+ if (info->UseVGAHW) {
+ if (!info->IsSecondary) {
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ vgaHWUnlock(hwp);
+ vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE | VGA_SR_FONTS);
+ vgaHWLock(hwp);
+ } else {
+ R128EntPtr pR128Ent = R128EntPriv(pScrn);
+ ScrnInfoPtr pScrn0 = pR128Ent->pPrimaryScrn;
+ vgaHWPtr hwp0;
+
+ hwp0 = VGAHWPTR(pScrn0);
+ vgaHWUnlock(hwp0);
+ vgaHWRestore(pScrn0, &hwp0->SavedReg, VGA_SR_MODE | VGA_SR_FONTS);
+ vgaHWLock(hwp0);
+ }
+ }
R128WaitForVerticalSync(pScrn);
R128Unblank(pScrn);
@@ -2897,7 +3446,7 @@ static Bool R128InitCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr save,
int vsync_wid;
int hsync_fudge_default[] = { 0x00, 0x12, 0x09, 0x09, 0x06, 0x05 };
int hsync_fudge_fp[] = { 0x12, 0x11, 0x09, 0x09, 0x05, 0x05 };
- int hsync_fudge_fp_crt[] = { 0x12, 0x10, 0x08, 0x08, 0x04, 0x04 };
+/* int hsync_fudge_fp_crt[] = { 0x12, 0x10, 0x08, 0x08, 0x04, 0x04 }; */
switch (info->CurrentLayout.pixel_code) {
case 4: format = 1; break;
@@ -2913,18 +3462,11 @@ static Bool R128InitCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr save,
return FALSE;
}
- switch (info->BIOSDisplay) {
- case R128_BIOS_DISPLAY_FP:
+ if ((info->DisplayType == MT_DFP) ||
+ (info->DisplayType == MT_LCD))
hsync_fudge = hsync_fudge_fp[format-1];
- break;
- case R128_BIOS_DISPLAY_FP_CRT:
- hsync_fudge = hsync_fudge_fp_crt[format-1];
- break;
- case R128_BIOS_DISPLAY_CRT:
- default:
+ else
hsync_fudge = hsync_fudge_default[format-1];
- break;
- }
save->crtc_gen_cntl = (R128_CRTC_EXT_DISP_EN
| R128_CRTC_EN
@@ -2939,7 +3481,19 @@ static Bool R128InitCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr save,
? R128_CRTC_CSYNC_EN
: 0));
- save->crtc_ext_cntl = R128_VGA_ATI_LINEAR | R128_XCRT_CNT_EN;
+ if((info->DisplayType == MT_DFP) ||
+ (info->DisplayType == MT_LCD))
+ {
+ save->crtc_ext_cntl = R128_VGA_ATI_LINEAR |
+ R128_XCRT_CNT_EN;
+ save->crtc_gen_cntl &= ~(R128_CRTC_DBL_SCAN_EN |
+ R128_CRTC_INTERLACE_EN);
+ }
+ else
+ save->crtc_ext_cntl = R128_VGA_ATI_LINEAR |
+ R128_XCRT_CNT_EN |
+ R128_CRTC_CRT_ON;
+
save->dac_cntl = (R128_DAC_MASK_ALL
| R128_DAC_VGA_ADR_EN
| (info->dac6bits ? 0 : R128_DAC_8BIT_EN));
@@ -2947,16 +3501,16 @@ static Bool R128InitCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr save,
if(info->isDFP && !info->isPro2)
{
- if(info->PanelXRes < mode->CrtcHDisplay)
- mode->HDisplay = mode->CrtcHDisplay = info->PanelXRes;
- if(info->PanelYRes < mode->CrtcVDisplay)
- mode->VDisplay = mode->CrtcVDisplay = info->PanelYRes;
- 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;
+ if(info->PanelXRes < mode->CrtcHDisplay)
+ mode->HDisplay = mode->CrtcHDisplay = info->PanelXRes;
+ if(info->PanelYRes < mode->CrtcVDisplay)
+ mode->VDisplay = mode->CrtcVDisplay = info->PanelYRes;
+ 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;
}
save->crtc_h_total_disp = ((((mode->CrtcHTotal / 8) - 1) & 0xffff)
@@ -3016,6 +3570,92 @@ static Bool R128InitCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr save,
return TRUE;
}
+/* Define CRTC2 registers for requested video mode. */
+static Bool R128InitCrtc2Registers(ScrnInfoPtr pScrn, R128SavePtr save,
+ DisplayModePtr mode, R128InfoPtr info)
+{
+ int format;
+ int hsync_start;
+ int hsync_wid;
+ int hsync_fudge;
+ int vsync_wid;
+ int bytpp;
+ int hsync_fudge_default[] = { 0x00, 0x12, 0x09, 0x09, 0x06, 0x05 };
+
+ switch (info->CurrentLayout.pixel_code) {
+ case 4: format = 1; bytpp = 0; break;
+ case 8: format = 2; bytpp = 1; break;
+ case 15: format = 3; bytpp = 2; break; /* 555 */
+ case 16: format = 4; bytpp = 2; break; /* 565 */
+ case 24: format = 5; bytpp = 3; break; /* RGB */
+ case 32: format = 6; bytpp = 4; break; /* xRGB */
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Unsupported pixel depth (%d)\n", info->CurrentLayout.bitsPerPixel);
+ return FALSE;
+ }
+ R128TRACE(("Format = %d (%d bytes per pixel)\n", format, bytpp));
+
+ hsync_fudge = hsync_fudge_default[format-1];
+
+ save->crtc2_gen_cntl = (R128_CRTC2_EN
+ | (format << 8)
+ | ((mode->Flags & V_DBLSCAN)
+ ? R128_CRTC2_DBL_SCAN_EN
+ : 0));
+/*
+ save->crtc2_gen_cntl &= ~R128_CRTC_EXT_DISP_EN;
+ save->crtc2_gen_cntl |= (1 << 21);
+*/
+ save->crtc2_h_total_disp = ((((mode->CrtcHTotal / 8) - 1) & 0xffff)
+ | (((mode->CrtcHDisplay / 8) - 1) << 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 + hsync_fudge;
+
+ save->crtc2_h_sync_strt_wid = ((hsync_start & 0xfff)
+ | (hsync_wid << 16)
+ | ((mode->Flags & V_NHSYNC)
+ ? R128_CRTC2_H_SYNC_POL
+ : 0));
+
+#if 1
+ /* This works for double scan mode. */
+ save->crtc2_v_total_disp = (((mode->CrtcVTotal - 1) & 0xffff)
+ | ((mode->CrtcVDisplay - 1) << 16));
+#else
+ /* This is what cce/nbmode.c example code
+ does -- is this correct? */
+ save->crtc2_v_total_disp = (((mode->CrtcVTotal - 1) & 0xffff)
+ | ((mode->CrtcVDisplay
+ * ((mode->Flags & V_DBLSCAN) ? 2 : 1) - 1)
+ << 16));
+#endif
+
+ 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)
+ ? R128_CRTC2_V_SYNC_POL
+ : 0));
+
+ save->crtc2_offset = 0;
+ save->crtc2_offset_cntl = 0;
+
+ save->crtc2_pitch = info->CurrentLayout.displayWidth / 8;
+
+ R128TRACE(("Pitch = %d bytes (virtualX = %d, displayWidth = %d)\n",
+ save->crtc2_pitch, pScrn->virtualX,
+ info->CurrentLayout.displayWidth));
+ return TRUE;
+}
+
/* Define CRTC registers for requested video mode. */
static void R128InitFPRegisters(R128SavePtr orig, R128SavePtr save,
DisplayModePtr mode, R128InfoPtr info)
@@ -3025,20 +3665,20 @@ static void R128InitFPRegisters(R128SavePtr orig, R128SavePtr save,
float Hratio, Vratio;
if (info->BIOSDisplay == R128_BIOS_DISPLAY_CRT) {
- save->crtc_ext_cntl |= R128_CRTC_CRT_ON;
- save->crtc2_gen_cntl = 0;
- save->fp_gen_cntl = orig->fp_gen_cntl;
- save->fp_gen_cntl &= ~(R128_FP_FPON |
- R128_FP_CRTC_USE_SHADOW_VEND |
- R128_FP_CRTC_HORZ_DIV2_EN |
- R128_FP_CRTC_HOR_CRT_DIV2_DIS |
- R128_FP_USE_SHADOW_EN);
- save->fp_gen_cntl |= (R128_FP_SEL_CRTC2 |
- R128_FP_CRTC_DONT_SHADOW_VPAR);
- save->fp_panel_cntl = orig->fp_panel_cntl & (CARD32)~R128_FP_DIGON;
- save->lvds_gen_cntl = orig->lvds_gen_cntl &
+ save->crtc_ext_cntl |= R128_CRTC_CRT_ON;
+ save->crtc2_gen_cntl = 0;
+ save->fp_gen_cntl = orig->fp_gen_cntl;
+ save->fp_gen_cntl &= ~(R128_FP_FPON |
+ R128_FP_CRTC_USE_SHADOW_VEND |
+ R128_FP_CRTC_HORZ_DIV2_EN |
+ R128_FP_CRTC_HOR_CRT_DIV2_DIS |
+ R128_FP_USE_SHADOW_EN);
+ save->fp_gen_cntl |= (R128_FP_SEL_CRTC2 |
+ R128_FP_CRTC_DONT_SHADOW_VPAR);
+ save->fp_panel_cntl = orig->fp_panel_cntl & (CARD32)~R128_FP_DIGON;
+ save->lvds_gen_cntl = orig->lvds_gen_cntl &
(CARD32)~(R128_LVDS_ON | R128_LVDS_BLON);
- return;
+ return;
}
if (xres > info->PanelXRes) xres = info->PanelXRes;
@@ -3051,14 +3691,14 @@ static void R128InitFPRegisters(R128SavePtr orig, R128SavePtr save,
(((((int)(Hratio * R128_HORZ_STRETCH_RATIO_MAX + 0.5))
& R128_HORZ_STRETCH_RATIO_MASK) << R128_HORZ_STRETCH_RATIO_SHIFT) |
(orig->fp_horz_stretch & (R128_HORZ_PANEL_SIZE |
- R128_HORZ_FP_LOOP_STRETCH |
- R128_HORZ_STRETCH_RESERVED)));
+ R128_HORZ_FP_LOOP_STRETCH |
+ R128_HORZ_STRETCH_RESERVED)));
save->fp_horz_stretch &= ~R128_HORZ_AUTO_RATIO_FIX_EN;
save->fp_horz_stretch &= ~R128_AUTO_HORZ_RATIO;
if (xres == info->PanelXRes)
- save->fp_horz_stretch &= ~(R128_HORZ_STRETCH_BLEND | R128_HORZ_STRETCH_ENABLE);
+ save->fp_horz_stretch &= ~(R128_HORZ_STRETCH_BLEND | R128_HORZ_STRETCH_ENABLE);
else
- save->fp_horz_stretch |= (R128_HORZ_STRETCH_BLEND | R128_HORZ_STRETCH_ENABLE);
+ save->fp_horz_stretch |= (R128_HORZ_STRETCH_BLEND | R128_HORZ_STRETCH_ENABLE);
save->fp_vert_stretch =
(((((int)(Vratio * R128_VERT_STRETCH_RATIO_MAX + 0.5))
@@ -3067,9 +3707,9 @@ static void R128InitFPRegisters(R128SavePtr orig, R128SavePtr save,
R128_VERT_STRETCH_RESERVED)));
save->fp_vert_stretch &= ~R128_VERT_AUTO_RATIO_EN;
if (yres == info->PanelYRes)
- save->fp_vert_stretch &= ~(R128_VERT_STRETCH_ENABLE | R128_VERT_STRETCH_BLEND);
+ save->fp_vert_stretch &= ~(R128_VERT_STRETCH_ENABLE | R128_VERT_STRETCH_BLEND);
else
- save->fp_vert_stretch |= (R128_VERT_STRETCH_ENABLE | R128_VERT_STRETCH_BLEND);
+ save->fp_vert_stretch |= (R128_VERT_STRETCH_ENABLE | R128_VERT_STRETCH_BLEND);
save->fp_gen_cntl = (orig->fp_gen_cntl &
(CARD32)~(R128_FP_SEL_CRTC2 |
@@ -3088,35 +3728,40 @@ static void R128InitFPRegisters(R128SavePtr orig, R128SavePtr save,
the flat panel and external CRT to either simultaneously display
the same image or display two different images. */
+
if(!info->isDFP){
- if (info->BIOSDisplay == R128_BIOS_DISPLAY_FP_CRT) {
+ if (info->BIOSDisplay == R128_BIOS_DISPLAY_FP_CRT) {
+ save->crtc_ext_cntl |= R128_CRTC_CRT_ON;
+ } else if (info->BIOSDisplay == R128_DUALHEAD) {
save->crtc_ext_cntl |= R128_CRTC_CRT_ON;
- } else {
+ save->dac_cntl |= R128_DAC_CRT_SEL_CRTC2;
+ save->dac_cntl |= R128_DAC_PALETTE2_SNOOP_EN;
+ } else {
save->crtc_ext_cntl &= ~R128_CRTC_CRT_ON;
save->dac_cntl |= R128_DAC_CRT_SEL_CRTC2;
save->crtc2_gen_cntl = 0;
- }
+ }
}
/* WARNING: Be careful about turning on the flat panel */
if(info->isDFP){
- save->fp_gen_cntl = orig->fp_gen_cntl;
-
- save->fp_gen_cntl &= ~(R128_FP_CRTC_USE_SHADOW_VEND |
- R128_FP_CRTC_USE_SHADOW_ROWCUR |
- R128_FP_CRTC_HORZ_DIV2_EN |
- R128_FP_CRTC_HOR_CRT_DIV2_DIS |
- R128_FP_CRT_SYNC_SEL |
- R128_FP_USE_SHADOW_EN);
-
- save->fp_panel_cntl |= (R128_FP_DIGON | R128_FP_BLON);
- save->fp_gen_cntl |= (R128_FP_FPON | R128_FP_TDMS_EN |
- R128_FP_CRTC_DONT_SHADOW_VPAR | R128_FP_CRTC_DONT_SHADOW_HEND);
- save->tmds_transmitter_cntl = (orig->tmds_transmitter_cntl
- & ~(CARD32)R128_TMDS_PLLRST) | R128_TMDS_PLLEN;
+ save->fp_gen_cntl = orig->fp_gen_cntl;
+
+ save->fp_gen_cntl &= ~(R128_FP_CRTC_USE_SHADOW_VEND |
+ R128_FP_CRTC_USE_SHADOW_ROWCUR |
+ R128_FP_CRTC_HORZ_DIV2_EN |
+ R128_FP_CRTC_HOR_CRT_DIV2_DIS |
+ R128_FP_CRT_SYNC_SEL |
+ R128_FP_USE_SHADOW_EN);
+
+ save->fp_panel_cntl |= (R128_FP_DIGON | R128_FP_BLON);
+ save->fp_gen_cntl |= (R128_FP_FPON | R128_FP_TDMS_EN |
+ R128_FP_CRTC_DONT_SHADOW_VPAR | R128_FP_CRTC_DONT_SHADOW_HEND);
+ save->tmds_transmitter_cntl = (orig->tmds_transmitter_cntl
+ & ~(CARD32)R128_TMDS_PLLRST) | R128_TMDS_PLLEN;
}
else
- save->lvds_gen_cntl |= (R128_LVDS_ON | R128_LVDS_BLON);
+ save->lvds_gen_cntl |= (R128_LVDS_ON | R128_LVDS_BLON);
save->fp_crtc_h_total_disp = save->crtc_h_total_disp;
save->fp_crtc_v_total_disp = save->crtc_v_total_disp;
@@ -3176,10 +3821,62 @@ static void R128InitPLLRegisters(ScrnInfoPtr pScrn, R128SavePtr save,
}
+/* Define PLL2 registers for requested video mode. */
+static void R128InitPLL2Registers(R128SavePtr save, R128PLLPtr 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 */
+ /* bitvalue = 5 is reserved */
+ { 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) {
+ 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;
+ }
+
+ save->dot_clock_freq_2 = freq;
+ save->feedback_div_2 = R128Div(pll->reference_div
+ * save->pll_output_freq_2,
+ pll->reference_freq);
+ save->post_div_2 = post_div->divider;
+
+ R128TRACE(("dc=%d, of=%d, 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;
+}
+
/* Define DDA registers for requested video mode. */
static Bool R128InitDDARegisters(ScrnInfoPtr pScrn, R128SavePtr save,
R128PLLPtr pll, R128InfoPtr info,
- DisplayModePtr mode)
+ DisplayModePtr mode)
{
int DisplayFifoWidth = 128;
int DisplayFifoDepth = 32;
@@ -3197,8 +3894,8 @@ static Bool R128InitDDARegisters(ScrnInfoPtr pScrn, R128SavePtr save,
pll->reference_div * save->post_div);
if(info->isDFP && !info->isPro2){
- if(info->PanelXRes != mode->CrtcHDisplay)
- VclkFreq = (VclkFreq * mode->CrtcHDisplay)/info->PanelXRes;
+ if(info->PanelXRes != mode->CrtcHDisplay)
+ VclkFreq = (VclkFreq * mode->CrtcHDisplay)/info->PanelXRes;
}
XclksPerTransfer = R128Div(XclkFreq * DisplayFifoWidth,
@@ -3245,6 +3942,77 @@ static Bool R128InitDDARegisters(ScrnInfoPtr pScrn, R128SavePtr save,
return TRUE;
}
+/* Define DDA2 registers for requested video mode. */
+static Bool R128InitDDA2Registers(ScrnInfoPtr pScrn, R128SavePtr save,
+ R128PLLPtr pll, R128InfoPtr info,
+ DisplayModePtr mode)
+{
+ int DisplayFifoWidth = 128;
+ int DisplayFifoDepth = 32;
+ int XclkFreq;
+ int VclkFreq;
+ int XclksPerTransfer;
+ int XclksPerTransferPrecise;
+ int UseablePrecision;
+ int Roff;
+ int Ron;
+
+ XclkFreq = pll->xclk;
+
+ VclkFreq = R128Div(pll->reference_freq * save->feedback_div_2,
+ pll->reference_div * save->post_div_2);
+
+ if(info->isDFP && !info->isPro2){
+ if(info->PanelXRes != mode->CrtcHDisplay)
+ VclkFreq = (VclkFreq * mode->CrtcHDisplay)/info->PanelXRes;
+ }
+
+ XclksPerTransfer = R128Div(XclkFreq * DisplayFifoWidth,
+ VclkFreq * (info->CurrentLayout.pixel_bytes * 8));
+
+ UseablePrecision = R128MinBits(XclksPerTransfer) + 1;
+
+ XclksPerTransferPrecise = R128Div((XclkFreq * DisplayFifoWidth)
+ << (11 - UseablePrecision),
+ VclkFreq * (info->CurrentLayout.pixel_bytes * 8));
+
+ Roff = XclksPerTransferPrecise * (DisplayFifoDepth - 4);
+
+ Ron = (4 * info->ram->MB
+ + 3 * MAX(info->ram->Trcd - 2, 0)
+ + 2 * info->ram->Trp
+ + info->ram->Twr
+ + info->ram->CL
+ + info->ram->Tr2w
+ + XclksPerTransfer) << (11 - UseablePrecision);
+
+
+ if (Ron + info->ram->Rloop >= Roff) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "(Ron = %d) + (Rloop = %d) >= (Roff = %d)\n",
+ Ron, info->ram->Rloop, Roff);
+ return FALSE;
+ }
+
+ save->dda2_config = (XclksPerTransferPrecise
+ | (UseablePrecision << 16)
+ | (info->ram->Rloop << 20));
+
+ /*save->dda2_on_off = (Ron << 16) | Roff;*/
+ /* shift most be 18 otherwise there's corruption on crtc2 */
+ save->dda2_on_off = (Ron << 18) | Roff;
+
+ R128TRACE(("XclkFreq = %d; VclkFreq = %d; per = %d, %d (useable = %d)\n",
+ XclkFreq,
+ VclkFreq,
+ XclksPerTransfer,
+ XclksPerTransferPrecise,
+ UseablePrecision));
+ R128TRACE(("Roff = %d, Ron = %d, Rloop = %d\n",
+ Roff, Ron, info->ram->Rloop));
+
+ return TRUE;
+}
#if 0
/* Define initial palette for requested video mode. This doesn't do
@@ -3312,21 +4080,42 @@ static Bool R128Init(ScrnInfoPtr pScrn, DisplayModePtr mode, R128SavePtr save)
info->Flags = mode->Flags;
- R128InitCommonRegisters(save, info);
- if (!R128InitCrtcRegisters(pScrn, save, mode, info)) return FALSE;
- if (info->HasPanelRegs || info->isDFP)
- R128InitFPRegisters(&info->SavedReg, save, mode, info);
- if(dot_clock > 0){
- R128InitPLLRegisters(pScrn, save, &info->pll, dot_clock);
- if (!R128InitDDARegisters(pScrn, save, &info->pll, info, mode))
+ if(info->IsSecondary)
+ {
+ if (!R128InitCrtc2Registers(pScrn, save,
+ pScrn->currentMode,info))
+ return FALSE;
+ R128InitPLL2Registers(save, &info->pll, dot_clock);
+ if (!R128InitDDA2Registers(pScrn, save, &info->pll, info, mode))
+ return FALSE;
+ }
+ else
+ {
+ R128InitCommonRegisters(save, info);
+ if(!R128InitCrtcRegisters(pScrn, save, mode, info))
+ return FALSE;
+ if(dot_clock)
+ {
+ R128InitPLLRegisters(pScrn, save, &info->pll, dot_clock);
+ if (!R128InitDDARegisters(pScrn, save, &info->pll, info, mode))
return FALSE;
+ }
+ 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;
+ save->dda_config = info->SavedReg.dda_config;
+ save->dda_on_off = info->SavedReg.dda_on_off;
+ }
+ /* not used for now */
+ /*if (!info->PaletteSavedOnVT) RADEONInitPalette(save);*/
}
- 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;
- save->dda_config = info->SavedReg.dda_config;
- save->dda_on_off = info->SavedReg.dda_on_off;
+
+ if (((info->DisplayType == MT_DFP) ||
+ (info->DisplayType == MT_LCD)))
+ {
+ R128InitFPRegisters(&info->SavedReg, save, mode, info);
}
R128TRACE(("R128Init returns %p\n", save));
@@ -3368,9 +4157,21 @@ static Bool R128SaveScreen(ScreenPtr pScreen, int mode)
return TRUE;
}
+/*
+ * SwitchMode() doesn't work right on crtc2 on some laptops.
+ * The workaround is to switch the mode, then switch to another VT, then
+ * switch back. --AGD
+ */
Bool R128SwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
{
- return R128ModeInit(xf86Screens[scrnIndex], mode);
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ R128InfoPtr info = R128PTR(pScrn);
+ Bool ret;
+
+ info->SwitchingMode = TRUE;
+ ret = R128ModeInit(xf86Screens[scrnIndex], mode);
+ info->SwitchingMode = FALSE;
+ return ret;
}
/* Used to disallow modes that are not supported by the hardware. */
@@ -3381,20 +4182,19 @@ ModeStatus R128ValidMode(int scrnIndex, DisplayModePtr mode,
R128InfoPtr info = R128PTR(pScrn);
if(info->isDFP) {
- if(info->PanelXRes < mode->CrtcHDisplay ||
- info->PanelYRes < mode->CrtcVDisplay)
- return MODE_NOMODE;
- else
- return MODE_OK;
+ if(info->PanelXRes < mode->CrtcHDisplay ||
+ info->PanelYRes < mode->CrtcVDisplay)
+ return MODE_NOMODE;
+ else
+ return MODE_OK;
}
- if (info->HasPanelRegs) {
+ if (info->DisplayType == MT_LCD) {
if (mode->Flags & V_INTERLACE) return MODE_NO_INTERLACE;
if (mode->Flags & V_DBLSCAN) return MODE_NO_DBLESCAN;
}
- if (info->HasPanelRegs &&
- info->BIOSDisplay != R128_BIOS_DISPLAY_CRT &&
+ if (info->DisplayType == MT_LCD &&
info->VBIOS) {
int i;
for (i = info->FPBIOSstart+64; R128_BIOS16(i) != 0; i += 2) {
@@ -3459,7 +4259,7 @@ void R128AdjustFrame(int scrnIndex, int x, int y, int flags)
int Base;
if(info->showCache && y && pScrn->vtSema)
- y += pScrn->virtualY - 1;
+ y += pScrn->virtualY - 1;
Base = y * info->CurrentLayout.displayWidth + x;
@@ -3475,7 +4275,14 @@ void R128AdjustFrame(int scrnIndex, int x, int y, int flags)
if (info->CurrentLayout.pixel_code == 24)
Base += 8 * (Base % 3); /* Must be multiple of 8 and 3 */
+ if(info->IsSecondary)
+ {
+ Base += pScrn->fbOffset;
+ OUTREG(R128_CRTC2_OFFSET, Base);
+ }
+ else
OUTREG(R128_CRTC_OFFSET, Base);
+
}
/* Called when VT switching back to the X server. Reinitialize the video
@@ -3487,9 +4294,9 @@ Bool R128EnterVT(int scrnIndex, int flags)
R128TRACE(("R128EnterVT\n"));
if (info->FBDev) {
- if (!fbdevHWEnterVT(scrnIndex,flags)) return FALSE;
+ if (!fbdevHWEnterVT(scrnIndex,flags)) return FALSE;
} else
- if (!R128ModeInit(pScrn, pScrn->currentMode)) return FALSE;
+ if (!R128ModeInit(pScrn, pScrn->currentMode)) return FALSE;
if (info->accelOn)
R128EngineInit(pScrn);
@@ -3529,9 +4336,9 @@ void R128LeaveVT(int scrnIndex, int flags)
R128SavePalette(pScrn, save);
info->PaletteSavedOnVT = TRUE;
if (info->FBDev)
- fbdevHWLeaveVT(scrnIndex,flags);
+ fbdevHWLeaveVT(scrnIndex,flags);
else
- R128Restore(pScrn);
+ R128Restore(pScrn);
}
@@ -3571,7 +4378,7 @@ static Bool R128CloseScreen(int scrnIndex, ScreenPtr pScreen)
info->DGAModes = NULL;
if (info->adaptor) {
- xfree(info->adaptor->pPortPrivates[0].ptr);
+ xfree(info->adaptor->pPortPrivates[0].ptr);
xf86XVFreeVideoAdaptorRec(info->adaptor);
info->adaptor = NULL;
}
@@ -3586,9 +4393,10 @@ static Bool R128CloseScreen(int scrnIndex, ScreenPtr pScreen)
void R128FreeScreen(int scrnIndex, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ R128InfoPtr info = R128PTR(pScrn);
R128TRACE(("R128FreeScreen\n"));
- if (xf86LoaderCheckSymbol("vgaHWFreeHWRec"))
+ if (info->UseVGAHW)
vgaHWFreeHWRec(pScrn);
R128FreeRec(pScrn);
}
@@ -3602,27 +4410,52 @@ static void R128DisplayPowerManagementSet(ScrnInfoPtr pScrn,
int mask = (R128_CRTC_DISPLAY_DIS
| R128_CRTC_HSYNC_DIS
| R128_CRTC_VSYNC_DIS);
+ int mask2 = R128_CRTC2_DISP_DIS;
switch (PowerManagementMode) {
case DPMSModeOn:
/* Screen: On; HSync: On, VSync: On */
- OUTREGP(R128_CRTC_EXT_CNTL, 0, ~mask);
+ if (info->IsSecondary)
+ OUTREGP(R128_CRTC2_GEN_CNTL, 0, ~mask2);
+ else
+ OUTREGP(R128_CRTC_EXT_CNTL, 0, ~mask);
break;
case DPMSModeStandby:
/* Screen: Off; HSync: Off, VSync: On */
- OUTREGP(R128_CRTC_EXT_CNTL,
- R128_CRTC_DISPLAY_DIS | R128_CRTC_HSYNC_DIS, ~mask);
+ if (info->IsSecondary)
+ OUTREGP(R128_CRTC2_GEN_CNTL, R128_CRTC2_DISP_DIS, ~mask2);
+ else
+ OUTREGP(R128_CRTC_EXT_CNTL,
+ R128_CRTC_DISPLAY_DIS | R128_CRTC_HSYNC_DIS, ~mask);
break;
case DPMSModeSuspend:
/* Screen: Off; HSync: On, VSync: Off */
- OUTREGP(R128_CRTC_EXT_CNTL,
- R128_CRTC_DISPLAY_DIS | R128_CRTC_VSYNC_DIS, ~mask);
+ if (info->IsSecondary)
+ OUTREGP(R128_CRTC2_GEN_CNTL, R128_CRTC2_DISP_DIS, ~mask2);
+ else
+ OUTREGP(R128_CRTC_EXT_CNTL,
+ R128_CRTC_DISPLAY_DIS | R128_CRTC_VSYNC_DIS, ~mask);
break;
case DPMSModeOff:
/* Screen: Off; HSync: Off, VSync: Off */
- OUTREGP(R128_CRTC_EXT_CNTL, mask, ~mask);
+ if (info->IsSecondary)
+ OUTREGP(R128_CRTC2_GEN_CNTL, mask2, ~mask2);
+ else
+ OUTREGP(R128_CRTC_EXT_CNTL, mask, ~mask);
break;
}
+ if(info->isDFP) {
+ switch (PowerManagementMode) {
+ case DPMSModeOn:
+ OUTREG(R128_FP_GEN_CNTL, INREG(R128_FP_GEN_CNTL) | (R128_FP_FPON | R128_FP_TDMS_EN));
+ break;
+ case DPMSModeStandby:
+ case DPMSModeSuspend:
+ case DPMSModeOff:
+ OUTREG(R128_FP_GEN_CNTL, INREG(R128_FP_GEN_CNTL) & ~(R128_FP_FPON | R128_FP_TDMS_EN));
+ break;
+ }
+ }
}
static int r128_set_backlight_enable(ScrnInfoPtr pScrn, int on);
@@ -3638,7 +4471,7 @@ static void R128DisplayPowerManagementSetLCD(ScrnInfoPtr pScrn,
case DPMSModeOn:
/* Screen: On; HSync: On, VSync: On */
OUTREGP(R128_LVDS_GEN_CNTL, 0, ~mask);
- r128_set_backlight_enable(pScrn, 1);
+ r128_set_backlight_enable(pScrn, 1);
break;
case DPMSModeStandby:
/* Fall through */
@@ -3648,21 +4481,21 @@ static void R128DisplayPowerManagementSetLCD(ScrnInfoPtr pScrn,
case DPMSModeOff:
/* Screen: Off; HSync: Off, VSync: Off */
OUTREGP(R128_LVDS_GEN_CNTL, mask, ~mask);
- r128_set_backlight_enable(pScrn, 0);
+ r128_set_backlight_enable(pScrn, 0);
break;
}
}
static int r128_set_backlight_enable(ScrnInfoPtr pScrn, int on)
{
- R128InfoPtr info = R128PTR(pScrn);
- unsigned char *R128MMIO = info->MMIO;
+ R128InfoPtr info = R128PTR(pScrn);
+ unsigned char *R128MMIO = info->MMIO;
unsigned int lvds_gen_cntl = INREG(R128_LVDS_GEN_CNTL);
lvds_gen_cntl |= (/*R128_LVDS_BL_MOD_EN |*/ R128_LVDS_BLON);
if (on) {
lvds_gen_cntl |= R128_LVDS_DIGON;
- if (!lvds_gen_cntl & R128_LVDS_ON) {
+ if (!(lvds_gen_cntl & R128_LVDS_ON)) {
lvds_gen_cntl &= ~R128_LVDS_BLON;
OUTREG(R128_LVDS_GEN_CNTL, lvds_gen_cntl);
(void)INREG(R128_LVDS_GEN_CNTL);
diff --git a/programs/Xserver/hw/xfree86/drivers/ati/r128_probe.c b/programs/Xserver/hw/xfree86/drivers/ati/r128_probe.c
index 303250e62..385fe3b1f 100644
--- a/programs/Xserver/hw/xfree86/drivers/ati/r128_probe.c
+++ b/programs/Xserver/hw/xfree86/drivers/ati/r128_probe.c
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_probe.c,v 1.19 2006/03/02 03:00:37 dawes Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_probe.c,v 1.20tsi Exp $ */
/*
* Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario,
* Precision Insight, Inc., Cedar Park, Texas, and
@@ -180,6 +180,8 @@ PciChipsets R128PciChipsets[] = {
{ -1, -1, RES_UNDEFINED }
};
+int gR128EntityIndex = -1;
+
/* Return the options for supported chipset 'n'; NULL otherwise */
const OptionInfoRec *
R128AvailableOptions(int chipid, int busid)
@@ -216,7 +218,6 @@ R128Probe(DriverPtr drv, int flags)
int numDevSections, nATIGDev, nR128GDev;
int *usedChips;
GDevPtr *devSections, *ATIGDevs, *R128GDevs;
- EntityInfoPtr pEnt;
Bool foundScreen = FALSE;
int i;
@@ -262,10 +263,11 @@ R128Probe(DriverPtr drv, int flags)
if (flags & PROBE_DETECT)
foundScreen = TRUE;
else for (i = 0; i < numUsed; i++) {
- pEnt = xf86GetEntityInfo(usedChips[i]);
+ ScrnInfoPtr pScrn;
+ EntityInfoPtr pEnt;
- if (pEnt->active) {
- ScrnInfoPtr pScrn = xf86AllocateScreen(drv, 0);
+ if ((pScrn = xf86ConfigPciEntity(NULL, 0, usedChips[i],
+ R128PciChipsets, 0, 0, 0, 0, 0))) {
#ifdef XFree86LOADER
ModuleDescPtr pModule;
@@ -293,13 +295,47 @@ R128Probe(DriverPtr drv, int flags)
pScrn->LeaveVT = R128LeaveVT;
pScrn->FreeScreen = R128FreeScreen;
pScrn->ValidMode = R128ValidMode;
+ pScrn->Probe = R128Probe;
foundScreen = TRUE;
- xf86ConfigActivePciEntity(pScrn, usedChips[i], R128PciChipsets,
- 0, 0, 0, 0, 0);
+ pEnt = xf86GetEntityInfo(usedChips[i]);
+
+ /* mobility cards support Dual-Head, mark the entity as sharable */
+ if (pEnt->chipset == PCI_CHIP_RAGE128LE ||
+ pEnt->chipset == PCI_CHIP_RAGE128LF ||
+ pEnt->chipset == PCI_CHIP_RAGE128MF ||
+ pEnt->chipset == PCI_CHIP_RAGE128ML) {
+ static int instance = 0;
+ DevUnion* pPriv;
+
+ xf86SetEntitySharable(usedChips[i]);
+ xf86SetEntityInstanceForScreen(pScrn,
+ pScrn->entityList[0], instance);
+
+ if (gR128EntityIndex < 0)
+ {
+ gR128EntityIndex = xf86AllocateEntityPrivateIndex();
+ pPriv = xf86GetEntityPrivate(pScrn->entityList[0],
+ gR128EntityIndex);
+
+ if (!pPriv->ptr)
+ {
+ R128EntPtr pR128Ent;
+ pPriv->ptr = xnfcalloc(sizeof(R128EntRec), 1);
+ pR128Ent = pPriv->ptr;
+ pR128Ent->IsDRIEnabled = FALSE;
+ pR128Ent->BypassSecondary = FALSE;
+ pR128Ent->HasSecondary = FALSE;
+ pR128Ent->IsSecondaryRestored = FALSE;
+ }
+ }
+
+ instance++;
+ }
+
+ xfree(pEnt);
}
- xfree(pEnt);
}
xfree(usedChips);
diff --git a/programs/Xserver/hw/xfree86/drivers/ati/r128_probe.h b/programs/Xserver/hw/xfree86/drivers/ati/r128_probe.h
index 8fb20c466..0226a4ead 100644
--- a/programs/Xserver/hw/xfree86/drivers/ati/r128_probe.h
+++ b/programs/Xserver/hw/xfree86/drivers/ati/r128_probe.h
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_probe.h,v 1.10tsi Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_probe.h,v 1.11tsi Exp $ */
/*
* Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
* VA Linux Systems Inc., Fremont, California.
@@ -41,6 +41,21 @@
#include "xf86str.h"
+typedef struct
+{
+ Bool IsDRIEnabled;
+
+ Bool HasSecondary;
+ Bool BypassSecondary;
+ /*These two registers are used to make sure the CRTC2 is
+ retored before CRTC_EXT, otherwise it could lead to blank screen.*/
+ Bool IsSecondaryRestored;
+ Bool RestorePrimary;
+
+ ScrnInfoPtr pSecondaryScrn;
+ ScrnInfoPtr pPrimaryScrn;
+} R128EntRec, *R128EntPtr;
+
/* r128_probe.c */
extern const OptionInfoRec * R128AvailableOptions
FunctionPrototype((int, int));
diff --git a/programs/Xserver/hw/xfree86/drivers/ati/r128_reg.h b/programs/Xserver/hw/xfree86/drivers/ati/r128_reg.h
index cdd8751a1..9ca104f5f 100644
--- a/programs/Xserver/hw/xfree86/drivers/ati/r128_reg.h
+++ b/programs/Xserver/hw/xfree86/drivers/ati/r128_reg.h
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_reg.h,v 1.17 2003/09/28 20:15:54 alanh Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_reg.h,v 1.18tsi Exp $ */
/*
* Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario,
* Precision Insight, Inc., Cedar Park, Texas, and
@@ -68,7 +68,7 @@
do { \
CARD32 tmp = INREG(addr); \
tmp &= (mask); \
- tmp |= (val); \
+ tmp |= ((val) & ~(mask)); \
OUTREG(addr, tmp); \
} while (0)
@@ -76,7 +76,7 @@
#define OUTPLL(addr, val) \
do { \
- OUTREG8(R128_CLOCK_CNTL_INDEX, ((addr) & 0x1f) | R128_PLL_WR_EN); \
+ OUTREG8(R128_CLOCK_CNTL_INDEX, ((addr) & 0x3f) | R128_PLL_WR_EN); \
OUTREG(R128_CLOCK_CNTL_DATA, val); \
} while (0)
@@ -84,7 +84,7 @@
do { \
CARD32 tmp = INPLL(pScrn, addr); \
tmp &= (mask); \
- tmp |= (val); \
+ tmp |= ((val) & ~(mask)); \
OUTPLL(addr, tmp); \
} while (0)
@@ -151,9 +151,6 @@
#define R128_AMCGPIO_EN_REG 0x01a8
#define R128_AMCGPIO_MASK 0x0194
#define R128_AMCGPIO_Y_REG 0x01a4
-#define R128_ATTRDR 0x03c1 /* VGA */
-#define R128_ATTRDW 0x03c0 /* VGA */
-#define R128_ATTRX 0x03c0 /* VGA */
#define R128_AUX_SC_CNTL 0x1660
# define R128_AUX1_SC_EN (1 << 0)
# define R128_AUX1_SC_MODE_OR (0 << 1)
@@ -189,6 +186,9 @@
# define R128_BIOS_DISPLAY_FP (1 << 0)
# define R128_BIOS_DISPLAY_CRT (2 << 0)
# define R128_BIOS_DISPLAY_FP_CRT (3 << 0)
+/* R128_DUALHEAD is just a flag for the driver;
+ it doesn't actually correspond to any bits */
+# define R128_DUALHEAD 4
#define R128_BIOS_6_SCRATCH 0x0028
#define R128_BIOS_7_SCRATCH 0x002c
#define R128_BIOS_ROM 0x0f30 /* PCI */
@@ -284,6 +284,7 @@
#define R128_CLOCK_CNTL_INDEX 0x0008
# define R128_PLL_WR_EN (1 << 7)
# define R128_PLL_DIV_SEL (3 << 8)
+# define R128_PLL2_DIV_SEL_MASK ~(3 << 8)
#define R128_CLR_CMP_CLR_3D 0x1a24
#define R128_CLR_CMP_CLR_DST 0x15c8
#define R128_CLR_CMP_CLR_SRC 0x15c4
@@ -374,45 +375,77 @@
#define R128_CRTC2_CRNT_FRAME 0x0314
#define R128_CRTC2_DEBUG 0x031c
#define R128_CRTC2_GEN_CNTL 0x03f8
+# define R128_CRTC2_DBL_SCAN_EN (1 << 0)
+# define R128_CRTC2_CUR_EN (1 << 16)
+# define R128_CRTC2_ICON_EN (1 << 20)
+# define R128_CRTC2_DISP_DIS (1 << 23)
+# define R128_CRTC2_EN (1 << 25)
+# define R128_CRTC2_DISP_REQ_EN_B (1 << 26)
#define R128_CRTC2_GUI_TRIG_VLINE 0x0318
#define R128_CRTC2_H_SYNC_STRT_WID 0x0304
+# define R128_CRTC2_H_SYNC_STRT_PIX (0x07 << 0)
+# define R128_CRTC2_H_SYNC_STRT_CHAR (0x1ff << 3)
+# define R128_CRTC2_H_SYNC_STRT_CHAR_SHIFT 3
+# define R128_CRTC2_H_SYNC_WID (0x3f << 16)
+# define R128_CRTC2_H_SYNC_WID_SHIFT 16
+# define R128_CRTC2_H_SYNC_POL (1 << 23)
#define R128_CRTC2_H_TOTAL_DISP 0x0300
+# define R128_CRTC2_H_TOTAL (0x01ff << 0)
+# define R128_CRTC2_H_TOTAL_SHIFT 0
+# define R128_CRTC2_H_DISP (0x00ff << 16)
+# define R128_CRTC2_H_DISP_SHIFT 16
#define R128_CRTC2_OFFSET 0x0324
#define R128_CRTC2_OFFSET_CNTL 0x0328
+# define R128_CRTC2_TILE_EN (1 << 15)
#define R128_CRTC2_PITCH 0x032c
#define R128_CRTC2_STATUS 0x03fc
#define R128_CRTC2_V_SYNC_STRT_WID 0x030c
+# define R128_CRTC2_V_SYNC_STRT (0x7ff << 0)
+# define R128_CRTC2_V_SYNC_STRT_SHIFT 0
+# define R128_CRTC2_V_SYNC_WID (0x1f << 16)
+# define R128_CRTC2_V_SYNC_WID_SHIFT 16
+# define R128_CRTC2_V_SYNC_POL (1 << 23)
#define R128_CRTC2_V_TOTAL_DISP 0x0308
+# define R128_CRTC2_V_TOTAL (0x07ff << 0)
+# define R128_CRTC2_V_TOTAL_SHIFT 0
+# define R128_CRTC2_V_DISP (0x07ff << 16)
+# define R128_CRTC2_V_DISP_SHIFT 16
#define R128_CRTC2_VLINE_CRNT_VLINE 0x0310
-#define R128_CRTC8_DATA 0x03d5 /* VGA, 0x3b5 */
-#define R128_CRTC8_IDX 0x03d4 /* VGA, 0x3b4 */
#define R128_CUR_CLR0 0x026c
#define R128_CUR_CLR1 0x0270
#define R128_CUR_HORZ_VERT_OFF 0x0268
#define R128_CUR_HORZ_VERT_POSN 0x0264
#define R128_CUR_OFFSET 0x0260
# define R128_CUR_LOCK (1 << 31)
+#define R128_CUR2_CLR0 0x036c
+#define R128_CUR2_CLR1 0x0370
+#define R128_CUR2_HORZ_VERT_OFF 0x0368
+#define R128_CUR2_HORZ_VERT_POSN 0x0364
+#define R128_CUR2_OFFSET 0x0360
+# define R128_CUR2_LOCK (1 << 31)
#define R128_DAC_CNTL 0x0058
# define R128_DAC_RANGE_CNTL (3 << 0)
# define R128_DAC_BLANKING (1 << 2)
# define R128_DAC_CRT_SEL_CRTC2 (1 << 4)
# define R128_DAC_PALETTE_ACC_CTL (1 << 5)
+# define R128_DAC_PALETTE2_SNOOP_EN (1 << 6)
# define R128_DAC_8BIT_EN (1 << 8)
# define R128_DAC_VGA_ADR_EN (1 << 13)
# define R128_DAC_MASK_ALL (0xff << 24)
#define R128_DAC_CRC_SIG 0x02cc
-#define R128_DAC_DATA 0x03c9 /* VGA */
-#define R128_DAC_MASK 0x03c6 /* VGA */
-#define R128_DAC_R_INDEX 0x03c7 /* VGA */
-#define R128_DAC_W_INDEX 0x03c8 /* VGA */
#define R128_DDA_CONFIG 0x02e0
#define R128_DDA_ON_OFF 0x02e4
+#define R128_DDA2_CONFIG 0x03e0
+#define R128_DDA2_ON_OFF 0x03e4
#define R128_DEFAULT_OFFSET 0x16e0
#define R128_DEFAULT_PITCH 0x16e4
#define R128_DEFAULT_SC_BOTTOM_RIGHT 0x16e8
# define R128_DEFAULT_SC_RIGHT_MAX (0x1fff << 0)
# define R128_DEFAULT_SC_BOTTOM_MAX (0x1fff << 16)
+#define R128_DEFAULT2_OFFSET 0x16f8
+#define R128_DEFAULT2_PITCH 0x16fc
+#define R128_DEFAULT2_SC_BOTTOM_RIGHT 0x16dc
#define R128_DESTINATION_3D_CLR_CMP_VAL 0x1820
#define R128_DESTINATION_3D_CLR_CMP_MSK 0x1824
#define R128_DEVICE_ID 0x0f02 /* PCI */
@@ -613,13 +646,6 @@
# define R128_SOFT_RESET_PCLK (1 << 9)
# define R128_SOFT_RESET_DISPENG_XCLK (1 << 11)
# define R128_SOFT_RESET_MEMCTLR_XCLK (1 << 12)
-#define R128_GENENB 0x03c3 /* VGA */
-#define R128_GENFC_RD 0x03ca /* VGA */
-#define R128_GENFC_WT 0x03da /* VGA, 0x03ba */
-#define R128_GENMO_RD 0x03cc /* VGA */
-#define R128_GENMO_WT 0x03c2 /* VGA */
-#define R128_GENS0 0x03c2 /* VGA */
-#define R128_GENS1 0x03da /* VGA, 0x03ba */
#define R128_GPIO_MONID 0x0068
# define R128_GPIO_MONID_A_0 (1 << 0)
# define R128_GPIO_MONID_A_1 (1 << 1)
@@ -638,8 +664,6 @@
# define R128_GPIO_MONID_MASK_2 (1 << 26)
# define R128_GPIO_MONID_MASK_3 (1 << 27)
#define R128_GPIO_MONIDB 0x006c
-#define R128_GRPH8_DATA 0x03cf /* VGA */
-#define R128_GRPH8_IDX 0x03ce /* VGA */
#define R128_GUI_DEBUG0 0x16a0
#define R128_GUI_DEBUG1 0x16a4
#define R128_GUI_DEBUG2 0x16a8
@@ -670,6 +694,7 @@
#define R128_HOST_DATA_LAST 0x17e0
#define R128_HOST_PATH_CNTL 0x0130
#define R128_HTOTAL_CNTL 0x0009 /* PLL */
+#define R128_HTOTAL2_CNTL 0x002e /* PLL */
#define R128_HW_DEBUG 0x0128
#define R128_HW_DEBUG2 0x011c
@@ -875,6 +900,19 @@
# define R128_PPLL_REF_DIV_MASK 0x03ff
# define R128_PPLL_ATOMIC_UPDATE_R (1 << 15) /* same as _W */
# define R128_PPLL_ATOMIC_UPDATE_W (1 << 15) /* same as _R */
+#define R128_P2PLL_CNTL 0x002a /* P2PLL */
+# define R128_P2PLL_RESET (1 << 0)
+# define R128_P2PLL_SLEEP (1 << 1)
+# define R128_P2PLL_ATOMIC_UPDATE_EN (1 << 16)
+# define R128_P2PLL_VGA_ATOMIC_UPDATE_EN (1 << 17)
+# define R128_P2PLL_ATOMIC_UPDATE_VSYNC (1 << 18)
+#define R128_P2PLL_DIV_0 0x002c
+# define R128_P2PLL_FB0_DIV_MASK 0x07ff
+# define R128_P2PLL_POST0_DIV_MASK 0x00070000
+#define R128_P2PLL_REF_DIV 0x002B /* PLL */
+# define R128_P2PLL_REF_DIV_MASK 0x03ff
+# define R128_P2PLL_ATOMIC_UPDATE_R (1 << 15) /* same as _W */
+# define R128_P2PLL_ATOMIC_UPDATE_W (1 << 15) /* same as _R */
#define R128_PWR_MNGMT_CNTL_STATUS 0x0f60 /* PCI */
#define R128_REG_BASE 0x0f18 /* PCI */
#define R128_REGPROG_INF 0x0f09 /* PCI */
@@ -888,8 +926,6 @@
#define R128_SC_TOP 0x1648
#define R128_SC_TOP_LEFT 0x16ec
#define R128_SC_TOP_LEFT_C 0x1c88
-#define R128_SEQ8_DATA 0x03c5 /* VGA */
-#define R128_SEQ8_IDX 0x03c4 /* VGA */
#define R128_SNAPSHOT_F_COUNT 0x0244
#define R128_SNAPSHOT_VH_COUNTS 0x0240
#define R128_SNAPSHOT_VIF_COUNT 0x024c
@@ -935,7 +971,14 @@
#define R128_TRAIL_X_SUB 0x1620
#define R128_VCLK_ECP_CNTL 0x0008 /* PLL */
+# define R128_VCLK_SRC_SEL_MASK 0x03
+# define R128_VCLK_SRC_SEL_CPUCLK 0x00
+# define R128_VCLK_SRC_SEL_PPLLCLK 0x03
# define R128_ECP_DIV_MASK (3 << 8)
+#define R128_V2CLK_VCLKTV_CNTL 0x002d /* PLL */
+# define R128_V2CLK_SRC_SEL_MASK 0x03
+# define R128_V2CLK_SRC_SEL_CPUCLK 0x00
+# define R128_V2CLK_SRC_SEL_P2PLLCLK 0x03
#define R128_VENDOR_ID 0x0f00 /* PCI */
#define R128_VGA_DDA_CONFIG 0x02e8
#define R128_VGA_DDA_ON_OFF 0x02ec
diff --git a/programs/Xserver/hw/xfree86/drivers/ati/r128_version.h b/programs/Xserver/hw/xfree86/drivers/ati/r128_version.h
index 78dd5a580..34b0e660a 100644
--- a/programs/Xserver/hw/xfree86/drivers/ati/r128_version.h
+++ b/programs/Xserver/hw/xfree86/drivers/ati/r128_version.h
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_version.h,v 1.10tsi Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_version.h,v 1.11tsi Exp $ */
/*
* Copyright 2000 through 2008 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org
*
@@ -38,8 +38,8 @@
#define R128_DRIVER_NAME "r128"
#define R128_VERSION_MAJOR 4
-#define R128_VERSION_MINOR 0
-#define R128_VERSION_PATCH 1
+#define R128_VERSION_MINOR 1
+#define R128_VERSION_PATCH 0
#ifndef R128_VERSION_EXTRA
#define R128_VERSION_EXTRA ""
diff --git a/programs/Xserver/hw/xfree86/drivers/ati/r128_video.c b/programs/Xserver/hw/xfree86/drivers/ati/r128_video.c
index 7b3f08b8c..5b57d1a7a 100644
--- a/programs/Xserver/hw/xfree86/drivers/ati/r128_video.c
+++ b/programs/Xserver/hw/xfree86/drivers/ati/r128_video.c
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_video.c,v 1.32tsi Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_video.c,v 1.33tsi Exp $ */
#include "r128.h"
#include "r128_reg.h"
@@ -579,20 +579,20 @@ R128AllocateMemory(
pScreen = screenInfo.screens[pScrn->scrnIndex];
- new_linear = xf86AllocateOffscreenLinear(pScreen, size, 16,
+ new_linear = xf86AllocateOffscreenLinear(pScreen, size, 8,
NULL, NULL, NULL);
if(!new_linear) {
int max_size;
- xf86QueryLargestOffscreenLinear(pScreen, &max_size, 16,
+ xf86QueryLargestOffscreenLinear(pScreen, &max_size, 8,
PRIORITY_EXTREME);
if(max_size < size)
return NULL;
xf86PurgeUnlockedOffscreenAreas(pScreen);
- new_linear = xf86AllocateOffscreenLinear(pScreen, size, 16,
+ new_linear = xf86AllocateOffscreenLinear(pScreen, size, 8,
NULL, NULL, NULL);
}