#ifndef _RADEON_TVOUT_H_
#define _RADEON_TVOUT_H_

#include "radeon.h"
#include "radeon_reg.h"
#include "theatre_reg.h"

#define VERT_LEAD_IN_LINES 2
#define FRAC_BITS 0xe
#define FRAC_MASK 0x3fff

typedef struct
{
    unsigned long h_total;
    unsigned long h_sync_len;
    unsigned long h_genclk_del;
    unsigned long h_setup_del;
    unsigned long h_active_del;
    unsigned long h_active_len;
    unsigned long v_total;
    unsigned long v_active_lines;
    unsigned long v_field_total;
    unsigned long v_fields;
}
TVTimingParam;

typedef struct
{
    unsigned long h_disp;
    unsigned long v_disp;
    unsigned long h_total_ntsc;
    unsigned long v_total_ntsc;
    unsigned long h_total_pal;
    unsigned long v_total_pal;
    unsigned long h_crtc_total;
    unsigned long v_crtc_total;
    unsigned long h_crtc_sync_start;
    unsigned long v_crtc_sync_start;
    unsigned long h_crtc_sync_end;
    unsigned long v_crtc_sync_end;
}
TVOutModes;

enum
{
    NTSC,
    PAL,
    PALM,
    PALCN,
    SCART_PAL,
    PAL60
}
TVFormat;

typedef enum
{
    VCHIP_UNKNOWN,
    VCHIP_IMPACTV,
    VCHIP_RT1,			/*Rage Theatre */
    VCHIP_RT2			/*Rage Theatre II */
}
RADEONVideoChipType;

typedef enum
{
    TVOUT_UNKNOWN,
    TVOUT_IMPACTV,
    TVOUT_RT1,			/*Rage Theatre */
    TVOUT_INTERNAL		/*On chip tvout */
}
RADEONTvoutType;

/* Structure definition for SetClk() input variables */
typedef struct _SETCLK_INPUT
{
    long RefClk;		/* reference clock frequency */
    long ReqdClk;		/* desired output clock frequency */
    long MinPLLInputFreq;	/* minimum allowable input frequency for PLL */
    long MinPLLOutputFreq;	/* minimum allowable output frequency for PLL */
    long MaxPLLOutputFreq;	/* maximum allowable output frequency for PLL */
    long BestPLLOutputFreq;	/* value of the PLL output frequency that minimizes jitter */
    int FBDivMult;		/* This is the value of the fixed divider in front of the PLL feedback divider */
    int FixedPostDiv;		/* This is the value of the fixed postdivider. 0 => no fixed postdivider */
    int PUpperLimit;		/* maximum value of postdivider */
    int ErrSign;		/* ErrSign =  1 chose output clock should be faster than target,
                                           = -1 chose output clock should be slower than target,
                                           =  0 chose smallest absolute error
				 */
    int CalculateCRTClkValues;	/* Use to determine if we are calculate TV or CRT clock values; */
    long ulChipType;
}
SETCLK_INPUT, *LPSETCLK_INPUT;


/* Structure definition for SetClk() output variables */
typedef struct _SETCLK_OUTPUT
{
    long BestN;			/* feedback divider value for best solution found */
    long BestM;			/* reference divider value for best solution found */
    long BestP;			/* postdivider value for best solution found */
    long BestError;		/* difference between best solution found and desired
                                   output clock frequency
                                   BestError = (RefClk * BestN / BestM / BestP - ReqdClk) / ReqdClk
				 */
    long BestPLLInputFreq;	/* PLL input frequency for best solution found */
    long BestPLLOutputFreq;	/* PLL output frequency for best solution found */
    long BestClk;		/* best solution found */
}
SETCLK_OUTPUT, *LPSETCLK_OUTPUT;

/* Structure definition for SetCrtMN() input variables */
typedef struct _SETCRTMN_INPUT
{
    int noCLKBY2;		/* Set to 1 if there is no CRTCLK_USE_CLKBY2 parameter
                                   Set to 1 for ImpacTV, 0 for Rage Theatre */
    int CRTFBDivMult;		/* This is the value of the fixed divider in front of the feedback divider
                                   Set to 1 for Rage Theatre, 2 for ImpacTV */
    long MinCRTPLLInputFreq;	/* minimum allowable input frequency for CRT PLL */
    long MinCRTPLLOutputFreq;	/* minimum allowable output frequency for CRT PLL */
    long MaxCRTPLLOutputFreq;	/* maximum allowable output frequency for CRT PLL */
    long BestCRTPLLOutputFreq;	/* value of the output frequency that minimizes jitter */
    long CRT_VTotal;		/* target total number of lines in CRT frame (= 1 + (VTOTAL from register)) */
    long CRT_HTotal;		/* target total number of pixels per CRT line (= 1 + (HTOTAL from register)) */
    int MaxVDelta;		/* maximum allowable change in CRT_VTotal */
    int MaxHDelta;		/* maximum allowable change in CRT_HTotal */
    long CRTRefClk;		/* reference clock frequency for CRT PLL (may be crystal clock or
                                   clock from a secondary reference or another PLL) */
    long TVRefClk;		/* reference clock frequency for TV PLL */
    int TVFBDivMult;		/* Fixed TV feedback divider multiplier */
    long TV_M;			/* TV reference divider value */
    long TV_N;			/* TV feedback divider value */
    long TV_P;			/* TV postdivider value */
    long TV_HTotal;		/* total number of lines in TV frame */
    long TV_VTotal;		/* total number of pixels per TV line */
    int BytesPerPixel;		/* number of bytes per CRT pixel (= 2 + RGB_IS_888_PACK) {2, 3} */
    int FrameSizeAdjust;	/* dotcrawl */
    int PUpperLimit;		/* maximum value of postdivider */
    int ErrSign;		/* ErrSign =  1 chose CRT frame rate should be faster than TV,
                                           = -1 chose CRT frame rate should be slower than TV,
                                           =  0 chose smallest absolute error
				 */
    int FrameRateDiffTol;	/* maximum allowable difference between CRT and TV frame rate (in TV clocks) */
    int FixedPostDiv;		/* This is the value of the fixed postdivider.  0 => no fixed postdivider */
    long ulChipType;

}
SETCRTMN_INPUT, *LPSETCRTMN_INPUT;


