Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 89987 Details for
Bug 127642
[patch] enable tv-out/tvoutput for modular xorg >7.x (x11-drivers/xf86-video-ati)
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
patch for xorg 7 modular v 6.6.1 to enable tvoutput in ATI driver
xf86-video-ati-6.6.1-tvout.patch (text/plain), 133.61 KB, created by
Anton Bolshakov
on 2006-06-24 02:16:49 UTC
(
hide
)
Description:
patch for xorg 7 modular v 6.6.1 to enable tvoutput in ATI driver
Filename:
MIME Type:
Creator:
Anton Bolshakov
Created:
2006-06-24 02:16:49 UTC
Size:
133.61 KB
patch
obsolete
>diff -Naur xf86-video-ati.orig/src/tvo_set/Imakefile xf86-video-ati/src/tvo_set/Imakefile >--- xf86-video-ati.orig/src/tvo_set/Imakefile 1970-01-01 00:00:00.000000000 +0000 >+++ xf86-video-ati/src/tvo_set/Imakefile 2006-04-02 16:44:41.000000000 +0000 >@@ -0,0 +1,37 @@ >+XCOMM $Id: Imakefile,v 1.1.2.1 2004/01/27 22:55:40 fulivi Exp $ >+XCOMM >+XCOMM Imakefile for tvo_set utility >+XCOMM >+XCOMM Copyright (C) 2004 Federico Ulivi >+XCOMM >+XCOMM This program is free software; you can redistribute it and/or modify >+XCOMM it under the terms of the GNU General Public License as published by >+XCOMM the Free Software Foundation; either version 2 of the License, or >+XCOMM (at your option) any later version. >+XCOMM >+XCOMM This program is distributed in the hope that it will be useful, >+XCOMM but WITHOUT ANY WARRANTY; without even the implied warranty of >+XCOMM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+XCOMM GNU General Public License for more details. >+XCOMM >+XCOMM You should have received a copy of the GNU General Public License >+XCOMM along with this program; if not, write to the Free Software >+XCOMM Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA >+XCOMM >+XCOMM AUTHORS: F.Ulivi >+XCOMM NOTES: >+XCOMM $Log: Imakefile,v $ >+XCOMM Revision 1.1.2.1 2004/01/27 22:55:40 fulivi >+XCOMM Initial release >+XCOMM >+XCOMM Revision 1.1.2.1 2004/01/25 23:07:31 fede >+XCOMM *** empty log message *** >+XCOMM >+XCOMM >+ >+ DEPLIBS = $(DEPXVLIB) $(DEPXLIB) >+LOCAL_LIBRARIES = $(XVLIB) $(XLIB) >+ SRCS = tvo_set.c >+ OBJS = tvo_set.o >+ >+ComplexProgramTargetNoMan(tvo_set) >diff -Naur xf86-video-ati.orig/src/Makefile.am xf86-video-ati/src/Makefile.am >--- xf86-video-ati.orig/src/Makefile.am 2006-04-02 16:44:26.000000000 +0000 >+++ xf86-video-ati/src/Makefile.am 2006-04-02 16:44:41.000000000 +0000 >@@ -95,6 +95,15 @@ > theatre_drv_la_SOURCES = \ > theatre.c theatre_module.c > >+theater_out_drv_la_LTLIBRARIES = theater_out_drv.la >+theater_out_drv_la_LDFLAGS = -module -avoid-version >+theater_out_drv_ladir = @moduledir@/multimedia >+theater_out_drv_la_CFLAGS = \ >+ $(AM_CFLAGS) -DMICROC_DIR=\"$(theater_out_drv_ladir)\" >+theater_out_drv_la_SOURCES = \ >+ theater_out.c theater_out_module.c >+ >+ > theatre200_drv_la_LTLIBRARIES = theatre200_drv.la > theatre200_drv_la_LDFLAGS = -module -avoid-version > theatre200_drv_ladir = @moduledir@/multimedia >@@ -188,6 +197,7 @@ > radeon_sarea.h \ > radeon_version.h \ > radeon_video.h \ >+ theater_out.h \ > theatre200.h \ > theatre_detect.h \ > theatre.h \ >\ No newline at end of file >diff -Naur xf86-video-ati.orig/src/README.tvout xf86-video-ati/src/README.tvout >--- xf86-video-ati.orig/src/README.tvout 1970-01-01 00:00:00.000000000 +0000 >+++ xf86-video-ati/src/README.tvout 2006-04-02 16:44:41.000000000 +0000 >@@ -0,0 +1,236 @@ >+ >+ ******************************************************* >+ ** XFree86 driver for TV output on ATI Radeon cards ** >+ ******************************************************* >+ >+Copyright (c) 2003-2004, by Federico Ulivi <fulivi@lycos.com> >+Released under the GNU General Public License, version 2. >+ >+1. About this driver >+-------------------- >+ >+This driver was developped as a part of ati.2 project. Its purpose >+is to enable the TV output of ATI Radeon cards when running the >+XFree86 graphical environment. >+ >+2. Status of the driver >+----------------------- >+ >+The driver is in early development stage. It currently works with >+those cards having a Rage Theater chip for TV output or with cards >+having the tv module inside the Radeon chip (ERT, Embedded Rage >+Theater, is my name for the latter). >+The driver was successfully tested on these cards: >+- Radeon 7200 / European model (TV out hw: RT 100) >+- Radeon 9000 (TV out hw: ERT) >+- Radeon 9200SE (TV out hw: ERT) >+- Radeon 7000 (TV out hw: ERT) >+ >+3. Making it work >+----------------- >+ >+The driver is always loaded by the Radeon driver. If you need to >+disable this auto-loading mechanism, just set the "TVOutput" option >+(see below) to "NOLOAD". >+In principle the driver should coexist with video grabbing functions, >+especially on those AIW cards where TV output is done by ERT >+inside Radeon. >+ >+Principle of operation of the driver is very simple. Driver enables >+tv output whenever the current screen resolution and tv standard match >+one of a set of pre-computed combinations. In all other cases tv output >+is simply kept disabled. >+The driver currently works in the so-called "clone" mode only. This means >+that the image on the TV screen is exactly the same as the one on the >+monitor. >+ >+The driver is enabled by adding a "TVOutput" line in the "device" >+section of XF86Config-4 file (this file is usually located in /etc/X11 >+directory). Syntax of this option is very simple: >+ >+Section "Device" >+ .. >+ .. >+ Option "TVOuput" "<name of tv standard>" >+EndSection >+ >+Names of recognized TV standards are: >+"NTSC" >+"NTSC-J" >+"PAL" >+"PAL-CN" >+"PAL-M" >+"PAL-N" >+"PAL-60" >+ >+If "TVOutput" is not present or its value is invalid, TV output is kept disabled. >+ >+In the current version of the driver these are the recognized TV standard & >+resolution combinations: >+ >+PAL 800x600 >+NTSC 800x600 >+ >+More combinations will be added in future releases. >+ >+4. XV Interface >+--------------- >+ >+The driver has an external interface through some Xv attributes. >+You can change the value of these attributes by using the tvo_set utility >+(see below). >+ >+XV_TVO_STANDARD Settable/Gettable >+ This is the tv standard in use by the driver. Its value is encoded >+ according to this table: >+ >+ 0 NTSC >+ 1 PAL >+ 2 PAL-M >+ 3 PAL-60 >+ 4 NTSC-J >+ 5 PAL-CN >+ 6 PAL-N >+ 7 Keep TV off >+ >+XV_TVO_MODE_COMPAT Gettable >+ This attribute is set to 1 whenever TV output is enabled, i.e. >+ whenever the current resolution & tv standard combination is >+ recognized by the driver. >+ >+XV_TVO_HPOS Settable/Gettable >+ Horizontal position, valid range is [-5..+5]. >+ This attribute defines the horizontal position of the TV image. >+ Higher values shift the image to the right, lower values to the left. >+ >+XV_TVO_VPOS Settable/Gettable >+ Vertical position, valid range is [-5..+5]. >+ This attribute defines the vertical position of the TV image. >+ Higher values shift the image upward, lower values downward. >+ >+XV_TVO_HSIZE Settable/Gettable >+ Horizontal size, valid range is [-5..+5]. >+ This attribute is used to set the horizontal size of TV image. >+ Higher values enlarge TV lines, lower values reduce them. >+ >+Default value for XV_TVO_HPOS, XV_TVO_VPOS & XV_TVO_HSIZE just after >+X Window start is 0. >+ >+You might ask where a vertical size attribute has gone. It was not included >+because it's quite hard to implement (it requires changing many timings in >+the CRTC). For the moment I'm not planning to work on it. >+ >+5. tvo_set utility >+------------------ >+ >+tvo_set is a command line utility that is used to change TV output >+attributes while X Window is running. It offers a somewhat more >+friendly interface to XV_TVO_* attributes. >+ >+This is how to compile tvo_set: >+- cd to tvo_set directory >+- xmkmf >+- make >+- make install >+Last step should place the executable (tvo_set) in /usr/X11R6/bin. >+ >+This is the invocation syntax: >+tvo_set [-display host:dpy] [<cmd> <attribute> [<value>]] >+ >+tvo_set is not case sensitive for <cmd>, <attribute> & <value> >+fields. >+When no <cmd> is given, tvo_set just dumps the current state of >+TV attributes. >+ >+Recognized commands: >+set <attribute> <value> Set <attribute> to <value> >+inc <attribute> Increment <attribute> by 1 >+dec <attribute> Decrement <attribute> by 1 >+zero <attribute> Set <attribute> to 0 >+ >+Recognized values for <attribute> field: >+hpos Horizontal position >+vpos Vertical position >+hsize Horizontal size >+std TV Standard >+ >+When setting "std" attribute, both the numeric value and the name of the >+standard are valid, see following table. >+ >+Table of TV standards: >+0 NTSC >+1 PAL >+2 PAL-M >+3 PAL-60 >+4 NTSC-J >+5 PAL-CN >+6 PAL-N >+7 OFF >+ >+Examples: >+"tvo_set set std ntsc" >+ Set standard to NTSC >+ >+"tvo_set set std off" >+ Turn off TV output >+ >+"tvo_set set hsize 5" >+ Set hsize to 5 >+ >+"tvo_set inc hpos" >+ Shift image a bit to the right (increment hpos by 1) >+ >+"tvo_set zero vpos" >+ Restore default value for vpos >+ >+ >+6. WARNING >+---------- >+ >+It's important that you are aware of the fact that, when TV output is active, >+the monitor is driven at the same vertical refresh frequency as that of the >+TV output. This means 50 or 60 Hz according to the standard you're using. >+NO CHECK IS DONE IN THE DRIVER ABOUT THE CAPABILITY OF THE MONITOR TO >+SUSTAIN THESE FREQUENCIES. You should look up in the monitor manual >+and check that 50/60 Hz is within the limits. IT IS POTENTIALLY HARMFUL >+TO THE MONITOR TO BE DRIVEN AT A FREQUENCY OUTSIDE ITS OPERATING RANGE. >+ >+Note, however, that most monitors should accept a 60 Hz vertical frequency, >+since this is used in standard VGA modes. You should really check for 50 Hz >+compatibility if you are going to use any related standard (PAL mostly). >+ATI manuals recommend checking for 50 Hz compatibility (they take >+60 Hz for granted). >+ >+One last thing: I did no testing on cards having DVI/LCD outputs >+so I'm not sure about the driver behaviour with this kind of displays. >+Be warned. >+ >+6. Credits >+---------- >+ >+Vladimir Dergachev For leading the GATOS project, for all the good >+ advices he gave me about dealing with ATI and for >+ all his precious technical hints. >+ >+ATI external developer office >+ For providing me the Rage Theater documentation. >+ >+7. Revision history >+-------------------- >+ >+ >+2003-09-23 >+========== >+ >+Initial release >+ >+2003-11-26 >+========== >+ >+Support for ERT added >+ >+2004-01-27 >+========== >+ >+Support for sizing/positioning of TV image added >+ >diff -Naur xf86-video-ati.orig/src/radeon.h xf86-video-ati/src/radeon.h >--- xf86-video-ati.orig/src/radeon.h 2006-04-02 16:44:26.000000000 +0000 >+++ xf86-video-ati/src/radeon.h 2006-04-02 16:46:07.000000000 +0000 >@@ -63,6 +63,11 @@ > #include "xf86xv.h" > > #include "radeon_probe.h" >+ >+//20060402 >+#include "radeon_version.h" >+#include "generic_bus.h" >+ > /* DRI support */ > #ifdef XF86DRI > #define _XF86DRI_SERVER_ >@@ -222,6 +227,9 @@ > unsigned ppll_div_3; > CARD32 htotal_cntl; > >+//2006021904 >+ CARD32 vclk_ecp_cntl; >+ > /* Computed values for PLL2 */ > CARD32 dot_clock_freq_2; > CARD32 pll_output_freq_2; >@@ -637,6 +645,10 @@ > char* RageTheatreMicrocPath; > char* RageTheatreMicrocType; > Bool MM_TABLE_valid; >+//2006021905 >+ GENERIC_BUS_Ptr VIP; >+//2006021908 >+ struct TheaterOut *theaterOut; > struct { > CARD8 table_revision; > CARD8 table_size; >@@ -733,6 +745,9 @@ > info->fifo_slots -= entries; \ > } while (0) > >+//2006021908 >+#include "theater_out.h" >+ > extern RADEONEntPtr RADEONEntPriv(ScrnInfoPtr pScrn); > extern void RADEONWaitForFifoFunction(ScrnInfoPtr pScrn, int entries); > extern void RADEONWaitForIdleMMIO(ScrnInfoPtr pScrn); >@@ -743,6 +758,14 @@ > extern void RADEONDoAdjustFrame(ScrnInfoPtr pScrn, int x, int y, > int clone); > >+//2006021919 >+extern void RADEONTheaterOutSetStandard(ScrnInfoPtr, TVStd); >+extern TVStd RADEONTheaterOutGetStandard(ScrnInfoPtr); >+extern Bool RADEONTheaterOutGetCompatMode(ScrnInfoPtr); >+extern void RADEONTheaterOutSetAttr(ScrnInfoPtr, TheaterOutAttr, int); >+extern int RADEONTheaterOutGetAttr(ScrnInfoPtr, TheaterOutAttr); >+extern void RADEONTheaterOutGetAttrLimits(ScrnInfoPtr, TheaterOutAttr, int *, int *); >+ > extern void RADEONEngineReset(ScrnInfoPtr pScrn); > extern void RADEONEngineFlush(ScrnInfoPtr pScrn); > extern void RADEONEngineRestore(ScrnInfoPtr pScrn); >@@ -774,7 +797,12 @@ > > extern int RADEONMinBits(int val); > >-extern void RADEONInitVideo(ScreenPtr pScreen); >+//2006021919 >+extern GENERIC_BUS_Ptr RADEONAllocateVIP(ScrnInfoPtr pScrn); >+ >+//2006021911 >+//extern void RADEONInitVideo(ScreenPtr pScreen); >+extern void RADEONInitVideo(ScreenPtr pScreen , GENERIC_BUS_Ptr VIP , Bool loadTheatre); > extern void RADEONResetVideo(ScrnInfoPtr pScrn); > extern void R300CGWorkaround(ScrnInfoPtr pScrn); > >diff -Naur xf86-video-ati.orig/src/radeon_driver.c xf86-video-ati/src/radeon_driver.c >--- xf86-video-ati.orig/src/radeon_driver.c 2006-04-02 16:44:26.000000000 +0000 >+++ xf86-video-ati/src/radeon_driver.c 2006-04-02 16:44:41.000000000 +0000 >@@ -76,6 +76,8 @@ > #include "radeon_macros.h" > #include "radeon_probe.h" > #include "radeon_version.h" >+//2006021906 >+#include "theater_out.h" > #include "radeon_mergedfb.h" > > #ifdef XF86DRI >@@ -188,6 +190,8 @@ > OPTION_RAGE_THEATRE_COMPOSITE_PORT, > OPTION_RAGE_THEATRE_SVIDEO_PORT, > OPTION_TUNER_TYPE, >+//2006021906 >+ OPTION_TV_OUTPUT, > OPTION_RAGE_THEATRE_MICROC_PATH, > OPTION_RAGE_THEATRE_MICROC_TYPE, > #endif >@@ -252,6 +256,8 @@ > { OPTION_RAGE_THEATRE_COMPOSITE_PORT, "RageTheatreCompositePort", OPTV_INTEGER, {0}, FALSE }, > { OPTION_RAGE_THEATRE_SVIDEO_PORT, "RageTheatreSVideoPort", OPTV_INTEGER, {0}, FALSE }, > { OPTION_TUNER_TYPE, "TunerType", OPTV_INTEGER, {0}, FALSE }, >+//2006021906 >+ { OPTION_TV_OUTPUT, "TVOutput", OPTV_ANYSTR, {0}, FALSE }, > { OPTION_RAGE_THEATRE_MICROC_PATH, "RageTheatreMicrocPath", OPTV_STRING, {0}, FALSE }, > { OPTION_RAGE_THEATRE_MICROC_TYPE, "RageTheatreMicrocType", OPTV_STRING, {0}, FALSE }, > #endif >@@ -5716,6 +5722,63 @@ > > info->PaletteSavedOnVT = FALSE; > >+//2006021909 >+ RADEONTRACE(("Allocating VIP interface")); >+ info->VIP = RADEONAllocateVIP(pScrn); >+ >+/* >+if (info->VIP != NULL) >+{ >+ RADEONTRACE(("\n061:NOT NULL\n")); >+} >+else >+{ >+ RADEONTRACE(("\n062:NULL\n")); >+} >+*/ >+ >+//2006021907 >+if ((s = xf86GetOptValString(info->Options , OPTION_TV_OUTPUT)) != NULL && xf86NameCmp(s , "NOLOAD") != 0) >+{ >+ //RADEONTRACE(("TVOUT OPTION ON\n")); >+ RADEONTRACE(("TVOutput opt = %s\n" , s)); >+ if(!xf86LoadSubModule(pScrn , "theater_out")) >+ { >+ RADEONTRACE(("Failed to find theater_out module\n")); >+ xf86DrvMsg(pScrn->scrnIndex , X_ERROR , "Unable to load TV output module\n"); >+ info->theaterOut = NULL; >+ } >+ else >+ { >+ RADEONTRACE(("Found theater_out module\n")); >+ xf86LoaderReqSymbols(THEATER_OUT_SYMBOLS , NULL); >+// RADEONTRACE(("071:OK\n")); >+ >+ info->theaterOut = xf86_detectTheaterOut(pScrn , FALSE,info->VIP); >+// RADEONTRACE(("072:OK\n")); >+ if (info->theaterOut != NULL) >+ { >+// RADEONTRACE(("072:NOT NULL\n")); >+ xf86_initTheaterOut(info->theaterOut , s); >+// RADEONTRACE(("073:start init\n")); >+ } >+ else >+ { >+ RADEONTRACE(("TheaterOut is NULL!!\n")); >+ } >+ >+ } >+ >+} >+else >+{ >+// RADEONTRACE(("NO TVOUT OPTION\n")); >+} >+ >+ >+ >+ >+ > RADEONSave(pScrn); > > if ((!info->IsSecondary) && info->IsMobility) { >@@ -6125,7 +6188,9 @@ > > /* Init Xv */ > RADEONTRACE(("Initializing Xv\n")); >- RADEONInitVideo(pScreen); >+//2006021911 >+// RADEONInitVideo(pScreen); >+RADEONInitVideo(pScreen , info->VIP , TRUE); > > if(info->MergedFB) > /* need this here to fix up sarea values */ >@@ -6341,7 +6406,12 @@ > OUTREG(RADEON_OVR_WID_TOP_BOTTOM, restore->ovr_wid_top_bottom); > OUTREG(RADEON_OV0_SCALE_CNTL, restore->ov0_scale_cntl); > OUTREG(RADEON_SUBPIC_CNTL, restore->subpic_cntl); >- OUTREG(RADEON_VIPH_CONTROL, restore->viph_control); >+//2006021914 >+// OUTREG(RADEON_VIPH_CONTROL, restore->viph_control); >+ /* >+ * fulivi: removed. It messes the VIP access up >+ */ >+ > OUTREG(RADEON_I2C_CNTL_1, restore->i2c_cntl_1); > OUTREG(RADEON_GEN_INT_CNTL, restore->gen_int_cntl); > OUTREG(RADEON_CAP0_TRIG_CNTL, restore->cap0_trig_cntl); >@@ -6427,6 +6497,8 @@ > OUTREG(RADEON_CRTC_OFFSET, restore->crtc_offset); > OUTREG(RADEON_CRTC_OFFSET_CNTL, restore->crtc_offset_cntl); > OUTREG(RADEON_CRTC_PITCH, restore->crtc_pitch); >+//2006021914 >+OUTREG(RADEON_DISP_OUTPUT_CNTL, restore->disp_output_cntl); > OUTREG(RADEON_DISP_MERGE_CNTL, restore->disp_merge_cntl); > OUTREG(RADEON_CRTC_MORE_CNTL, restore->crtc_more_cntl); > >@@ -6609,12 +6681,49 @@ > ~(RADEON_P2PLL_ATOMIC_UPDATE_W)); > } > >+//2006021914 >+static >+CARD8 >+RADEONComputePLLGain( >+ CARD16 reference_freq, >+ CARD16 ref_div, >+ CARD16 fb_div >+ ) >+{ >+ unsigned vcoFreq; >+ >+ vcoFreq = ((unsigned)reference_freq * fb_div) / ref_div; >+ >+ /* >+ * This is orribly crude: the VCO frequency range is divided into >+ * 3 parts, each part having a fixed PLL gain value. >+ */ >+ if (vcoFreq >= 30000) >+ /* >+ * [300..max] MHz : 7 >+ */ >+ return 7; >+ else if (vcoFreq >= 18000) >+ /* >+ * [180..300) MHz : 4 >+ */ >+ return 4; >+ else >+ /* >+ * [0..180) MHz : 1 >+ */ >+ return 1; >+} >+ >+ > /* Write PLL registers */ > static void RADEONRestorePLLRegisters(ScrnInfoPtr pScrn, > RADEONSavePtr restore) > { > RADEONInfoPtr info = RADEONPTR(pScrn); > unsigned char *RADEONMMIO = info->MMIO; >+//2006021914 >+CARD8 pllGain; > > if (info->IsMobility) { > /* A temporal workaround for the occational blanking on certain laptop panels. >@@ -6637,15 +6746,28 @@ > OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL, > RADEON_VCLK_SRC_SEL_CPUCLK, > ~(RADEON_VCLK_SRC_SEL_MASK)); >+//2006021914 >+ pllGain = RADEONComputePLLGain(info->pll.reference_freq, >+ restore->ppll_ref_div & RADEON_PPLL_REF_DIV_MASK, >+ restore->ppll_div_3 & RADEON_PPLL_FB3_DIV_MASK); >+ >+ > > OUTPLLP(pScrn, > RADEON_PPLL_CNTL, > RADEON_PPLL_RESET > | RADEON_PPLL_ATOMIC_UPDATE_EN >- | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN, >+//2006021914 >+// | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN, >+ | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN >+ | ((CARD32)pllGain << RADEON_PPLL_PVG_SHIFT), > ~(RADEON_PPLL_RESET > | RADEON_PPLL_ATOMIC_UPDATE_EN >- | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN)); >+//2006021914 >+// | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN)); >+ | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN >+ | RADEON_PPLL_PVG_MASK)); >+ > > OUTREGP(RADEON_CLOCK_CNTL_INDEX, > RADEON_PLL_DIV_SEL, >@@ -6705,9 +6827,14 @@ > > usleep(50000); /* Let the clock to lock */ > >- OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL, >- RADEON_VCLK_SRC_SEL_PPLLCLK, >- ~(RADEON_VCLK_SRC_SEL_MASK)); >+//2006021914 >+// OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL, >+// RADEON_VCLK_SRC_SEL_PPLLCLK, >+// ~(RADEON_VCLK_SRC_SEL_MASK)); >+ OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL , restore->vclk_ecp_cntl); >+ >+ RADEONTRACE(("VCLK_ECP_CNTL = %08X\n" , restore->vclk_ecp_cntl)); >+ > } > > >@@ -7120,6 +7247,8 @@ > save->crtc_offset = INREG(RADEON_CRTC_OFFSET); > save->crtc_offset_cntl = INREG(RADEON_CRTC_OFFSET_CNTL); > save->crtc_pitch = INREG(RADEON_CRTC_PITCH); >+//2006021915 >+save->disp_output_cntl = INREG(RADEON_DISP_OUTPUT_CNTL); > save->disp_merge_cntl = INREG(RADEON_DISP_MERGE_CNTL); > save->crtc_more_cntl = INREG(RADEON_CRTC_MORE_CNTL); > >@@ -7189,6 +7318,8 @@ > save->ppll_ref_div = INPLL(pScrn, RADEON_PPLL_REF_DIV); > save->ppll_div_3 = INPLL(pScrn, RADEON_PPLL_DIV_3); > save->htotal_cntl = INPLL(pScrn, RADEON_HTOTAL_CNTL); >+ //2006021915 >+ save->vclk_ecp_cntl= INPLL(pScrn, RADEON_VCLK_ECP_CNTL); > > RADEONTRACE(("Read: 0x%08x 0x%08x 0x%08lx\n", > save->ppll_ref_div, >@@ -7198,6 +7329,8 @@ > save->ppll_ref_div & RADEON_PPLL_REF_DIV_MASK, > save->ppll_div_3 & RADEON_PPLL_FB3_DIV_MASK, > (save->ppll_div_3 & RADEON_PPLL_POST3_DIV_MASK) >> 16)); >+//2006021915 >+RADEONTRACE(("Read VCLK_ECP_CNTL = %08x\n" , save->vclk_ecp_cntl)); > } > > /* Read PLL registers */ >@@ -7306,6 +7439,16 @@ > RADEONSaveMode(pScrn, save); > if (!info->IsSecondary) > RADEONSaveSurfaces(pScrn, save); >+ >+//2006021915 >+ /* >+ * Save initial RT state >+ */ >+ if (info->theaterOut != NULL) >+ { >+// RADEONTRACE(("2006021915\n")); >+ xf86_theaterOutSave(info->theaterOut , pScrn); >+ } > } > > /* Restore the original (text) mode */ >@@ -7348,6 +7491,14 @@ > if (!info->IsSecondary) > RADEONRestoreSurfaces(pScrn, restore); > >+ /* >+ * Restore RT state >+ */ >+ if (info->theaterOut != NULL) >+ { >+// RADEONTRACE(("2006021915-2\n")); >+ xf86_theaterOutRestore(info->theaterOut , pScrn); >+ } > #if 0 > /* Temp fix to "solve" VT switch problems. When switching VTs on > * some systems, the console can either hang or the fonts can be >@@ -8098,7 +8249,12 @@ > save->crtc2_gen_cntl = (RADEON_CRTC2_EN | (format << 8)); > save->fp2_h_sync_strt_wid = save->crtc2_h_sync_strt_wid; > save->fp2_v_sync_strt_wid = save->crtc2_v_sync_strt_wid; >- save->fp2_gen_cntl = info->SavedReg.fp2_gen_cntl | RADEON_FP2_ON; >+//2006021915 >+// save->fp2_gen_cntl = info->SavedReg.fp2_gen_cntl | RADEON_FP2_ON; >+ save->fp2_gen_cntl = info->SavedReg.fp2_gen_cntl >+ | RADEON_FP2_SRC_SEL_CRTC2 >+ | RADEON_FP2_ON; >+ > save->fp2_gen_cntl &= ~(RADEON_FP2_BLANK_EN); > > if ((info->ChipFamily == CHIP_FAMILY_R200) || >@@ -8444,15 +8600,20 @@ > pll->reference_freq); > save->post_div = post_div->divider; > >+ //2006021915 >+ /* > RADEONTRACE(("dc=%ld, of=%ld, fd=%d, pd=%d\n", > save->dot_clock_freq, > save->pll_output_freq, > save->feedback_div, > save->post_div)); >+ */ > > save->ppll_ref_div = pll->reference_div; > save->ppll_div_3 = (save->feedback_div | (post_div->bitvalue << 16)); > save->htotal_cntl = 0; >+ //2006021915 >+ save->vclk_ecp_cntl = (save->vclk_ecp_cntl & ~RADEON_VCLK_SRC_SEL_MASK) | RADEON_VCLK_SRC_SEL_PPLLCLK; > } > > /* Define PLL2 registers for requested video mode */ >@@ -8505,12 +8666,14 @@ > * save->pll_output_freq_2, > pll->reference_freq); > save->post_div_2 = post_div->divider; >- >+ //2006021915 >+ /* > RADEONTRACE(("dc=%ld, of=%ld, fd=%d, pd=%d\n", > save->dot_clock_freq_2, > save->pll_output_freq_2, > save->feedback_div_2, > save->post_div_2)); >+ */ > > save->p2pll_ref_div = pll->reference_div; > save->p2pll_div_0 = (save->feedback_div_2 | >@@ -8585,6 +8748,13 @@ > #endif > > info->Flags = mode->Flags; >+//2006021916 >+ /* >+ * Some registers are initialized from text mode state >+ */ >+ save->disp_output_cntl = RADEONPTR(pScrn)->SavedReg.disp_output_cntl; >+ save->vclk_ecp_cntl = RADEONPTR(pScrn)->SavedReg.vclk_ecp_cntl; >+ > > RADEONInitMemMapRegisters(pScrn, save, info); > RADEONInitCommonRegisters(save, info); >@@ -8653,9 +8823,34 @@ > > if (!RADEONInit(pScrn, mode, &info->ModeReg)) return FALSE; > >+//2006021917 >+ /* >+ * Define RT state >+ */ >+ if (info->theaterOut != NULL) >+ { >+// RADEONTRACE(("2006021917\n")); >+ Bool res = xf86_theaterOutInit(info->theaterOut , mode , &info->ModeReg); >+ RADEONTRACE(("theaterOutInit returns %d\n" , res)); >+ } >+ >+ > pScrn->vtSema = TRUE; > RADEONBlank(pScrn); > RADEONRestoreMode(pScrn, &info->ModeReg); >+ >+//2006021918 >+ >+ /* >+ * Set RT to new mode >+ */ >+ if (info->theaterOut != NULL) >+ { >+// RADEONTRACE(("2006021918\n")); >+ xf86_theaterOutRestoreMode(info->theaterOut , pScrn); >+ } >+ >+ > RADEONUnblank(pScrn); > > info->CurrentLayout.mode = mode; >@@ -10037,3 +10232,103 @@ > pScrn->FreeScreen = RADEONFreeScreen; > pScrn->ValidMode = RADEONValidMode; > } >+ >+ >+/* >+ * fulivi: interface functions between RADEONSet/GetPortAttribute (in radeon_video.c) and >+ * theater_out module. >+ */ >+static >+void >+RADEONRedoSwitchMode( >+ ScrnInfoPtr pScrn >+ ) >+{ >+ int scrnIndex = pScrn->scrnIndex; >+ >+ /* >+ * It seems that last parameter (flags) is not used >+ */ >+ RADEONSwitchMode(scrnIndex , pScrn->currentMode , 0); >+} >+ >+void >+RADEONTheaterOutSetStandard( >+ ScrnInfoPtr pScrn, >+ TVStd std >+ ) >+{ >+ RADEONInfoPtr info = RADEONPTR(pScrn); >+ >+ RADEONTRACE(("RADEONTheaterOutSetStandard std = %d" , std)); >+ >+ if (info->theaterOut != NULL && xf86_theaterOutSetStandard(info->theaterOut , std)) >+ RADEONRedoSwitchMode(pScrn); >+} >+ >+TVStd >+RADEONTheaterOutGetStandard( >+ ScrnInfoPtr pScrn >+ ) >+{ >+ RADEONInfoPtr info = RADEONPTR(pScrn); >+ >+ if (info->theaterOut != NULL) >+ return xf86_theaterOutGetStandard(info->theaterOut); >+ else >+ return TV_STD_KEEP_OFF; >+} >+ >+Bool >+RADEONTheaterOutGetCompatMode( >+ ScrnInfoPtr pScrn >+ ) >+{ >+ RADEONInfoPtr info = RADEONPTR(pScrn); >+ >+ if (info->theaterOut != NULL) >+ return xf86_theaterOutGetCompatMode(info->theaterOut); >+ else >+ return FALSE; >+} >+ >+void >+RADEONTheaterOutSetAttr( >+ ScrnInfoPtr pScrn, >+ TheaterOutAttr attr, >+ int value >+ ) >+{ >+ RADEONInfoPtr info = RADEONPTR(pScrn); >+ >+ if (info->theaterOut != NULL) >+ xf86_theaterOutSetAttr(info->theaterOut , attr , value); >+} >+ >+int >+RADEONTheaterOutGetAttr( >+ ScrnInfoPtr pScrn, >+ TheaterOutAttr attr >+ ) >+{ >+ RADEONInfoPtr info = RADEONPTR(pScrn); >+ >+ if (info->theaterOut != NULL) >+ return xf86_theaterOutGetAttr(info->theaterOut , attr); >+ else >+ return 0; >+} >+ >+void >+RADEONTheaterOutGetAttrLimits( >+ ScrnInfoPtr pScrn, >+ TheaterOutAttr attr, >+ int *maxValue, >+ int *minValue >+ ) >+{ >+ RADEONInfoPtr info = RADEONPTR(pScrn); >+ >+ if (info->theaterOut != NULL) >+ xf86_theaterOutGetAttrLimits(info->theaterOut , attr , maxValue , minValue); >+} >diff -Naur xf86-video-ati.orig/src/radeon_reg.h xf86-video-ati/src/radeon_reg.h >--- xf86-video-ati.orig/src/radeon_reg.h 2006-04-02 16:44:26.000000000 +0000 >+++ xf86-video-ati/src/radeon_reg.h 2006-04-02 16:44:41.000000000 +0000 >@@ -1223,6 +1223,10 @@ > # define RADEON_PPLL_SLEEP (1 << 1) > # define RADEON_PPLL_ATOMIC_UPDATE_EN (1 << 16) > # define RADEON_PPLL_VGA_ATOMIC_UPDATE_EN (1 << 17) >+//2006021914 >+# define RADEON_PPLL_PVG_MASK (7 << 11) >+# define RADEON_PPLL_PVG_SHIFT 11 >+ > # define RADEON_PPLL_ATOMIC_UPDATE_VSYNC (1 << 18) > #define RADEON_PPLL_DIV_0 0x0004 /* PLL */ > #define RADEON_PPLL_DIV_1 0x0005 /* PLL */ >diff -Naur xf86-video-ati.orig/src/radeon_video.c xf86-video-ati/src/radeon_video.c >--- xf86-video-ati.orig/src/radeon_video.c 2006-04-02 16:44:26.000000000 +0000 >+++ xf86-video-ati/src/radeon_video.c 2006-04-02 16:44:41.000000000 +0000 >@@ -82,7 +82,9 @@ > > static void RADEONInitOffscreenImages(ScreenPtr); > >-static XF86VideoAdaptorPtr RADEONSetupImageVideo(ScreenPtr); >+//2006021912 >+//static XF86VideoAdaptorPtr RADEONSetupImageVideo(ScreenPtr); >+static XF86VideoAdaptorPtr RADEONSetupImageVideo(ScreenPtr , GENERIC_BUS_Ptr , Bool); > static int RADEONSetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer); > static int RADEONGetPortAttribute(ScrnInfoPtr, Atom ,INT32 *, pointer); > static void RADEONStopVideo(ScrnInfoPtr, pointer, Bool); >@@ -123,6 +125,24 @@ > > static Atom xvOvAlpha, xvGrAlpha, xvAlphaMode; > >+//2006021920 >+static Atom xvTvoStandard , xvTvoModeCompat; >+ >+typedef struct >+{ >+ char *name; >+ TheaterOutAttr attr; >+ Atom atom; >+} TVOAttr; >+ >+static >+TVOAttr theaterOutAttrs[] = >+{ >+ {"XV_TVO_HPOS" , THEATER_OUT_HPOS , 0 }, >+ {"XV_TVO_VPOS" , THEATER_OUT_VPOS , 0 }, >+ {"XV_TVO_HSIZE" , THEATER_OUT_HSIZE , 0 } >+}; >+#define N_TVO_ATTRS (sizeof(theaterOutAttrs) / sizeof(theaterOutAttrs[ 0 ])) > > #define GET_PORT_PRIVATE(pScrn) \ > (RADEONPortPrivPtr)((RADEONPTR(pScrn))->adaptor->pPortPrivates[0].ptr) >@@ -141,14 +161,18 @@ > } > #endif /* USE_EXA */ > >-void RADEONInitVideo(ScreenPtr pScreen) >+//2006021911 >+//void RADEONInitVideo(ScreenPtr pScreen) >+void RADEONInitVideo(ScreenPtr pScreen , GENERIC_BUS_Ptr VIP , Bool loadTheatre) > { > ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; > XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL; > XF86VideoAdaptorPtr newAdaptor = NULL; > int num_adaptors; > >- newAdaptor = RADEONSetupImageVideo(pScreen); >+//2006021911 >+// newAdaptor = RADEONSetupImageVideo(pScreen); >+newAdaptor = RADEONSetupImageVideo(pScreen , VIP , loadTheatre); > RADEONInitOffscreenImages(pScreen); > num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors); > >@@ -241,7 +265,9 @@ > > #endif > >-#define NUM_ATTRIBUTES 22 >+//2006021920 >+//#define NUM_ATTRIBUTES 22 >+#define NUM_ATTRIBUTES 22+5 > #define NUM_DEC_ATTRIBUTES (NUM_ATTRIBUTES+12) > > static XF86AttributeRec Attributes[NUM_DEC_ATTRIBUTES+1] = >@@ -257,6 +283,14 @@ > {XvSettable | XvGettable, 0, 255, "XV_OVERLAY_ALPHA"}, > {XvSettable | XvGettable, 0, 255, "XV_GRAPHICS_ALPHA"}, > {XvSettable | XvGettable, 0, 1, "XV_ALPHA_MODE"}, >+ >+//2006021920 >+ {XvSettable | XvGettable, 0, TV_STD_N_STANDARDS-1, "XV_TVO_STANDARD"}, >+ { XvGettable, 0, ~0, "XV_TVO_MODE_COMPAT"}, >+ {XvSettable | XvGettable, -1000, 1000, "XV_TVO_HPOS"}, >+ {XvSettable | XvGettable, -1000, 1000, "XV_TVO_VPOS"}, >+ {XvSettable | XvGettable, -1000, 1000, "XV_TVO_HSIZE"}, >+ > {XvSettable | XvGettable, -1000, 1000, "XV_BRIGHTNESS"}, > {XvSettable | XvGettable, -1000, 1000, "XV_CONTRAST"}, > {XvSettable | XvGettable, -1000, 1000, "XV_SATURATION"}, >@@ -1062,6 +1096,8 @@ > RADEONPortPrivPtr pPriv = info->adaptor->pPortPrivates[0].ptr; > char tmp[200]; > >+//2006021920 >+unsigned i; > /* this function is called from ScreenInit. pScreen is used > by XAA internally, but not valid until ScreenInit finishs. > */ >@@ -1075,6 +1111,19 @@ > xvLocationID = MAKE_ATOM("XV_LOCATION_ID"); > xvDumpStatus = MAKE_ATOM("XV_DUMP_STATUS"); > >+//2006021920 >+ xvTvoStandard = MAKE_ATOM("XV_TVO_STANDARD"); >+ xvTvoModeCompat = MAKE_ATOM("XV_TVO_MODE_COMPAT"); >+ >+ for (i = 0; i < N_TVO_ATTRS; i++) >+ { >+ char *name; >+ name = theaterOutAttrs[ i ].name; >+ theaterOutAttrs[ i ].atom = MakeAtom(name, strlen(name), TRUE); >+ >+ RADEONTRACE(("RADEONResetVideo,name=%s,atom=%d\n",name,theaterOutAttrs[ i ].atom)); >+ } >+ > xvBrightness = MAKE_ATOM("XV_BRIGHTNESS"); > xvSaturation = MAKE_ATOM("XV_SATURATION"); > xvColor = MAKE_ATOM("XV_COLOR"); >@@ -1276,7 +1325,9 @@ > } > > static XF86VideoAdaptorPtr >-RADEONAllocAdaptor(ScrnInfoPtr pScrn) >+RADEONAllocAdaptor(ScrnInfoPtr pScrn, GENERIC_BUS_Ptr VIP) >+//2006021913 >+//RADEONAllocAdaptor(ScrnInfoPtr pScrn) > { > XF86VideoAdaptorPtr adapt; > RADEONInfoPtr info = RADEONPTR(pScrn); >@@ -1402,7 +1453,10 @@ > #endif > > /* Initialize VIP bus */ >- RADEONVIP_init(pScrn, pPriv); >+//2006021921 >+// RADEONVIP_init(pScrn, pPriv); >+pPriv->VIP = VIP; >+ > info->adaptor = adapt; > > if(!xf86LoadSubModule(pScrn,"theatre_detect")) >@@ -1484,13 +1538,19 @@ > } > > static XF86VideoAdaptorPtr >-RADEONSetupImageVideo(ScreenPtr pScreen) >+RADEONSetupImageVideo(ScreenPtr pScreen , GENERIC_BUS_Ptr VIP , Bool loadTheatre) >+//2006021912 >+//RADEONSetupImageVideo(ScreenPtr pScreen) > { > ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; > RADEONPortPrivPtr pPriv; > XF86VideoAdaptorPtr adapt; >+//2006021912 >+unsigned i; > >- if(!(adapt = RADEONAllocAdaptor(pScrn))) >+//2006021912 >+// if(!(adapt = RADEONAllocAdaptor(pScrn))) >+if(!(adapt = RADEONAllocAdaptor(pScrn, VIP))) > return NULL; > > adapt->type = XvWindowMask | XvInputMask | XvImageMask; >@@ -1516,6 +1576,27 @@ > adapt->PutImage = RADEONPutImage; > adapt->QueryImageAttributes = RADEONQueryImageAttributes; > >+//2006021921 >+ /* >+ * fulivi: set limits of theater_out attributes >+ */ >+ for (i = 0; i < N_TVO_ATTRS; i++) >+ { >+ int maxValue; >+ int minValue; >+ unsigned j; >+ >+ RADEONTheaterOutGetAttrLimits(pScrn , theaterOutAttrs[ i ].attr , &maxValue , &minValue); >+ >+ for (j = 0; i < NUM_DEC_ATTRIBUTES; j++) >+ if (strcmp(theaterOutAttrs[ i ].name , Attributes[ j ].name) == 0) >+ { >+ Attributes[ j ].min_value = minValue; >+ Attributes[ j ].max_value = maxValue; >+ break; >+ } >+ } >+ > pPriv = (RADEONPortPrivPtr)(adapt->pPortPrivates[0].ptr); > REGION_NULL(pScreen, &(pPriv->clip)); > >@@ -1818,8 +1899,27 @@ > RADEON_TDA9885_SetEncoding(pPriv); > } > } >- else >- return BadMatch; >+//2006021922 >+// else >+// return BadMatch; >+ else if (attribute == xvTvoStandard) >+ { >+ value = ClipValue(value , 0 , TV_STD_N_STANDARDS-1); >+ RADEONTheaterOutSetStandard(pScrn , (TVStd)value); >+ } >+ else >+ { >+ unsigned i; >+ >+ for (i = 0; i < N_TVO_ATTRS; i++) >+ if (theaterOutAttrs[ i ].atom == attribute) >+ { >+ RADEONTheaterOutSetAttr(pScrn , theaterOutAttrs[ i ].attr , value); >+ break; >+ } >+ if (i == N_TVO_ATTRS) >+ return BadMatch; >+ } > > if (setTransform) > { >@@ -1923,8 +2023,26 @@ > *value = pPriv->instance_id; > else if(attribute == xvAdjustment) > *value = pPriv->adjustment; >- else >- return BadMatch; >+ else if(attribute == xvTvoStandard) // 2006021923 >+ *value = (INT32)RADEONTheaterOutGetStandard(pScrn); >+ else if(attribute == xvTvoModeCompat) >+ *value = (INT32)RADEONTheaterOutGetCompatMode(pScrn); >+ else { >+ unsigned i; >+ >+ for (i = 0; i < N_TVO_ATTRS; i++) { >+ if (theaterOutAttrs[ i ].atom == attribute) { >+ *value = (INT32)RADEONTheaterOutGetAttr(pScrn , theaterOutAttrs[ i].attr); >+ break; >+ } >+ } >+ if (i == N_TVO_ATTRS) >+ return BadMatch; >+ } >+ >+//2006021923 >+// else >+// return BadMatch; > > return Success; > } >diff -Naur xf86-video-ati.orig/src/radeon_video.h xf86-video-ati/src/radeon_video.h >--- xf86-video-ati.orig/src/radeon_video.h 2006-04-02 16:44:26.000000000 +0000 >+++ xf86-video-ati/src/radeon_video.h 2006-04-02 16:44:41.000000000 +0000 >@@ -47,6 +47,8 @@ > GENERIC_BUS_Ptr VIP; > TheatrePtr theatre; > >+/* TheaterOutPtr theaterOut; */ >+ > Bool video_stream_active; > int encoding; > CARD32 frequency; >diff -Naur xf86-video-ati.orig/src/radeon_vip.c xf86-video-ati/src/radeon_vip.c >--- xf86-video-ati.orig/src/radeon_vip.c 2006-04-02 16:44:26.000000000 +0000 >+++ xf86-video-ati/src/radeon_vip.c 2006-04-02 16:44:41.000000000 +0000 >@@ -342,6 +342,7 @@ > > void RADEONVIP_init(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) > { >+/* > pPriv->VIP=xcalloc(1,sizeof(GENERIC_BUS_Rec)); > pPriv->VIP->scrnIndex=pScrn->scrnIndex; > pPriv->VIP->DriverPrivate.ptr=pPriv; >@@ -350,6 +351,32 @@ > pPriv->VIP->write=RADEONVIP_write; > pPriv->VIP->fifo_read=RADEONVIP_fifo_read; > pPriv->VIP->fifo_write=RADEONVIP_fifo_write; >- > RADEONVIP_reset(pScrn, pPriv); >+*/ >+pPriv->VIP = RADEONAllocateVIP(pScrn); > } >+ >+/* >+ * fulivi: This new function was created because I needed VIP access from radeon_driver module >+ * (where port private data doesn't exist) >+ */ >+GENERIC_BUS_Ptr >+RADEONAllocateVIP( >+ ScrnInfoPtr pScrn >+ ) >+{ >+ GENERIC_BUS_Ptr VIP=NULL; >+ >+ VIP = xcalloc(1 , sizeof(GENERIC_BUS_Rec)); >+ VIP->DriverPrivate.ptr = NULL; /* Nobody seems to use this */ >+ VIP->scrnIndex = pScrn->scrnIndex; >+ VIP->ioctl = RADEONVIP_ioctl; >+ VIP->read = RADEONVIP_read; >+ VIP->write = RADEONVIP_write; >+ VIP->fifo_read=RADEONVIP_fifo_read; >+ VIP->fifo_write=RADEONVIP_fifo_write; >+ >+ RADEONVIP_reset(pScrn,NULL); >+ >+ return VIP; >+ } >diff -Naur xf86-video-ati.orig/src/theater_out.c xf86-video-ati/src/theater_out.c >--- xf86-video-ati.orig/src/theater_out.c 1970-01-01 00:00:00.000000000 +0000 >+++ xf86-video-ati/src/theater_out.c 2006-04-02 16:44:41.000000000 +0000 >@@ -0,0 +1,2830 @@ >+/********************************************************************* >+ * >+ * $Id: theater_out.c,v 1.1.2.3 2004/01/27 22:50:35 fulivi Exp $ >+ * >+ * Main file for tv output handling of ATI Rage Theater chip >+ * >+ * Copyright (C) 2003 Federico Ulivi >+ * >+ * This program is free software; you can redistribute it and/or modify >+ * it under the terms of the GNU General Public License as published by >+ * the Free Software Foundation; either version 2 of the License, or >+ * (at your option) any later version. >+ * >+ * This program is distributed in the hope that it will be useful, >+ * but WITHOUT ANY WARRANTY; without even the implied warranty of >+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+ * GNU General Public License for more details. >+ * >+ * You should have received a copy of the GNU General Public License >+ * along with this program; if not, write to the Free Software >+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA >+ * >+ * AUTHORS: F.Ulivi >+ * NOTES: >+ * $Log: theater_out.c,v $ >+ * Revision 1.1.2.3 2004/01/27 22:50:35 fulivi >+ * Support for positioning/sizing of image added >+ * >+ * Revision 1.1.1.1.2.12 2004/01/18 22:59:29 fede >+ * hSize handling added >+ * Functions for get/setting h/v pos/size replaced by >+ * theaterOutSetAttr/theaterOutGetAttr/theaterOutGetAttrLimits >+ * >+ * Revision 1.1.1.1.2.11 2004/01/11 21:29:04 fede >+ * Fixes in H/V position handling >+ * >+ * Revision 1.1.1.1.2.10 2004/01/05 00:08:16 fede >+ * Functions for setting H/V position added >+ * Functions for setting/getting on/off attribute removed >+ * >+ * Revision 1.1.2.2 2003/11/26 19:50:10 fulivi >+ * Support for ERT added >+ * >+ * Revision 1.1.1.1.2.9 2003/11/25 20:46:44 fede >+ * "enabled" state removed >+ * Handling of disabled tv output fixed >+ * >+ * Revision 1.1.1.1.2.8 2003/11/23 00:47:28 fede >+ * Major cleanup of #define names >+ * >+ * Revision 1.1.1.1.2.7 2003/11/17 22:26:12 fede >+ * Support for tv standards added >+ * Support for NTSC added >+ * >+ * Revision 1.1.1.1.2.6 2003/10/14 18:40:34 fede >+ * Autodetection of ERT moved to front >+ * Some minor cleanups >+ * >+ * Revision 1.1.1.1.2.5 2003/10/11 12:29:50 fede >+ * Support for ERT added >+ * >+ * Revision 1.1 2003/09/28 21:42:37 fulivi >+ * Theater_out module added >+ * >+ * Revision 1.1.1.1.2.4 2003/09/28 15:11:57 fede >+ * Some minor aesthetic changes >+ * >+ * Revision 1.1.1.1.2.2 2003/08/31 13:35:58 fede >+ * Adapted for XFree86 >+ * >+ * Revision 1.1.1.1.2.1 2003/08/09 23:20:46 fede >+ * Switched to memory mapped IO >+ * Some magic numbers turned into named constants >+ * >+ * Revision 1.1.1.1 2003/07/24 15:37:27 fede >+ * Initial version >+ * >+ * >+ *********************************************************************/ >+ >+#include "xf86.h" >+#include "generic_bus.h" >+#include "theatre_reg.h" >+#include "radeon_reg.h" >+#include "radeon_macros.h" >+#include "theater_out.h" >+#define RADEON_NAME "RADEON" >+ >+#undef read >+#undef write >+#undef ioctl >+ >+#if RADEON_DEBUG >+#define RTTRACE(x) \ >+do { \ >+ ErrorF("(**) %s(%d): ", RADEON_NAME, 0); \ >+ ErrorF x; \ >+} while (0); >+#else >+#define RTTRACE(x) >+#endif >+ >+/********************************************************************** >+ * >+ * MASK_N_BIT >+ * >+ **********************************************************************/ >+ >+#define MASK_N_BIT(n) (1UL << (n)) >+ >+/********************************************************************** >+ * >+ * Constants >+ * >+ **********************************************************************/ >+ >+/* >+ * Reference frequency >+ * FIXME: This should be extracted from BIOS data >+ */ >+#define REF_FREQUENCY 27000 >+ >+#define TV_PLL_FINE_INI 0X10000000 >+ >+/* >+ * VIP_TV_PLL_CNTL >+ */ >+#define VIP_TV_PLL_CNTL_M_SHIFT 0 >+#define VIP_TV_PLL_CNTL_NLO 0x1ff >+#define VIP_TV_PLL_CNTL_NLO_SHIFT 8 >+#define VIP_TV_PLL_CNTL_NHI 0x600 >+#define VIP_TV_PLL_CNTL_NHI_SHIFT (21-9) >+#define VIP_TV_PLL_CNTL_P_SHIFT 24 >+ >+/* >+ * VIP_CRT_PLL_CNTL >+ */ >+#define VIP_CRT_PLL_CNTL_M 0xff >+#define VIP_CRT_PLL_CNTL_M_SHIFT 0 >+#define VIP_CRT_PLL_CNTL_NLO 0x1ff >+#define VIP_CRT_PLL_CNTL_NLO_SHIFT 8 >+#define VIP_CRT_PLL_CNTL_NHI 0x600 >+#define VIP_CRT_PLL_CNTL_NHI_SHIFT (21-9) >+#define VIP_CRT_PLL_CNTL_CLKBY2 MASK_N_BIT(25) >+ >+/* >+ * Value for VIP_PLL_CNTL0 >+ */ >+#define VIP_PLL_CNTL0_INI 0x00acac18 >+#define VIP_PLL_CNTL0_TVSLEEPB MASK_N_BIT(3) >+#define VIP_PLL_CNTL0_CRTSLEEPB MASK_N_BIT(4) >+ >+/* >+ * Value for VIP_PLL_TEST_CNTL >+ */ >+#define VIP_PLL_TEST_CNTL_INI 0 >+ >+/* >+ * VIP_CLOCK_SEL_CNTL >+ */ >+#define VIP_CLOCK_SEL_CNTL_INI 0x33 >+#define VIP_CLOCK_SEL_CNTL_BYTCLK_SHIFT 2 >+#define VIP_CLOCK_SEL_CNTL_BYTCLK 0xc >+#define VIP_CLOCK_SEL_CNTL_REGCLK MASK_N_BIT(5) >+#define VIP_CLOCK_SEL_CNTL_BYTCLKD_SHIFT 8 >+ >+/* >+ * Value for VIP_CLKOUT_CNTL >+ */ >+#define VIP_CLKOUT_CNTL_INI 0x29 >+ >+/* >+ * Value for VIP_SYNC_LOCK_CNTL >+ */ >+#define VIP_SYNC_LOCK_CNTL_INI 0x01000000 >+ >+/* >+ * Value for VIP_TVO_SYNC_PAT_EXPECT >+ */ >+#define VIP_TVO_SYNC_PAT_EXPECT_INI 0x00000001 >+ >+/* >+ * VIP_RGB_CNTL >+ */ >+#define VIP_RGB_CNTL_RGB_IS_888_PACK MASK_N_BIT(0) >+ >+/* >+ * Value for VIP_VSCALER_CNTL2 >+ */ >+#define VIP_VSCALER_CNTL2_INI 0x10000000 >+ >+/* >+ * Value for VIP_Y_FALL_CNTL >+ */ >+/* #define VIP_Y_FALL_CNTL_INI 0x00010200 */ >+#define VIP_Y_FALL_CNTL_INI 0x80030400 >+ >+/* >+ * VIP_UV_ADR >+ */ >+#define VIP_UV_ADR_INI 0xc8 >+#define VIP_UV_ADR_HCODE_TABLE_SEL 0x06000000 >+#define VIP_UV_ADR_HCODE_TABLE_SEL_SHIFT 25 >+#define VIP_UV_ADR_VCODE_TABLE_SEL 0x18000000 >+#define VIP_UV_ADR_VCODE_TABLE_SEL_SHIFT 27 >+#define VIP_UV_ADR_MAX_UV_ADR 0x000000ff >+#define VIP_UV_ADR_MAX_UV_ADR_SHIFT 0 >+#define VIP_UV_ADR_TABLE1_BOT_ADR 0x0000ff00 >+#define VIP_UV_ADR_TABLE1_BOT_ADR_SHIFT 8 >+#define VIP_UV_ADR_TABLE3_TOP_ADR 0x00ff0000 >+#define VIP_UV_ADR_TABLE3_TOP_ADR_SHIFT 16 >+#define MAX_FIFO_ADDR_RT 0x1a7 >+#define MAX_FIFO_ADDR_ERT 0x1ff >+ >+/* >+ * VIP_HOST_RD_WT_CNTL >+ */ >+#define VIP_HOST_RD_WT_CNTL_RD MASK_N_BIT(12) >+#define VIP_HOST_RD_WT_CNTL_RD_ACK MASK_N_BIT(13) >+#define VIP_HOST_RD_WT_CNTL_WT MASK_N_BIT(14) >+#define VIP_HOST_RD_WT_CNTL_WT_ACK MASK_N_BIT(15) >+ >+/* >+ * Value for VIP_SYNC_CNTL >+ */ >+#define VIP_SYNC_CNTL_INI 0x28 >+ >+/* >+ * VIP_VSCALER_CNTL1 >+ */ >+#define VIP_VSCALER_CNTL1_UV_INC 0xffff >+#define VIP_VSCALER_CNTL1_UV_INC_SHIFT 0 >+ >+/* >+ * VIP_TIMING_CNTL >+ */ >+#define VIP_TIMING_CNTL_UV_OUT_POST_SCALE_SHIFT 24 >+#define VIP_TIMING_CNTL_INI 0x000b0000 >+#define VIP_TIMING_CNTL_H_INC_SHIFT 0 >+#define VIP_TIMING_CNTL_H_INC 0xfff >+ >+/* >+ * Value for VIP_PRE_DAC_MUX_CNTL >+ */ >+#define VIP_PRE_DAC_MUX_CNTL_INI 0x0000000f >+ >+/* >+ * VIP_TV_DAC_CNTL >+ */ >+#define VIP_TV_DAC_CNTL_NBLANK MASK_N_BIT(0) >+#define VIP_TV_DAC_CNTL_DASLEEP MASK_N_BIT(3) >+#define VIP_TV_DAC_CNTL_BGSLEEP MASK_N_BIT(6) >+ >+/* >+ * Value for VIP_FRAME_LOCK_CNTL >+ */ >+#define VIP_FRAME_LOCK_CNTL_INI 0x0000000f >+ >+/* >+ * Value for VIP_HW_DEBUG >+ */ >+#define VIP_HW_DEBUG_INI 0x00000200 >+ >+/* >+ * VIP_MASTER_CNTL >+ */ >+#define VIP_MASTER_CNTL_TV_ASYNC_RST MASK_N_BIT(0) >+#define VIP_MASTER_CNTL_CRT_ASYNC_RST MASK_N_BIT(1) >+#define VIP_MASTER_CNTL_RESTART_PHASE_FIX MASK_N_BIT(3) >+#define VIP_MASTER_CNTL_TV_FIFO_ASYNC_RST MASK_N_BIT(4) >+#define VIP_MASTER_CNTL_VIN_ASYNC_RST MASK_N_BIT(5) >+#define VIP_MASTER_CNTL_AUD_ASYNC_RST MASK_N_BIT(6) >+#define VIP_MASTER_CNTL_DVS_ASYNC_RST MASK_N_BIT(7) >+#define VIP_MASTER_CNTL_CRT_FIFO_CE_EN MASK_N_BIT(9) >+#define VIP_MASTER_CNTL_TV_FIFO_CE_EN MASK_N_BIT(10) >+#define VIP_MASTER_CNTL_ON_INI (VIP_MASTER_CNTL_RESTART_PHASE_FIX | \ >+ VIP_MASTER_CNTL_VIN_ASYNC_RST | \ >+ VIP_MASTER_CNTL_AUD_ASYNC_RST | \ >+ VIP_MASTER_CNTL_DVS_ASYNC_RST | \ >+ VIP_MASTER_CNTL_CRT_FIFO_CE_EN | \ >+ VIP_MASTER_CNTL_TV_FIFO_CE_EN) >+#define VIP_MASTER_CNTL_OFF_INI (VIP_MASTER_CNTL_TV_ASYNC_RST | \ >+ VIP_MASTER_CNTL_CRT_ASYNC_RST | \ >+ VIP_MASTER_CNTL_RESTART_PHASE_FIX | \ >+ VIP_MASTER_CNTL_TV_FIFO_ASYNC_RST | \ >+ VIP_MASTER_CNTL_VIN_ASYNC_RST | \ >+ VIP_MASTER_CNTL_AUD_ASYNC_RST | \ >+ VIP_MASTER_CNTL_DVS_ASYNC_RST | \ >+ VIP_MASTER_CNTL_CRT_FIFO_CE_EN | \ >+ VIP_MASTER_CNTL_TV_FIFO_CE_EN) >+ >+/* >+ * Value for VIP_LINEAR_GAIN_SETTINGS >+ */ >+#define VIP_LINEAR_GAIN_SETTINGS_INI 0x01000100 >+ >+/* >+ * Value for VIP_GAIN_LIMIT_SETTINGS_INI >+ */ >+#define VIP_GAIN_LIMIT_SETTINGS_INI 0x017f05ff >+ >+/* >+ * Value for VIP_UPSAMP_AND_GAIN_CNTL >+ */ >+#define VIP_UPSAMP_AND_GAIN_CNTL_INI 0x00000005 >+ >+/* >+ * RADEON_VCLK_ECP_CNTL >+ */ >+#define RADEON_VCLK_ECP_CNTL_BYTECLK_POSTDIV 0x00030000 >+#define RADEON_VCLK_ECP_CNTL_BYTECLK_NODIV 0x00000000 >+ >+/* >+ * RADEON_PLL_TEST_CNTL >+ */ >+#define RADEON_PLL_TEST_CNTL_PLL_MASK_READ_B MASK_N_BIT(9) >+ >+/* >+ * RADEON_DAC_CNTL >+ */ >+#define RADEON_DAC_CNTL_DAC_TVO_EN MASK_N_BIT(10) >+ >+#define RADEON_PPLL_POST3_DIV_BY_2 0x10000 >+#define RADEON_PPLL_POST3_DIV_BY_3 0x40000 >+#define RADEON_PPLL_FB3_DIV_SHIFT 0 >+#define RADEON_PPLL_POST3_DIV_SHIFT 16 >+ >+/* >+ * RADEON_DISP_MERGE_CNTL >+ */ >+//#define RADEON_DISP_MERGE_CNTL 0xd60 >+#define RADEON_DISP_MERGE_CNTL_INI 0xffff0000 >+ >+/* >+ * RADEON_HTOTAL_CNTL >+ */ >+#define RADEON_HTOTAL_CNTL_HTOT_PIX_SLIP_SHIFT 0 >+#define RADEON_HTOTAL_CNTL_HTOT_CNTL_VGA_EN MASK_N_BIT(28) >+ >+/* >+ * RADEON_DISP_OUTPUT_CNTL >+ */ >+#define RADEON_DISP_TV_SOURCE MASK_N_BIT(16) >+#define RADEON_DISP_TV_MODE_MASK (3 << 17) >+#define RADEON_DISP_TV_MODE_888 (0 << 17) >+#define RADEON_DISP_TV_MODE_565 (1 << 17) >+#define RADEON_DISP_TV_YG_DITH_EN MASK_N_BIT(19) >+#define RADEON_DISP_TV_CBB_CRR_DITH_EN MASK_N_BIT(20) >+#define RADEON_DISP_TV_BIT_WIDTH MASK_N_BIT(21) >+#define RADEON_DISP_TV_SYNC_MODE_MASK (3 << 22) >+#define RADEON_DISP_TV_SYNC_COLOR_MASK (3 << 25) >+ >+/* >+ * ERT registers >+ */ >+#define TV_MASTER_CNTL 0x0800 >+#define TV_MASTER_CNTL_TVCLK_ALWAYS_ON MASK_N_BIT(30) >+#define TV_MASTER_CNTL_TV_ON MASK_N_BIT(31) >+#define TV_MASTER_CNTL_ON_INI (VIP_MASTER_CNTL_VIN_ASYNC_RST | \ >+ VIP_MASTER_CNTL_CRT_FIFO_CE_EN | \ >+ VIP_MASTER_CNTL_TV_FIFO_CE_EN | \ >+ TV_MASTER_CNTL_TVCLK_ALWAYS_ON | \ >+ TV_MASTER_CNTL_TV_ON) >+#define TV_MASTER_CNTL_OFF_INI (VIP_MASTER_CNTL_TV_ASYNC_RST | \ >+ VIP_MASTER_CNTL_CRT_ASYNC_RST | \ >+ VIP_MASTER_CNTL_TV_FIFO_ASYNC_RST | \ >+ VIP_MASTER_CNTL_CRT_FIFO_CE_EN | \ >+ VIP_MASTER_CNTL_TV_FIFO_CE_EN | \ >+ TV_MASTER_CNTL_TVCLK_ALWAYS_ON) >+#define TV_RGB_CNTL 0x0804 >+#define TV_RGB_CNTL_INI 0x007b0004 >+#define TV_SYNC_CNTL 0x0808 >+#define TV_HTOTAL 0x080c >+#define TV_HDISP 0x0810 >+#define TV_HSTART 0x0818 >+#define TV_HCOUNT 0x081c >+#define TV_VTOTAL 0x0820 >+#define TV_VDISP 0x0824 >+#define TV_VCOUNT 0x0828 >+#define TV_FTOTAL 0x082c >+#define TV_FCOUNT 0x0830 >+#define TV_FRESTART 0x0834 >+#define TV_HRESTART 0x0838 >+#define TV_VRESTART 0x083c >+#define TV_HOST_READ_DATA 0x0840 >+#define TV_HOST_WRITE_DATA 0x0844 >+#define TV_HOST_RD_WT_CNTL 0x0848 >+#define TV_VSCALER_CNTL1 0x084c >+#define TV_VSCALER_CNTL1_RESTART_FIELD MASK_N_BIT(29) >+#define TV_TIMING_CNTL 0x0850 >+#define TV_VSCALER_CNTL2 0x0854 >+#define TV_Y_FALL_CNTL 0x0858 >+#define TV_Y_RISE_CNTL 0x085c >+#define TV_Y_SAWTOOTH_CNTL 0x0860 >+#define TV_UPSAMP_AND_GAIN_CNTL 0x0864 >+#define TV_GAIN_LIMIT_SETTINGS 0x0868 >+#define TV_LINEAR_GAIN_SETTINGS 0x086c >+#define TV_MODULATOR_CNTL1 0x0870 >+#define TV_MODULATOR_CNTL2 0x0874 >+#define TV_PRE_DAC_MUX_CNTL 0x0888 >+#define TV_DAC_CNTL 0x088c >+#define TV_DAC_CNTL_NBLANK MASK_N_BIT(0) >+#define TV_DAC_CNTL_NHOLD MASK_N_BIT(1) >+#define TV_DAC_CNTL_BGSLEEP MASK_N_BIT(6) >+#define TV_DAC_CNTL_RDACPD MASK_N_BIT(24) >+#define TV_DAC_CNTL_GDACPD MASK_N_BIT(25) >+#define TV_DAC_CNTL_BDACPD MASK_N_BIT(26) >+#define TV_CRC_CNTL 0x0890 >+#define TV_UV_ADR 0x08ac >+ >+/* >+ * ERT PLL registers >+ */ >+#define TV_PLL_CNTL 0x21 >+#define TV_PLL_CNTL1 0x22 >+#define TV_PLL_CNTL1_TVPLL_RESET MASK_N_BIT(1) >+#define TV_PLL_CNTL1_TVPLL_SLEEP MASK_N_BIT(3) >+#define TV_PLL_CNTL1_TVPDC_SHIFT 14 >+#define TV_PLL_CNTL1_TVPDC_MASK (3 << 14) >+#define TV_PLL_CNTL1_TVCLK_SRC_SEL MASK_N_BIT(30) >+ >+/* >+ * Constant upsampler coefficients >+ */ >+static >+const >+CARD32 upsamplerCoeffs[] = >+{ >+ 0x3f010000, >+ 0x7b008002, >+ 0x00003f01, >+ 0x341b7405, >+ 0x7f3a7617, >+ 0x00003d04, >+ 0x2d296c0a, >+ 0x0e316c2c, >+ 0x00003e7d, >+ 0x2d1f7503, >+ 0x2927643b, >+ 0x0000056f, >+ 0x29257205, >+ 0x25295050, >+ 0x00000572 >+}; >+#define N_UPSAMPLER_COEFFS (sizeof(upsamplerCoeffs) / sizeof(upsamplerCoeffs[ 0 ])) >+ >+/* >+ * Maximum length of horizontal/vertical code timing tables for state storage >+ */ >+#define MAX_H_CODE_TIMING_LEN 32 >+#define MAX_V_CODE_TIMING_LEN 32 >+ >+/* >+ * Type of VIP bus >+ */ >+#define VIP_TYPE "ATI VIP BUS" >+ >+/* >+ * Limits of h/v positions (hPos & vPos in TheaterOutRec) >+ */ >+#define MAX_H_POSITION 5 /* Range: [-5..5], negative is on the left, 0 is default, positive is on the right */ >+#define MAX_V_POSITION 5 /* Range: [-5..5], negative is up, 0 is default, positive is down */ >+ >+/* >+ * Unit for hPos (in TV clock periods) >+ */ >+#define H_POS_UNIT 10 >+ >+/* >+ * Indexes in h. code timing table for horizontal line position adjustment >+ */ >+#define H_TABLE_POS1 6 >+#define H_TABLE_POS2 8 >+ >+/* >+ * Limits of hor. size (hSize in TheaterOutRec) >+ */ >+#define MAX_H_SIZE 5 /* Range: [-5..5], negative is smaller, positive is larger */ >+ >+/********************************************************************** >+ * >+ * TimingTableEl >+ * >+ * Elements of H/V code timing tables >+ * >+ **********************************************************************/ >+ >+typedef CARD16 TimingTableEl; /* Bits 0 to 13 only are actually used */ >+ >+/********************************************************************** >+ * >+ * ModeConstants >+ * >+ * Storage of constants related to a single video mode >+ * >+ **********************************************************************/ >+ >+typedef struct >+{ >+ CARD16 horResolution; >+ CARD16 verResolution; >+ TVStd standard; >+ CARD16 horTotal; >+ CARD16 verTotal; >+ CARD16 horStart; >+ CARD16 horSyncStart; >+ CARD16 verSyncStart; >+ unsigned defRestart; >+ CARD32 vScalerCntl1; >+ CARD32 yRiseCntl; >+ CARD32 ySawtoothCntl; >+ CARD16 crtcPLL_N; >+ CARD8 crtcPLL_M; >+ Bool crtcPLL_divBy2; >+ CARD8 crtcPLL_byteClkDiv; >+ CARD8 crtcPLL_postDiv; >+ Bool use888RGB; /* False: RGB data is 565 packed (2 bytes/pixel) */ >+ /* True : RGB data is 888 packed (3 bytes/pixel) */ >+ unsigned pixToTV; >+ CARD8 byteClkDelay; >+ CARD32 tvoDataDelayA; >+ CARD32 tvoDataDelayB; >+ const TimingTableEl *horTimingTable; >+ const TimingTableEl *verTimingTable; >+} ModeConstants; >+ >+/********************************************************************** >+ * >+ * TheaterState >+ * >+ * Storage of RT state >+ * >+ **********************************************************************/ >+ >+typedef struct >+{ >+ CARD32 clkout_cntl; >+ CARD32 clock_sel_cntl; >+ CARD32 crc_cntl; >+ CARD32 crt_pll_cntl; >+ CARD32 dfrestart; >+ CARD32 dhrestart; >+ CARD32 dvrestart; >+ CARD32 frame_lock_cntl; >+ CARD32 gain_limit_settings; >+ CARD32 hdisp; >+ CARD32 hstart; >+ CARD32 htotal; >+ CARD32 hw_debug; >+ CARD32 linear_gain_settings; >+ CARD32 master_cntl; >+ CARD32 modulator_cntl1; >+ CARD32 modulator_cntl2; >+ CARD32 pll_cntl0; >+ CARD32 pll_test_cntl; >+ CARD32 pre_dac_mux_cntl; >+ CARD32 rgb_cntl; >+ CARD32 sync_cntl; >+ CARD32 sync_lock_cntl; >+ CARD32 sync_size; >+ CARD32 timing_cntl; >+ CARD32 tvo_data_delay_a; >+ CARD32 tvo_data_delay_b; >+ CARD32 tvo_sync_pat_expect; >+ CARD32 tvo_sync_threshold; >+ CARD32 tv_dac_cntl; >+ CARD32 tv_pll_cntl; >+ CARD32 tv_pll_fine_cntl; >+ CARD32 upsamp_and_gain_cntl; >+ CARD32 upsamp_coeffs[ N_UPSAMPLER_COEFFS ]; >+ CARD32 uv_adr; >+ CARD32 vdisp; >+ CARD32 vftotal; >+ CARD32 vscaler_cntl1; >+ CARD32 vscaler_cntl2; >+ CARD32 vtotal; >+ CARD32 y_fall_cntl; >+ CARD32 y_rise_cntl; >+ CARD32 y_saw_tooth_cntl; >+ CARD32 disp_merge_cntl; >+ >+ TimingTableEl h_code_timing[ MAX_H_CODE_TIMING_LEN ]; >+ TimingTableEl v_code_timing[ MAX_V_CODE_TIMING_LEN ]; >+} TheaterState , *TheaterStatePtr; >+ >+/********************************************************************** >+ * >+ * TheaterOutRec , TheaterOutPtr >+ * >+ * Global state of module >+ * >+ **********************************************************************/ >+ >+typedef struct TheaterOut >+{ >+ GENERIC_BUS_Ptr VIP; >+ unsigned char *MMIO; >+ >+ int theatre_num; /* Negative when driving an ERT */ >+ /* Positive or null: index of RT on VIP bus */ >+ >+ TVStd standard; >+ Bool compatibleMode; >+ >+ const ModeConstants *currentMode; >+ >+ int hPos; >+ int vPos; >+ int hSize; >+ >+ TheaterState savedState; >+ TheaterState modeState; >+} TheaterOutRec; >+ >+/********************************************************************** >+ * >+ * TVConstants >+ * >+ * Constants that depend on tv standard only >+ * >+ **********************************************************************/ >+ >+typedef struct >+{ >+ CARD8 tvPLL_M; >+ CARD16 tvPLL_N; >+ CARD8 tvPLL_postDiv; >+ CARD32 tvClockT; /* Period of TV clock (unit = 100 psec) */ >+ CARD32 modulatorCntl1; >+ CARD32 modulatorCntl2; >+ CARD32 vip_tvDAC_Cntl; >+ CARD32 ert_tvDAC_Cntl; >+ CARD32 vftotal; >+ unsigned linesFrame; >+ unsigned zeroHSize; /* Length of the picture part of a hor. line for hSize = 0 (unit = 100 psec) */ >+ unsigned hSizeUnit; /* Value of hSize = 1 (unit = 100 psec) */ >+} TVConstants; >+ >+/********************************************************************** >+ * >+ * tvStdConsts >+ * >+ * Table of constants for tv standards (index is a TVStd) >+ * >+ **********************************************************************/ >+ >+static >+const >+TVConstants tvStdConsts[] = >+ { >+ /* >+ * NTSC >+ */ >+ { >+ 22, /* tvPLL_M */ >+ 175, /* tvPLL_N */ >+ 5, /* tvPLL_postDiv */ >+ 233, /* tvClockT */ >+ 0x60bb468c, /* modulatorCntl1 */ >+ 0x00000191, /* modulatorCntl2 */ >+ 0x00000113, /* vip_tvDAC_Cntl */ >+ 0x00680113, /* ert_tvDAC_Cntl */ >+ 1, /* vftotal */ >+ 525, /* linesFrame */ >+ 479166, /* zeroHSize */ >+ 9478 /* hSizeUnit */ >+ }, >+ /* >+ * PAL >+ */ >+ { >+ 113, /* tvPLL_M */ >+ 668, /* tvPLL_N */ >+ 3, /* tvPLL_postDiv */ >+ 188, /* tvClockT */ >+ 0x60bb3bcc, /* modulatorCntl1 */ >+ 0x003e01b2, /* modulatorCntl2 */ >+ 0x00000013, /* vip_tvDAC_Cntl */ >+ 0x00680013, /* ert_tvDAC_Cntl */ >+ 3, /* vftotal */ >+ 625, /* linesFrame */ >+ 473200, /* zeroHSize */ >+ 9360 /* hSizeUnit */ >+ } >+ }; >+ >+/********************************************************************** >+ * >+ * availableModes >+ * >+ * Table of all allowed modes for tv output >+ * >+ **********************************************************************/ >+ >+static >+const >+TimingTableEl horTimingNTSC_BIOS[] = >+ { >+ 0x0007, >+ 0x003f, >+ 0x0263, >+ 0x0a24, >+ 0x2a6b, >+ 0x0a36, >+ 0x126d, /* H_TABLE_POS1 */ >+ 0x1bfe, >+ 0x1a8f, /* H_TABLE_POS2 */ >+ 0x1ec7, >+ 0x3863, >+ 0x1bfe, >+ 0x1bfe, >+ 0x1a2a, >+ 0x1e95, >+ 0x0e31, >+ 0x201b, >+ 0 >+ }; >+ >+static >+const >+TimingTableEl verTimingNTSC_BIOS[] = >+ { >+ 0x2001, >+ 0x200d, >+ 0x1006, >+ 0x0c06, >+ 0x1006, >+ 0x1818, >+ 0x21e3, >+ 0x1006, >+ 0x0c06, >+ 0x1006, >+ 0x1817, >+ 0x21d4, >+ 0x0002, >+ 0 >+ }; >+ >+static >+const >+TimingTableEl horTimingPAL_BIOS[] = >+ { >+ 0x0007, >+ 0x0058, >+ 0x027c, >+ 0x0a31, >+ 0x2a77, >+ 0x0a95, >+ 0x124f, /* H_TABLE_POS1 */ >+ 0x1bfe, >+ 0x1b22, /* H_TABLE_POS2 */ >+ 0x1ef9, >+ 0x387c, >+ 0x1bfe, >+ 0x1bfe, >+ 0x1b31, >+ 0x1eb5, >+ 0x0e43, >+ 0x201b, >+ 0 >+ }; >+ >+static >+const >+TimingTableEl verTimingPAL_BIOS[] = >+ { >+ 0x2001, >+ 0x200c, >+ 0x1005, >+ 0x0c05, >+ 0x1005, >+ 0x1401, >+ 0x1821, >+ 0x2240, >+ 0x1005, >+ 0x0c05, >+ 0x1005, >+ 0x1401, >+ 0x1822, >+ 0x2230, >+ 0x0002, >+ 0 >+ }; >+ >+static >+const >+ModeConstants availableModes[] = >+ { >+ { >+ 800, /* horResolution */ >+ 600, /* verResolution */ >+ TV_STD_NTSC, /* standard */ >+ 990, /* horTotal */ >+ 740, /* verTotal */ >+ 813, /* horStart */ >+ 824, /* horSyncStart */ >+ 632, /* verSyncStart */ >+ 625592, /* defRestart */ >+ 0x0900b46b, /* vScalerCntl1 */ >+ 0x00012c00, /* yRiseCntl */ >+ 0x10002d1a, /* ySawtoothCntl */ >+ 592, /* crtcPLL_N */ >+ 91, /* crtcPLL_M */ >+ TRUE, /* crtcPLL_divBy2 */ >+ 0, /* crtcPLL_byteClkDiv */ >+ 4, /* crtcPLL_postDiv */ >+ FALSE, /* use888RGB */ >+ 1022, /* pixToTV */ >+ 1, /* byteClkDelay */ >+ 0x0a0b0907, /* tvoDataDelayA */ >+ 0x060a090a, /* tvoDataDelayB */ >+ horTimingNTSC_BIOS,/* horTimingTable */ >+ verTimingNTSC_BIOS/* verTimingTable */ >+ }, >+ { >+ 800, /* horResolution */ >+ 600, /* verResolution */ >+ TV_STD_PAL, /* standard */ >+ 1144, /* horTotal */ >+ 706, /* verTotal */ >+ 812, /* horStart */ >+ 824, /* horSyncStart */ >+ 669, /* verSyncStart */ >+ 696700, /* defRestart */ >+ 0x09009097, /* vScalerCntl1 */ >+ 0x000007da, /* yRiseCntl */ >+ 0x10002426, /* ySawtoothCntl */ >+ 1382, /* crtcPLL_N */ >+ 231, /* crtcPLL_M */ >+ TRUE, /* crtcPLL_divBy2 */ >+ 0, /* crtcPLL_byteClkDiv */ >+ 4, /* crtcPLL_postDiv */ >+ FALSE, /* use888RGB */ >+ 759, /* pixToTV */ >+ 1, /* byteClkDelay */ >+ 0x0a0b0907, /* tvoDataDelayA */ >+ 0x060a090a, /* tvoDataDelayB */ >+ horTimingPAL_BIOS,/* horTimingTable */ >+ verTimingPAL_BIOS /* verTimingTable */ >+ } >+ }; >+ >+#define N_AVAILABLE_MODES (sizeof(availableModes) / sizeof(availableModes[ 0 ])) >+ >+/********************************************************************** >+ * >+ * theatre_read >+ * >+ * Read from a RT register >+ * >+ **********************************************************************/ >+ >+static >+Bool >+theatre_read( >+ TheaterOutPtr t, >+ CARD32 reg, >+ CARD32 *data >+ ) >+{ >+ if (t->theatre_num < 0) >+ return FALSE; >+ >+ return t->VIP->read(t->VIP, ((t->theatre_num & 0x3) << 14) | reg , 4 , (CARD8*)data); >+} >+ >+/********************************************************************** >+ * >+ * theatre_write >+ * >+ * Write to a RT register >+ * >+ **********************************************************************/ >+ >+static >+Bool >+theatre_write( >+ TheaterOutPtr t, >+ CARD32 reg, >+ CARD32 data >+ ) >+{ >+ if (t->theatre_num < 0) >+ return FALSE; >+ >+ return t->VIP->write(t->VIP , ((t->theatre_num & 0x03) << 14) | reg , 4 , (CARD8*)&data); >+} >+ >+/********************************************************************** >+ * >+ * ert_read >+ * >+ * Read from an ERT register >+ * >+ **********************************************************************/ >+ >+static >+void >+ert_read( >+ TheaterOutPtr t, >+ CARD32 reg, >+ CARD32 *data >+ ) >+{ >+ unsigned char *RADEONMMIO = t->MMIO; >+ >+ if (t->theatre_num < 0) >+ *data = INREG(reg); >+} >+ >+/********************************************************************** >+ * >+ * ert_write >+ * >+ * Write to an ERT register >+ * >+ **********************************************************************/ >+static >+void >+ert_write( >+ TheaterOutPtr t, >+ CARD32 reg, >+ CARD32 data >+ ) >+{ >+ unsigned char *RADEONMMIO = t->MMIO; >+ >+ if (t->theatre_num < 0) >+ OUTREG(reg , data); >+} >+ >+/********************************************************************** >+ * >+ * waitPLL_lock >+ * >+ * Wait for PLLs to lock >+ * >+ **********************************************************************/ >+ >+static >+void >+waitPLL_lock( >+ TheaterOutPtr t, >+ ScrnInfoPtr pScrn, >+ unsigned nTests, >+ unsigned nWaitLoops, >+ unsigned cntThreshold >+ ) >+{ >+ unsigned char *RADEONMMIO = t->MMIO; >+ CARD32 savePLLTest; >+ unsigned i; >+ unsigned j; >+ >+ OUTREG(RADEON_TEST_DEBUG_MUX , (INREG(RADEON_TEST_DEBUG_MUX) & 0xffff60ff) | 0x100); >+ >+ savePLLTest = INPLL(pScrn , RADEON_PLL_TEST_CNTL); >+ >+ OUTPLL(pScrn , RADEON_PLL_TEST_CNTL , savePLLTest & ~RADEON_PLL_TEST_CNTL_PLL_MASK_READ_B); >+ >+ OUTREG8(RADEON_CLOCK_CNTL_INDEX , RADEON_PLL_TEST_CNTL); >+ >+ for (i = 0; i < nTests; i++) >+ { >+ OUTREG8(RADEON_CLOCK_CNTL_DATA + 3 , 0); >+ >+ for (j = 0; j < nWaitLoops; j++) >+ if (INREG8(RADEON_CLOCK_CNTL_DATA + 3) >= cntThreshold) >+ break; >+ } >+ >+ OUTPLL(pScrn , RADEON_PLL_TEST_CNTL , savePLLTest); >+ >+ OUTREG(RADEON_TEST_DEBUG_MUX , INREG(RADEON_TEST_DEBUG_MUX) & 0xffffe0ff); >+} >+ >+/********************************************************************** >+ * >+ * restorePLL >+ * >+ * Set PLLs for CRTC pixel clock & TV color burst generation >+ * >+ **********************************************************************/ >+ >+static >+void >+restorePLL( >+ TheaterOutPtr t, >+ ScrnInfoPtr pScrn, >+ TheaterStatePtr restore >+ ) >+{ >+ unsigned i; >+ >+ /* >+ * Set TV PLL >+ */ >+ RTTRACE(("restorePLL: TV_PLL_CNTL = %08x\n" , restore->tv_pll_cntl)); >+ theatre_write(t , VIP_TV_PLL_CNTL , restore->tv_pll_cntl); >+ theatre_write(t , VIP_TV_PLL_FINE_CNTL , restore->tv_pll_fine_cntl); >+ >+ /* >+ * Set CRT PLL (for byte and pixel clock generation) >+ */ >+ RTTRACE(("restorePLL: CRT_PLL_CNTL = %08x\n" , restore->crt_pll_cntl)); >+ theatre_write(t , VIP_CRT_PLL_CNTL , restore->crt_pll_cntl); >+ >+ theatre_write(t , VIP_PLL_CNTL0 , restore->pll_cntl0); >+ >+ theatre_write(t , VIP_PLL_TEST_CNTL , restore->pll_test_cntl); >+ >+ /* >+ * Set coefficients for upsampler >+ */ >+ for (i = 0; i < N_UPSAMPLER_COEFFS; i++) >+ theatre_write(t , VIP_UPSAMP_COEFF0_0 + i * 4 , restore->upsamp_coeffs[ i ]); >+ >+ /* >+ * Waiting for PLLs to settle is skipped when restoring a state with stopped PLLs >+ */ >+ if ((~restore->pll_cntl0 & (VIP_PLL_CNTL0_TVSLEEPB | VIP_PLL_CNTL0_CRTSLEEPB)) == 0) >+ { >+ waitPLL_lock(t , pScrn , 3000 , 160 , 27); >+ >+ theatre_write(t , VIP_CLOCK_SEL_CNTL , restore->clock_sel_cntl & ~VIP_CLOCK_SEL_CNTL_REGCLK); >+ >+ waitPLL_lock(t , pScrn , 3000 , 160 , 27); >+ } >+ >+ RTTRACE(("restorePLL: CLOCK_SEL_CNTL = %08x\n" , restore->clock_sel_cntl)); >+ theatre_write(t , VIP_CLOCK_SEL_CNTL , restore->clock_sel_cntl); >+ >+ theatre_write(t , VIP_CLKOUT_CNTL , restore->clkout_cntl); >+} >+ >+/********************************************************************** >+ * >+ * restoreTVO_SYNC >+ * >+ * Set TVO_SYNC_* registers >+ * >+ **********************************************************************/ >+ >+static >+void >+restoreTVO_SYNC( >+ TheaterOutPtr t, >+ TheaterStatePtr restore >+ ) >+{ >+ theatre_write(t , VIP_SYNC_LOCK_CNTL , restore->sync_lock_cntl); >+ theatre_write(t , VIP_TVO_SYNC_THRESHOLD , restore->tvo_sync_threshold); >+ theatre_write(t , VIP_TVO_SYNC_PAT_EXPECT , restore->tvo_sync_pat_expect); >+} >+ >+/********************************************************************** >+ * >+ * restoreTVO_DataDelay >+ * >+ * Set TVO_DATA_DELAY_* registers >+ * >+ **********************************************************************/ >+ >+static >+void >+restoreTVO_DataDelay( >+ TheaterOutPtr t, >+ TheaterStatePtr restore >+ ) >+{ >+ theatre_write(t , VIP_TVO_DATA_DELAY_A , restore->tvo_data_delay_a); >+ theatre_write(t , VIP_TVO_DATA_DELAY_B , restore->tvo_data_delay_b); >+} >+ >+/********************************************************************** >+ * >+ * restoreRT_HV >+ * >+ * Set RT horizontal/vertical settings >+ * >+ **********************************************************************/ >+ >+static >+void >+restoreRT_HV( >+ TheaterOutPtr t, >+ TheaterStatePtr restore >+ ) >+{ >+ theatre_write(t , VIP_RGB_CNTL , restore->rgb_cntl); >+ >+ theatre_write(t , VIP_HTOTAL , restore->htotal); >+ theatre_write(t , VIP_HDISP , restore->hdisp); >+ theatre_write(t , VIP_HSTART , restore->hstart); >+ >+ theatre_write(t , VIP_VTOTAL , restore->vtotal); >+ theatre_write(t , VIP_VDISP , restore->vdisp); >+ >+ theatre_write(t , VIP_VFTOTAL , restore->vftotal); >+ >+ theatre_write(t , VIP_SYNC_SIZE , restore->sync_size); >+ >+ theatre_write(t , VIP_VSCALER_CNTL1 , restore->vscaler_cntl1); >+ theatre_write(t , VIP_VSCALER_CNTL2 , restore->vscaler_cntl2); >+ >+ theatre_write(t , VIP_Y_FALL_CNTL , restore->y_fall_cntl); >+ theatre_write(t , VIP_Y_RISE_CNTL , restore->y_rise_cntl); >+ theatre_write(t , VIP_Y_SAW_TOOTH_CNTL , restore->y_saw_tooth_cntl); >+} >+ >+/********************************************************************** >+ * >+ * restoreRestarts >+ * >+ * Set RT D*RESTART registers >+ * >+ **********************************************************************/ >+ >+static >+void >+restoreRestarts( >+ TheaterOutPtr t, >+ TheaterStatePtr restore >+ ) >+{ >+ theatre_write(t , VIP_DFRESTART , restore->dfrestart); >+ theatre_write(t , VIP_DHRESTART , restore->dhrestart); >+ theatre_write(t , VIP_DVRESTART , restore->dvrestart); >+} >+ >+/********************************************************************** >+ * >+ * writeFIFO >+ * >+ * Write to RT FIFO RAM >+ * >+ **********************************************************************/ >+ >+static >+void >+writeFIFO( >+ TheaterOutPtr t, >+ CARD16 addr, >+ CARD32 value >+ ) >+{ >+ CARD32 tmp; >+ >+ if (t->theatre_num >= 0) >+ { >+ theatre_write(t , VIP_HOST_WRITE_DATA , value); >+ >+ theatre_write(t , VIP_HOST_RD_WT_CNTL , addr | VIP_HOST_RD_WT_CNTL_WT); >+ >+ do >+ { >+ if (!theatre_read(t , VIP_HOST_RD_WT_CNTL , &tmp)) >+ break; >+ } >+ while ((tmp & VIP_HOST_RD_WT_CNTL_WT_ACK) == 0); >+ >+ theatre_write(t , VIP_HOST_RD_WT_CNTL , 0); >+ } >+ else >+ { >+ ert_write(t , TV_HOST_WRITE_DATA , value); >+ >+ ert_write(t , TV_HOST_RD_WT_CNTL , addr | VIP_HOST_RD_WT_CNTL_WT); >+ >+ do >+ { >+ ert_read(t , TV_HOST_RD_WT_CNTL , &tmp); >+ } >+ while ((tmp & VIP_HOST_RD_WT_CNTL_WT_ACK) == 0); >+ >+ ert_write(t , TV_HOST_RD_WT_CNTL , 0); >+ } >+} >+ >+/********************************************************************** >+ * >+ * readFIFO >+ * >+ * Read from RT FIFO RAM >+ * >+ **********************************************************************/ >+ >+static >+void >+readFIFO( >+ TheaterOutPtr t, >+ CARD16 addr, >+ CARD32 *value >+ ) >+{ >+ CARD32 tmp; >+ >+ if (t->theatre_num >= 0) >+ { >+ theatre_write(t , VIP_HOST_RD_WT_CNTL , addr | VIP_HOST_RD_WT_CNTL_RD); >+ >+ do >+ { >+ if (!theatre_read(t , VIP_HOST_RD_WT_CNTL , &tmp)) >+ break; >+ } >+ while ((tmp & VIP_HOST_RD_WT_CNTL_RD_ACK) == 0); >+ >+ theatre_write(t , VIP_HOST_RD_WT_CNTL , 0); >+ >+ theatre_read(t , VIP_HOST_READ_DATA , value); >+ } >+ else >+ { >+ ert_write(t , TV_HOST_RD_WT_CNTL , addr | VIP_HOST_RD_WT_CNTL_RD); >+ >+ do >+ { >+ ert_read(t , TV_HOST_RD_WT_CNTL , &tmp); >+ } >+ while ((tmp & VIP_HOST_RD_WT_CNTL_RD_ACK) == 0); >+ >+ ert_write(t , TV_HOST_RD_WT_CNTL , 0); >+ >+ ert_read(t , TV_HOST_READ_DATA , value); >+ } >+} >+ >+/********************************************************************** >+ * >+ * getTimingTablesAddr >+ * >+ * Get FIFO addresses of horizontal & vertical code timing tables from >+ * settings of uv_adr register. >+ * >+ **********************************************************************/ >+ >+static >+void >+getTimingTablesAddr( >+ CARD32 uv_adr, >+ Bool isERT, >+ CARD16 *hTable, >+ CARD16 *vTable >+ ) >+{ >+ switch ((uv_adr & VIP_UV_ADR_HCODE_TABLE_SEL) >> VIP_UV_ADR_HCODE_TABLE_SEL_SHIFT) >+ { >+ case 0: >+ *hTable = isERT ? MAX_FIFO_ADDR_ERT : MAX_FIFO_ADDR_RT; >+ break; >+ >+ case 1: >+ *hTable = ((uv_adr & VIP_UV_ADR_TABLE1_BOT_ADR) >> VIP_UV_ADR_TABLE1_BOT_ADR_SHIFT) * 2; >+ break; >+ >+ case 2: >+ *hTable = ((uv_adr & VIP_UV_ADR_TABLE3_TOP_ADR) >> VIP_UV_ADR_TABLE3_TOP_ADR_SHIFT) * 2; >+ break; >+ >+ default: >+ /* >+ * Of course, this should never happen >+ */ >+ *hTable = 0; >+ break; >+ } >+ >+ switch ((uv_adr & VIP_UV_ADR_VCODE_TABLE_SEL) >> VIP_UV_ADR_VCODE_TABLE_SEL_SHIFT) >+ { >+ case 0: >+ *vTable = ((uv_adr & VIP_UV_ADR_MAX_UV_ADR) >> VIP_UV_ADR_MAX_UV_ADR_SHIFT) * 2 + 1; >+ break; >+ >+ case 1: >+ *vTable = ((uv_adr & VIP_UV_ADR_TABLE1_BOT_ADR) >> VIP_UV_ADR_TABLE1_BOT_ADR_SHIFT) * 2 + 1; >+ break; >+ >+ case 2: >+ *vTable = ((uv_adr & VIP_UV_ADR_TABLE3_TOP_ADR) >> VIP_UV_ADR_TABLE3_TOP_ADR_SHIFT) * 2 + 1; >+ break; >+ >+ default: >+ /* >+ * Of course, this should never happen >+ */ >+ *vTable = 0; >+ break; >+ } >+} >+ >+/********************************************************************** >+ * >+ * saveTimingTables >+ * >+ * Save horizontal/vertical timing code tables >+ * >+ **********************************************************************/ >+static >+void >+saveTimingTables( >+ TheaterOutPtr t, >+ TheaterStatePtr save >+ ) >+{ >+ CARD16 hTable; >+ CARD16 vTable; >+ CARD32 tmp; >+ unsigned i; >+ >+ if (t->theatre_num >= 0) >+ { >+ theatre_read(t , VIP_UV_ADR , &save->uv_adr); >+ getTimingTablesAddr(save->uv_adr , FALSE , &hTable , &vTable); >+ } >+ else >+ { >+ ert_read(t , TV_UV_ADR , &save->uv_adr); >+ getTimingTablesAddr(save->uv_adr , TRUE , &hTable , &vTable); >+ } >+ >+ /* >+ * Reset FIFO arbiter in order to be able to access FIFO RAM >+ */ >+ if (t->theatre_num >= 0) >+ { >+ theatre_write(t , >+ VIP_MASTER_CNTL , >+ save->master_cntl | >+ VIP_MASTER_CNTL_CRT_ASYNC_RST | >+ VIP_MASTER_CNTL_TV_FIFO_ASYNC_RST | >+ VIP_MASTER_CNTL_TV_ASYNC_RST); >+ theatre_write(t , >+ VIP_MASTER_CNTL , >+ save->master_cntl | >+ VIP_MASTER_CNTL_TV_ASYNC_RST | >+ VIP_MASTER_CNTL_CRT_ASYNC_RST); >+ } >+ else >+ { >+ ert_write(t , >+ TV_MASTER_CNTL , >+ save->master_cntl | TV_MASTER_CNTL_TV_ON); >+ } >+ >+ RTTRACE(("saveTimingTables: reading timing tables\n")); >+ >+ for (i = 0; i < MAX_H_CODE_TIMING_LEN; i += 2) >+ { >+ readFIFO(t , hTable-- , &tmp); >+ save->h_code_timing[ i ] = (CARD16)((tmp >> 14) & 0x3fff); >+ save->h_code_timing[ i + 1 ] = (CARD16)(tmp & 0x3fff); >+ >+ if (save->h_code_timing[ i ] == 0 || save->h_code_timing[ i + 1 ] == 0) >+ break; >+ } >+ >+ for (i = 0; i < MAX_V_CODE_TIMING_LEN; i += 2) >+ { >+ readFIFO(t , vTable++ , &tmp); >+ save->v_code_timing[ i ] = (CARD16)(tmp & 0x3fff); >+ save->v_code_timing[ i + 1 ] = (CARD16)((tmp >> 14) & 0x3fff); >+ >+ if (save->v_code_timing[ i ] == 0 || save->v_code_timing[ i + 1 ] == 0) >+ break; >+ } >+} >+ >+/********************************************************************** >+ * >+ * restoreTimingTables >+ * >+ * Load horizontal/vertical timing code tables >+ * >+ **********************************************************************/ >+ >+static >+void >+restoreTimingTables( >+ TheaterOutPtr t, >+ TheaterStatePtr restore >+ ) >+{ >+ CARD16 hTable; >+ CARD16 vTable; >+ CARD32 tmp; >+ unsigned i; >+ >+ if (t->theatre_num >= 0) >+ { >+ theatre_write(t , VIP_UV_ADR , restore->uv_adr); >+ getTimingTablesAddr(restore->uv_adr , FALSE , &hTable , &vTable); >+ } >+ else >+ { >+ ert_write(t , TV_UV_ADR , restore->uv_adr); >+ getTimingTablesAddr(restore->uv_adr , TRUE , &hTable , &vTable); >+ } >+ >+ for (i = 0; i < MAX_H_CODE_TIMING_LEN; i += 2 , hTable--) >+ { >+ tmp = ((CARD32)restore->h_code_timing[ i ] << 14) | ((CARD32)restore->h_code_timing[ i + 1 ]); >+ writeFIFO(t , hTable , tmp); >+ if (restore->h_code_timing[ i ] == 0 || restore->h_code_timing[ i + 1 ] == 0) >+ break; >+ } >+ >+ for (i = 0; i < MAX_V_CODE_TIMING_LEN; i += 2 , vTable++) >+ { >+ tmp = ((CARD32)restore->v_code_timing[ i + 1 ] << 14) | ((CARD32)restore->v_code_timing[ i ]); >+ writeFIFO(t , vTable , tmp); >+ if (restore->v_code_timing[ i ] == 0 || restore->v_code_timing[ i + 1 ] == 0) >+ break; >+ } >+} >+ >+/********************************************************************** >+ * >+ * restoreOutputStd >+ * >+ * Set tv standard & output muxes >+ * >+ **********************************************************************/ >+ >+static >+void >+restoreOutputStd( >+ TheaterOutPtr t, >+ TheaterStatePtr restore >+ ) >+{ >+ theatre_write(t , VIP_SYNC_CNTL , restore->sync_cntl); >+ >+ theatre_write(t , VIP_TIMING_CNTL , restore->timing_cntl); >+ >+ theatre_write(t , VIP_MODULATOR_CNTL1 , restore->modulator_cntl1); >+ theatre_write(t , VIP_MODULATOR_CNTL2 , restore->modulator_cntl2); >+ >+ theatre_write(t , VIP_PRE_DAC_MUX_CNTL , restore->pre_dac_mux_cntl); >+ >+ theatre_write(t , VIP_CRC_CNTL , restore->crc_cntl); >+ >+ theatre_write(t , VIP_FRAME_LOCK_CNTL , restore->frame_lock_cntl); >+ >+ theatre_write(t , VIP_HW_DEBUG , restore->hw_debug); >+} >+ >+/********************************************************************** >+ * >+ * enableTV_DAC >+ * >+ * Enable/disable tv output DAC >+ * >+ **********************************************************************/ >+ >+static >+void >+enableTV_DAC( >+ TheaterOutPtr t, >+ Bool enable >+ ) >+{ >+ CARD32 tmp; >+ >+ theatre_read(t , VIP_TV_DAC_CNTL , &tmp); >+ >+ if (enable) >+ { >+ tmp |= VIP_TV_DAC_CNTL_NBLANK; >+ tmp &= ~VIP_TV_DAC_CNTL_DASLEEP; >+ tmp &= ~VIP_TV_DAC_CNTL_BGSLEEP; >+ } >+ else >+ { >+ tmp &= ~VIP_TV_DAC_CNTL_NBLANK; >+ tmp |= VIP_TV_DAC_CNTL_DASLEEP; >+ tmp |= VIP_TV_DAC_CNTL_BGSLEEP; >+ } >+ >+ theatre_write(t , VIP_TV_DAC_CNTL , tmp); >+} >+ >+/********************************************************************** >+ * >+ * ERT_RestorePLL >+ * >+ * Set ERT PLLs >+ * >+ **********************************************************************/ >+static >+void >+ERT_RestorePLL( >+ TheaterOutPtr t, >+ ScrnInfoPtr pScrn, >+ TheaterStatePtr restore >+ ) >+{ >+ unsigned char *RADEONMMIO = t->MMIO; >+ >+ OUTPLLP(pScrn , TV_PLL_CNTL1 , 0 , ~TV_PLL_CNTL1_TVCLK_SRC_SEL); >+ OUTPLL(pScrn , TV_PLL_CNTL , restore->tv_pll_cntl); >+ OUTPLLP(pScrn , TV_PLL_CNTL1 , TV_PLL_CNTL1_TVPLL_RESET , ~TV_PLL_CNTL1_TVPLL_RESET); >+ >+ waitPLL_lock(t , pScrn , 200 , 800 , 135); >+ >+ OUTPLLP(pScrn , TV_PLL_CNTL1 , 0 , ~TV_PLL_CNTL1_TVPLL_RESET); >+ >+ waitPLL_lock(t , pScrn , 300 , 160 , 27); >+ waitPLL_lock(t , pScrn , 200 , 800 , 135); >+ >+ OUTPLLP(pScrn , TV_PLL_CNTL1 , 0 , ~0xf); >+ OUTPLLP(pScrn , TV_PLL_CNTL1 , TV_PLL_CNTL1_TVCLK_SRC_SEL , ~TV_PLL_CNTL1_TVCLK_SRC_SEL); >+ >+ OUTPLLP(pScrn , TV_PLL_CNTL1 , (1 << TV_PLL_CNTL1_TVPDC_SHIFT) , ~TV_PLL_CNTL1_TVPDC_MASK); >+ OUTPLLP(pScrn , TV_PLL_CNTL1 , 0 , ~TV_PLL_CNTL1_TVPLL_SLEEP); >+} >+ >+/********************************************************************** >+ * >+ * ERT_RestoreHV >+ * >+ * Set ERT horizontal/vertical settings >+ * >+ **********************************************************************/ >+ >+static >+void >+ERT_RestoreHV( >+ TheaterOutPtr t, >+ TheaterStatePtr restore >+ ) >+{ >+ ert_write(t , TV_RGB_CNTL , restore->rgb_cntl); >+ >+ ert_write(t , TV_HTOTAL , restore->htotal); >+ ert_write(t , TV_HDISP , restore->hdisp); >+ ert_write(t , TV_HSTART , restore->hstart); >+ >+ ert_write(t , TV_VTOTAL , restore->vtotal); >+ ert_write(t , TV_VDISP , restore->vdisp); >+ >+ ert_write(t , TV_FTOTAL , restore->vftotal); >+ >+ ert_write(t , TV_VSCALER_CNTL1 , restore->vscaler_cntl1); >+ ert_write(t , TV_VSCALER_CNTL2 , restore->vscaler_cntl2); >+ >+ ert_write(t , TV_Y_FALL_CNTL , restore->y_fall_cntl); >+ ert_write(t , TV_Y_RISE_CNTL , restore->y_rise_cntl); >+ ert_write(t , TV_Y_SAWTOOTH_CNTL , restore->y_saw_tooth_cntl); >+} >+ >+/********************************************************************** >+ * >+ * ERT_RestoreRestarts >+ * >+ * Set ERT TV_*RESTART registers >+ * >+ **********************************************************************/ >+ >+static >+void >+ERT_RestoreRestarts( >+ TheaterOutPtr t, >+ TheaterStatePtr restore >+ ) >+{ >+ ert_write(t , TV_FRESTART , restore->dfrestart); >+ ert_write(t , TV_HRESTART , restore->dhrestart); >+ ert_write(t , TV_VRESTART , restore->dvrestart); >+} >+ >+/********************************************************************** >+ * >+ * ERT_RestoreOutputStd >+ * >+ * Set tv standard & output muxes >+ * >+ **********************************************************************/ >+static >+void >+ERT_RestoreOutputStd( >+ TheaterOutPtr t, >+ TheaterStatePtr restore >+ ) >+{ >+ ert_write(t , TV_SYNC_CNTL , restore->sync_cntl); >+ >+ ert_write(t , TV_TIMING_CNTL , restore->timing_cntl); >+ >+ ert_write(t , TV_MODULATOR_CNTL1 , restore->modulator_cntl1); >+ ert_write(t , TV_MODULATOR_CNTL2 , restore->modulator_cntl2); >+ >+ ert_write(t , TV_PRE_DAC_MUX_CNTL , restore->pre_dac_mux_cntl); >+ >+ ert_write(t , TV_CRC_CNTL , restore->crc_cntl); >+} >+ >+/********************************************************************** >+ * >+ * ERT_IsOn >+ * >+ * Test if tv output would be enabled with a given value in TV_DAC_CNTL >+ * >+ **********************************************************************/ >+static >+Bool >+ERT_IsOn( >+ CARD32 tv_dac_cntl >+ ) >+{ >+ if (tv_dac_cntl & TV_DAC_CNTL_BGSLEEP) >+ return FALSE; >+ else if ((tv_dac_cntl & (TV_DAC_CNTL_RDACPD | TV_DAC_CNTL_GDACPD | TV_DAC_CNTL_BDACPD)) == >+ (TV_DAC_CNTL_RDACPD | TV_DAC_CNTL_GDACPD | TV_DAC_CNTL_BDACPD)) >+ return FALSE; >+ else >+ return TRUE; >+} >+ >+/********************************************************************** >+ * >+ * ERT_Restore >+ * >+ * Restore state of ERT >+ * >+ **********************************************************************/ >+static >+void >+ERT_Restore( >+ TheaterOutPtr t, >+ ScrnInfoPtr pScrn, >+ TheaterStatePtr restore >+ ) >+{ >+ RTTRACE(("Entering ERT_Restore\n")); >+ >+ ert_write(t , >+ TV_MASTER_CNTL , >+ restore->master_cntl | TV_MASTER_CNTL_TV_ON); >+ >+ ert_write(t, >+ TV_MASTER_CNTL , >+ restore->master_cntl | >+ VIP_MASTER_CNTL_TV_ASYNC_RST | >+ VIP_MASTER_CNTL_CRT_ASYNC_RST | >+ VIP_MASTER_CNTL_RESTART_PHASE_FIX | >+ VIP_MASTER_CNTL_TV_FIFO_ASYNC_RST); >+ >+ /* >+ * Temporarily turn the TV DAC off >+ */ >+ ert_write(t , >+ TV_DAC_CNTL , >+ (restore->tv_dac_cntl & ~TV_DAC_CNTL_NBLANK) | >+ TV_DAC_CNTL_BGSLEEP | >+ TV_DAC_CNTL_RDACPD | >+ TV_DAC_CNTL_GDACPD | >+ TV_DAC_CNTL_BDACPD); >+ >+ RTTRACE(("ERT_Restore: checkpoint 1\n")); >+ ERT_RestorePLL(t , pScrn , restore); >+ >+ RTTRACE(("ERT_Restore: checkpoint 2\n")); >+ ERT_RestoreHV(t , restore); >+ >+ ert_write(t, >+ TV_MASTER_CNTL , >+ restore->master_cntl | >+ VIP_MASTER_CNTL_TV_ASYNC_RST | >+ VIP_MASTER_CNTL_CRT_ASYNC_RST | >+ VIP_MASTER_CNTL_RESTART_PHASE_FIX); >+ >+ RTTRACE(("ERT_Restore: checkpoint 3\n")); >+ ERT_RestoreRestarts(t , restore); >+ >+ RTTRACE(("ERT_Restore: checkpoint 4\n")); >+ >+ /* >+ * Timing tables are only restored when tv output is active >+ */ >+ if (ERT_IsOn(restore->tv_dac_cntl)) >+ restoreTimingTables(t , restore); >+ >+ ert_write(t, >+ TV_MASTER_CNTL , >+ restore->master_cntl | >+ VIP_MASTER_CNTL_TV_ASYNC_RST | >+ VIP_MASTER_CNTL_RESTART_PHASE_FIX); >+ >+ RTTRACE(("ERT_Restore: checkpoint 5\n")); >+ ERT_RestoreOutputStd(t , restore); >+ >+ ert_write(t , >+ TV_MASTER_CNTL , >+ restore->master_cntl); >+ >+ ert_write(t , RADEON_DISP_MERGE_CNTL , restore->disp_merge_cntl); >+ >+ ert_write(t , TV_GAIN_LIMIT_SETTINGS , restore->gain_limit_settings); >+ ert_write(t , TV_LINEAR_GAIN_SETTINGS , restore->linear_gain_settings); >+ >+ ert_write(t , TV_DAC_CNTL , restore->tv_dac_cntl); >+ >+ RTTRACE(("Leaving ERT_Restore\n")); >+} >+ >+/********************************************************************** >+ * >+ * RT_Restore >+ * >+ * Restore state of RT >+ * >+ **********************************************************************/ >+ >+static >+void >+RT_Restore( >+ TheaterOutPtr t, >+ ScrnInfoPtr pScrn, >+ TheaterStatePtr restore >+ ) >+{ >+ if (t->theatre_num < 0) >+ { >+ ERT_Restore(t , pScrn , restore); >+ return; >+ } >+ >+ RTTRACE(("Entering RT_Restore\n")); >+ >+ theatre_write(t , >+ VIP_MASTER_CNTL , >+ restore->master_cntl | >+ VIP_MASTER_CNTL_TV_ASYNC_RST | >+ VIP_MASTER_CNTL_CRT_ASYNC_RST | >+ VIP_MASTER_CNTL_TV_FIFO_ASYNC_RST); >+ >+ /* >+ * Temporarily turn the TV DAC off >+ */ >+ theatre_write(t , >+ VIP_TV_DAC_CNTL , >+ (restore->tv_dac_cntl & ~VIP_TV_DAC_CNTL_NBLANK) | >+ VIP_TV_DAC_CNTL_DASLEEP | >+ VIP_TV_DAC_CNTL_BGSLEEP); >+ >+ RTTRACE(("RT_Restore: checkpoint 1\n")); >+ restoreTVO_SYNC(t , restore); >+ >+ RTTRACE(("RT_Restore: checkpoint 2\n")); >+ restorePLL(t , pScrn , restore); >+ >+ RTTRACE(("RT_Restore: checkpoint 3\n")); >+ restoreTVO_DataDelay(t , restore); >+ >+ RTTRACE(("RT_Restore: checkpoint 4\n")); >+ restoreRT_HV(t , restore); >+ >+ theatre_write(t , >+ VIP_MASTER_CNTL , >+ restore->master_cntl | >+ VIP_MASTER_CNTL_TV_ASYNC_RST | >+ VIP_MASTER_CNTL_CRT_ASYNC_RST); >+ >+ RTTRACE(("RT_Restore: checkpoint 5\n")); >+ restoreRestarts(t , restore); >+ >+ RTTRACE(("RT_Restore: checkpoint 6\n")); >+ >+ /* >+ * Timing tables are restored when tv output is active >+ */ >+ if ((restore->tv_dac_cntl & (VIP_TV_DAC_CNTL_DASLEEP | VIP_TV_DAC_CNTL_BGSLEEP)) == 0) >+ restoreTimingTables(t , restore); >+ >+ theatre_write(t , >+ VIP_MASTER_CNTL , >+ restore->master_cntl | >+ VIP_MASTER_CNTL_TV_ASYNC_RST); >+ >+ RTTRACE(("RT_Restore: checkpoint 7\n")); >+ restoreOutputStd(t , restore); >+ >+ theatre_write(t , >+ VIP_MASTER_CNTL , >+ restore->master_cntl); >+ >+ theatre_write(t , VIP_GAIN_LIMIT_SETTINGS , restore->gain_limit_settings); >+ theatre_write(t , VIP_LINEAR_GAIN_SETTINGS , restore->linear_gain_settings); >+ >+ theatre_write(t , VIP_TV_DAC_CNTL , restore->tv_dac_cntl); >+ >+ RTTRACE(("Leaving RT_Restore\n")); >+} >+ >+/********************************************************************** >+ * >+ * RT_Save >+ * >+ * Save state of RT >+ * >+ **********************************************************************/ >+ >+static >+void >+RT_Save( >+ TheaterOutPtr t, >+ ScrnInfoPtr pScrn, >+ TheaterStatePtr save >+ ) >+{ >+ unsigned i; >+ >+ RTTRACE(("Entering RT_Save\n")); >+ >+ if (t->theatre_num >= 0) >+ { >+ theatre_read(t , VIP_CLKOUT_CNTL , &save->clkout_cntl); >+ theatre_read(t , VIP_CLOCK_SEL_CNTL , &save->clock_sel_cntl); >+ theatre_read(t , VIP_CRC_CNTL , &save->crc_cntl); >+ theatre_read(t , VIP_CRT_PLL_CNTL , &save->crt_pll_cntl); >+ theatre_read(t , VIP_DFRESTART , &save->dfrestart); >+ theatre_read(t , VIP_DHRESTART , &save->dhrestart); >+ theatre_read(t , VIP_DVRESTART , &save->dvrestart); >+ theatre_read(t , VIP_FRAME_LOCK_CNTL , &save->frame_lock_cntl); >+ theatre_read(t , VIP_GAIN_LIMIT_SETTINGS , &save->gain_limit_settings); >+ theatre_read(t , VIP_HDISP , &save->hdisp); >+ theatre_read(t , VIP_HSTART , &save->hstart); >+ theatre_read(t , VIP_HTOTAL , &save->htotal); >+ theatre_read(t , VIP_HW_DEBUG , &save->hw_debug); >+ theatre_read(t , VIP_LINEAR_GAIN_SETTINGS, &save->linear_gain_settings); >+ theatre_read(t , VIP_MASTER_CNTL , &save->master_cntl); >+ theatre_read(t , VIP_MODULATOR_CNTL1 , &save->modulator_cntl1); >+ theatre_read(t , VIP_MODULATOR_CNTL2 , &save->modulator_cntl2); >+ theatre_read(t , VIP_PLL_CNTL0 , &save->pll_cntl0); >+ theatre_read(t , VIP_PLL_TEST_CNTL , &save->pll_test_cntl); >+ theatre_read(t , VIP_PRE_DAC_MUX_CNTL , &save->pre_dac_mux_cntl); >+ theatre_read(t , VIP_RGB_CNTL , &save->rgb_cntl); >+ theatre_read(t , VIP_SYNC_CNTL , &save->sync_cntl); >+ theatre_read(t , VIP_SYNC_LOCK_CNTL , &save->sync_lock_cntl); >+ theatre_read(t , VIP_SYNC_SIZE , &save->sync_size); >+ theatre_read(t , VIP_TIMING_CNTL , &save->timing_cntl); >+ theatre_read(t , VIP_TVO_DATA_DELAY_A , &save->tvo_data_delay_a); >+ theatre_read(t , VIP_TVO_DATA_DELAY_B , &save->tvo_data_delay_b); >+ theatre_read(t , VIP_TVO_SYNC_PAT_EXPECT , &save->tvo_sync_pat_expect); >+ theatre_read(t , VIP_TVO_SYNC_THRESHOLD , &save->tvo_sync_threshold); >+ theatre_read(t , VIP_TV_DAC_CNTL , &save->tv_dac_cntl); >+ theatre_read(t , VIP_TV_PLL_CNTL , &save->tv_pll_cntl); >+ theatre_read(t , VIP_TV_PLL_FINE_CNTL , &save->tv_pll_fine_cntl); >+ theatre_read(t , VIP_UPSAMP_AND_GAIN_CNTL, &save->upsamp_and_gain_cntl); >+ theatre_read(t , VIP_VDISP , &save->vdisp); >+ theatre_read(t , VIP_VFTOTAL , &save->vftotal); >+ theatre_read(t , VIP_VSCALER_CNTL1 , &save->vscaler_cntl1); >+ theatre_read(t , VIP_VSCALER_CNTL2 , &save->vscaler_cntl2); >+ theatre_read(t , VIP_VTOTAL , &save->vtotal); >+ theatre_read(t , VIP_Y_FALL_CNTL , &save->y_fall_cntl); >+ theatre_read(t , VIP_Y_RISE_CNTL , &save->y_rise_cntl); >+ theatre_read(t , VIP_Y_SAW_TOOTH_CNTL , &save->y_saw_tooth_cntl); >+ >+ for (i = 0; i < N_UPSAMPLER_COEFFS; i++) >+ theatre_read(t , VIP_UPSAMP_COEFF0_0 + i * 4 , &save->upsamp_coeffs[ i ]); >+ >+ /* >+ * Read H/V code timing tables (current tables only are saved) >+ * This step is skipped when tv output is disabled in current RT state >+ * (see RT_Restore) >+ */ >+ if ((save->tv_dac_cntl & (VIP_TV_DAC_CNTL_DASLEEP | VIP_TV_DAC_CNTL_BGSLEEP)) == 0) >+ saveTimingTables(t , save); >+ } >+ else >+ { >+ /* >+ * ERT >+ */ >+ ert_read(t , TV_CRC_CNTL , &save->crc_cntl); >+ ert_read(t , TV_FRESTART , &save->dfrestart); >+ ert_read(t , TV_HRESTART , &save->dhrestart); >+ ert_read(t , TV_VRESTART , &save->dvrestart); >+ ert_read(t , TV_GAIN_LIMIT_SETTINGS , &save->gain_limit_settings); >+ ert_read(t , TV_HDISP , &save->hdisp); >+ ert_read(t , TV_HSTART , &save->hstart); >+ ert_read(t , TV_HTOTAL , &save->htotal); >+ ert_read(t , TV_LINEAR_GAIN_SETTINGS , &save->linear_gain_settings); >+ ert_read(t , TV_MASTER_CNTL , &save->master_cntl); >+ ert_read(t , TV_RGB_CNTL , &save->rgb_cntl); >+ ert_read(t , TV_MODULATOR_CNTL1 , &save->modulator_cntl1); >+ ert_read(t , TV_MODULATOR_CNTL2 , &save->modulator_cntl2); >+ ert_read(t , TV_PRE_DAC_MUX_CNTL , &save->pre_dac_mux_cntl); >+ ert_read(t , TV_SYNC_CNTL , &save->sync_cntl); >+ ert_read(t , TV_TIMING_CNTL , &save->timing_cntl); >+ ert_read(t , TV_DAC_CNTL , &save->tv_dac_cntl); >+ ert_read(t , TV_UPSAMP_AND_GAIN_CNTL , &save->upsamp_and_gain_cntl); >+ ert_read(t , TV_VDISP , &save->vdisp); >+ ert_read(t , TV_FTOTAL , &save->vftotal); >+ ert_read(t , TV_VSCALER_CNTL1 , &save->vscaler_cntl1); >+ ert_read(t , TV_VSCALER_CNTL2 , &save->vscaler_cntl2); >+ ert_read(t , TV_VTOTAL , &save->vtotal); >+ ert_read(t , TV_Y_FALL_CNTL , &save->y_fall_cntl); >+ ert_read(t , TV_Y_RISE_CNTL , &save->y_rise_cntl); >+ ert_read(t , TV_Y_SAWTOOTH_CNTL , &save->y_saw_tooth_cntl); >+ >+ ert_read(t , RADEON_DISP_MERGE_CNTL , &save->disp_merge_cntl); >+ >+ save->tv_pll_cntl = INPLL(pScrn , TV_PLL_CNTL); >+ >+ /* >+ * Read H/V code timing tables (current tables only are saved) >+ * This step is skipped when tv output is disabled in current RT state >+ * (see RT_Restore) >+ */ >+ if (ERT_IsOn(save->tv_dac_cntl)) >+ saveTimingTables(t , save); >+ } >+ >+ >+ RTTRACE(("RT_Save returning\n")); >+} >+ >+/********************************************************************** >+ * >+ * computeRestarts >+ * >+ * Compute F,V,H restarts from default restart position and >+ * hPos & vPos >+ * Return TRUE when code timing table was changed >+ * >+ **********************************************************************/ >+ >+static >+Bool >+computeRestarts( >+ const ModeConstants *constPtr, >+ TVStd tvStd, >+ int hPos, >+ int vPos, >+ int hSize, >+ TheaterStatePtr save >+ ) >+{ >+ int restart; >+ const TVConstants *pTvStd = &tvStdConsts[ tvStd ]; >+ unsigned hTotal; >+ unsigned vTotal; >+ unsigned fTotal; >+ int vOffset; >+ int hOffset; >+ TimingTableEl p1; >+ TimingTableEl p2; >+ Bool hChanged; >+ CARD16 hInc; >+ >+ hTotal = constPtr->horTotal; >+ vTotal = constPtr->verTotal; >+ fTotal = pTvStd->vftotal + 1; >+ >+ /* >+ * Adjust positions 1&2 in hor. code timing table >+ */ >+ hOffset = hPos * H_POS_UNIT; >+ >+ p1 = constPtr->horTimingTable[ H_TABLE_POS1 ]; >+ p2 = constPtr->horTimingTable[ H_TABLE_POS2 ]; >+ >+ p1 = (TimingTableEl)((int)p1 + hOffset); >+ p2 = (TimingTableEl)((int)p2 - hOffset); >+ >+ hChanged = (p1 != save->h_code_timing[ H_TABLE_POS1 ] || >+ p2 != save->h_code_timing[ H_TABLE_POS2 ]); >+ >+ save->h_code_timing[ H_TABLE_POS1 ] = p1; >+ save->h_code_timing[ H_TABLE_POS2 ] = p2; >+ >+ /* >+ * Convert hOffset from n. of TV clock periods to n. of CRTC clock periods (CRTC pixels) >+ */ >+ hOffset = (hOffset * (int)(constPtr->pixToTV)) / 1000; >+ >+ /* >+ * Adjust restart >+ */ >+ restart = constPtr->defRestart; >+ >+ /* >+ * Convert vPos TV lines to n. of CRTC pixels >+ * Be verrrrry careful when mixing signed & unsigned values in C.. >+ */ >+ vOffset = ((int)(vTotal * hTotal) * 2 * vPos) / (int)(pTvStd->linesFrame); >+ >+ restart -= vOffset + hOffset; >+ >+ RTTRACE(("computeRestarts: def = %u, h = %d , v = %d , p1=%04x , p2=%04x , restart = %d\n" , constPtr->defRestart , hPos , vPos , p1 , p2 , restart)); >+ >+ save->dhrestart = restart % hTotal; >+ restart /= hTotal; >+ save->dvrestart = restart % vTotal; >+ restart /= vTotal; >+ save->dfrestart = restart % fTotal; >+ >+ RTTRACE(("computeRestarts: F/H/V=%u,%u,%u\n" , save->dfrestart , save->dvrestart , save->dhrestart)); >+ >+ /* >+ * Compute H_INC from hSize >+ */ >+ hInc = (CARD16)((int)(constPtr->horResolution * 4096 * pTvStd->tvClockT) / >+ (hSize * (int)(pTvStd->hSizeUnit) + (int)(pTvStd->zeroHSize))); >+ save->timing_cntl = (save->timing_cntl & ~VIP_TIMING_CNTL_H_INC) | >+ ((CARD32)hInc << VIP_TIMING_CNTL_H_INC_SHIFT); >+ >+ RTTRACE(("computeRestarts: hSize=%d,hInc=%u\n" , hSize , hInc)); >+ >+ return hChanged; >+} >+ >+/********************************************************************** >+ * >+ * RT_Init >+ * >+ * Define RT state for a given standard/resolution combination >+ * >+ **********************************************************************/ >+ >+static >+void >+RT_Init( >+ const ModeConstants *constPtr, >+ TVStd tvStd, >+ Bool isErt, >+ Bool enable, >+ int hPos, >+ int vPos, >+ int hSize, >+ TheaterStatePtr save >+ ) >+{ >+ unsigned i; >+ CARD32 tmp; >+ const TVConstants *pTvStd = &tvStdConsts[ tvStd ]; >+ >+ save->clkout_cntl = VIP_CLKOUT_CNTL_INI; >+ >+ save->clock_sel_cntl = VIP_CLOCK_SEL_CNTL_INI | >+ (constPtr->crtcPLL_byteClkDiv << VIP_CLOCK_SEL_CNTL_BYTCLK_SHIFT) | >+ (constPtr->byteClkDelay << VIP_CLOCK_SEL_CNTL_BYTCLKD_SHIFT); >+ >+ save->crc_cntl = 0; >+ >+ tmp = ((CARD32)constPtr->crtcPLL_M << VIP_CRT_PLL_CNTL_M_SHIFT) | >+ (((CARD32)constPtr->crtcPLL_N & VIP_CRT_PLL_CNTL_NLO) << VIP_CRT_PLL_CNTL_NLO_SHIFT) | >+ (((CARD32)constPtr->crtcPLL_N & VIP_CRT_PLL_CNTL_NHI) << VIP_CRT_PLL_CNTL_NHI_SHIFT); >+ if (constPtr->crtcPLL_divBy2) >+ tmp |= VIP_CRT_PLL_CNTL_CLKBY2; >+ save->crt_pll_cntl = tmp; >+ >+ save->frame_lock_cntl = VIP_FRAME_LOCK_CNTL_INI; >+ >+ save->gain_limit_settings = VIP_GAIN_LIMIT_SETTINGS_INI; >+ >+ save->hdisp = constPtr->horResolution - 1; >+ save->hstart = constPtr->horStart; >+ save->htotal = constPtr->horTotal - 1; >+ >+ save->hw_debug = VIP_HW_DEBUG_INI; >+ >+ save->linear_gain_settings = VIP_LINEAR_GAIN_SETTINGS_INI; >+ >+ /* >+ * TEST TEST TEST TEST TEST TEST TEST TEST TEST >+ */ >+ if (isErt) >+ save->master_cntl = enable ? TV_MASTER_CNTL_ON_INI : TV_MASTER_CNTL_OFF_INI; >+ else >+ save->master_cntl = enable ? VIP_MASTER_CNTL_ON_INI : VIP_MASTER_CNTL_OFF_INI; >+ >+ save->modulator_cntl1 = pTvStd->modulatorCntl1; >+ save->modulator_cntl2 = pTvStd->modulatorCntl2; >+ >+ save->pll_cntl0 = VIP_PLL_CNTL0_INI; >+ save->pll_test_cntl = VIP_PLL_TEST_CNTL_INI; >+ >+ save->pre_dac_mux_cntl = VIP_PRE_DAC_MUX_CNTL_INI; >+ >+ if (isErt) >+ save->rgb_cntl = TV_RGB_CNTL_INI; >+ else >+ /* >+ * Instruct RT to accept either 565 or 888 packed pixels >+ */ >+ save->rgb_cntl = constPtr->use888RGB ? VIP_RGB_CNTL_RGB_IS_888_PACK : 0; >+ >+ save->sync_cntl = VIP_SYNC_CNTL_INI; >+ >+ save->sync_lock_cntl = VIP_SYNC_LOCK_CNTL_INI; >+ >+ save->sync_size = constPtr->horResolution + 8; >+ >+ tmp = (constPtr->vScalerCntl1 >> VIP_VSCALER_CNTL1_UV_INC_SHIFT) & VIP_VSCALER_CNTL1_UV_INC; >+ tmp = ((16384 * 256 * 10) / tmp + 5) / 10; >+ tmp = (tmp << VIP_TIMING_CNTL_UV_OUT_POST_SCALE_SHIFT) | >+ VIP_TIMING_CNTL_INI; >+ save->timing_cntl = tmp; >+ >+ save->tvo_data_delay_a = constPtr->tvoDataDelayA; >+ save->tvo_data_delay_b = constPtr->tvoDataDelayB; >+ >+ save->tvo_sync_pat_expect = VIP_TVO_SYNC_PAT_EXPECT_INI; >+ >+ if (constPtr->use888RGB) >+ save->tvo_sync_threshold = constPtr->horResolution + constPtr->horResolution / 2; >+ else >+ save->tvo_sync_threshold = constPtr->horResolution; >+ >+ if (isErt) >+ { >+ if (enable) >+ save->tv_dac_cntl = pTvStd->ert_tvDAC_Cntl; >+ else >+ save->tv_dac_cntl = (pTvStd->ert_tvDAC_Cntl & ~(TV_DAC_CNTL_NBLANK | TV_DAC_CNTL_NHOLD)) | >+ (TV_DAC_CNTL_BGSLEEP | TV_DAC_CNTL_RDACPD | TV_DAC_CNTL_GDACPD | TV_DAC_CNTL_BDACPD); >+ } >+ else >+ { >+ if (enable) >+ save->tv_dac_cntl = pTvStd->vip_tvDAC_Cntl; >+ else >+ save->tv_dac_cntl = (pTvStd->vip_tvDAC_Cntl & ~VIP_TV_DAC_CNTL_NBLANK) | >+ (VIP_TV_DAC_CNTL_DASLEEP | VIP_TV_DAC_CNTL_BGSLEEP); >+ } >+ >+ tmp = ((CARD32)(pTvStd->tvPLL_M) << VIP_TV_PLL_CNTL_M_SHIFT) | >+ (((CARD32)(pTvStd->tvPLL_N) & VIP_TV_PLL_CNTL_NLO) << VIP_TV_PLL_CNTL_NLO_SHIFT) | >+ (((CARD32)(pTvStd->tvPLL_N) & VIP_TV_PLL_CNTL_NHI) << VIP_TV_PLL_CNTL_NHI_SHIFT) | >+ ((CARD32)(pTvStd->tvPLL_postDiv) << VIP_TV_PLL_CNTL_P_SHIFT); >+ save->tv_pll_cntl = tmp; >+ save->tv_pll_fine_cntl = TV_PLL_FINE_INI; >+ >+ save->upsamp_and_gain_cntl = VIP_UPSAMP_AND_GAIN_CNTL_INI; >+ >+ memcpy(&save->upsamp_coeffs[ 0 ] , upsamplerCoeffs , sizeof(save->upsamp_coeffs)); >+ >+ save->uv_adr = VIP_UV_ADR_INI; >+ >+ save->vdisp = constPtr->verResolution - 1; >+ save->vftotal = pTvStd->vftotal; >+ >+ save->vscaler_cntl1 = constPtr->vScalerCntl1; >+ if (isErt) >+ save->vscaler_cntl1 |= TV_VSCALER_CNTL1_RESTART_FIELD; >+ save->vscaler_cntl2 = VIP_VSCALER_CNTL2_INI; >+ >+ save->vtotal = constPtr->verTotal - 1; >+ >+ save->y_fall_cntl = VIP_Y_FALL_CNTL_INI; >+ save->y_rise_cntl = constPtr->yRiseCntl; >+ save->y_saw_tooth_cntl = constPtr->ySawtoothCntl; >+ >+ save->disp_merge_cntl = RADEON_DISP_MERGE_CNTL_INI; >+ >+ for (i = 0; i < MAX_H_CODE_TIMING_LEN; i++) >+ { >+ if ((save->h_code_timing[ i ] = constPtr->horTimingTable[ i ]) == 0) >+ break; >+ } >+ >+ for (i = 0; i < MAX_V_CODE_TIMING_LEN; i++) >+ { >+ if ((save->v_code_timing[ i ] = constPtr->verTimingTable[ i ]) == 0) >+ break; >+ } >+ >+ /* >+ * This must be called AFTER loading timing tables as they are modified by this function >+ */ >+ computeRestarts(constPtr , tvStd , hPos , vPos , hSize , save); >+} >+ >+/********************************************************************** >+ * >+ * RT_InitCRTC >+ * >+ **********************************************************************/ >+static >+void >+RT_InitCRTC( >+ const ModeConstants *constPtr, >+ Bool isErt, >+ RADEONSavePtr save >+ ) >+{ >+ save->crtc_h_total_disp = (((constPtr->horResolution / 8) - 1) << RADEON_CRTC_H_DISP_SHIFT) | >+ (((constPtr->horTotal / 8) - 1) << RADEON_CRTC_H_TOTAL_SHIFT); >+ >+ save->crtc_h_sync_strt_wid = (save->crtc_h_sync_strt_wid & ~(RADEON_CRTC_H_SYNC_STRT_PIX | RADEON_CRTC_H_SYNC_STRT_CHAR)) | >+ (((constPtr->horSyncStart / 8) - 1) << RADEON_CRTC_H_SYNC_STRT_CHAR_SHIFT) | >+ (constPtr->horSyncStart & 7); >+ >+ save->crtc_v_total_disp = ((constPtr->verResolution - 1) << RADEON_CRTC_V_DISP_SHIFT) | >+ ((constPtr->verTotal - 1) << RADEON_CRTC_V_TOTAL_SHIFT); >+ >+ save->crtc_v_sync_strt_wid = (save->crtc_v_sync_strt_wid & ~RADEON_CRTC_V_SYNC_STRT) | >+ ((constPtr->verSyncStart - 1) << RADEON_CRTC_V_SYNC_STRT_SHIFT); >+ >+ save->htotal_cntl = ((constPtr->horTotal & 7) << RADEON_HTOTAL_CNTL_HTOT_PIX_SLIP_SHIFT) | RADEON_HTOTAL_CNTL_HTOT_CNTL_VGA_EN; >+ >+ if (isErt) >+ { >+ unsigned postDiv; >+ >+ save->ppll_ref_div = constPtr->crtcPLL_M; >+ >+ switch (constPtr->crtcPLL_postDiv) >+ { >+ case 1: >+ postDiv = 0; >+ break; >+ >+ case 2: >+ postDiv = 1; >+ break; >+ >+ case 3: >+ postDiv = 4; >+ break; >+ >+ case 4: >+ postDiv = 2; >+ break; >+ >+ case 6: >+ postDiv = 6; >+ break; >+ >+ case 8: >+ postDiv = 3; >+ break; >+ >+ case 12: >+ postDiv = 7; >+ break; >+ >+ case 16: >+ default: >+ postDiv = 5; >+ break; >+ } >+ >+ save->ppll_div_3 = (constPtr->crtcPLL_N << RADEON_PPLL_FB3_DIV_SHIFT) | >+ (postDiv << RADEON_PPLL_POST3_DIV_SHIFT); >+ >+ save->vclk_ecp_cntl &= ~RADEON_VCLK_SRC_SEL_MASK; >+ save->vclk_ecp_cntl |= RADEON_VCLK_SRC_SEL_PPLLCLK; >+ } >+ else >+ { >+ save->ppll_div_3 &= ~RADEON_PPLL_POST3_DIV_MASK; >+ save->ppll_div_3 |= (constPtr->use888RGB ? RADEON_PPLL_POST3_DIV_BY_3 : RADEON_PPLL_POST3_DIV_BY_2); >+ >+ /* >+ * Set Radeon to be clocked from RT >+ */ >+ save->vclk_ecp_cntl &= ~RADEON_VCLK_SRC_SEL_MASK; >+ save->vclk_ecp_cntl |= RADEON_VCLK_SRC_SEL_BYTECLK; >+ >+ save->vclk_ecp_cntl &= ~RADEON_VCLK_ECP_CNTL_BYTECLK_POSTDIV; >+ save->vclk_ecp_cntl |= RADEON_VCLK_ECP_CNTL_BYTECLK_NODIV; >+ >+ /* >+ * Instruct Radeon to output either 565 or 888 packed pixels >+ */ >+ save->disp_output_cntl &= >+ ~(RADEON_DISP_TV_SOURCE | >+ RADEON_DISP_TV_MODE_MASK | >+ RADEON_DISP_TV_CBB_CRR_DITH_EN | >+ RADEON_DISP_TV_BIT_WIDTH | >+ RADEON_DISP_TV_SYNC_MODE_MASK | >+ RADEON_DISP_TV_SYNC_COLOR_MASK); >+ save->disp_output_cntl |= (constPtr->use888RGB ? >+ RADEON_DISP_TV_YG_DITH_EN | RADEON_DISP_TV_MODE_888 : >+ RADEON_DISP_TV_YG_DITH_EN | RADEON_DISP_TV_MODE_565); >+ >+ save->crtc_ext_cntl |= RADEON_CRTC_VGA_XOVERSCAN; >+ save->dac_cntl |= RADEON_DAC_CNTL_DAC_TVO_EN; >+ } >+} >+ >+/********************************************************************** >+ * >+ * ERTAutoDetect >+ * >+ **********************************************************************/ >+static >+Bool >+ERTAutoDetect( >+ ScrnInfoPtr pScrn >+ ) >+{ >+ RADEONInfoPtr info = RADEONPTR(pScrn); >+ unsigned char *RADEONMMIO = info->MMIO; >+ CARD32 saveReg = INREG(TV_LINEAR_GAIN_SETTINGS); >+ Bool detected = FALSE; >+ >+ /* >+ * Ultra-dumb way of detecting an ERT: check that a register is present >+ * @ TV_LINEAR_GAIN_SETTINGS (this is probably one of the most harmless >+ * register to touch) >+ */ >+ OUTREG(TV_LINEAR_GAIN_SETTINGS , 0x15500aa); >+ >+ if (INREG(TV_LINEAR_GAIN_SETTINGS) == 0x15500aa) >+ { >+ OUTREG(TV_LINEAR_GAIN_SETTINGS , 0x0aa0155); >+ if (INREG(TV_LINEAR_GAIN_SETTINGS) == 0x0aa0155) >+ detected = TRUE; >+ } >+ >+ OUTREG(TV_LINEAR_GAIN_SETTINGS , saveReg); >+ >+ return detected; >+} >+ >+/********************************************************************** >+ * >+ * detectTheaterOut >+ * >+ * Detect presence of a RT chip >+ * >+ **********************************************************************/ >+ >+TheaterOutPtr >+detectTheaterOut( >+ ScrnInfoPtr pScrn, >+ Bool forceVIP, >+ GENERIC_BUS_Ptr b >+ ) >+{ >+ RADEONInfoPtr info = RADEONPTR(pScrn); >+ //GENERIC_BUS_Ptr b = info->VIP; >+ TheaterOutPtr t; >+ int i; >+ CARD32 val; >+ char s[20]; >+ >+if (b != NULL) >+{ >+// RTTRACE(("0711:OK\n")); >+} >+else >+{ >+// RTTRACE(("0712:FAILED\n")); >+} >+ >+ >+ b->ioctl(b , GB_IOCTL_GET_TYPE , 20 , s); >+ >+//RTTRACE(("0713: %s vs %s\n",VIP_TYPE,s)); >+ >+ if (strcmp(VIP_TYPE , s)) >+ { >+ xf86DrvMsg(b->scrnIndex , X_ERROR , "detectTheaterOut must be called with bus of type \"%s\", not \"%s\"\n", >+ VIP_TYPE , s); >+ return NULL; >+ } >+ >+ t = xcalloc(1 , sizeof(TheaterOutRec)); >+ t->theatre_num = -1; >+ t->MMIO = info->MMIO; >+ t->VIP = b; >+ >+ if (!forceVIP && ERTAutoDetect(pScrn)) >+ xf86DrvMsg(b->scrnIndex , X_INFO , "Embedded Rage Theater detected\n"); >+ else >+ { >+ // >+ // Is this really needed? >+ // >+ b->read(b , VIP_VIP_VENDOR_DEVICE_ID , 4 , (CARD8*)&val); >+ >+ for (i = 0; i < 4; i++) >+ { >+// RTTRACE(("0713X\n")); >+ if(b->read(b , ((i & 0x03) << 14) | VIP_VIP_VENDOR_DEVICE_ID , 4 , (CARD8*)&val)) >+ { >+ if (val) >+ { >+ xf86DrvMsg(b->scrnIndex , X_INFO , "Device %d on VIP bus ids as 0x%08x\n" , i , val); >+// RTTRACE(("07130\n")); >+ } >+ if (t->theatre_num >= 0) >+ { >+// RTTRACE(("07131\n")); >+ continue; // already found one instance >+ } >+ if (val == RT100_ATI_ID) >+ { >+// RTTRACE(("07132\n")); >+ t->theatre_num = i; >+ } >+ } >+ else >+ { >+// RTTRACE(("0713Y\n")); >+ xf86DrvMsg(b->scrnIndex , X_INFO , "No response from device %d on VIP bus\n" , i); >+ } >+ } >+// RTTRACE(("0713Z\n")); >+ if (t->theatre_num >= 0) >+ { >+// RTTRACE(("0714:OK\n")); >+ xf86DrvMsg(b->scrnIndex , X_INFO , >+ "Detected Rage Theatre as device %d on VIP bus\n" , t->theatre_num); >+ theatre_read(t , VIP_VIP_REVISION_ID , &val); >+ xf86DrvMsg(b->scrnIndex , X_INFO , "Detected Rage Theatre revision %8.8X\n" , val); >+ } >+ else >+ { >+// RTTRACE(("0714:FAILED\n")); >+ xfree(t); >+ return NULL; >+ } >+ } >+ >+ return t; >+} >+ >+/********************************************************************** >+ * >+ * initTheaterOut >+ * >+ * Initialization of module >+ * >+ * 's' should be the value of TV_Output option (i.e. the initial TV >+ * standard) >+ * >+ **********************************************************************/ >+ >+void >+initTheaterOut( >+ TheaterOutPtr t, >+ const char *s >+ ) >+{ >+ RTTRACE(("Entering initTheaterOut, s = %s\n" , s)); >+ /* >+ * TEST TEST TEST TEST TEST TEST TEST TEST TEST >+ */ >+ if (xf86NameCmp(s , "NTSC") == 0) >+ t->standard = TV_STD_NTSC; >+ else if (xf86NameCmp(s , "PAL") == 0) >+ t->standard = TV_STD_PAL; >+ else if (xf86NameCmp(s , "PAL-M") == 0) >+ t->standard = TV_STD_PAL_M; >+ else if (xf86NameCmp(s , "PAL-60") == 0) >+ t->standard = TV_STD_PAL_60; >+ else if (xf86NameCmp(s , "NTSC-J") == 0) >+ t->standard = TV_STD_NTSC_J; >+ else if (xf86NameCmp(s , "PAL-CN") == 0) >+ t->standard = TV_STD_PAL_CN; >+ else if (xf86NameCmp(s , "PAL-N") == 0) >+ t->standard = TV_STD_PAL_N; >+ else >+ { >+ xf86DrvMsg(0 , X_WARNING , "Unrecognized TV standard in TVOutput option (%s), TV output is disabled\n" , s); >+ t->standard = TV_STD_KEEP_OFF; >+ } >+ t->compatibleMode = FALSE; >+ >+ t->hPos = 0; >+ t->vPos = 0; >+ t->hSize = 0; >+} >+ >+/********************************************************************** >+ * >+ * theaterOutSave >+ * >+ * Save current state of RT as initial state (the one that is restored >+ * when switching back to text mode) >+ * >+ **********************************************************************/ >+ >+void >+theaterOutSave( >+ TheaterOutPtr t, >+ ScrnInfoPtr pScrn >+ ) >+{ >+ RTTRACE(("Entering theaterOutSave\n")); >+ RT_Save(t , pScrn , &t->savedState); >+} >+ >+/********************************************************************** >+ * >+ * theaterOutRestore >+ * >+ * Restore state of RT from initial state (the one saved through >+ * theaterOutSave) >+ * >+ **********************************************************************/ >+ >+void >+theaterOutRestore( >+ TheaterOutPtr t, >+ ScrnInfoPtr pScrn >+ ) >+{ >+ RTTRACE(("Entering theaterOutRestore\n")); >+ RT_Restore(t , pScrn , &t->savedState); >+} >+ >+/********************************************************************** >+ * >+ * theaterOutInit >+ * >+ * Define state for cloning current CRTC mode on TV output >+ * It works in this way: >+ * 1. It checks if resolution in "mode" parameter is one of those >+ * allowing tv output >+ * 2. If resolution is OK, define RT state according to resolution and >+ * and current settings (tv standard etc.) >+ * If resolution is not ok, define RT state to turn tv output off >+ * 3. If resolution is OK, modify Radeon state to make it correct for >+ * tv output (this is needed,e.g., to set vertical frequency to 50/60 Hz) >+ * >+ * Return value is TRUE when mode is OK for cloning on tv and tv output >+ * is enabled, FALSE otherwise >+ * >+ **********************************************************************/ >+ >+Bool >+theaterOutInit( >+ TheaterOutPtr t, >+ DisplayModePtr mode, >+ RADEONSavePtr save >+ ) >+{ >+ const ModeConstants *p; >+ Bool isErt = t->theatre_num < 0; >+ >+ RTTRACE(("Entering theaterOutInit: std=%u h=%u v=%u\n" , t->standard , mode->HDisplay , mode->VDisplay)); >+ >+ t->compatibleMode = FALSE; >+ >+ if (t->standard != TV_STD_KEEP_OFF) >+ { >+ /* >+ * Search mode among available ones >+ */ >+ for (p = availableModes; p < (availableModes + N_AVAILABLE_MODES); p++) >+ { >+ if (p->horResolution == mode->HDisplay && >+ p->verResolution == mode->VDisplay && >+ p->standard == t->standard) >+ { >+ /* >+ * Match found >+ */ >+ t->compatibleMode = TRUE; >+ t->currentMode = p; >+ >+ RT_Init(p , t->standard , isErt , TRUE , t->hPos , t->vPos , t->hSize , &t->modeState); >+ RT_InitCRTC(p , isErt , save); >+ >+ return TRUE; >+ } >+ } >+ } >+ >+ /* >+ * Match not found or tv output disabled >+ * First parameter is dummy when setting for no tv output, so any mode >+ * will do (here first mode in table is passed). >+ */ >+ RT_Init(availableModes , TV_STD_NTSC , isErt , FALSE , t->hPos , t->vPos , t->hSize , &t->modeState); >+ return FALSE; >+} >+ >+/********************************************************************** >+ * >+ * theaterOutRestoreMode >+ * >+ * Set state of RT to the one defined by last call to theaterOutInit >+ * >+ **********************************************************************/ >+ >+void >+theaterOutRestoreMode( >+ TheaterOutPtr t, >+ ScrnInfoPtr pScrn >+ ) >+{ >+ RTTRACE(("Entering theaterOutRestoreMode\n")); >+ RT_Restore(t , pScrn , &t->modeState); >+} >+ >+/********************************************************************** >+ * >+ * theaterOutSetStandard >+ * >+ * Set TV output standard >+ * >+ * Return value is TRUE when video mode should be set again >+ * >+ **********************************************************************/ >+Bool >+theaterOutSetStandard( >+ TheaterOutPtr t, >+ TVStd std >+ ) >+{ >+ TVStd oldStd = t->standard; >+ >+ RTTRACE(("Entering theaterOutSetStandard\n")); >+ >+ if (std >= TV_STD_N_STANDARDS) >+ std = TV_STD_KEEP_OFF; >+ >+ t->standard = std; >+ >+ if (t->compatibleMode) >+ return oldStd != std; >+ else >+ return std != TV_STD_KEEP_OFF && oldStd == TV_STD_KEEP_OFF; >+} >+ >+/********************************************************************** >+ * >+ * theaterOutGetStandard >+ * >+ * Get current TV output standard >+ * >+ **********************************************************************/ >+TVStd >+theaterOutGetStandard( >+ TheaterOutPtr t >+ ) >+{ >+ return t->standard; >+} >+ >+/********************************************************************** >+ * >+ * theaterOutGetCompatMode >+ * >+ * Return whether the current mode is compatible with tv output or not >+ * >+ **********************************************************************/ >+Bool >+theaterOutGetCompatMode( >+ TheaterOutPtr t >+ ) >+{ >+ return t->compatibleMode; >+} >+ >+/********************************************************************** >+ * >+ * updateHVPosition >+ * >+ * Set hw registers for a new h/v position & h size >+ * >+ **********************************************************************/ >+static >+void >+updateHVPosition( >+ TheaterOutPtr t >+ ) >+{ >+ Bool reloadTable; >+ >+ reloadTable = computeRestarts(t->currentMode , t->standard , t->hPos , t->vPos , t->hSize , &t->modeState); >+ >+ if (t->theatre_num < 0) >+ { >+ ERT_RestoreRestarts(t , &t->modeState); >+ ert_write(t , TV_TIMING_CNTL , t->modeState.timing_cntl); >+ >+ if (reloadTable) >+ { >+ ert_write(t, >+ TV_MASTER_CNTL , >+ t->modeState.master_cntl | >+ VIP_MASTER_CNTL_TV_ASYNC_RST | >+ VIP_MASTER_CNTL_CRT_ASYNC_RST | >+ VIP_MASTER_CNTL_RESTART_PHASE_FIX); >+ >+ restoreTimingTables(t , &t->modeState); >+ >+ ert_write(t , >+ TV_MASTER_CNTL , >+ t->modeState.master_cntl); >+ } >+ } >+ else >+ { >+ restoreRestarts(t , &t->modeState); >+ theatre_write(t , VIP_TIMING_CNTL , t->modeState.timing_cntl); >+ >+ if (reloadTable) >+ { >+ theatre_write(t , >+ VIP_MASTER_CNTL , >+ t->modeState.master_cntl | >+ VIP_MASTER_CNTL_TV_ASYNC_RST | >+ VIP_MASTER_CNTL_CRT_ASYNC_RST); >+ >+ restoreTimingTables(t , &t->modeState); >+ >+ theatre_write(t , >+ VIP_MASTER_CNTL , >+ t->modeState.master_cntl); >+ } >+ } >+} >+ >+/********************************************************************** >+ * >+ * theaterOutSetAttr >+ * >+ * Set an attribute >+ * >+ **********************************************************************/ >+void >+theaterOutSetAttr( >+ TheaterOutPtr t, >+ TheaterOutAttr attr, >+ int value >+ ) >+{ >+ switch (attr) >+ { >+ case THEATER_OUT_HPOS: >+ if (value < -MAX_H_POSITION) >+ t->hPos = -MAX_H_POSITION; >+ else if (value > MAX_H_POSITION) >+ t->hPos = MAX_H_POSITION; >+ else >+ t->hPos = value; >+ break; >+ >+ case THEATER_OUT_VPOS: >+ if (value < -MAX_V_POSITION) >+ t->vPos = -MAX_V_POSITION; >+ else if (value > MAX_V_POSITION) >+ t->vPos = MAX_V_POSITION; >+ else >+ t->vPos = value; >+ break; >+ >+ case THEATER_OUT_HSIZE: >+ if (value < -MAX_H_SIZE) >+ t->hSize = -MAX_H_SIZE; >+ else if (value > MAX_H_SIZE) >+ t->hSize = MAX_H_SIZE; >+ else >+ t->hSize = value; >+ break; >+ >+ default: >+ return; >+ } >+ >+ if (t->compatibleMode) >+ updateHVPosition(t); >+} >+ >+/********************************************************************** >+ * >+ * theaterOutGetAttr >+ * >+ * Get an attribute >+ * >+ **********************************************************************/ >+int >+theaterOutGetAttr( >+ TheaterOutPtr t, >+ TheaterOutAttr attr >+ ) >+{ >+ switch (attr) >+ { >+ case THEATER_OUT_HPOS: >+ return t->hPos; >+ >+ case THEATER_OUT_VPOS: >+ return t->vPos; >+ >+ case THEATER_OUT_HSIZE: >+ return t->hSize; >+ >+ default: >+ return 0; >+ } >+} >+ >+/********************************************************************** >+ * >+ * theaterOutGetAttrLimits >+ * >+ * Get limits for an attribute value >+ * >+ **********************************************************************/ >+void >+theaterOutGetAttrLimits( >+ TheaterOutPtr t, >+ TheaterOutAttr attr, >+ int *maxValue, >+ int *minValue >+ ) >+{ >+ switch (attr) >+ { >+ case THEATER_OUT_HPOS: >+ *maxValue = MAX_H_POSITION; >+ *minValue = -MAX_H_POSITION; >+ break; >+ >+ case THEATER_OUT_VPOS: >+ *maxValue = MAX_V_POSITION; >+ *minValue = -MAX_V_POSITION; >+ break; >+ >+ case THEATER_OUT_HSIZE: >+ *maxValue = MAX_H_SIZE; >+ *minValue = -MAX_H_SIZE; >+ break; >+ >+ default: >+ break; >+ } >+} >diff -Naur xf86-video-ati.orig/src/theater_out.h xf86-video-ati/src/theater_out.h >--- xf86-video-ati.orig/src/theater_out.h 1970-01-01 00:00:00.000000000 +0000 >+++ xf86-video-ati/src/theater_out.h 2006-04-02 16:44:41.000000000 +0000 >@@ -0,0 +1,370 @@ >+/********************************************************************* >+ * >+ * $Id: theater_out.h,v 1.1.2.2 2004/01/27 22:50:35 fulivi Exp $ >+ * >+ * Interface file for theater_out module >+ * >+ * Copyright (C) 2003 Federico Ulivi >+ * >+ * This program is free software; you can redistribute it and/or modify >+ * it under the terms of the GNU General Public License as published by >+ * the Free Software Foundation; either version 2 of the License, or >+ * (at your option) any later version. >+ * >+ * This program is distributed in the hope that it will be useful, >+ * but WITHOUT ANY WARRANTY; without even the implied warranty of >+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+ * GNU General Public License for more details. >+ * >+ * You should have received a copy of the GNU General Public License >+ * along with this program; if not, write to the Free Software >+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA >+ * >+ * AUTHORS: F.Ulivi >+ * NOTES: >+ * $Log: theater_out.h,v $ >+ * Revision 1.1.2.2 2004/01/27 22:50:35 fulivi >+ * Support for positioning/sizing of image added >+ * >+ * Revision 1.1.2.9 2004/01/18 23:01:12 fede >+ * Functions for get/setting h/v pos/size replaced by >+ * theaterOutSetAttr/theaterOutGetAttr/theaterOutGetAttrLimits >+ * Circular inclusion with radeon.h fixed >+ * >+ * Revision 1.1.2.8 2004/01/11 21:43:32 fede >+ * Fixed problem with definition of TVStd >+ * >+ * Revision 1.1.2.7 2004/01/05 00:09:59 fede >+ * Functions for setting/getting H/V position added >+ * Functions for setting/getting on/off attribute removed >+ * >+ * Revision 1.1.2.1 2003/11/26 19:50:10 fulivi >+ * Support for ERT added >+ * >+ * Revision 1.1.2.6 2003/11/25 20:44:00 fede >+ * TV_STD_KEEP_OFF added >+ * >+ * Revision 1.1.2.5 2003/10/14 18:41:32 fede >+ * forceERT changed to forceVIP >+ * >+ * Revision 1.1.2.4 2003/10/11 12:30:30 fede >+ * Support for ERT added >+ * >+ * Revision 1.1 2003/09/28 21:42:37 fulivi >+ * Theater_out module added >+ * >+ * Revision 1.1.2.3 2003/09/28 15:26:09 fede >+ * Minor aesthetic changes >+ * >+ * Revision 1.1.2.1 2003/08/31 13:36:35 fede >+ * *** empty log message *** >+ * >+ * >+ *********************************************************************/ >+ >+#ifndef _THEATER_OUT_H >+#define _THEATER_OUT_H >+ >+/********************************************************************** >+ * >+ * TheaterOutPtr >+ * >+ * Pointer to TheaterOut struct. Actual definition is in theater_out.c >+ * >+ **********************************************************************/ >+typedef struct TheaterOut *TheaterOutPtr; >+ >+/********************************************************************** >+ * >+ * TVStd >+ * >+ * Tv standard >+ * >+ **********************************************************************/ >+typedef enum >+ { >+ TV_STD_NTSC, >+ TV_STD_PAL, >+ TV_STD_PAL_M, >+ TV_STD_PAL_60, >+ TV_STD_NTSC_J, >+ TV_STD_PAL_CN, >+ TV_STD_PAL_N, >+ TV_STD_KEEP_OFF, >+ TV_STD_N_STANDARDS /* Must be last */ >+ } TVStd; >+ >+/********************************************************************** >+ * >+ * TheaterOutAttr >+ * >+ * Integer-valued attributes of this module >+ * >+ **********************************************************************/ >+typedef enum >+ { >+ THEATER_OUT_HPOS, /* Horizontal position */ >+ THEATER_OUT_VPOS, /* Vertical position */ >+ THEATER_OUT_HSIZE /* Horizontal size */ >+ } TheaterOutAttr; >+ >+#ifndef _RADEON_H_ >+#include "radeon.h" >+#endif >+ >+/********************************************************************** >+ * >+ * detectTheaterOut >+ * >+ * Detect presence of a RT chip >+ * >+ **********************************************************************/ >+ >+extern >+TheaterOutPtr >+detectTheaterOut( >+ ScrnInfoPtr pScrn, >+ Bool forceVIP, >+GENERIC_BUS_Ptr b >+ ); >+ >+/********************************************************************** >+ * >+ * initTheaterOut >+ * >+ * Initialization of module >+ * >+ * 's' should be the value of TV_Output option (i.e. the initial TV >+ * standard) >+ * >+ **********************************************************************/ >+ >+extern >+void >+initTheaterOut( >+ TheaterOutPtr t, >+ const char *s >+ ); >+ >+/********************************************************************** >+ * >+ * theaterOutSave >+ * >+ * Save current state of RT as initial state (the one that is restored >+ * when switching back to text mode) >+ * >+ **********************************************************************/ >+ >+extern >+void >+theaterOutSave( >+ TheaterOutPtr t, >+ ScrnInfoPtr pScrn >+ ); >+ >+/********************************************************************** >+ * >+ * theaterOutRestore >+ * >+ * Restore state of RT from initial state (the one saved through >+ * theaterOutSave) >+ * >+ **********************************************************************/ >+ >+extern >+void >+theaterOutRestore( >+ TheaterOutPtr t, >+ ScrnInfoPtr pScrn >+ ); >+ >+/********************************************************************** >+ * >+ * theaterOutInit >+ * >+ * Define state for cloning current CRTC mode on TV output >+ * It works in this way: >+ * 1. It checks if resolution in "mode" parameter is one of those >+ * allowing tv output >+ * 2. If resolution is OK, define RT state according to resolution and >+ * and current settings (tv standard etc.) >+ * If resolution is not ok, define RT state to turn tv output off >+ * 3. If resolution is OK, modify Radeon state to make it correct for >+ * tv output (this is needed,e.g., to set vertical frequency to 50/60 Hz) >+ * >+ * Return value is TRUE when mode is OK for cloning on tv and tv output >+ * is enabled, FALSE otherwise >+ * >+ **********************************************************************/ >+ >+extern >+Bool >+theaterOutInit( >+ TheaterOutPtr t, >+ DisplayModePtr mode, >+ RADEONSavePtr save >+ ); >+ >+/********************************************************************** >+ * >+ * theaterOutRestoreMode >+ * >+ * Set state of RT to the one defined by last call to theaterOutInit >+ * >+ **********************************************************************/ >+ >+extern >+void >+theaterOutRestoreMode( >+ TheaterOutPtr t, >+ ScrnInfoPtr pScrn >+ ); >+ >+/********************************************************************** >+ * >+ * theaterOutSetStandard >+ * >+ * Set TV output standard >+ * >+ * Return value is TRUE when video mode should be set again >+ * >+ **********************************************************************/ >+ >+extern >+Bool >+theaterOutSetStandard( >+ TheaterOutPtr t, >+ TVStd std >+ ); >+ >+/********************************************************************** >+ * >+ * theaterOutGetStandard >+ * >+ * Get current TV output standard >+ * >+ **********************************************************************/ >+extern >+TVStd >+theaterOutGetStandard( >+ TheaterOutPtr t >+ ); >+ >+/********************************************************************** >+ * >+ * theaterOutGetCompatMode >+ * >+ * Return whether the current mode is compatible with tv output or not >+ * >+ **********************************************************************/ >+extern >+Bool >+theaterOutGetCompatMode( >+ TheaterOutPtr t >+ ); >+ >+/********************************************************************** >+ * >+ * theaterOutSetAttr >+ * >+ * Set an attribute >+ * >+ **********************************************************************/ >+extern >+void >+theaterOutSetAttr( >+ TheaterOutPtr t, >+ TheaterOutAttr attr, >+ int value >+ ); >+ >+/********************************************************************** >+ * >+ * theaterOutGetAttr >+ * >+ * Get an attribute >+ * >+ **********************************************************************/ >+extern >+int >+theaterOutGetAttr( >+ TheaterOutPtr t, >+ TheaterOutAttr attr >+ ); >+ >+/********************************************************************** >+ * >+ * theaterOutGetAttrLimits >+ * >+ * Get limits for an attribute value >+ * >+ **********************************************************************/ >+extern >+void >+theaterOutGetAttrLimits( >+ TheaterOutPtr t, >+ TheaterOutAttr attr, >+ int *maxValue, >+ int *minValue >+ ); >+ >+/********************************************************************** >+ * >+ * THEATER_OUT_SYMBOLS >+ * >+ * Symbol list for module loading >+ * >+ **********************************************************************/ >+ >+#define THEATER_OUT_SYMBOLS "detectTheaterOut", \ >+ "initTheaterOut", \ >+ "theaterOutSave", \ >+ "theaterOutRestore", \ >+ "theaterOutInit", \ >+ "theaterOutRestoreMode", \ >+ "theaterOutSetStandard", \ >+ "theaterOutGetStandard", \ >+ "theaterOutGetCompatMode", \ >+ "theaterOutSetAttr", \ >+ "theaterOutGetAttr", \ >+ "theaterOutGetAttrLimits" >+ >+/********************************************************************** >+ * >+ * External access to module functions >+ * >+ **********************************************************************/ >+ >+#ifdef XFree86LOADER >+ >+#define xf86_detectTheaterOut ((TheaterOutPtr (*)(ScrnInfoPtr , Bool,GENERIC_BUS_Ptr))LoaderSymbol("detectTheaterOut")) >+#define xf86_initTheaterOut ((void (*)(TheaterOutPtr , const char*))LoaderSymbol("initTheaterOut")) >+#define xf86_theaterOutSave ((void (*)(TheaterOutPtr , ScrnInfoPtr))LoaderSymbol("theaterOutSave")) >+#define xf86_theaterOutRestore ((void (*)(TheaterOutPtr , ScrnInfoPtr))LoaderSymbol("theaterOutRestore")) >+#define xf86_theaterOutInit ((Bool (*)(TheaterOutPtr , DisplayModePtr , RADEONSavePtr))LoaderSymbol("theaterOutInit")) >+#define xf86_theaterOutRestoreMode ((void (*)(TheaterOutPtr , ScrnInfoPtr))LoaderSymbol("theaterOutRestoreMode")) >+#define xf86_theaterOutSetStandard ((Bool (*)(TheaterOutPtr , TVStd))LoaderSymbol("theaterOutSetStandard")) >+#define xf86_theaterOutGetStandard ((TVStd (*)(TheaterOutPtr))LoaderSymbol("theaterOutGetStandard")) >+#define xf86_theaterOutGetCompatMode ((Bool (*)(TheaterOutPtr))LoaderSymbol("theaterOutGetCompatMode")) >+#define xf86_theaterOutSetAttr ((void (*)(TheaterOutPtr , TheaterOutAttr , int))LoaderSymbol("theaterOutSetAttr")) >+#define xf86_theaterOutGetAttr ((int (*)(TheaterOutPtr , TheaterOutAttr))LoaderSymbol("theaterOutGetAttr")) >+#define xf86_theaterOutGetAttrLimits ((void (*)(TheaterOutPtr , TheaterOutAttr , int * , int *))LoaderSymbol("theaterOutGetAttrLimits")) >+ >+#else >+ >+#define xf86_detectTheaterOut detectTheaterOut >+#define xf86_initTheaterOut initTheaterOut >+#define xf86_theaterOutSave theaterOutSave >+#define xf86_theaterOutRestore theaterOutRestore >+#define xf86_theaterOutInit theaterOutInit >+#define xf86_theaterOutRestoreMode theaterOutRestoreMode >+#define xf86_theaterOutSetStandard theaterOutSetStandard >+#define xf86_theaterOutGetStandard theaterOutGetStandard >+#define xf86_theaterOutGetCompatMode theaterOutGetCompatMode >+#define xf86_theaterOutSetAttr theaterOutSetAttr >+#define xf86_theaterOutGetAttr theaterOutGetAttr >+#define xf86_theaterOutGetAttrLimits theaterOutGetAttrLimits >+ >+#endif /* XFree86LOADER */ >+ >+#endif /* _THEATER_OUT_H */ >diff -Naur xf86-video-ati.orig/src/theater_out_module.c xf86-video-ati/src/theater_out_module.c >--- xf86-video-ati.orig/src/theater_out_module.c 1970-01-01 00:00:00.000000000 +0000 >+++ xf86-video-ati/src/theater_out_module.c 2006-04-02 16:44:41.000000000 +0000 >@@ -0,0 +1,45 @@ >+#ifdef HAVE_CONFIG_H >+#include "config.h" >+#endif >+ >+#include "xf86Module.h" >+ >+static MODULESETUPPROTO(theaterOutSetup); >+ >+static >+XF86ModuleVersionInfo >+theaterVersRec = >+{ >+ "theater_out", /* modname */ >+ MODULEVENDORSTRING, /* vendor */ >+ MODINFOSTRING1, /* _modinfo1_ */ >+ MODINFOSTRING2, /* _modinfo2_ */ >+ XORG_VERSION_CURRENT, /* xf86version */ >+ 1, /* majorversion */ >+ 0, /* minorversion */ >+ 0, /* patchlevel */ >+ ABI_CLASS_VIDEODRV, /* abiclass */ >+ ABI_VIDEODRV_VERSION, /* abiversion */ >+ MOD_CLASS_NONE, /* moduleclass */ >+ { 0 , 0 , 0 , 0 } /* checksum */ >+}; >+ >+_X_EXPORT XF86ModuleData >+theater_outModuleData = >+ { >+ &theaterVersRec, >+ theaterOutSetup, >+ NULL >+ }; >+ >+static >+pointer >+theaterOutSetup( >+ pointer module, >+ pointer opts, >+ int *errmaj, >+ int *errmin >+ ) >+{ >+ return (pointer)1; >+} >diff -Naur xf86-video-ati.orig/src/tvo_set/tvo_set.c xf86-video-ati/src/tvo_set/tvo_set.c >--- xf86-video-ati.orig/src/tvo_set/tvo_set.c 1970-01-01 00:00:00.000000000 +0000 >+++ xf86-video-ati/src/tvo_set/tvo_set.c 2006-04-02 16:44:41.000000000 +0000 >@@ -0,0 +1,472 @@ >+/********************************************************************* >+ * >+ * $Id: tvo_set.c,v 1.1.2.1 2004/01/27 22:55:40 fulivi Exp $ >+ * >+ * Main (and only) module of tvo_set utility. >+ * The purpose of this utility is to set various parameters of >+ * tv output module. >+ * >+ * Copyright (C) 2004 Federico Ulivi >+ * >+ * This program is free software; you can redistribute it and/or modify >+ * it under the terms of the GNU General Public License as published by >+ * the Free Software Foundation; either version 2 of the License, or >+ * (at your option) any later version. >+ * >+ * This program is distributed in the hope that it will be useful, >+ * but WITHOUT ANY WARRANTY; without even the implied warranty of >+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+ * GNU General Public License for more details. >+ * >+ * You should have received a copy of the GNU General Public License >+ * along with this program; if not, write to the Free Software >+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA >+ * >+ * AUTHORS: F.Ulivi >+ * NOTES: >+ * $Log: tvo_set.c,v $ >+ * Revision 1.1.2.1 2004/01/27 22:55:40 fulivi >+ * Initial release >+ * >+ * Revision 1.1.2.2 2004/01/25 23:07:47 fede >+ * GPL notice added >+ * >+ * Revision 1.1.2.1 2004/01/25 15:09:42 fede >+ * First version >+ * >+ * >+ *********************************************************************/ >+ >+#include <X11/X.h> >+#include <X11/Xlib.h> >+#include <X11/extensions/Xvlib.h> >+#include <stdio.h> >+#include <stdlib.h> >+#include <errno.h> >+#include <string.h> >+ >+/********************************************************************** >+ * >+ * program_name >+ * >+ **********************************************************************/ >+static >+const char *program_name; >+ >+/********************************************************************** >+ * >+ * Action >+ * >+ **********************************************************************/ >+typedef enum >+ { >+ ACT_FULL_DUMP, >+ ACT_SET, >+ ACT_INC, >+ ACT_DEC, >+ ACT_ZERO >+ } Action; >+ >+/********************************************************************** >+ * >+ * attrNames / attrData >+ * >+ **********************************************************************/ >+typedef struct >+{ >+ Atom atom; >+ int minValue; >+ int maxValue; >+} AttrData; >+ >+typedef struct >+{ >+ char* extName; >+ char* attrName; >+ char* description; >+} AttrName; >+ >+static >+const AttrName attrNames[] = >+ { >+ { "hpos" , "XV_TVO_HPOS" , "Horizontal position" }, >+ { "vpos" , "XV_TVO_VPOS" , "Vertical position" }, >+ { "hsize" , "XV_TVO_HSIZE" , "Horizontal size" }, >+ { "std" , "XV_TVO_STANDARD" , "TV Standard" } >+ }; >+ >+#define N_ATTRS (sizeof(attrNames) / sizeof(attrNames[ 0 ])) >+/* >+ * Index of TV standard attribute >+ */ >+#define STD_ATTR 3 >+ >+static >+AttrData attrData[ N_ATTRS ]; >+ >+/********************************************************************** >+ * >+ * stdNames >+ * >+ **********************************************************************/ >+static >+const char *stdNames[] = >+ { >+ "NTSC", >+ "PAL", >+ "PAL-M", >+ "PAL-60", >+ "NTSC-J", >+ "PAL-CN", >+ "PAL-N", >+ "OFF" >+ }; >+#define N_STDS (sizeof(stdNames) / sizeof(stdNames[ 0 ])) >+ >+/********************************************************************** >+ * >+ * scanAttributes >+ * >+ **********************************************************************/ >+static >+Bool >+subScanAttributes( >+ Display *dpy, >+ XvAttribute *pAttributes, >+ int nAttributes >+ ) >+{ >+ unsigned i; >+ unsigned j; >+ Atom theAtom; >+ >+ for (i = 0; i < N_ATTRS; i++) >+ { >+ const char* name = attrNames[ i ].attrName; >+ >+ for (j = 0; j < nAttributes; j++) >+ { >+ if (strcmp(name , pAttributes[ j ].name) == 0) >+ { >+ attrData[ i ].minValue = pAttributes[ j ].min_value; >+ attrData[ i ].maxValue = pAttributes[ j ].max_value; >+ if ((pAttributes[ j ].flags & (XvGettable | XvSettable)) != (XvGettable | XvSettable)) >+ return False; >+ >+ theAtom = XInternAtom(dpy , name , True); >+ if (theAtom == None) >+ return False; >+ >+ attrData[ i ].atom = theAtom; >+ >+ break; >+ } >+ } >+ if (j == nAttributes) >+ return False; >+ } >+ >+ return True; >+} >+ >+static >+Bool >+scanAttributes( >+ Display *dpy, >+ XvPortID portID >+ ) >+{ >+ XvAttribute *pAttributes; >+ int nAttributes; >+ Bool res = False; >+ >+ if ((pAttributes = XvQueryPortAttributes(dpy , portID , &nAttributes)) == 0) >+ return False; >+ >+ if (nAttributes > 0) >+ res = subScanAttributes(dpy , pAttributes , nAttributes); >+ >+ XFree(pAttributes); >+ return res; >+} >+ >+/********************************************************************** >+ * >+ * getAttribute >+ * >+ **********************************************************************/ >+static >+void >+getAttribute( >+ Display *dpy, >+ XvPortID portID, >+ int attribute, >+ int *value >+ ) >+{ >+ if (XvGetPortAttribute(dpy , >+ portID , >+ attrData[ attribute ].atom , >+ value) == Success) >+ return; >+ >+ fprintf(stderr , "%s: Unable to get value of attribute %s\n" , program_name , attrNames[ attribute ].attrName); >+ exit(2); >+} >+ >+/********************************************************************** >+ * >+ * setAttribute >+ * >+ **********************************************************************/ >+static >+void >+setAttribute( >+ Display *dpy, >+ XvPortID portID, >+ int attribute, >+ int value >+ ) >+{ >+ int dummy; >+ >+ if (XvSetPortAttribute(dpy , portID , attrData[ attribute ].atom , value) != Success) >+ { >+ fprintf(stderr , "%s: Unable to set value of attribute %s\n" , program_name , attrNames[ attribute ].attrName); >+ exit(2); >+ } >+ >+ getAttribute(dpy , portID , attribute , &dummy); >+} >+ >+/********************************************************************** >+ * >+ * parseAttribute >+ * >+ **********************************************************************/ >+static >+int >+parseAttribute( >+ const char *name >+ ) >+{ >+ int i; >+ >+ for (i = 0; i < N_ATTRS; i++) >+ if (strcasecmp(name , attrNames[ i ].extName) == 0) >+ return i; >+ >+ return -1; >+} >+ >+/********************************************************************** >+ * >+ * parseStd >+ * >+ **********************************************************************/ >+static >+int >+parseStd( >+ const char *name >+ ) >+{ >+ int i; >+ >+ for (i = 0; i < N_STDS; i++) >+ if (strcasecmp(name , stdNames[ i ]) == 0) >+ return i; >+ >+ return -1; >+} >+ >+/********************************************************************** >+ * >+ * printUsage >+ * >+ **********************************************************************/ >+static >+void >+printUsage(void) >+{ >+ unsigned i; >+ >+ fprintf(stderr , "Usage:\n" >+ "%s [-display host:dpy] [<cmd> <attribute> [<value>]]\n\n" , program_name); >+ fprintf(stderr , "When <cmd> is absent, a dump of all attributes is done\n"); >+ fprintf(stderr , "Allowed <cmd>s:\n" >+ "set <attribute> <value> Set <attribute> to <value>\n" >+ "inc <attribute> Increment <attribute> by 1\n" >+ "dec <attribute> Decrement <attribute> by 1\n" >+ "zero <attribute> Set <attribute> to 0\n" >+ "\nAllowed <attribute>s:\n"); >+ >+ for (i = 0; i < N_ATTRS; i++) >+ fprintf(stderr , "%-6s %s\n" , attrNames[ i ].extName , attrNames[ i ].description); >+ >+ fprintf(stderr , "\nFor %s attribute, both the numeric value and the name of the standard are valid.\n" , >+ attrNames[ STD_ATTR ].extName); >+ >+ fprintf(stderr , "\nAllowed standards:\n"); >+ >+ for (i = 0; i < N_STDS; i++) >+ fprintf(stderr , "%d %s\n" , i , stdNames[ i ]); >+ >+ exit(1); >+} >+ >+/********************************************************************** >+ * >+ * main >+ * >+ **********************************************************************/ >+int >+main( >+ int argc, >+ char *argv[] >+ ) >+{ >+ Action action; >+ Display *dpy; >+ char *disname = NULL; >+ unsigned argIdx = 1; >+ int attribute; >+ int value; >+ unsigned ver, rev, eventB, reqB, errorB; >+ XvAdaptorInfo *ainfo; >+ unsigned nadaptors; >+ unsigned i; >+ XvPortID portID; >+ >+ program_name = argv[ 0 ]; >+ >+ if (argc >= 3 && >+ strcmp(argv[ argIdx ] , "-display") == 0) >+ { >+ argIdx++; >+ disname = argv[ argIdx++ ]; >+ } >+ >+ if (argIdx < argc) >+ { >+ if (strcasecmp(argv[ argIdx ] , "set") == 0) >+ action = ACT_SET; >+ else if (strcasecmp(argv[ argIdx ] , "inc") == 0) >+ action = ACT_INC; >+ else if (strcasecmp(argv[ argIdx ] , "dec") == 0) >+ action = ACT_DEC; >+ else if (strcasecmp(argv[ argIdx ] , "zero") == 0) >+ action = ACT_ZERO; >+ else >+ printUsage(); >+ >+ argIdx++; >+ if (argIdx >= argc) >+ printUsage(); >+ >+ if ((attribute = parseAttribute(argv[ argIdx ])) < 0) >+ { >+ fprintf(stderr , "%s: Unrecognized attribute name (%s)\n" , program_name , argv[ argIdx ]); >+ printUsage(); >+ } >+ argIdx++; >+ >+ if (action == ACT_SET) >+ { >+ if (argIdx >= argc) >+ printUsage(); >+ if (sscanf(argv[ argIdx ] , "%d" , &value) != 1 && >+ (attribute != STD_ATTR || (value = parseStd(argv[ argIdx ])) < 0)) >+ printUsage(); >+ } >+ } >+ else >+ action = ACT_FULL_DUMP; >+ >+ /* >+ * Open display >+ */ >+ if (!(dpy = XOpenDisplay(disname))) >+ { >+ fprintf(stderr , "%s: Unable to open display %s\n" , program_name , >+ (disname != NULL) ? disname : XDisplayName(NULL)); >+ return -1; >+ } >+ >+ if (XvQueryExtension(dpy, &ver, &rev, &reqB, &eventB, &errorB) != Success) >+ { >+ fprintf(stderr , "%s: No XV Extension on %s\n" , program_name , >+ (disname != NULL) ? disname : XDisplayName(NULL)); >+ return 0; >+ } >+ >+ /* >+ * Use screen #0 >+ */ >+ XvQueryAdaptors(dpy , RootWindow(dpy , 0) , &nadaptors , &ainfo); >+ >+ if (!nadaptors) >+ { >+ fprintf(stderr , "%s: No adaptors present\n" , program_name); >+ return 0; >+ } >+ >+ /* >+ * Use adaptor #0 >+ */ >+ portID = ainfo[ 0 ].base_id; >+ if (!scanAttributes(dpy , portID)) >+ { >+ fprintf(stderr , "%s: Invalid attributes in XV adaptor\n" , program_name); >+ return 0; >+ } >+ >+ switch (action) >+ { >+ case ACT_FULL_DUMP: >+ for(i = 0; i < nadaptors; i++) >+ { >+ printf("Adaptor #%d: \"%s\"\n" , i , ainfo[ i ].name); >+ printf(" number of ports : %d\n" , ainfo[ i ].num_ports); >+ printf(" port base : %d\n" , ainfo[ i ].base_id); >+ printf(" number of adaptors: %u\n" , ainfo[ i ].num_adaptors); >+ } >+ for (i = 0; i < N_ATTRS; i++) >+ { >+ getAttribute(dpy , portID , i , &value); >+ if (i == STD_ATTR) >+ if (value < 0 || value >= N_STDS) >+ printf ("%s = ??? (%d)\n" , attrNames[ i ].extName , value); >+ else >+ printf ("%s = %s (%d)\n" , attrNames[ i ].extName , stdNames[ value ] , value); >+ else >+ printf("%s = %d\n" , attrNames[ i ].extName , value); >+ } >+ break; >+ >+ case ACT_SET: >+ setAttribute(dpy , portID , attribute , value); >+ break; >+ >+ case ACT_INC: >+ getAttribute(dpy , portID , attribute , &value); >+ value++; >+ if (value > attrData[ attribute ].maxValue) >+ value = attrData[ attribute ].minValue; >+ setAttribute(dpy , portID , attribute , value); >+ break; >+ >+ case ACT_DEC: >+ getAttribute(dpy , portID , attribute , &value); >+ value--; >+ if (value < attrData[ attribute ].minValue) >+ value = attrData[ attribute ].maxValue; >+ setAttribute(dpy , portID , attribute , value); >+ break; >+ >+ case ACT_ZERO: >+ setAttribute(dpy , portID , attribute , 0); >+ break; >+ } >+ >+ return 0; >+}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 127642
:
83174
|
84891
|
89986
|
89987
|
95893
|
96124
|
96125
|
96126
|
96376
|
115364
|
115366
|
115513