From 04cbb8d174cc5e3c7ecdd4e171170213ecb3c7ed Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sat, 26 Mar 2005 00:53:01 +0000 Subject: bugzilla #2057 (https://bugs.freedesktop.org/show_bug.cgi?id=2057) attachment #1516 (https://bugs.freedesktop.org/attachment.cgi?id=1516) Add TVOUT Support for Mach64 (Leif Delgass, fixed up for Xorg by me). --- src/atimode.c | 145 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 136 insertions(+), 9 deletions(-) (limited to 'src/atimode.c') diff --git a/src/atimode.c b/src/atimode.c index 02cf319..63b0dcd 100644 --- a/src/atimode.c +++ b/src/atimode.c @@ -1,6 +1,6 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atimode.c,v 1.17 2003/04/23 21:51:29 tsi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atimode.c,v 1.18 2004/01/05 16:42:03 tsi Exp $ */ /* - * Copyright 2000 through 2003 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org + * Copyright 2000 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -35,6 +35,18 @@ #include "atiwonder.h" #include "atiwonderio.h" +#ifdef TV_OUT + +#include "vbe.h" + +static const char *vbeSymbols[] = { + "VBESetVBEMode", + "vbeFree", + NULL +}; + +#endif /* TV_OUT */ + #ifndef AVOID_CPIO /* @@ -125,7 +137,6 @@ ATISwap seq4 = GetReg(SEQX, 0x04U); gra1 = GetReg(GRAX, 0x01U); gra3 = GetReg(GRAX, 0x03U); - gra4 = GetReg(GRAX, 0x04U); gra5 = GetReg(GRAX, 0x05U); gra6 = GetReg(GRAX, 0x06U); gra8 = GetReg(GRAX, 0x08U); @@ -365,7 +376,7 @@ ATIModeSave int Index; - /* Get bank to bank 0 */ + /* Get back to bank 0 */ (*pATIHW->SetBank)(pATI, 0); #endif /* AVOID_CPIO */ @@ -908,11 +919,17 @@ ATIModeCalculate else MaxScalerClock = 80000; /* Conservative */ pATIHW->pll_vclk_cntl &= ~PLL_ECP_DIV; - /* XXX Don't do this for TVOut! */ - ECPClock = pMode->SynthClock; - for (Index = 0; (ECPClock > MaxScalerClock) && (Index < 2); Index++) - ECPClock >>= 1; - pATIHW->pll_vclk_cntl |= SetBits(Index, PLL_ECP_DIV); +#ifdef TV_OUT + if (!pATI->OptionTvOut) { +#endif /* TV_OUT */ + /* XXX Don't do this for TVOut! */ + ECPClock = pMode->SynthClock; + for (Index = 0; (ECPClock > MaxScalerClock) && (Index < 2); Index++) + ECPClock >>= 1; + pATIHW->pll_vclk_cntl |= SetBits(Index, PLL_ECP_DIV); +#ifdef TV_OUT + } +#endif /* TV_OUT */ } else if (pATI->DAC == ATI_DAC_IBMRGB514) { @@ -922,6 +939,108 @@ ATIModeCalculate return TRUE; } +#ifdef TV_OUT + +static void +ATISetVBEMode +( + ScrnInfoPtr pScreenInfo, + ATIPtr pATI, + ATIHWPtr pATIHW +) +{ + + xf86LoaderRefSymLists(vbeSymbols, NULL); + + if (pATIHW->crtc == ATI_CRTC_MACH64) { + int vbemode, modekey; + + /* Find a suitable VESA VBE mode, if one exists */ + modekey = (pScreenInfo->depth << 16) | + (pScreenInfo->currentMode->HDisplay); + + switch (modekey) { + case (15<<16)|(640): + vbemode = 0x110; + break; + case (16<<16)|(640): + vbemode = 0x111; + break; +#if 0 + case (24<<16)|(640): + vbemode = 0x112; + break; +#endif + case (15<<16)|(800): + vbemode = 0x113; + break; + case (16<<16)|(800): + vbemode = 0x114; + break; +#if 0 + case (24<<16)|(800): + vbemode = 0x115; + break; +#endif + case (15<<16)|(1024): + vbemode = 0x116; + break; + case (16<<16)|(1024): + vbemode = 0x117; + break; +#if 0 + case (24<<16)|(1024): + vbemode = 0x118; + break; +#endif + default: + xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, + "Mode not supported for TV-Out: depth: %ld HDisplay: %ld\n", + modekey>>16, modekey & 0xffff); + return; + } + + if (pATI->pVBE) { + + /* Preserve video memory contents */ + vbemode |= (1<<15); + + if (VBESetVBEMode(pATI->pVBE, vbemode, NULL)) { + xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, + "VBESetMode: 0x%X (width: %d, pitch: %d, depth: %d)\n", + vbemode, + pScreenInfo->currentMode->HDisplay, + pScreenInfo->displayWidth, + pScreenInfo->depth); + outr(CRTC_OFF_PITCH, + SetBits(pScreenInfo->displayWidth>>3, CRTC_PITCH)); + } else { + xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, "VBESetMode failed.\n"); + } + } else { + xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, "VBE module not loaded.\n"); + } + } else { + /* restore text mode with VBESetMode */ + if (pATI->pVBE) { + if (VBESetVBEMode(pATI->pVBE, pATI->vbemode, NULL)) { + xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, "Restoring VESA mode: 0x%x\n", + pATI->vbemode); + } else { + xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, "VBESetMode failed.\n"); + } + } else { + xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, "VBE module not loaded.\n"); + } + } + if (xf86ServerIsExiting()) { + if (pATI->pVBE) vbeFree(pATI->pVBE); + if (pATI->pInt10) xf86FreeInt10(pATI->pInt10); + } +} + +#endif /* TV_OUT */ + /* * ATIModeSet -- * @@ -1165,6 +1284,14 @@ ATIModeSet /* Reset hardware cursor caching */ pATI->CursorXOffset = pATI->CursorYOffset = (CARD16)(-1); +#ifdef TV_OUT + + /* Set VBE mode for TV-Out */ + if (pATI->OptionTvOut /* && pATI->tvActive */) + ATISetVBEMode(pScreenInfo, pATI, pATIHW); + +#endif /* TV_OUT */ + #ifndef AVOID_CPIO /* Restore video memory */ -- cgit v1.2.3