Commit 7c7b2788 authored by Alex Deucher's avatar Alex Deucher

- Add support for Dualhead on M3/M4 (bug 1760)

parent 08a45118
......@@ -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
......@@ -108,7 +109,11 @@ are used, the system may hang.
Enable or disable use of an OS-specific framebuffer device interface
(which is not supported on all OSs). See fbdevhw(__drivermansuffix__)
for further information.
Default: off.
Default:
.BI on
for PowerPC,
.BI off
for other architectures.
.TP
.BI "Option \*qDMAForXv\*q \*q" boolean \*q
Try or don't try to use DMA for Xv image transfers. This will reduce CPU
......@@ -135,6 +140,12 @@ on PowerPC and
.B on
on other architectures.
.PP
.B Dualhead Note:
Changing modes on crtc2 in dualhead mode causes problems in
some configurations. The workaround is to switch the mode, change to another
VT, then change back.
.SH "SEE ALSO"
__xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), xorgconfig(__appmansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__)
.SH AUTHORS
......
......@@ -53,6 +53,8 @@
/* Xv support */
#include "xf86xv.h"
#include "r128_probe.h"
/* DRI support */
#ifdef XF86DRI
#define _XF86DRI_SERVER_
......@@ -135,6 +137,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;
......@@ -160,13 +169,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 {
......@@ -186,6 +211,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;
......@@ -403,6 +438,14 @@ typedef struct {
Bool VGAAccess;
/****** 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*/
} R128InfoRec, *R128InfoPtr;
#define R128WaitForFifo(pScrn, entries) \
......@@ -411,6 +454,7 @@ do { \
info->fifo_slots -= entries; \
} while (0)
extern R128EntPtr R128EntPriv(ScrnInfoPtr pScrn);
extern void R128WaitForFifoFunction(ScrnInfoPtr pScrn, int entries);
extern void R128WaitForIdle(ScrnInfoPtr pScrn);
extern void R128EngineReset(ScrnInfoPtr pScrn);
......
......@@ -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)
{
......@@ -1023,7 +1026,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);
......@@ -1647,6 +1650,25 @@ 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);
......@@ -1707,9 +1729,31 @@ 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);
......@@ -1788,6 +1832,22 @@ 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
......
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_cursor.c,v 1.6 2003/02/13 20:28:40 tsi Exp $ */
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_cursor.c,v 1.5tsi 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,15 @@ 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. */
......
......@@ -55,6 +55,8 @@
* overlay planes
*
* Modified by Marc Aurele La France <tsi@xfree86.org> for ATI driver merge.
*
* Dualhead support - Alex Deucher <agd5f@yahoo.com>
*/
......@@ -355,6 +357,17 @@ void R128LoaderRefSymLists(void)
NULL);
}
extern int gR128EntityIndex;
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)
{
......@@ -463,7 +476,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);
}
......@@ -497,10 +510,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. */
......@@ -509,12 +542,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. */
......@@ -577,7 +637,73 @@ 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
......@@ -925,6 +1051,7 @@ static Bool R128PreInitConfig(ScrnInfoPtr pScrn)
} else {
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.
......@@ -974,7 +1101,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:
......@@ -1022,6 +1153,8 @@ static Bool R128PreInitConfig(ScrnInfoPtr pScrn)
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"))
......@@ -1078,13 +1211,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");
......@@ -1869,9 +2024,44 @@ 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;
......@@ -2030,12 +2220,20 @@ 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;
/* 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);
/* Select palette 0 (main CRTC) if using FP-enabled chip */
if (info->HasPanelRegs || info->isDFP) PAL_SELECT(0);
/*if (info->HasPanelRegs || info->isDFP) PAL_SELECT(0);*/
if (info->CurrentLayout.depth == 15) {
/* 15bpp mode. This sends 32 values. */
......@@ -2113,6 +2311,7 @@ Bool R128ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
if (!R128MapMem(pScrn)) return FALSE;
pScrn->fbOffset = 0;
if(info->IsSecondary) pScrn->fbOffset = pScrn->videoRam * 1024;
#ifdef XF86DRI
info->fbX = 0;
info->fbY = 0;
......@@ -2166,7 +2365,33 @@ Bool R128ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
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]))
{
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");
}
else
info->directRenderingEnabled =
R128DRIScreenInit(pScreen);
if(xf86IsEntityShared(pScrn->entityList[0]))
{
DevUnion* pPriv;
R128EntPtr pR128Ent;
pPriv = xf86GetEntityPrivate(pScrn->entityList[0],
gR128EntityIndex);
pR128Ent = pPriv->ptr;
pR128Ent->IsDRIEnabled = info->directRenderingEnabled;
}
}
}
}
#endif
......@@ -2479,14 +2704,16 @@ Bool R128ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
/* DPMS setup - FIXME: also for mirror mode in non-fbdev case? - Michel */
if (info->FBDev)
xf86DPMSInit(pScreen, fbdevHWDPMSSetWeak(), 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;
......@@ -2567,6 +2794,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);