summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkem <kem>2000-08-28 20:18:02 +0000
committerkem <kem>2000-08-28 20:18:02 +0000
commit48580b2370b758d623b4eb1722760d14226d4aca (patch)
tree70428e22a8a5da189cb6d1d4fb199d6e9a142565
parente71d8df117a712d1e1209344aca4db9d8055cf33 (diff)
Initial support for the Rage 128 Mobility chips (M3/M4). Pleasem3-0-0-1-branch
note the following caveats: - We have not put this driver through our normal testing and verification procedure. - This driver has only been minimally tested on a Dell M3 system. - Spread spectrum is not yet supported. - HW-accelerated 3D is not yet supported. - External CRT display is not yet supported. - If the user hits the LCD/CRT hotkey, the results are undefined since currently we have no way to trap the hotkey. - This driver has not been tested with Linux's FBDev support. - This driver has not been tested on Sharp panels. - There are known display problems in 24 bpp and 32 bpp modes for the following display resolutions: 1024x768, 800x600 and 640x480 - When exiting the X server, the machine sometimes, but very rarely, locks up. - XFree86 -configure does not generate a useful XF86Config file. - Starting up the X server when the VGA console is in simultaneous LCD/CRT mode might result in the flat panel not being initialized properly. - Non-standard modes (e.g., 1400x1050) will require an appropriate Modeline in the XF86Config file. - The "Monitor" section of the XF86Config file need to have appropriate horizontal sync and vertical refresh timings for the panel.
-rw-r--r--xc/programs/Xserver/hw/xfree86/common/xf86PciInfo.h12
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/r128/r128.h15
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/r128/r128_driver.c593
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/r128/r128_reg.h12
4 files changed, 394 insertions, 238 deletions
diff --git a/xc/programs/Xserver/hw/xfree86/common/xf86PciInfo.h b/xc/programs/Xserver/hw/xfree86/common/xf86PciInfo.h
index 060c4ef7d..36738a836 100644
--- a/xc/programs/Xserver/hw/xfree86/common/xf86PciInfo.h
+++ b/xc/programs/Xserver/hw/xfree86/common/xf86PciInfo.h
@@ -229,6 +229,8 @@
#define PCI_CHIP_MACH64LP 0x4C50
#define PCI_CHIP_MACH64LR 0x4C52
#define PCI_CHIP_MACH64LS 0x4C53
+#define PCI_CHIP_RAGE128MF 0x4D46
+#define PCI_CHIP_RAGE128ML 0x4D4C
#define PCI_CHIP_RAGE128PF 0x5046
#define PCI_CHIP_RAGE128PR 0x5052
#define PCI_CHIP_RAGE128RE 0x5245
@@ -766,8 +768,8 @@ static pciVendorDeviceInfo xf86PCIVendorInfoData[] = {
{PCI_CHIP_MACH64GZ, "Mach64 GZ",0},
{PCI_CHIP_MACH64LB, "Mach64 LB",0},
{PCI_CHIP_MACH64LD, "Mach64 LD",0},
- {PCI_CHIP_RAGE128LE, "Rage 128 Mobility LE",0},
- {PCI_CHIP_RAGE128LF, "Rage 128 Mobility LF",0},
+ {PCI_CHIP_RAGE128LE, "Rage 128 Mobility LE",0},
+ {PCI_CHIP_RAGE128LF, "Rage 128 Mobility LF",0},
{PCI_CHIP_MACH64LG, "Mach64 LG",0},
{PCI_CHIP_MACH64LI, "Mach64 LI",0},
{PCI_CHIP_MACH64LM, "Mach64 LM",0},
@@ -775,8 +777,10 @@ static pciVendorDeviceInfo xf86PCIVendorInfoData[] = {
{PCI_CHIP_MACH64LP, "Mach64 LP",0},
{PCI_CHIP_MACH64LR, "Mach64 LR",0},
{PCI_CHIP_MACH64LS, "Mach64 LS",0},
- {PCI_CHIP_RAGE128PF, "Rage 128 Pro PF",0},
- {PCI_CHIP_RAGE128PR, "Rage 128 Pro PR",0},
+ {PCI_CHIP_RAGE128MF, "Rage 128 Mobility MF",0},
+ {PCI_CHIP_RAGE128ML, "Rage 128 Mobility ML",0},
+ {PCI_CHIP_RAGE128PF, "Rage 128 Pro PF",0},
+ {PCI_CHIP_RAGE128PR, "Rage 128 Pro PR",0},
{PCI_CHIP_RAGE128RE, "Rage 128 RE",0},
{PCI_CHIP_RAGE128RF, "Rage 128 RF",0},
{PCI_CHIP_RAGE128RK, "Rage 128 RK",0},
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128.h b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128.h
index 7adb19523..2bd636927 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128.h
+++ b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128.h
@@ -40,6 +40,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#define R128_TIMEOUT 2000000 /* Fall out of wait loops after this count */
#define R128_MMIOSIZE 0x80000
+#define R128_VBIOS_SIZE 0x00010000
+
/* R128_NAME is used for the server-side
ddx driver, the client-side DRI driver,
and the kernel-level DRM driver. */
@@ -179,6 +181,7 @@ typedef struct {
unsigned long LinearAddr; /* Frame buffer physical address */
unsigned long MMIOAddr; /* MMIO region physical address */
unsigned long BIOSAddr; /* BIOS physical address */
+ Bool BIOSFromPCI; /* BIOS is read from PCI space */
unsigned char *MMIO; /* Map of MMIO region */
unsigned char *FB; /* Map of frame buffer */
@@ -188,19 +191,15 @@ typedef struct {
unsigned long FbMapSize; /* Size of frame buffer, in bytes */
int Flags; /* Saved copy of mode flags */
- Bool EnableFP; /* Enable use of FP registers */
- Bool CRTOnly; /* Only use External CRT instead of FP */
Bool HasPanelRegs; /* Current chip can connect to a FP */
+ Bool CRTOnly; /* Only use External CRT instead of FP */
+ CARD8 *VBIOS; /* Video BIOS for mode validation on FPs */
+ int FPBIOSstart; /* Start of the flat panel info */
/* Computed values for FPs */
int PanelXRes;
int PanelYRes;
- int PanelHNonVis;
- int PanelHOverPlus;
- int PanelHSyncWidth;
- int PanelVNonVis;
- int PanelVOverPlus;
- int PanelVSyncWidth;
+ int PanelPwrDly;
R128PLLRec pll;
R128RAMPtr ram;
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_driver.c
index 215761d29..058685d8c 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_driver.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_driver.c
@@ -171,6 +171,8 @@ static SymTabRec R128Chipsets[] = {
{ PCI_CHIP_RAGE128PF, "ATI Rage 128 Pro PF (AGP)" },
{ PCI_CHIP_RAGE128LE, "ATI Rage 128 Mobility LE (PCI)" },
{ PCI_CHIP_RAGE128LF, "ATI Rage 128 Mobility LF (AGP)" },
+ { PCI_CHIP_RAGE128MF, "ATI Rage 128 Mobility MF (AGP)" },
+ { PCI_CHIP_RAGE128ML, "ATI Rage 128 Mobility ML (AGP)" },
{ -1, NULL }
};
@@ -182,6 +184,8 @@ static PciChipsets R128PciChipsets[] = {
{ PCI_CHIP_RAGE128PF, PCI_CHIP_RAGE128PF, RES_SHARED_VGA },
{ PCI_CHIP_RAGE128LE, PCI_CHIP_RAGE128LE, RES_SHARED_VGA },
{ PCI_CHIP_RAGE128LF, PCI_CHIP_RAGE128LF, RES_SHARED_VGA },
+ { PCI_CHIP_RAGE128MF, PCI_CHIP_RAGE128MF, RES_SHARED_VGA },
+ { PCI_CHIP_RAGE128ML, PCI_CHIP_RAGE128ML, RES_SHARED_VGA },
{ -1, -1, RES_UNDEFINED }
};
@@ -203,8 +207,12 @@ typedef enum {
OPTION_VBUF_SIZE,
OPTION_USE_CCE_2D,
#endif
- OPTION_ENABLE_FP,
+#if 0
+ /* FIXME: Disable CRTOnly until it is tested */
OPTION_CRT,
+#endif
+ OPTION_PANEL_WIDTH,
+ OPTION_PANEL_HEIGHT,
OPTION_FBDEV
} R128Opts;
@@ -226,8 +234,12 @@ static OptionInfoRec R128Options[] = {
{ OPTION_VBUF_SIZE, "VBSize", OPTV_INTEGER, {0}, FALSE },
{ OPTION_USE_CCE_2D, "UseCCEfor2D", OPTV_BOOLEAN, {0}, FALSE },
#endif
- { OPTION_ENABLE_FP, "EnableFP", OPTV_BOOLEAN, {0}, FALSE },
+#if 0
+ /* FIXME: Disable CRTOnly until it is tested */
{ OPTION_CRT, "CRTOnly", OPTV_BOOLEAN, {0}, FALSE },
+#endif
+ { OPTION_PANEL_WIDTH, "PanelWidth", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_PANEL_HEIGHT, "PanelHeight", OPTV_INTEGER, {0}, FALSE },
{ OPTION_FBDEV, "UseFBDev", OPTV_BOOLEAN, {0}, FALSE },
{ -1, NULL, OPTV_NONE, {0}, FALSE }
};
@@ -280,12 +292,6 @@ static const char *fbdevHWSymbols[] = {
NULL
};
-static const char *vbeSymbols[] = {
- "VBEInit",
- "vbeDoEDID",
- NULL
-};
-
#if 0
/* Not used until DDC is supported. */
static const char *ddcSymbols[] = {
@@ -303,6 +309,12 @@ static const char *i2cSymbols[] = {
#endif
#ifdef XFree86LOADER
+static const char *vbeSymbols[] = {
+ "VBEInit",
+ "vbeDoEDID",
+ NULL
+};
+
#ifdef USE_FB
static const char *fbSymbols[] = {
"fbScreenInit",
@@ -525,7 +537,7 @@ static Bool R128UnmapFB(ScrnInfoPtr pScrn)
{
R128InfoPtr info = R128PTR(pScrn);
- if(info->FBDev)
+ if (info->FBDev)
fbdevHWUnmapVidmem(pScrn);
else
xf86UnMapVidMem(pScrn->scrnIndex, info->FB, info->FbMapSize);
@@ -615,6 +627,118 @@ static int R128Div(int n, int d)
return (n + (d / 2)) / d;
}
+/* Read the Video BIOS block and the FP registers (if applicable). */
+static Bool R128GetBIOSParameters(ScrnInfoPtr pScrn)
+{
+ R128InfoPtr info = R128PTR(pScrn);
+ int i;
+ int FPHeader = 0;
+
+#define R128ReadBIOS(offset, buffer, length) \
+ (info->BIOSFromPCI ? \
+ xf86ReadPciBIOS(offset, info->PciTag, 0, buffer, length) : \
+ xf86ReadBIOS(info->BIOSAddr, offset, buffer, length))
+
+#define R128_BIOS8(v) (*((CARD8 *)(info->VBIOS + (v))))
+#define R128_BIOS16(v) (*((CARD16 *)(info->VBIOS + (v))))
+#define R128_BIOS32(v) (*((CARD32 *)(info->VBIOS + (v))))
+
+ if (!(info->VBIOS = xalloc(R128_VBIOS_SIZE))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Cannot allocate space for hold Video BIOS!\n");
+ return FALSE;
+ }
+
+ info->BIOSFromPCI = TRUE;
+ R128ReadBIOS(0x0000, info->VBIOS, R128_VBIOS_SIZE);
+ if (info->VBIOS[0] != 0x55 || info->VBIOS[1] != 0xaa) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Video BIOS not detected in PCI space!\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Attempting to read Video BIOS from legacy ISA space!\n");
+ info->BIOSFromPCI = FALSE;
+ info->BIOSAddr = 0x000c0000;
+ R128ReadBIOS(0x0000, info->VBIOS, R128_VBIOS_SIZE);
+ }
+ if (info->VBIOS[0] != 0x55 || info->VBIOS[1] != 0xaa) {
+ info->BIOSAddr = 0x00000000;
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Video BIOS not found!\n");
+ }
+
+ if (info->HasPanelRegs) {
+ info->FPBIOSstart = 0;
+
+ /* FIXME: There should be direct access to the start of the FP info
+ tables, but until we find out where that offset is stored, we
+ must search for the ATI signature string: "M3 ". */
+ for (i = 4; i < R128_VBIOS_SIZE-8; i++) {
+ if (R128_BIOS8(i) == 'M' &&
+ R128_BIOS8(i+1) == '3' &&
+ R128_BIOS8(i+2) == ' ' &&
+ R128_BIOS8(i+3) == ' ' &&
+ R128_BIOS8(i+4) == ' ' &&
+ R128_BIOS8(i+5) == ' ' &&
+ R128_BIOS8(i+6) == ' ' &&
+ R128_BIOS8(i+7) == ' ') {
+ FPHeader = i-2;
+ break;
+ }
+ }
+
+ if (!FPHeader) return TRUE;
+
+ /* Assume that only one panel is attached and supported */
+ for (i = FPHeader+20; i < FPHeader+84; i += 2) {
+ if (R128_BIOS16(i) != 0) {
+ info->FPBIOSstart = R128_BIOS16(i);
+ break;
+ }
+ }
+ if (!info->FPBIOSstart) return TRUE;
+
+ if (!info->PanelXRes)
+ info->PanelXRes = R128_BIOS16(info->FPBIOSstart+25);
+ if (!info->PanelYRes)
+ info->PanelYRes = R128_BIOS16(info->FPBIOSstart+27);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel size: %dx%d\n",
+ info->PanelXRes, info->PanelYRes);
+
+ info->PanelPwrDly = R128_BIOS8(info->FPBIOSstart+56);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel ID: ");
+ for (i = 1; i <= 24; i++)
+ ErrorF("%c", R128_BIOS8(info->FPBIOSstart+i));
+ ErrorF("\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel Type: ");
+ i = R128_BIOS16(info->FPBIOSstart+29);
+ if (i & 1) ErrorF("Color, ");
+ else ErrorF("Monochrome, ");
+ if (i & 2) ErrorF("Dual(split), ");
+ else ErrorF("Single, ");
+ switch ((i >> 2) & 0x3f) {
+ case 0: ErrorF("STN"); break;
+ case 1: ErrorF("TFT"); break;
+ case 2: ErrorF("Active STN"); break;
+ case 3: ErrorF("EL"); break;
+ case 4: ErrorF("Plasma"); break;
+ default: ErrorF("UNKNOWN"); break;
+ }
+ ErrorF("\n");
+ if (R128_BIOS8(info->FPBIOSstart+61) & 1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel Interface: LVDS\n");
+ } else {
+ /* FIXME: Add Non-LVDS flat pael support */
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Non-LVDS panel interface detected! "
+ "This support is untested and may not "
+ "function properly\n");
+ }
+ }
+
+ return TRUE;
+}
+
/* Read PLL parameters from BIOS block. Default to typical values if there
is no BIOS. */
static Bool R128GetPLLParameters(ScrnInfoPtr pScrn)
@@ -623,26 +747,8 @@ static Bool R128GetPLLParameters(ScrnInfoPtr pScrn)
R128PLLPtr pll = &info->pll;
CARD16 bios_header;
CARD16 pll_info_block;
- CARD8 tmp[64];
- Bool BIOSFromPCI = TRUE;
-#define R128ReadBIOS(offset, buffer, length) \
- (BIOSFromPCI ? \
- xf86ReadPciBIOS(offset, info->PciTag, 0, buffer, length) : \
- xf86ReadBIOS(info->BIOSAddr, offset, buffer, length))
-
- R128ReadBIOS(0, tmp, sizeof(tmp));
- if (tmp[0] != 0x55 || tmp[1] != 0xaa)
- {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Video BIOS not detected in PCI space!\n");
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Attempting to read Video BIOS from legacy ISA space!\n");
- BIOSFromPCI = FALSE;
- info->BIOSAddr = 0x000c0000;
- R128ReadBIOS(0, tmp, sizeof(tmp));
- }
- if (tmp[0] != 0x55 || tmp[1] != 0xaa) {
+ if (!info->VBIOS) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Video BIOS not detected, using default PLL parameters!\n");
/* These probably aren't going to work for
@@ -655,27 +761,16 @@ static Bool R128GetPLLParameters(ScrnInfoPtr pScrn)
pll->max_pll_freq = 25000;
pll->xclk = 10300;
} else {
- R128ReadBIOS(0x48,
- (CARD8 *)&bios_header, sizeof(bios_header));
- R128ReadBIOS(bios_header + 0x30,
- (CARD8 *)&pll_info_block, sizeof(pll_info_block));
+ bios_header = R128_BIOS16(0x48);
+ pll_info_block = R128_BIOS16(bios_header + 0x30);
R128TRACE(("Header at 0x%04x; PLL Information at 0x%04x\n",
bios_header, pll_info_block));
- R128ReadBIOS(pll_info_block + 0x0e,
- (CARD8 *)&pll->reference_freq,
- sizeof(pll->reference_freq));
- R128ReadBIOS(pll_info_block + 0x10,
- (CARD8 *)&pll->reference_div,
- sizeof(pll->reference_div));
- R128ReadBIOS(pll_info_block + 0x12,
- (CARD8 *)&pll->min_pll_freq,
- sizeof(pll->min_pll_freq));
- R128ReadBIOS(pll_info_block + 0x16,
- (CARD8 *)&pll->max_pll_freq,
- sizeof(pll->max_pll_freq));
- R128ReadBIOS(pll_info_block + 0x08,
- (CARD8 *)&pll->xclk, sizeof(pll->xclk));
+ pll->reference_freq = R128_BIOS16(pll_info_block + 0x0e);
+ pll->reference_div = R128_BIOS16(pll_info_block + 0x10);
+ pll->min_pll_freq = R128_BIOS32(pll_info_block + 0x12);
+ pll->max_pll_freq = R128_BIOS32(pll_info_block + 0x16);
+ pll->xclk = R128_BIOS16(pll_info_block + 0x08);
}
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
@@ -863,9 +958,6 @@ static Bool R128PreInitConfig(ScrnInfoPtr pScrn)
int offset = 0; /* RAM Type */
MessageType from;
unsigned char *R128MMIO;
- CARD32 fp_horz_stretch = 0, fp_vert_stretch = 0;
- CARD32 crtc_h_total_disp = 0, crtc_v_total_disp = 0;
- CARD32 crtc_h_sync_strt_wid = 0, crtc_v_sync_strt_wid = 0;
/* Chipset */
from = X_PROBED;
@@ -953,7 +1045,9 @@ static Bool R128PreInitConfig(ScrnInfoPtr pScrn)
/* FIXME: Make this an option */
switch (info->Chipset) {
case PCI_CHIP_RAGE128LE:
- case PCI_CHIP_RAGE128LF: info->HasPanelRegs = TRUE; break;
+ case PCI_CHIP_RAGE128LF:
+ case PCI_CHIP_RAGE128MF:
+ case PCI_CHIP_RAGE128ML: info->HasPanelRegs = TRUE; break;
case PCI_CHIP_RAGE128RE:
case PCI_CHIP_RAGE128RF:
case PCI_CHIP_RAGE128RK:
@@ -972,14 +1066,6 @@ static Bool R128PreInitConfig(ScrnInfoPtr pScrn)
pScrn->videoRam = INREG(R128_CONFIG_MEMSIZE) / 1024;
info->MemCntl = INREG(R128_MEM_CNTL);
info->BusCntl = INREG(R128_BUS_CNTL);
- if (info->HasPanelRegs) {
- fp_horz_stretch = INREG(R128_FP_HORZ_STRETCH);
- fp_vert_stretch = INREG(R128_FP_VERT_STRETCH);
- crtc_h_total_disp = INREG(R128_CRTC_H_TOTAL_DISP);
- crtc_v_total_disp = INREG(R128_CRTC_V_TOTAL_DISP);
- crtc_h_sync_strt_wid = INREG(R128_CRTC_H_SYNC_STRT_WID);
- crtc_v_sync_strt_wid = INREG(R128_CRTC_V_SYNC_STRT_WID);
- }
R128MMIO = NULL;
R128UnmapMMIO(pScrn);
@@ -989,6 +1075,8 @@ static Bool R128PreInitConfig(ScrnInfoPtr pScrn)
switch (info->Chipset) {
case PCI_CHIP_RAGE128LE:
case PCI_CHIP_RAGE128LF:
+ case PCI_CHIP_RAGE128MF:
+ case PCI_CHIP_RAGE128ML:
case PCI_CHIP_RAGE128RE:
case PCI_CHIP_RAGE128RF: offset = 0; break; /* 128-bit SDR SGRAM 1:1 */
case PCI_CHIP_RAGE128RK:
@@ -1016,10 +1104,12 @@ static Bool R128PreInitConfig(ScrnInfoPtr pScrn)
"VideoRAM: %d kByte (%s)\n", pScrn->videoRam, info->ram->name);
/* Flat panel (part 2) */
- if ((info->EnableFP = xf86ReturnOptValBool(R128Options,
- OPTION_ENABLE_FP, FALSE))) {
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
- "Enabling use of flat panel registers\n");
+ if (info->HasPanelRegs) {
+#if 1
+ info->CRTOnly = FALSE;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Using flat panel for display\n");
+#else
if ((info->CRTOnly = xf86ReturnOptValBool(R128Options,
OPTION_CRT, FALSE))) {
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
@@ -1029,57 +1119,24 @@ static Bool R128PreInitConfig(ScrnInfoPtr pScrn)
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Using flat panel for display\n");
}
+#endif
+ } else {
+ info->CRTOnly = FALSE;
}
if (info->HasPanelRegs) {
- int tmp;
-
- info->PanelXRes =
- (fp_horz_stretch & R128_HORZ_PANEL_SIZE) >> R128_HORZ_PANEL_SHIFT;
- info->PanelXRes = (info->PanelXRes + 1) * 8;
- info->PanelYRes =
- (fp_vert_stretch & R128_VERT_PANEL_SIZE) >> R128_VERT_PANEL_SHIFT;
- info->PanelYRes += 1;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel dimensions: %dx%d\n",
- info->PanelXRes, info->PanelYRes);
-
- info->PanelHNonVis =
- (crtc_h_total_disp & R128_CRTC_H_TOTAL) >> R128_CRTC_H_TOTAL_SHIFT;
- info->PanelHNonVis += 4; /* Add 4 since we are in VGA mode */
- tmp =
- (crtc_h_total_disp & R128_CRTC_H_DISP) >> R128_CRTC_H_DISP_SHIFT;
- info->PanelHNonVis -= tmp;
- info->PanelHOverPlus =
- (crtc_h_sync_strt_wid & R128_CRTC_H_SYNC_STRT_CHAR)
- >> R128_CRTC_H_SYNC_STRT_CHAR_SHIFT;
- info->PanelHOverPlus -= tmp;
- switch (info->CurrentLayout.pixel_code) {
- /* Adjustments are from ATI */
- case 8: info->PanelHOverPlus += 2; break;
- case 15:
- case 16: info->PanelHOverPlus += 1; break;
- case 24:
- case 32: info->PanelHOverPlus += 0; break;
+ info->PanelXRes = 0;
+ info->PanelYRes = 0;
+ if (xf86GetOptValInteger(R128Options,
+ OPTION_PANEL_WIDTH, &(info->PanelXRes))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Flat panel width: %d\n", info->PanelXRes);
+ }
+ if (xf86GetOptValInteger(R128Options,
+ OPTION_PANEL_HEIGHT, &(info->PanelYRes))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Flat panel height: %d\n", info->PanelYRes);
}
- info->PanelHSyncWidth =
- (crtc_h_sync_strt_wid & R128_CRTC_H_SYNC_WID)
- >> R128_CRTC_H_SYNC_WID_SHIFT;
- info->PanelHSyncWidth += 14; /* ??? */
-
- info->PanelVNonVis =
- (crtc_v_total_disp & R128_CRTC_V_TOTAL) >> R128_CRTC_V_TOTAL_SHIFT;
- info->PanelVNonVis += 1; /* Add 1 since we are in VGA mode */
- tmp =
- (crtc_v_total_disp & R128_CRTC_V_DISP) >> R128_CRTC_V_DISP_SHIFT;
- info->PanelVNonVis -= tmp;
- info->PanelVOverPlus =
- (crtc_v_sync_strt_wid & R128_CRTC_V_SYNC_STRT)
- >> R128_CRTC_V_SYNC_STRT_SHIFT;
- info->PanelVOverPlus -= tmp + 1;
- info->PanelVSyncWidth =
- (crtc_v_sync_strt_wid & R128_CRTC_V_SYNC_WID)
- >> R128_CRTC_V_SYNC_WID_SHIFT;
- info->PanelVSyncWidth -= 2; /* ??? */
}
#ifdef XF86DRI
@@ -1093,6 +1150,8 @@ static Bool R128PreInitConfig(ScrnInfoPtr pScrn)
case PCI_CHIP_RAGE128RE:
case PCI_CHIP_RAGE128RK: info->IsPCI = TRUE; break;
case PCI_CHIP_RAGE128LF:
+ case PCI_CHIP_RAGE128MF:
+ case PCI_CHIP_RAGE128ML:
case PCI_CHIP_RAGE128RF:
case PCI_CHIP_RAGE128RL:
case PCI_CHIP_RAGE128PF:
@@ -1155,14 +1214,19 @@ static Bool R128PreInitModes(ScrnInfoPtr pScrn)
const char *Sym = NULL;
/* Get mode information */
- pScrn->progClock = TRUE;
- clockRanges = xnfcalloc(sizeof(*clockRanges), 1);
- clockRanges->next = NULL;
- clockRanges->minClock = info->pll.min_pll_freq;
- clockRanges->maxClock = info->pll.max_pll_freq * 10;
- clockRanges->clockIndex = -1;
- clockRanges->interlaceAllowed = TRUE;
- clockRanges->doubleScanAllowed = TRUE;
+ 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) {
+ clockRanges->interlaceAllowed = FALSE;
+ clockRanges->doubleScanAllowed = FALSE;
+ } else {
+ clockRanges->interlaceAllowed = TRUE;
+ clockRanges->doubleScanAllowed = TRUE;
+ }
modesFound = xf86ValidateModes(pScrn,
pScrn->monitor->Modes,
@@ -1263,13 +1327,11 @@ static Bool R128PreInitDRI(ScrnInfoPtr pScrn)
R128InfoPtr info = R128PTR(pScrn);
if (info->IsPCI) {
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "CCE in PIO mode\n");
info->CCEMode = R128_DEFAULT_CCE_PIO_MODE;
} else if (xf86ReturnOptValBool(R128Options, OPTION_CCE_PIO, FALSE)) {
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "CCE in PIO mode\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Forcing CCE into PIO mode\n");
info->CCEMode = R128_DEFAULT_CCE_PIO_MODE;
} else {
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "CCE in BM mode\n");
info->CCEMode = R128_DEFAULT_CCE_BM_MODE;
}
@@ -1370,19 +1432,6 @@ static Bool R128PreInitDRI(ScrnInfoPtr pScrn)
info->agpTexSize = info->agpSize - (info->ringSize +
info->vbSize +
info->indSize);
-
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
- "Using %d MB AGP aperture\n", info->agpSize);
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
- "Using %d MB for the ring buffer\n", info->ringSize);
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
- "Using %d MB for vertex buffers\n", info->vbSize);
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
- "Using %d MB for indirect buffers\n", info->indSize);
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
- "Using %d MB for AGP textures\n", info->agpTexSize);
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
- "Using %d byte vertex buffers\n", info->vbBufSize);
}
if (xf86GetOptValInteger(R128Options, OPTION_USEC_TIMEOUT,
@@ -1475,30 +1524,45 @@ static Bool R128PreInit(ScrnInfoPtr pScrn, int flags)
}
if (!info->FBDev)
- if (!R128PreInitInt10(pScrn)) goto fail;
+ if (!R128PreInitInt10(pScrn)) goto fail;
+
+ if (!R128PreInitConfig(pScrn)) goto fail;
- if (!R128PreInitConfig(pScrn)) goto fail;
+ if (!R128GetBIOSParameters(pScrn)) goto fail;
- if (!R128GetPLLParameters(pScrn)) goto fail;
+ if (!R128GetPLLParameters(pScrn)) goto fail;
- if (!R128PreInitDDC(pScrn)) goto fail;
+ if (!R128PreInitDDC(pScrn)) goto fail;
- if (!R128PreInitGamma(pScrn)) goto fail;
+ if (!R128PreInitGamma(pScrn)) goto fail;
- if (!R128PreInitModes(pScrn)) goto fail;
+ if (!R128PreInitModes(pScrn)) goto fail;
- if (!R128PreInitCursor(pScrn)) goto fail;
+ if (!R128PreInitCursor(pScrn)) goto fail;
- if (!R128PreInitAccel(pScrn)) goto fail;
+ if (!R128PreInitAccel(pScrn)) goto fail;
#ifdef XF86DRI
- if (!R128PreInitDRI(pScrn)) goto fail;
+ if (!R128PreInitDRI(pScrn)) goto fail;
#endif
+ /* Free the video bios (if applicable) */
+ if (info->VBIOS) {
+ xfree(info->VBIOS);
+ info->VBIOS = NULL;
+ }
+
return TRUE;
fail:
/* Pre-init failed. */
+
+ /* Free the video bios (if applicable) */
+ if (info->VBIOS) {
+ xfree(info->VBIOS);
+ info->VBIOS = NULL;
+ }
+
vgaHWFreeHWRec(pScrn);
R128FreeRec(pScrn);
return FALSE;
@@ -1602,10 +1666,25 @@ static Bool R128ScreenInit(int scrnIndex, ScreenPtr pScreen,
called. cfbScreenInit will eventually
call the driver's InitGLXVisuals call
back. */
- if (!xf86ReturnOptValBool(R128Options, OPTION_NOACCEL, FALSE))
- info->directRenderingEnabled = R128DRIScreenInit(pScreen);
- else
- info->directRenderingEnabled = FALSE;
+ {
+ /* FIXME: When we move to dynamic allocation of back and depth
+ buffers, we will want to revisit the following check for 3
+ times the virtual size of the screen below. */
+ int width_bytes = (pScrn->displayWidth *
+ info->CurrentLayout.pixel_bytes);
+ int maxy = info->FbMapSize / width_bytes;
+
+ if (!xf86ReturnOptValBool(R128Options, OPTION_NOACCEL, FALSE) &&
+ (maxy > pScrn->virtualY * 3)
+#if 1
+ /* FIXME: Disable 3D support for FPs until it is tested */
+ && !info->HasPanelRegs
+#endif
+ )
+ info->directRenderingEnabled = R128DRIScreenInit(pScreen);
+ else
+ info->directRenderingEnabled = FALSE;
+ }
#endif
#ifdef USE_FB
@@ -1727,7 +1806,32 @@ static Bool R128ScreenInit(int scrnIndex, ScreenPtr pScreen,
info->CurrentLayout.pixel_bytes);
int maxy = info->FbMapSize / width_bytes;
int l;
-
+
+ switch (info->CCEMode) {
+ case R128_DEFAULT_CCE_PIO_MODE:
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CCE in PIO mode\n");
+ break;
+ case R128_DEFAULT_CCE_BM_MODE:
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CCE in BM mode\n");
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CCE in UNKNOWN mode\n");
+ break;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Using %d MB AGP aperture\n", info->agpSize);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Using %d MB for the ring buffer\n", info->ringSize);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Using %d MB for vertex buffers\n", info->vbSize);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Using %d MB for indirect buffers\n", info->indSize);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Using %d MB for AGP textures\n", info->agpTexSize);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Using %d byte vertex buffers\n", info->vbBufSize);
+
/* Allocate the shared back buffer */
if ((fbarea = xf86AllocateOffscreenArea(pScreen,
pScrn->virtualX,
@@ -1874,7 +1978,8 @@ static Bool R128ScreenInit(int scrnIndex, ScreenPtr pScreen,
/* DPMS setup */
#ifdef DPMSExtension
- xf86DPMSInit(pScreen, R128DisplayPowerManagementSet, 0);
+ if (!info->HasPanelRegs || info->CRTOnly)
+ xf86DPMSInit(pScreen, R128DisplayPowerManagementSet, 0);
#endif
/* Xv setup */
@@ -1962,6 +2067,7 @@ static void R128RestoreCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
/* Write flat panel registers */
static void R128RestoreFPRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
{
+ CARD32 tmp;
R128MMIO_VARS();
OUTREG(R128_CRTC2_GEN_CNTL, restore->crtc2_gen_cntl);
@@ -1973,8 +2079,23 @@ static void R128RestoreFPRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
OUTREG(R128_FP_PANEL_CNTL, restore->fp_panel_cntl);
OUTREG(R128_FP_V_SYNC_STRT_WID, restore->fp_v_sync_strt_wid);
OUTREG(R128_FP_VERT_STRETCH, restore->fp_vert_stretch);
- OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl);
OUTREG(R128_TMDS_CRC, restore->tmds_crc);
+
+ tmp = INREG(R128_LVDS_GEN_CNTL);
+ if ((tmp & (R128_LVDS_ON | R128_LVDS_BLON)) ==
+ (restore->lvds_gen_cntl & (R128_LVDS_ON | R128_LVDS_BLON))) {
+ OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl);
+ } else {
+ if (restore->lvds_gen_cntl & (R128_LVDS_ON | R128_LVDS_BLON)) {
+ OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl & ~R128_LVDS_BLON);
+ usleep(R128PTR(pScrn)->PanelPwrDly * 1000);
+ OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl);
+ } else {
+ OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl | R128_LVDS_BLON);
+ usleep(R128PTR(pScrn)->PanelPwrDly * 1000);
+ OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl);
+ }
+ }
}
static void R128PLLWaitForReadUpdateComplete(ScrnInfoPtr pScrn)
@@ -2061,12 +2182,15 @@ static void R128RestorePalette(ScrnInfoPtr pScrn, R128SavePtr restore)
/* Write out state to define a new video mode. */
static void R128RestoreMode(ScrnInfoPtr pScrn, R128SavePtr restore)
{
+ R128InfoPtr info = R128PTR(pScrn);
+
R128TRACE(("R128RestoreMode(%p)\n", restore));
R128RestoreCommonRegisters(pScrn, restore);
R128RestoreCrtcRegisters(pScrn, restore);
- if (R128PTR(pScrn)->HasPanelRegs && R128PTR(pScrn)->EnableFP)
+ if (info->HasPanelRegs)
R128RestoreFPRegisters(pScrn, restore);
- R128RestorePLLRegisters(pScrn, restore);
+ if (!info->HasPanelRegs || info->CRTOnly)
+ R128RestorePLLRegisters(pScrn, restore);
R128RestoreDDARegisters(pScrn, restore);
R128RestorePalette(pScrn, restore);
}
@@ -2174,7 +2298,7 @@ static void R128SaveMode(ScrnInfoPtr pScrn, R128SavePtr save)
R128SaveCommonRegisters(pScrn, save);
R128SaveCrtcRegisters(pScrn, save);
- if (R128PTR(pScrn)->HasPanelRegs && R128PTR(pScrn)->EnableFP)
+ if (R128PTR(pScrn)->HasPanelRegs)
R128SaveFPRegisters(pScrn, save);
R128SavePLLRegisters(pScrn, save);
R128SaveDDARegisters(pScrn, save);
@@ -2273,14 +2397,17 @@ static Bool R128InitCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr save,
int hsync_fudge;
int vsync_wid;
int bytpp;
+ 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 };
switch (info->CurrentLayout.pixel_code) {
- case 4: format = 1; bytpp = 0; hsync_fudge = 0; break;
- case 8: format = 2; bytpp = 1; hsync_fudge = 18; break;
- case 15: format = 3; bytpp = 2; hsync_fudge = 9; break; /* 555 */
- case 16: format = 4; bytpp = 2; hsync_fudge = 9; break; /* 565 */
- case 24: format = 5; bytpp = 3; hsync_fudge = 6; break; /* RGB */
- case 32: format = 6; bytpp = 4; hsync_fudge = 5; break; /* xRGB */
+ 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);
@@ -2288,6 +2415,10 @@ static Bool R128InitCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr save,
}
R128TRACE(("Format = %d (%d bytes per pixel)\n", format, bytpp));
+ if (info->HasPanelRegs)
+ if (info->CRTOnly) hsync_fudge = hsync_fudge_fp_crt[format-1];
+ else hsync_fudge = hsync_fudge_fp[format-1];
+ else hsync_fudge = hsync_fudge_default[format-1];
save->crtc_gen_cntl = (R128_CRTC_EXT_DISP_EN
| R128_CRTC_EN
@@ -2358,7 +2489,6 @@ static void R128InitFPRegisters(ScrnInfoPtr pScrn, R128SavePtr orig,
int xres = mode->CrtcHDisplay;
int yres = mode->CrtcVDisplay;
float Hratio, Vratio;
- int disp_end;
if (info->CRTOnly) {
save->crtc_ext_cntl |= R128_CRTC_CRT_ON;
@@ -2372,7 +2502,8 @@ static void R128InitFPRegisters(ScrnInfoPtr pScrn, R128SavePtr orig,
save->fp_gen_cntl |= (R128_FP_SEL_CRTC2 |
R128_FP_CRTC_DONT_SHADOW_VPAR);
save->fp_panel_cntl = orig->fp_panel_cntl & ~R128_FP_DIGON;
- save->lvds_gen_cntl = orig->lvds_gen_cntl & ~R128_LVDS_ON;
+ save->lvds_gen_cntl = orig->lvds_gen_cntl & ~(R128_LVDS_ON |
+ R128_LVDS_BLON);
return;
}
@@ -2383,35 +2514,39 @@ static void R128InitFPRegisters(ScrnInfoPtr pScrn, R128SavePtr orig,
Vratio = (float)yres/(float)info->PanelYRes;
save->fp_horz_stretch =
- (((((int)(Hratio * R128_HORZ_STRETCH_RATIO_MAX))
+ (((((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)));
- if (Hratio != 1.0) save->fp_horz_stretch |= (R128_HORZ_STRETCH_BLEND |
- R128_HORZ_STRETCH_ENABLE);
+ save->fp_horz_stretch &= ~R128_HORZ_AUTO_RATIO_FIX_EN;
+ if (Hratio == 1.0) 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_vert_stretch =
- (((((int)(Vratio * R128_VERT_STRETCH_RATIO_MAX))
+ (((((int)(Vratio * R128_VERT_STRETCH_RATIO_MAX + 0.5))
& R128_VERT_STRETCH_RATIO_MASK) << R128_VERT_STRETCH_RATIO_SHIFT) |
(orig->fp_vert_stretch & (R128_VERT_PANEL_SIZE |
- R128_VERT_STRETCH_RESERVED |
- R128_VERT_STRETCH_BLEND)));
- if (Vratio == 1.0) save->fp_vert_stretch &= ~R128_VERT_STRETCH_ENABLE;
- else save->fp_vert_stretch |= R128_VERT_STRETCH_ENABLE;
-
- save->fp_gen_cntl = ((orig->fp_gen_cntl & ~(R128_FP_SEL_CRTC2 |
- R128_FP_CRTC_USE_SHADOW_VEND |
- R128_FP_CRTC_HORZ_DIV2_EN |
- R128_FP_CRTC_HOR_CRT_DIV2_DIS |
- R128_FP_USE_SHADOW_EN)) |
- R128_FP_CRTC_DONT_SHADOW_VPAR |
- R128_FP_TDMS_EN);
+ R128_VERT_STRETCH_RESERVED)));
+ save->fp_vert_stretch &= ~R128_VERT_AUTO_RATIO_EN;
+ if (Vratio == 1.0) 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_gen_cntl = (orig->fp_gen_cntl & ~(R128_FP_SEL_CRTC2 |
+ R128_FP_CRTC_USE_SHADOW_VEND |
+ R128_FP_CRTC_HORZ_DIV2_EN |
+ R128_FP_CRTC_HOR_CRT_DIV2_DIS |
+ R128_FP_USE_SHADOW_EN));
+ if (orig->fp_gen_cntl & R128_FP_DETECT_SENSE) {
+ save->fp_gen_cntl |= (R128_FP_CRTC_DONT_SHADOW_VPAR |
+ R128_FP_TDMS_EN);
+ }
+
save->fp_panel_cntl = orig->fp_panel_cntl;
- save->fp_crtc_h_total_disp = orig->fp_crtc_h_total_disp;
- save->fp_crtc_v_total_disp = orig->fp_crtc_v_total_disp;
- save->fp_h_sync_strt_wid = orig->fp_h_sync_strt_wid;
- save->fp_v_sync_strt_wid = orig->fp_v_sync_strt_wid;
save->lvds_gen_cntl = orig->lvds_gen_cntl;
save->tmds_crc = orig->tmds_crc;
@@ -2425,51 +2560,18 @@ static void R128InitFPRegisters(ScrnInfoPtr pScrn, R128SavePtr orig,
save->dac_cntl |= R128_DAC_CRT_SEL_CRTC2;
save->crtc2_gen_cntl = 0;
+ /* WARNING: Be careful about turning on the flat panel */
+#if 1
+ save->lvds_gen_cntl |= (R128_LVDS_ON | R128_LVDS_BLON);
+#else
save->fp_panel_cntl |= (R128_FP_DIGON | R128_FP_BLON);
save->fp_gen_cntl |= (R128_FP_FPON);
+#endif
- save->crtc_gen_cntl &= ~(R128_CRTC_DBL_SCAN_EN |
- R128_CRTC_INTERLACE_EN |
- R128_CRTC_CSYNC_EN |
- R128_CRTC_CUR_EN |
- R128_CRTC_CUR_MODE_MASK |
- R128_CRTC_ICON_EN |
- R128_CRTC_EXT_DISP_EN |
- R128_CRTC_EN |
- R128_CRTC_DISP_REQ_EN_B);
- save->crtc_gen_cntl |= R128_CRTC_EXT_DISP_EN | R128_CRTC_EN;
-
- disp_end = xres/8 - 1;
- save->crtc_h_total_disp = ((disp_end << R128_CRTC_H_DISP_SHIFT) |
- (disp_end + info->PanelHNonVis));
-
- save->crtc_h_sync_strt_wid &= ~(R128_CRTC_H_SYNC_STRT_PIX |
- R128_CRTC_H_SYNC_STRT_CHAR |
- R128_CRTC_H_SYNC_WID);
- save->crtc_h_sync_strt_wid |=
- (disp_end + info->PanelHOverPlus) << R128_CRTC_H_SYNC_STRT_CHAR_SHIFT;
- switch (info->CurrentLayout.pixel_code) {
- /* Adjustments are from ATI */
- case 8: save->crtc_h_sync_strt_wid |= 2; break;
- case 15:
- case 16: save->crtc_h_sync_strt_wid |= 1; break;
- case 24: save->crtc_h_sync_strt_wid |= 6; break;
- case 32: save->crtc_h_sync_strt_wid |= 5; break;
- }
- save->crtc_h_sync_strt_wid |=
- info->PanelHSyncWidth << R128_CRTC_H_SYNC_WID_SHIFT;
- save->crtc_h_sync_strt_wid |= R128_CRTC_H_SYNC_POL;
-
- disp_end = yres - 1;
- save->crtc_v_total_disp = ((disp_end << R128_CRTC_V_DISP_SHIFT) |
- (disp_end + info->PanelVNonVis));
-
- save->crtc_v_sync_strt_wid &= ~(R128_CRTC_V_SYNC_STRT |
- R128_CRTC_V_SYNC_WID);
- save->crtc_v_sync_strt_wid |= (disp_end + info->PanelVOverPlus);
- save->crtc_v_sync_strt_wid |=
- info->PanelVSyncWidth << R128_CRTC_V_SYNC_WID_SHIFT;
- save->crtc_v_sync_strt_wid |= R128_CRTC_V_SYNC_POL;
+ save->fp_crtc_h_total_disp = save->crtc_h_total_disp;
+ save->fp_crtc_v_total_disp = save->crtc_v_total_disp;
+ save->fp_h_sync_strt_wid = save->crtc_h_sync_strt_wid;
+ save->fp_v_sync_strt_wid = save->crtc_v_sync_strt_wid;
}
/* Define PLL registers for requested video mode. */
@@ -2653,7 +2755,7 @@ static Bool R128Init(ScrnInfoPtr pScrn, DisplayModePtr mode, R128SavePtr save)
R128InitCommonRegisters(save, mode, info);
if (!R128InitCrtcRegisters(pScrn, save, mode, info)) return FALSE;
- if (info->HasPanelRegs && info->EnableFP)
+ if (info->HasPanelRegs)
R128InitFPRegisters(pScrn, &info->SavedReg, save, mode, info);
R128InitPLLRegisters(pScrn, save, mode, &info->pll, dot_clock);
if (!R128InitDDARegisters(pScrn, save, mode, &info->pll, info))
@@ -2708,6 +2810,51 @@ Bool R128SwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
static int R128ValidMode(int scrnIndex, DisplayModePtr mode,
Bool verbose, int flag)
{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ R128InfoPtr info = R128PTR(pScrn);
+
+ if (info->HasPanelRegs) {
+ if (mode->Flags & V_INTERLACE) return MODE_NO_INTERLACE;
+ if (mode->Flags & V_DBLSCAN) return MODE_NO_DBLESCAN;
+ }
+
+ if (info->HasPanelRegs && !info->CRTOnly && info->VBIOS) {
+ int i;
+ for (i = info->FPBIOSstart+64; R128_BIOS16(i) != 0; i += 2) {
+ int j = R128_BIOS16(i);
+
+ if (mode->CrtcHDisplay == R128_BIOS16(j) &&
+ mode->CrtcVDisplay == R128_BIOS16(j+2)) {
+ /* Assume we are using expanded mode */
+ if (R128_BIOS16(j+5)) j = R128_BIOS16(j+5);
+ else j += 9;
+
+ mode->Clock = (CARD32)R128_BIOS16(j) * 10;
+
+ mode->HDisplay = mode->CrtcHDisplay =
+ ((R128_BIOS16(j+10) & 0x01ff)+1)*8;
+ mode->HSyncStart = mode->CrtcHSyncStart =
+ ((R128_BIOS16(j+12) & 0x01ff)+1)*8;
+ mode->HSyncEnd = mode->CrtcHSyncEnd =
+ mode->CrtcHSyncStart + (R128_BIOS8(j+14) & 0x1f);
+ mode->HTotal = mode->CrtcHTotal =
+ ((R128_BIOS16(j+8) & 0x01ff)+1)*8;
+
+ mode->VDisplay = mode->CrtcVDisplay =
+ (R128_BIOS16(j+17) & 0x07ff)+1;
+ mode->VSyncStart = mode->CrtcVSyncStart =
+ (R128_BIOS16(j+19) & 0x07ff)+1;
+ mode->VSyncEnd = mode->CrtcVSyncEnd =
+ mode->CrtcVSyncStart + ((R128_BIOS16(j+19) >> 11) & 0x1f);
+ mode->VTotal = mode->CrtcVTotal =
+ (R128_BIOS16(j+15) & 0x07ff)+1;
+
+ return MODE_OK;
+ }
+ }
+ return MODE_NOMODE;
+ }
+
return MODE_OK;
}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_reg.h b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_reg.h
index 0bc455afb..090ae6e85 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_reg.h
+++ b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_reg.h
@@ -536,6 +536,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#define R128_FP_GEN_CNTL 0x0284
# define R128_FP_FPON (1 << 0)
# define R128_FP_TDMS_EN (1 << 2)
+# define R128_FP_DETECT_SENSE (1 << 8)
# define R128_FP_SEL_CRTC2 (1 << 13)
# define R128_FP_CRTC_DONT_SHADOW_VPAR (1 << 16)
# define R128_FP_CRTC_USE_SHADOW_VEND (1 << 18)
@@ -553,7 +554,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
# define R128_HORZ_STRETCH_BLEND (1 << 25)
# define R128_HORZ_STRETCH_ENABLE (1 << 26)
# define R128_HORZ_FP_LOOP_STRETCH (0x7 << 27)
-# define R128_HORZ_STRETCH_RESERVED 0xc0000000
+# define R128_HORZ_STRETCH_RESERVED (1 << 30)
+# define R128_HORZ_AUTO_RATIO_FIX_EN (1 << 31)
#define R128_FP_PANEL_CNTL 0x0288
# define R128_FP_DIGON (1 << 0)
@@ -568,6 +570,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
# define R128_VERT_STRETCH_ENABLE (1 << 24)
# define R128_VERT_STRETCH_LINEREP (0 << 25)
# define R128_VERT_STRETCH_BLEND (1 << 25)
+# define R128_VERT_AUTO_RATIO_EN (1 << 26)
# define R128_VERT_STRETCH_RESERVED 0xf8e00000
#define R128_GEN_INT_CNTL 0x0040
@@ -652,8 +655,11 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#define R128_LEAD_BRES_LNTH 0x161c
#define R128_LEAD_BRES_LNTH_SUB 0x1624
#define R128_LVDS_GEN_CNTL 0x02d0
-# define R128_LVDS_ON (1 << 0)
-# define R128_LVDS_SEL_CRTC2 (1 << 23)
+# define R128_LVDS_ON (1 << 0)
+# define R128_LVDS_BLON (1 << 19)
+# define R128_LVDS_SEL_CRTC2 (1 << 23)
+# define R128_HSYNC_DELAY_SHIFT 28
+# define R128_HSYNC_DELAY_MASK (0xf << 28)
#define R128_MAX_LATENCY 0x0f3f /* PCI */
#define R128_MCLK_CNTL 0x000f /* PLL */