/* Structure definition for SetClk() output variables */
typedef struct _SETCRTMN_OUTPUT
{
    long CRT_N;			/* feedback divider value for best solution found */
    long CRT_M;			/* reference divider value for best solution found */
    long BYT_CLK_DIV; 
    long CRTCLK_USE_CLKBY2;
    long VTotal;		/* VTotal value after modification by function */
    long HTotal;		/* HTotal value after modification by function */
    long FrameError;		/* difference in CRT and TV frame times for solution 
				   that was found (in TV clocks) */

}
SETCRTMN_OUTPUT, *LPSETCRTMN_OUTPUT;

typedef struct _VT_MASTER_INPUT
{
    unsigned long TVClksToActive;	/* value returned by CalcTime */
    long TVHPeriod;		/* value returned by CalcTime */
    long TVHBlank;		/* value returned by CalcTime */
    unsigned long D_HTOTAL;	/* HTotal value of current CRT mode */
    unsigned long D_VTOTAL;	/* VTotal value of current CRT mode */
    unsigned long D_FTOTAL;	/* FTotal value of current CRT mode */
    unsigned long D_HDISP;	/* HDisp value of current CRT mode */
    unsigned long D_VDISP;	/* VDisp value of current CRT mode */
    long CRT_M;			/* PLL's M value of current CRT mode */
    long CRT_N;			/* PLL's N value of current CRT mode */
    long VideoType;		/* 0 - NTSC; 1 - PAL */
    long TV_M;			/* TV M value */
    long TV_N;			/* TV N value */
    long TV_P;
    long TV_Lines;		/* TV total number of lines */
    long TV_Fsc;		/* TV sub carrier frequency in MHz */
    long TV_Samples;		/* Number of samples per TV line */
    long Y_INC;			/* Y_INC value (TB1) */
    long Y_ACCUM_INIT;		/* Y_ACCUM_INIT value (TB1) */
    long UV_INC;		/* UV_INC value (TB2) */
    long UV_ACCUM_INIT;		/* UV_ACCUM_INIT value (TB2) */
    long CRTCLK_USE_CLKBY2;
    long BYT_CLK_DIV;
    long RGB_565_888;
    long TVFBDivMult;
    long CRTFBDivMult;
    long RefFreq;
}
VT_MASTER_INPUT, *LPVT_MASTER_INPUT;

/* Structure definition for VTMaster () output variables */

typedef struct _VT_MASTER_OUTPUT
{
    long D_FRESTART;		/* Field restart value */
    long D_VRESTART;		/* Vertical restart line position */
    long D_HRESTART;		/* Horizontal restart pixel position */
}
VT_MASTER_OUTPUT, *LPVT_MASTER_OUTPUT;

int VTMaster (LPVT_MASTER_INPUT lpInput, LPVT_MASTER_OUTPUT lpOutput);


int SetCrtMN (LPSETCRTMN_INPUT lpInput, LPSETCRTMN_OUTPUT lpOutput);

int SetClk (LPSETCLK_INPUT lpInput, LPSETCLK_OUTPUT lpOutput);

extern Bool RADEONVIPRead (ScrnInfoPtr pScrn, CARD32 address, CARD32 count,
			 CARD8 * buffer);
extern Bool RADEONVIPWrite (ScrnInfoPtr pScrn, CARD32 address, CARD32 count,
			  CARD8 * buffer);
extern void RADEONVIPReset (ScrnInfoPtr pScrn);
extern CARD32 RT_INREG (ScrnInfoPtr pScrn, CARD32 reg);
extern void RT_OUTREG (ScrnInfoPtr pScrn, CARD32 reg, CARD32 data);
extern Bool RADEONDetectTheatre (ScrnInfoPtr pScrn);

extern void RADEONDumpTVInfo (ScrnInfoPtr pScrn);

#endif

