1f29dbc25Smrg/* Copyright (c) 2005 Advanced Micro Devices, Inc.
2f29dbc25Smrg *
3f29dbc25Smrg * Permission is hereby granted, free of charge, to any person obtaining a copy
4f29dbc25Smrg * of this software and associated documentation files (the "Software"), to
5f29dbc25Smrg * deal in the Software without restriction, including without limitation the
6f29dbc25Smrg * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7f29dbc25Smrg * sell copies of the Software, and to permit persons to whom the Software is
8f29dbc25Smrg * furnished to do so, subject to the following conditions:
9f29dbc25Smrg *
10f29dbc25Smrg * The above copyright notice and this permission notice shall be included in
11f29dbc25Smrg * all copies or substantial portions of the Software.
12f29dbc25Smrg *
13f29dbc25Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14f29dbc25Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15f29dbc25Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16f29dbc25Smrg * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17f29dbc25Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18f29dbc25Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19f29dbc25Smrg * IN THE SOFTWARE.
20f29dbc25Smrg *
21f29dbc25Smrg * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
22f29dbc25Smrg * contributors may be used to endorse or promote products derived from this
23f29dbc25Smrg * software without specific prior written permission.
24f29dbc25Smrg * */
25f29dbc25Smrg
26f29dbc25Smrg#define	FS450_DIRECTREG	0
27f29dbc25Smrg
28f29dbc25Smrg#include "tv_fs450.h"
29f29dbc25Smrg
30f29dbc25Smrg/*==========================================================================
31f29dbc25Smrg *	Macros
32f29dbc25Smrg *==========================================================================
33f29dbc25Smrg */
34f29dbc25Smrg#undef		fsmax
35f29dbc25Smrg#undef		fsmin
36f29dbc25Smrg#define		fsmax(a, b)		((a) > (b) ? (a) : (b))
37f29dbc25Smrg#define		fsmin(a, b)		((a) < (b) ? (a) : (b))
38f29dbc25Smrg
39f29dbc25Smrg#undef range_limit
40f29dbc25Smrg#define range_limit(val,min_val,max_val) (fsmax((min_val),fsmin((val),(max_val))))
41f29dbc25Smrg
42f29dbc25Smrg/*==========================================================================
43f29dbc25Smrg *	Registers
44f29dbc25Smrg *==========================================================================
45f29dbc25Smrg */
46f29dbc25Smrg
47f29dbc25Smrg#define MAX_REGISTERS	32
48f29dbc25Smrg#define MAX_BITS		32
49f29dbc25Smrg
50f29dbc25Smrg#define READ	1
51f29dbc25Smrg#define WRITE	2
52f29dbc25Smrg#define READ_WRITE (READ | WRITE)
53f29dbc25Smrg
5404007ebaSmrgtypedef struct {
55f29dbc25Smrg    char *name;
56f29dbc25Smrg    unsigned long offset;
57f29dbc25Smrg    unsigned char bit_length;
58f29dbc25Smrg    unsigned char valid_bits;
59f29dbc25Smrg    unsigned char read_write;
60f29dbc25Smrg    char *bitfield_names[MAX_BITS];
61f29dbc25Smrg} S_REGISTER_DESCRIP;
62f29dbc25Smrg
6304007ebaSmrgtypedef struct {
64f29dbc25Smrg    int source;
65f29dbc25Smrg    char *name;
66f29dbc25Smrg    S_REGISTER_DESCRIP registers[MAX_REGISTERS];
67f29dbc25Smrg} S_SET_DESCRIP;
68f29dbc25Smrg
69f29dbc25Smrgconst S_SET_DESCRIP *houston_regs(void);
70f29dbc25Smrgconst S_SET_DESCRIP *encoder_regs(void);
71f29dbc25Smrgconst S_SET_DESCRIP *macrovision_regs(void);
72f29dbc25Smrgconst S_SET_DESCRIP *gcc_regs(void);
73f29dbc25Smrg
74f29dbc25Smrg/*==========================================================================
75f29dbc25Smrg *	Houston Register Addresses & Bit Definitions
76f29dbc25Smrg *==========================================================================
77f29dbc25Smrg */
78f29dbc25Smrg#define	HOUSTON_IHO				0x00    /* Input Horizontal Offset                      */
79f29dbc25Smrg#define	HOUSTON_IVO				0x02    /* Input Vertical Offset                        */
80f29dbc25Smrg#define	HOUSTON_IHA				0x04    /* Input Horizontal Active Width        */
8179d5fcd7Smrg#define	HOUSTON_VSC				0x06    /* Vertical Scaling Coefficient          */
8279d5fcd7Smrg#define	HOUSTON_HSC				0x08    /* Horizontal Scaling Coefficient        */
83f29dbc25Smrg#define	HOUSTON_BYP				0x0A    /* Bypass Register                                      */
84f29dbc25Smrg#define	HOUSTON_CR				0x0C    /* Control Register                             */
85f29dbc25Smrg#define	HOUSTON_SP				0x0E    /* Status                                                       */
86f29dbc25Smrg#define	HOUSTON_NCONL			0x10    /* NCO numerator low word                       */
87f29dbc25Smrg#define	HOUSTON_NCONH			0x12    /* NCO numerator high word                      */
88f29dbc25Smrg#define	HOUSTON_NCODL			0x14    /* NCO denominator low word             */
89f29dbc25Smrg#define	HOUSTON_NCODH			0x16    /* NCO denominator high word            */
90f29dbc25Smrg#define	HOUSTON_APO				0x18
91f29dbc25Smrg#define	HOUSTON_ALO				0x1A
92f29dbc25Smrg#define	HOUSTON_AFO				0x1C
93f29dbc25Smrg#define	HOUSTON_HSOUTWID		0x1E
94f29dbc25Smrg#define	HOUSTON_HSOUTST			0x20
95f29dbc25Smrg#define	HOUSTON_HSOUTEND		0x22
96f29dbc25Smrg#define	HOUSTON_SHP				0x24    /* Sharpness                                            */
97f29dbc25Smrg#define	HOUSTON_FLK				0x26    /* Flicker Filter                                       */
98f29dbc25Smrg#define	HOUSTON_BCONTL			0x28
99f29dbc25Smrg#define	HOUSTON_BCONTH			0x2A
100f29dbc25Smrg#define	HOUSTON_BDONE			0x2C
101f29dbc25Smrg#define	HOUSTON_BDIAGL			0x2E
102f29dbc25Smrg#define	HOUSTON_BDIAGH			0x30
103f29dbc25Smrg#define	HOUSTON_REV				0x32
104f29dbc25Smrg#define	HOUSTON_MISC			0x34
105f29dbc25Smrg#define	HOUSTON_FFO				0x36
106f29dbc25Smrg#define	HOUSTON_FFO_LAT			0x38
107f29dbc25Smrg#define HOUSTON_VSOUTWID		0x3A
108f29dbc25Smrg#define HOUSTON_VSOUTST			0x3C
109f29dbc25Smrg#define HOUSTON_VSOUTEND		0x3E
110f29dbc25Smrg/*		BYP Register Bits		*/
111f29dbc25Smrg#define	BYP_RGB_BYPASS			0x0001
112f29dbc25Smrg#define	BYP_HDS_BYPASS			0x0002
113f29dbc25Smrg#define	BYP_HDS_TBYPASS			0x0004
114f29dbc25Smrg#define	BYP_CAC_BYPASS			0x0008
115f29dbc25Smrg#define	BYP_R2V_SBYPASS			0x0010
116f29dbc25Smrg#define	BYP_R2V_BYPASS			0x0020
117f29dbc25Smrg#define	BYP_VDS_BYPASS			0x0040
118f29dbc25Smrg#define	BYP_FFT_BYPASS			0x0080
119f29dbc25Smrg#define	BYP_FIF_BYPASS			0x0100
120f29dbc25Smrg#define	BYP_FIF_TBYPASS			0x0200
121f29dbc25Smrg#define	BYP_HUS_BYPASS			0x0400
122f29dbc25Smrg#define	BYP_HUS_TBYPASS			0x0800
123f29dbc25Smrg#define	BYP_CCR_BYPASS			0x1000
124f29dbc25Smrg#define	BYP_PLL_BYPASS			0x2000
125f29dbc25Smrg#define	BYP_NCO_BYPASS			0x4000
126f29dbc25Smrg#define	BYP_ENC_BYPASS			0x8000
127f29dbc25Smrg/*		CR Register Bits		*/
128f29dbc25Smrg#define	CR_RESET				0x0001
129f29dbc25Smrg#define	CR_CLKOFF				0x0002
130f29dbc25Smrg#define	CR_NCO_EN				0x0004
131f29dbc25Smrg#define	CR_COMPOFF				0x0008
132f29dbc25Smrg#define	CR_YCOFF				0x0010
133f29dbc25Smrg#define	CR_LP_EN				0x0020
134f29dbc25Smrg#define	CR_CACQ_CLR				0x0040
135f29dbc25Smrg#define	CR_FFO_CLR				0x0080
136f29dbc25Smrg#define	CR_656_PAL_NTSC			0x0100
137f29dbc25Smrg#define	CR_656_STD_VMI			0x0200
138f29dbc25Smrg#define	CR_OFMT					0x0400
139f29dbc25Smrg#define	CR_UIM_CLK				0x0800
140f29dbc25Smrg#define	CR_UIM_DEC				0x1000
141f29dbc25Smrg#define	CR_BIPGEN_EN1			0x2000
142f29dbc25Smrg#define	CR_UIM_MOD0				0x4000
143f29dbc25Smrg#define	CR_UIM_MOD1				0x8000
144f29dbc25Smrg/*		Status Register Bits	*/
145f29dbc25Smrg#define	SP_CACQ_ST				0x0001
146f29dbc25Smrg#define	SP_FFO_ST				0x0002
147f29dbc25Smrg#define	SP_REVID_MASK			0x7FFC
148f29dbc25Smrg#define	SP_MV_EN				0x8000
149f29dbc25Smrg/*		BDONE Register Bits		*/
150f29dbc25Smrg#define	BDONE_BIST_DONE_A		0x0001
151f29dbc25Smrg#define	BDONE_BIST_DONE_B		0x0002
152f29dbc25Smrg#define	BDONE_BIST_DONE_C		0x0004
153f29dbc25Smrg#define	BDONE_BIST_DONE_D		0x0008
154f29dbc25Smrg#define	BDONE_BIST_DONE_E		0x0010
155f29dbc25Smrg#define	BDONE_BIST_DONE_F		0x0020
156f29dbc25Smrg#define	BDONE_BIST_DONE_G		0x0040
157f29dbc25Smrg/*		BDIAGL Register Bits	*/
158f29dbc25Smrg#define	BDIAGL_BIST_DIAG_A		0x000F
159f29dbc25Smrg#define	BDIAGL_BIST_DIAG_B		0x00F0
160f29dbc25Smrg#define	BDIAGL_BIST_DIAG_C		0x0F00
161f29dbc25Smrg#define	BDIAGL_BIST_DIAG_D		0xF000
162f29dbc25Smrg/*		BDIAGH Register Bits	*/
163f29dbc25Smrg#define	BDIAGH_BIST_DIAG_E		0x000F
164f29dbc25Smrg#define	BDIAGH_BIST_DIAG_F		0x000F
165f29dbc25Smrg#define	BDIAGH_BIST_DIAG_G		0x000F
166f29dbc25Smrg/*		MISC Register Bits		*/
167f29dbc25Smrg#define	MISC_TV_SHORT_FLD		0x0001
168f29dbc25Smrg#define	MISC_ENC_TEST			0x0002
169f29dbc25Smrg#define	MISC_DAC_TEST			0x0004
170f29dbc25Smrg#define	MISC_MV_SOFT_EN			0x0008
171f29dbc25Smrg#define	MISC_NCO_LOAD0			0x0010
172f29dbc25Smrg#define	MISC_NCO_LOAD1			0x0020
173f29dbc25Smrg#define	MISC_VGACKDIV			0x0200
174f29dbc25Smrg#define	MISC_BRIDGE_SYNC		0x0400
175f29dbc25Smrg#define	MISC_GTLIO_PD			0x8000
176f29dbc25Smrg/*==========================================================================
177f29dbc25Smrg *	Encoder Registers & Bit Definitions
178f29dbc25Smrg *==========================================================================
179f29dbc25Smrg */
180f29dbc25Smrg#define	ENC_CHROMA_FREQ		0x40
181f29dbc25Smrg#define	ENC_CHROMA_PHASE	0x44
182f29dbc25Smrg#define	ENC_REG05			0x45
183f29dbc25Smrg#define	ENC_REG06			0x46
184f29dbc25Smrg#define	ENC_REG07			0x47
185f29dbc25Smrg#define	ENC_HSYNC_WIDTH		0x48
186f29dbc25Smrg#define	ENC_BURST_WIDTH		0x49
187f29dbc25Smrg#define	ENC_BACK_PORCH		0x4A
188f29dbc25Smrg#define	ENC_CB_BURST_LEVEL	0x4B
189f29dbc25Smrg#define	ENC_CR_BURST_LEVEL	0x4C
190f29dbc25Smrg#define	ENC_SLAVE_MODE		0x4D
191f29dbc25Smrg#define	ENC_BLACK_LEVEL		0x4e
192f29dbc25Smrg#define	ENC_BLANK_LEVEL		0x50
193f29dbc25Smrg#define	ENC_NUM_LINES		0x57
194f29dbc25Smrg#define	ENC_WHITE_LEVEL		0x5e
195f29dbc25Smrg#define	ENC_CB_GAIN			0x60
196f29dbc25Smrg#define	ENC_CR_GAIN			0x62
197f29dbc25Smrg#define	ENC_TINT			0x65
198f29dbc25Smrg#define	ENC_BREEZE_WAY		0x69
199f29dbc25Smrg#define	ENC_FRONT_PORCH		0x6C
200f29dbc25Smrg#define	ENC_ACTIVELINE		0x71
201f29dbc25Smrg#define	ENC_FIRST_LINE		0x73
202f29dbc25Smrg#define	ENC_REG34			0x74
203f29dbc25Smrg#define	ENC_SYNC_LEVEL		0x75
204f29dbc25Smrg#define	ENC_VBI_BLANK_LEVEL	0x7C
205f29dbc25Smrg#define	ENC_RESET			0x7e
206f29dbc25Smrg#define	ENC_NOTCH_FILTER	0x8d
207f29dbc25Smrg/*==========================================================================
208f29dbc25Smrg * 	Macrovision Registers & Bit Definitions
209f29dbc25Smrg *==========================================================================
210f29dbc25Smrg */
211f29dbc25Smrg#define		MV_N0			0x59
212f29dbc25Smrg#define		MV_N1			0x52
213f29dbc25Smrg#define		MV_N2			0x7b
214f29dbc25Smrg#define		MV_N3			0x53
215f29dbc25Smrg#define		MV_N4			0x79
216f29dbc25Smrg#define		MV_N5			0x5d
217f29dbc25Smrg#define		MV_N6			0x7a
218f29dbc25Smrg#define		MV_N7			0x64
219f29dbc25Smrg#define		MV_N8			0x54
220f29dbc25Smrg#define		MV_N9			0x55
221f29dbc25Smrg#define		MV_N10			0x56
222f29dbc25Smrg#define		MV_N11			0x6d
223f29dbc25Smrg#define		MV_N12			0x6f
224f29dbc25Smrg#define		MV_N13			0x5a
225f29dbc25Smrg#define		MV_N14			0x5b
226f29dbc25Smrg#define		MV_N15			0x5c
227f29dbc25Smrg#define		MV_N16			0x63
228f29dbc25Smrg#define		MV_N17			0x66
229f29dbc25Smrg#define		MV_N18			0x68
230f29dbc25Smrg#define		MV_N19			0x67
231f29dbc25Smrg#define		MV_N20			0x61
232f29dbc25Smrg#define		MV_N21			0x6a
233f29dbc25Smrg#define		MV_N22			0x76
234f29dbc25Smrg#define		MV_AGC_PULSE_LEVEL	0x77
235f29dbc25Smrg#define		MV_BP_PULSE_LEVEL	0x78
236f29dbc25Smrg/*==========================================================================
237f29dbc25Smrg *	The TRACE macro can be used to display debug information.  It can display
238f29dbc25Smrg *	one or more parameters in a formatted string like printf.  No code will be
239f29dbc25Smrg *	generated for a release build.  Use double parentheses for compatibility
240f29dbc25Smrg *	with C #define statements.  Newline characters are not added
241f29dbc25Smrg *	automatically.  Usage example:
242f29dbc25Smrg *
243f29dbc25Smrg *	TRACE(("Number is %d, Name is %s.\n",iNumber,lpszName))
244f29dbc25Smrg *==========================================================================
245f29dbc25Smrg */
246f29dbc25Smrg#define TRACE(parameters) {}
247f29dbc25Smrg/*		GCC timing structure		*/
24804007ebaSmrgtypedef struct _S_TIMING_SPECS {
249f29dbc25Smrg    int vga_width;
250f29dbc25Smrg    int vga_lines;
251f29dbc25Smrg    int tv_width;
252f29dbc25Smrg    int tv_lines;
253f29dbc25Smrg    int h_total;
254f29dbc25Smrg    int h_sync;
255f29dbc25Smrg    int v_total;
256f29dbc25Smrg    int v_sync;
257f29dbc25Smrg} S_TIMING_SPECS;
258f29dbc25Smrg
259f29dbc25Smrg/*		Revision of Houston chip	*/
260f29dbc25Smrg#define HOUSTON_REV_A 0
261f29dbc25Smrg#define HOUSTON_REV_B 1
262f29dbc25Smrgstatic int houston_Rev(void);
263f29dbc25Smrg
264f29dbc25Smrg/*==========================================================================
265f29dbc25Smrg *	Functions
266f29dbc25Smrg *==========================================================================
267f29dbc25Smrg */
268f29dbc25Smrgstatic int houston_init(void);
269f29dbc25Smrg
270f29dbc25Smrgstatic unsigned char PLAL_FS450_i2c_address(void);
271f29dbc25Smrgstatic int PLAL_FS450_UIM_mode(void);
272f29dbc25Smrgstatic int PLAL_ReadRegister(S_REG_INFO * p_reg);
273f29dbc25Smrgstatic int PLAL_WriteRegister(const S_REG_INFO * p_reg);
274f29dbc25Smrgstatic int PLAL_IsTVOn(void);
275f29dbc25Smrgstatic int PLAL_EnableVga(void);
276f29dbc25Smrgstatic int PLAL_PrepForTVout(void);
277f29dbc25Smrgstatic int PLAL_SetTVTimingRegisters(const S_TIMING_SPECS * p_specs);
278f29dbc25Smrgstatic int PLAL_FinalEnableTVout(unsigned long vga_mode);
279f29dbc25Smrg
280f29dbc25Smrg/* Direct Memory Access Functions	*/
281f29dbc25Smrg/* NOTE: Cx5530 is assumed hardcoded at 0x10000 offset from MediaGX base.
282f29dbc25Smrg * F4Bar is bogus as described in the Cx5530 datasheet (actually points to GX
283f29dbc25Smrg * frame buffer).					*/
284f29dbc25Smrgstatic int
285f29dbc25SmrgDMAL_ReadUInt32(unsigned long phys_addr, unsigned long *p_data)
286f29dbc25Smrg{
287f29dbc25Smrg    *p_data = READ_REG32(phys_addr);
288f29dbc25Smrg    return 0;
289f29dbc25Smrg}
290f29dbc25Smrg
291f29dbc25Smrgstatic int
292f29dbc25SmrgDMAL_WriteUInt32(unsigned long phys_addr, unsigned long data)
293f29dbc25Smrg{
294f29dbc25Smrg    WRITE_REG32(phys_addr, data);
295f29dbc25Smrg    return 0;
296f29dbc25Smrg}
297f29dbc25Smrg
298f29dbc25Smrg/* Houston register access functions.	*/
299f29dbc25Smrgstatic int
300f29dbc25Smrghouston_ReadReg(unsigned int reg, unsigned long *p_value, unsigned int bytes)
301f29dbc25Smrg{
30204007ebaSmrg    return gfx_i2c_read(1, PLAL_FS450_i2c_address(), (unsigned char) reg,
30304007ebaSmrg                        (unsigned char) bytes, (unsigned char *) p_value);
304f29dbc25Smrg}
305f29dbc25Smrg
306f29dbc25Smrgstatic int
307f29dbc25Smrghouston_WriteReg(unsigned int reg, unsigned long value, unsigned int bytes)
308f29dbc25Smrg{
30904007ebaSmrg    return gfx_i2c_write(1, PLAL_FS450_i2c_address(), (unsigned char) reg,
31004007ebaSmrg                         (unsigned char) bytes, (unsigned char *) &value);
311f29dbc25Smrg}
312f29dbc25Smrg
313f29dbc25Smrg/* TV configuration functions.			*/
314f29dbc25Smrgstatic int config_init(void);
315f29dbc25Smrgstatic const S_TIMING_SPECS *p_specs(void);
316f29dbc25Smrgstatic void config_power(int on);
317f29dbc25Smrgstatic void config_vga_mode(unsigned long vga_mode);
318f29dbc25Smrgstatic void config_tv_std(unsigned long tv_std, unsigned int trigger_bits);
319f29dbc25Smrgstatic void conget_tv_std(unsigned long *p_tv_std);
320f29dbc25Smrgstatic unsigned long supported_standards(void);
321f29dbc25Smrgstatic void config_tvout_mode(unsigned long tvout_mode);
322f29dbc25Smrgstatic void conget_tvout_mode(unsigned long *p_tvout_mode);
323f29dbc25Smrgstatic void config_overscan_xy(unsigned long tv_std, unsigned long vga_mode,
32404007ebaSmrg                               int overscan_x, int overscan_y, int pos_x,
32504007ebaSmrg                               int pos_y);
326f29dbc25Smrgstatic void config_nco(unsigned long tv_std, unsigned long vga_mode);
327f29dbc25Smrgstatic void config_sharpness(int sharpness);
328f29dbc25Smrgstatic void conget_sharpness(int *p_sharpness);
329f29dbc25Smrgstatic void config_flicker(int flicker);
330f29dbc25Smrgstatic void conget_flicker(int *p_flicker);
331f29dbc25Smrgstatic void config_color(int color);
332f29dbc25Smrgstatic void conget_color(int *p_color);
333f29dbc25Smrgstatic void config_brightness_contrast(unsigned long tv_std,
33404007ebaSmrg                                       unsigned int trigger_bits,
33504007ebaSmrg                                       int brightness, int contrast);
336f29dbc25Smrgstatic void conget_brightness_contrast(unsigned long tv_std,
33704007ebaSmrg                                       unsigned int trigger_bits,
33804007ebaSmrg                                       int *p_brightness, int *p_contrast);
339f29dbc25Smrgstatic void config_yc_filter(unsigned long tv_std, int luma_filter,
34004007ebaSmrg                             int chroma_filter);
341f29dbc25Smrgstatic void conget_yc_filter(int *p_luma_filter, int *p_chroma_filter);
342f29dbc25Smrgstatic void config_macrovision(unsigned long tv_std,
34304007ebaSmrg                               unsigned int cp_trigger_bits);
344f29dbc25Smrgstatic void conget_macrovision(unsigned long tv_std,
34504007ebaSmrg                               unsigned int *p_cp_trigger_bits);
346f29dbc25Smrg
347f29dbc25Smrg/* Device settings.			*/
34804007ebaSmrgtypedef struct _S_DEVICE_SETTINGS {
349f29dbc25Smrg    int tv_on;
350f29dbc25Smrg    unsigned long vga_mode;
351f29dbc25Smrg    unsigned long tv_std;
352f29dbc25Smrg    unsigned long tvout_mode;
353f29dbc25Smrg    int overscan_x;
354f29dbc25Smrg    int overscan_y;
355f29dbc25Smrg    int position_x;
356f29dbc25Smrg    int position_y;
357f29dbc25Smrg    int sharpness;
358f29dbc25Smrg    int flicker;
359f29dbc25Smrg    int color;
360f29dbc25Smrg    int brightness;
361f29dbc25Smrg    int contrast;
362f29dbc25Smrg    unsigned char yc_filter;
363f29dbc25Smrg    unsigned int aps_trigger_bits;
364f29dbc25Smrg    int last_overscan_y;
365f29dbc25Smrg} S_DEVICE_SETTINGS;
366f29dbc25Smrg
367f29dbc25Smrgstatic S_DEVICE_SETTINGS d;
368f29dbc25Smrg
369f29dbc25Smrg/*==========================================================================
370f29dbc25Smrg * TV Setup Parameters
371f29dbc25Smrg *==========================================================================
372f29dbc25Smrg * */
373f29dbc25Smrg
37404007ebaSmrgstatic const struct {
375f29dbc25Smrg    unsigned long chroma_freq[5];
376f29dbc25Smrg    unsigned short chroma_phase[5];
377f29dbc25Smrg    unsigned short cphase_rst[5];
378f29dbc25Smrg    unsigned short color[5];
379f29dbc25Smrg    unsigned short cr_burst_level[5];
380f29dbc25Smrg    unsigned short cb_burst_level[5];
381f29dbc25Smrg    unsigned short sys625_50[5];
382f29dbc25Smrg    unsigned short vsync5[5];
383f29dbc25Smrg    unsigned short pal_mode[5];
384f29dbc25Smrg    unsigned short hsync_width[5];
385f29dbc25Smrg    unsigned short burst_width[5];
386f29dbc25Smrg    unsigned short back_porch[5];
387f29dbc25Smrg    unsigned short front_porch[5];
388f29dbc25Smrg    unsigned short breeze_way[5];
389f29dbc25Smrg    unsigned short activeline[5];
390f29dbc25Smrg    unsigned short blank_level[5];
391f29dbc25Smrg    unsigned short vbi_blank_level[5];
392f29dbc25Smrg    unsigned short black_level[5];
393f29dbc25Smrg    unsigned short white_level[5];
394f29dbc25Smrg    unsigned short hamp_offset[5];
395f29dbc25Smrg    unsigned short sync_level[5];
396f29dbc25Smrg    unsigned short tv_lines[5];
397f29dbc25Smrg    unsigned short tv_width[5];
398f29dbc25Smrg    unsigned short tv_active_lines[5];
399f29dbc25Smrg    unsigned short tv_active_width[5];
400f29dbc25Smrg    unsigned char notch_filter[5];
401f29dbc25Smrg    unsigned short houston_cr[5];
402f29dbc25Smrg    unsigned short houston_ncodl[5];
403f29dbc25Smrg    unsigned short houston_ncodh[5];
404f29dbc25Smrg} tvsetup = {
405f29dbc25Smrg    /*     ntsc,    pal,                ntsc-eij,   pal-m,      pal-n */
406f29dbc25Smrg    {
407f29dbc25Smrg    0x1f7cf021, 0xcb8a092a, 0x1f7cf021, 0xe3efe621, 0xcb8a092a},
408f29dbc25Smrg        /* chroma_freq                  */
409f29dbc25Smrg    {
410f29dbc25Smrg    0, 0, 0, 0, 0},
411f29dbc25Smrg        /* chroma_phase                 */
412f29dbc25Smrg    {
413f29dbc25Smrg    2, 0, 2, 0, 0},
414f29dbc25Smrg        /* cphase_rst                   */
415f29dbc25Smrg    {
416f29dbc25Smrg    54, 43, 54, 43, 43},
417f29dbc25Smrg        /* color                                */
418f29dbc25Smrg    {
419f29dbc25Smrg    0, 31, 0, 29, 29},
420f29dbc25Smrg        /* cr_burst_level               */
421f29dbc25Smrg    {
422f29dbc25Smrg    59, 44, 59, 41, 41},
423f29dbc25Smrg        /* cb_burst_level               */
424f29dbc25Smrg    {
425f29dbc25Smrg    0, 1, 0, 0, 1},
426f29dbc25Smrg        /* sys625_50                    */
427f29dbc25Smrg    {
428f29dbc25Smrg    0, 1, 0, 0, 0},
429f29dbc25Smrg        /* vsync5                               */
430f29dbc25Smrg    {
431f29dbc25Smrg    0, 1, 0, 1, 1},
432f29dbc25Smrg        /* pal_mode                     */
433f29dbc25Smrg    {
434f29dbc25Smrg    0x7a, 0x7a, 0x7a, 0x7a, 0x7a},
435f29dbc25Smrg        /* hsync_width                  */
436f29dbc25Smrg    {
437f29dbc25Smrg    0x40, 0x3c, 0x40, 0x40, 0x3c},
438f29dbc25Smrg        /* burst_width                  */
439f29dbc25Smrg    {
440f29dbc25Smrg    0x80, 0x9a, 0x80, 0x80, 0x9a},
441f29dbc25Smrg        /* back_porch                   */
442f29dbc25Smrg    {
443f29dbc25Smrg    0x24, 0x1e, 0x24, 0x24, 0x1e},
444f29dbc25Smrg        /* front_porch                  */
445f29dbc25Smrg    {
446f29dbc25Smrg    0x19, 0x1a, 0x19, 0x12, 0x1a},
447f29dbc25Smrg        /* breeze_way                   */
448f29dbc25Smrg    {
449f29dbc25Smrg    0xb4, 0xb4, 0xb4, 0xb4, 0xb4},
450f29dbc25Smrg        /* active_line                  */
451f29dbc25Smrg    {
452f29dbc25Smrg    240, 251, 240, 240, 240},
453f29dbc25Smrg        /* blank_level                  */
454f29dbc25Smrg    {
455f29dbc25Smrg    240, 251, 240, 240, 240},
456f29dbc25Smrg        /* vbi_blank_level              */
457f29dbc25Smrg    {
458f29dbc25Smrg    284, 252, 240, 252, 252},
459f29dbc25Smrg        /* black_level                  */
460f29dbc25Smrg    {
461f29dbc25Smrg    823, 821, 823, 821, 821},
462f29dbc25Smrg        /* white_level                  */
463f29dbc25Smrg    {
464f29dbc25Smrg    60, 48, 60, 48, 48},
465f29dbc25Smrg        /* hamp_offset                  */
466f29dbc25Smrg    {
467f29dbc25Smrg    0x08, 0x08, 0x08, 0x08, 0x08},
468f29dbc25Smrg        /* sync_level                   */
469f29dbc25Smrg    {
470f29dbc25Smrg    525, 625, 525, 525, 625},
471f29dbc25Smrg        /* tv_lines                     */
472f29dbc25Smrg    {
473f29dbc25Smrg    858, 864, 858, 858, 864},
474f29dbc25Smrg        /* tv_width                     */
475f29dbc25Smrg    {
476f29dbc25Smrg    487, 576, 487, 487, 576},
477f29dbc25Smrg        /* tv_active_lines              */
478f29dbc25Smrg    {
479f29dbc25Smrg    800, 800, 800, 800, 800},
480f29dbc25Smrg        /* tv_active_width              */
481f29dbc25Smrg    {
482f29dbc25Smrg    0x1a, 0x1d, 0x1a, 0x1d, 0x1d},
483f29dbc25Smrg        /* notch filter enabled */
484f29dbc25Smrg    {
485f29dbc25Smrg    0x0000, 0x0100, 0x0000, 0x0000, 0x0100},
486f29dbc25Smrg        /* houston cr pal               */
487f29dbc25Smrg    {
488f29dbc25Smrg    0x7e48, 0xf580, 0x7e48, 0x7e48, 0xf580},
489f29dbc25Smrg        /* houston ncodl                */
490f29dbc25Smrg    {
491f29dbc25Smrg    0x001b, 0x0020, 0x001b, 0x001b, 0x0020}
492f29dbc25Smrg    /* houston ncodh                */
493f29dbc25Smrg};
494f29dbc25Smrg
495f29dbc25Smrg/* MediaGX default underscan and centered position setups. */
496f29dbc25Smrg#define	SCANTABLE_ENTRIES	5
49704007ebaSmrgstruct _scantable {
498f29dbc25Smrg    unsigned long mode;
499f29dbc25Smrg    unsigned short v_total[5];
500f29dbc25Smrg    unsigned short v_sync[5];
501f29dbc25Smrg    unsigned short iha[5];
502f29dbc25Smrg    signed short iho[5];
503f29dbc25Smrg    signed short hsc[5];
504f29dbc25Smrg};
505f29dbc25Smrg
506f29dbc25Smrgstatic struct _scantable scantable[SCANTABLE_ENTRIES] = {
507f29dbc25Smrg    {
50804007ebaSmrg     GFX_VGA_MODE_640X480,
50904007ebaSmrg     {617, 624, 617, 624, 624}, /* v_total      */
51004007ebaSmrg     {69, 88, 69, 88, 88},      /* v_sync       */
51104007ebaSmrg     {720, 720, 720, 720, 720}, /* iha          */
51204007ebaSmrg     {0, 0, 0, 0, 0},           /* iho          */
51304007ebaSmrg     {-12, 0, -6, 0, 0}         /* hsc          */
51404007ebaSmrg     },
515f29dbc25Smrg    {
51604007ebaSmrg     GFX_VGA_MODE_800X600,
51704007ebaSmrg     {740, 740, 740, 740, 740}, /* v_total      */
51804007ebaSmrg     {90, 88, 90, 88, 88},      /* v_sync       */
51904007ebaSmrg     {720, 720, 508, 720, 720}, /* iha          */
52004007ebaSmrg     {-8, 11, -8, -8, 11},      /* iho          */
52104007ebaSmrg     {-27, -27, -27, -27, -27}  /* hsc          */
52204007ebaSmrg     },
523f29dbc25Smrg    {
52404007ebaSmrg     GFX_VGA_MODE_720X487,
52504007ebaSmrg     {525, 720, 525, 720, 720}, /* v_total      */
52604007ebaSmrg     {23, 230, 23, 230, 230},   /* v_sync       */
52704007ebaSmrg     {720, 720, 720, 720, 720}, /* iha          */
52804007ebaSmrg     {0xa2, 0xa2, 0xa2, 0xa2, 0xa2},    /* iho          */
52904007ebaSmrg     {0, 0, 0, 0, 0}            /* hsc          */
53004007ebaSmrg     },
531f29dbc25Smrg    {
53204007ebaSmrg     GFX_VGA_MODE_720X576,
53304007ebaSmrg     {720, 625, 720, 625, 625}, /* v_total      */
53404007ebaSmrg     {129, 25, 129, 25, 25},    /* v_sync       */
53504007ebaSmrg     {720, 720, 720, 720, 720}, /* iha          */
53604007ebaSmrg     {0xaa, 0xaa, 0xaa, 0xaa, 0xaa},    /* iho              */
53704007ebaSmrg     {0, 0, 0, 0, 0}            /* hsc          */
53804007ebaSmrg     },
539f29dbc25Smrg    {
54004007ebaSmrg     GFX_VGA_MODE_1024X768,
54104007ebaSmrg     {933, 942, 933, 806, 806}, /* v_total      */
54204007ebaSmrg     {121, 112, 121, 88, 88},   /* v_sync       */
54304007ebaSmrg     {600, 600, 600, 600, 600}, /* iha          */
54404007ebaSmrg     {0x3c, 0x23, 0x3c, 0x65, 0x65},    /* iho              */
54504007ebaSmrg     {35, 26, 35, 26, 26}       /* hsc          */
54604007ebaSmrg     },
547f29dbc25Smrg};
548f29dbc25Smrg
549f29dbc25Smrg/* Houston fifo configuration constants. */
55004007ebaSmrgstruct _ffolat {
551f29dbc25Smrg    int v_total;
552f29dbc25Smrg    unsigned short ffolat;
553f29dbc25Smrg};
554f29dbc25Smrg
55504007ebaSmrgstruct _ffolativo {
556f29dbc25Smrg    int v_total;
557f29dbc25Smrg    unsigned short ivo;
558f29dbc25Smrg    unsigned short ffolat;
559f29dbc25Smrg};
560f29dbc25Smrg
561f29dbc25Smrg/* h_total=832, ivo=40, tv_width=858, tv_lines=525, vga_lines=480 */
562f29dbc25Smrg#define SIZE6X4NTSC		66
563f29dbc25Smrgstatic struct _ffolat ffo6x4ntsc[SIZE6X4NTSC + 1] = {
564f29dbc25Smrg    {541, 0x40}, {545, 0x40}, {549, 0x40}, {553, 0x40},
565f29dbc25Smrg    {557, 0x58}, {561, 0x40}, {565, 0x40}, {569, 0x40},
566f29dbc25Smrg    {573, 0x48}, {577, 0x40}, {581, 0x40}, {585, 0x40},
567f29dbc25Smrg    {589, 0x40}, {593, 0x48}, {597, 0x40}, {601, 0x40},
568f29dbc25Smrg    {605, 0x40}, {609, 0x40}, {613, 0x5b}, {617, 0x48},
569f29dbc25Smrg    {621, 0x60}, {625, 0x48}, {629, 0x48}, {633, 0x40},
570f29dbc25Smrg    {637, 0x5e}, {641, 0x40}, {645, 0x50}, {649, 0x56},
571f29dbc25Smrg    {653, 0x58}, {657, 0x6c}, {661, 0x40}, {665, 0x40},
572f29dbc25Smrg    {669, 0x40}, {673, 0x40}, {677, 0x40}, {681, 0x40},
573f29dbc25Smrg    {685, 0x40}, {689, 0x40}, {693, 0x40}, {697, 0x40},
574f29dbc25Smrg    {701, 0x40}, {705, 0x40}, {709, 0x40}, {713, 0x40},
575f29dbc25Smrg    {717, 0x40}, {721, 0x40}, {725, 0x40}, {729, 0x40},
576f29dbc25Smrg    {733, 0x40}, {737, 0x40}, {741, 0x40}, {745, 0x40},
577f29dbc25Smrg    {749, 0x40}, {753, 0x40}, {757, 0x40}, {761, 0x40},
578f29dbc25Smrg    {765, 0x40}, {769, 0x40}, {773, 0x40}, {777, 0x40},
579f29dbc25Smrg    {781, 0x40}, {785, 0x40}, {789, 0x40}, {793, 0x40},
580f29dbc25Smrg    {797, 0x30}, {801, 0x40},
581f29dbc25Smrg    {-1, 0}
582f29dbc25Smrg};
583f29dbc25Smrg
584f29dbc25Smrg#define SIZE6X4PAL		45
585f29dbc25Smrgstatic struct _ffolat ffo6x4pal[SIZE6X4PAL + 1] = {
586f29dbc25Smrg    {625, 0x60}, {629, 0x60}, {633, 0x60}, {637, 0x60},
587f29dbc25Smrg    {641, 0x50}, {645, 0x60}, {649, 0x60}, {653, 0x60},
588f29dbc25Smrg    {657, 0x60}, {661, 0x60}, {665, 0x60}, {669, 0x60},
589f29dbc25Smrg    {673, 0x60}, {677, 0x60}, {681, 0x60}, {685, 0x60},
590f29dbc25Smrg    {689, 0x60}, {693, 0x60}, {697, 0x60}, {701, 0x60},
591f29dbc25Smrg    {705, 0x60}, {709, 0x60}, {713, 0x60}, {717, 0x60},
592f29dbc25Smrg    {721, 0x60}, {725, 0x60}, {729, 0x60}, {733, 0x60},
593f29dbc25Smrg    {737, 0x60}, {741, 0x60}, {745, 0x60}, {749, 0x60},
594f29dbc25Smrg    {753, 0x60}, {757, 0x60}, {761, 0x60}, {765, 0x60},
595f29dbc25Smrg    {769, 0x60}, {773, 0x60}, {777, 0x60}, {781, 0x60},
596f29dbc25Smrg    {785, 0x60}, {789, 0x60}, {793, 0x60}, {797, 0x60},
597f29dbc25Smrg    {801, 0x60},
598f29dbc25Smrg    {-1, 0}
599f29dbc25Smrg};
600f29dbc25Smrg
601f29dbc25Smrg#define SIZE7X4NTSC		40
602f29dbc25Smrgstatic struct _ffolat ffo7x4ntsc[SIZE7X4NTSC + 1] = {
603f29dbc25Smrg    {525, 0x52}, {529, 0x52}, {533, 0x52}, {537, 0x52},
604f29dbc25Smrg    {541, 0x52}, {545, 0x40}, {549, 0x40}, {553, 0x40},
605f29dbc25Smrg    {557, 0x58}, {561, 0x40}, {565, 0x58}, {569, 0x40},
606f29dbc25Smrg    {573, 0x48}, {577, 0x40}, {581, 0x40}, {585, 0x40},
607f29dbc25Smrg    {589, 0x40}, {593, 0x48}, {597, 0x40}, {601, 0x40},
608f29dbc25Smrg    {605, 0x40}, {609, 0x40}, {613, 0x5b}, {617, 0x48},
609f29dbc25Smrg    {621, 0x60}, {625, 0x48}, {629, 0x48}, {633, 0x40},
610f29dbc25Smrg    {637, 0x5e}, {641, 0x40}, {645, 0x50}, {649, 0x56},
611f29dbc25Smrg    {653, 0x58}, {657, 0x6c}, {661, 0x40}, {665, 0x40},
612f29dbc25Smrg    {669, 0x40}, {673, 0x40}, {677, 0x40}, {681, 0x40},
613f29dbc25Smrg    {-1, 0}
614f29dbc25Smrg};
615f29dbc25Smrg
616f29dbc25Smrg#define SIZE7X4PAL		24
617f29dbc25Smrgstatic struct _ffolat ffo7x4pal[SIZE7X4PAL + 1] = {
618f29dbc25Smrg    {625, 0x60}, {629, 0x60}, {633, 0x60}, {637, 0x60},
619f29dbc25Smrg    {641, 0x50}, {645, 0x60}, {649, 0x60}, {653, 0x60},
620f29dbc25Smrg    {657, 0x60}, {661, 0x60}, {665, 0x60}, {669, 0x60},
621f29dbc25Smrg    {673, 0x60}, {677, 0x60}, {681, 0x60}, {685, 0x60},
622f29dbc25Smrg    {689, 0x60}, {693, 0x60}, {697, 0x60}, {701, 0x60},
623f29dbc25Smrg    {705, 0x60}, {709, 0x60}, {713, 0x60}, {717, 0x60},
624f29dbc25Smrg    {-1, 0}
625f29dbc25Smrg};
626f29dbc25Smrg
627f29dbc25Smrg#define SIZE7X5NTSC		54
628f29dbc25Smrgstatic struct _ffolat ffo7x5ntsc[SIZE7X5NTSC + 1] = {
629f29dbc25Smrg    {590, 0x40}, {594, 0x48}, {598, 0x40}, {602, 0x40},
630f29dbc25Smrg    {606, 0x40}, {610, 0x40}, {614, 0x5b}, {618, 0x48},
631f29dbc25Smrg    {622, 0x60}, {626, 0x48}, {630, 0x48}, {634, 0x40},
632f29dbc25Smrg    {638, 0x5e}, {642, 0x40}, {646, 0x50}, {650, 0x56},
633f29dbc25Smrg    {654, 0x58}, {658, 0x6c}, {662, 0x40}, {666, 0x40},
634f29dbc25Smrg    {670, 0x40}, {674, 0x40}, {678, 0x40}, {682, 0x40},
635f29dbc25Smrg    {686, 0x40}, {690, 0x40}, {694, 0x40}, {698, 0x40},
636f29dbc25Smrg    {702, 0x40}, {706, 0x40}, {710, 0x40}, {714, 0x40},
637f29dbc25Smrg    {718, 0x40}, {722, 0x40}, {726, 0x40}, {730, 0x40},
638f29dbc25Smrg    {734, 0x40}, {738, 0x40}, {742, 0x40}, {746, 0x40},
639f29dbc25Smrg    {750, 0x40}, {754, 0x40}, {758, 0x40}, {762, 0x40},
640f29dbc25Smrg    {766, 0x40}, {770, 0x40}, {774, 0x40}, {778, 0x40},
641f29dbc25Smrg    {782, 0x40}, {786, 0x40}, {790, 0x40}, {794, 0x40},
642f29dbc25Smrg    {798, 0x30}, {802, 0x40},
643f29dbc25Smrg    {-1, 0}
644f29dbc25Smrg};
645f29dbc25Smrg
646f29dbc25Smrg#define SIZE7X5PAL		45
647f29dbc25Smrgstatic struct _ffolat ffo7x5pal[SIZE7X5PAL + 1] = {
648f29dbc25Smrg    {625, 0x60}, {629, 0x60}, {633, 0x60}, {637, 0x60},
649f29dbc25Smrg    {641, 0x50}, {645, 0x60}, {649, 0x60}, {653, 0x60},
650f29dbc25Smrg    {657, 0x60}, {661, 0x60}, {665, 0x60}, {669, 0x60},
651f29dbc25Smrg    {673, 0x60}, {677, 0x60}, {681, 0x60}, {685, 0x60},
652f29dbc25Smrg    {689, 0x60}, {693, 0x60}, {697, 0x60}, {701, 0x60},
653f29dbc25Smrg    {705, 0x60}, {709, 0x60}, {713, 0x60}, {717, 0x60},
654f29dbc25Smrg    {721, 0x60}, {725, 0x60}, {729, 0x60}, {733, 0x60},
655f29dbc25Smrg    {737, 0x60}, {741, 0x60}, {745, 0x60}, {749, 0x60},
656f29dbc25Smrg    {753, 0x60}, {757, 0x60}, {761, 0x60}, {765, 0x60},
657f29dbc25Smrg    {769, 0x60}, {773, 0x60}, {777, 0x60}, {781, 0x60},
658f29dbc25Smrg    {785, 0x60}, {789, 0x60}, {793, 0x60}, {797, 0x60},
659f29dbc25Smrg    {801, 0x60},
660f29dbc25Smrg    {-1, 0}
661f29dbc25Smrg};
662f29dbc25Smrg
663f29dbc25Smrg/* h_total=1056, vga_lines=600 */
664f29dbc25Smrg#define	SIZE8X6NTSC		37
665f29dbc25Smrgstatic struct _ffolat ffo8x6ntsc[SIZE8X6NTSC + 1] = {
66604007ebaSmrg    {620, 0x40},                /* v_total_min >= vsync+10 >= vga_lines+10 = 610 */
667f29dbc25Smrg    {625, 0x58}, {630, 0x40}, {635, 0x40}, {640, 0x40},
668f29dbc25Smrg    {645, 0x46}, {650, 0x46}, {655, 0x4f}, {660, 0x4c},
669f29dbc25Smrg    {665, 0x4a}, {670, 0x50}, {675, 0x2f}, {680, 0x48},
670f29dbc25Smrg    {685, 0x38}, {690, 0x31}, {695, 0x40}, {700, 0x21},
671f29dbc25Smrg    {705, 0x25}, {710, 0x40}, {715, 0x48}, {720, 0x50},
672f29dbc25Smrg    {725, 0x30}, {730, 0x50}, {735, 0x50}, {740, 0x50},
673f29dbc25Smrg    {745, 0x40}, {750, 0x38}, {755, 0x50}, {760, 0x50},
674f29dbc25Smrg    {765, 0x40}, {770, 0x38}, {775, 0x40}, {780, 0x40},
675f29dbc25Smrg    {785, 0x40}, {790, 0x38}, {795, 0x50}, {800, 0x50},
676f29dbc25Smrg    {-1, 0}
677f29dbc25Smrg};
678f29dbc25Smrg
679f29dbc25Smrg/* h_total=1056, vga_lines=600 */
680f29dbc25Smrg#define	SIZE8X6PAL		36
681f29dbc25Smrgstatic struct _ffolat ffo8x6pal[SIZE8X6PAL + 1] = {
682f29dbc25Smrg    {625, 0x80}, {630, 0x80}, {635, 0x5a}, {640, 0x55},
683f29dbc25Smrg    {645, 0x48}, {650, 0x65}, {655, 0x65}, {660, 0x50},
684f29dbc25Smrg    {665, 0x80}, {670, 0x70}, {675, 0x56}, {680, 0x80},
685f29dbc25Smrg    {685, 0x58}, {690, 0x31}, {695, 0x80}, {700, 0x60},
686f29dbc25Smrg    {705, 0x45}, {710, 0x4a}, {715, 0x50}, {720, 0x50},
687f29dbc25Smrg    {725, 0x50}, {730, 0x45}, {735, 0x50}, {740, 0x50},
688f29dbc25Smrg    {745, 0x50}, {750, 0x50}, {755, 0x50}, {760, 0x50},
689f29dbc25Smrg    {765, 0x50}, {770, 0x50}, {775, 0x50}, {780, 0x50},
690f29dbc25Smrg    {785, 0x50}, {790, 0x50}, {795, 0x50}, {800, 0x50},
691f29dbc25Smrg    {-1, 0}
692f29dbc25Smrg};
693f29dbc25Smrg
694f29dbc25Smrg/* h_total=1344, vga_lines=768 */
695f29dbc25Smrg#define	SIZE10X7NTSC		45
696f29dbc25Smrgstatic struct _ffolativo ffo10x7ntsc[SIZE10X7NTSC] = {
697f29dbc25Smrg    {783, 0x4d, 0x40},
698f29dbc25Smrg    {789, 0x47, 0x14},
699f29dbc25Smrg    {795, 0x47, 0x7f},
700f29dbc25Smrg    {801, 0x47, 0x53},
701f29dbc25Smrg    {807, 0x47, 0x11},
702f29dbc25Smrg    {813, 0x47, 0x78},
703f29dbc25Smrg    {819, 0x47, 0x54},
704f29dbc25Smrg    {825, 0x47, 0x40},
705f29dbc25Smrg    {831, 0x47, 0x0f},
706f29dbc25Smrg    {837, 0x4d, 0x40},
707f29dbc25Smrg    {843, 0x47, 0x5a},
708f29dbc25Smrg    {849, 0x4d, 0x40},
709f29dbc25Smrg    {855, 0x47, 0x4b},
710f29dbc25Smrg    {861, 0x4d, 0x40},
711f29dbc25Smrg    {867, 0x47, 0x4b},
712f29dbc25Smrg    {873, 0x4d, 0x40},
713f29dbc25Smrg    {879, 0x47, 0x07},
714f29dbc25Smrg    {885, 0x48, 0x20},
715f29dbc25Smrg    {891, 0x47, 0x82},
716f29dbc25Smrg    {897, 0x47, 0x60},
717f29dbc25Smrg    {903, 0x47, 0x7f},
718f29dbc25Smrg    {909, 0x4d, 0x40},
719f29dbc25Smrg    {915, 0x48, 0x40},
720f29dbc25Smrg    {921, 0x4c, 0x40},
721f29dbc25Smrg    {927, 0x49, 0x40},
722f29dbc25Smrg    {933, 0x48, 0x40},
723f29dbc25Smrg    {939, 0x4a, 0x40},
724f29dbc25Smrg    {945, 0x46, 0x40},
725f29dbc25Smrg    {951, 0x4a, 0x40},
726f29dbc25Smrg    {957, 0x4a, 0x40},
727f29dbc25Smrg    {963, 0x4b, 0x40},
728f29dbc25Smrg    {969, 0x4b, 0x40},
729f29dbc25Smrg    {975, 0x48, 0x40},
730f29dbc25Smrg    {981, 0x47, 0x40},
731f29dbc25Smrg    {987, 0x47, 0x40},
732f29dbc25Smrg    {993, 0x47, 0x40},
733f29dbc25Smrg    {999, 0x48, 0x40},
734f29dbc25Smrg    {1005, 0x48, 0x40},
735f29dbc25Smrg    {1011, 0x47, 0x40},
736f29dbc25Smrg    {1017, 0x47, 0x40},
737f29dbc25Smrg    {1023, 0x48, 0x40},
738f29dbc25Smrg    {1029, 0x48, 0x40},
739f29dbc25Smrg    {1035, 0x46, 0x40},
740f29dbc25Smrg    {1041, 0x47, 0x40},
741f29dbc25Smrg    {1047, 0x47, 0x40}
742f29dbc25Smrg};
743f29dbc25Smrg
744f29dbc25Smrg/* h_total=1344, vga_lines=768 */
745f29dbc25Smrg#define	SIZE10X7PAL		46
746f29dbc25Smrgstatic struct _ffolativo ffo10x7pal[SIZE10X7PAL] = {
747f29dbc25Smrg    {781, 0x49, 0x40},
748f29dbc25Smrg    {787, 0x46, 0x40},
749f29dbc25Smrg    {793, 0x48, 0x40},
750f29dbc25Smrg    {799, 0x46, 0x40},
751f29dbc25Smrg    {805, 0x49, 0x40},
752f29dbc25Smrg    {811, 0x47, 0x40},
753f29dbc25Smrg    {817, 0x46, 0x40},
754f29dbc25Smrg    {823, 0x46, 0x56},
755f29dbc25Smrg    {829, 0x46, 0x2d},
756f29dbc25Smrg    {835, 0x46, 0x40},
757f29dbc25Smrg    {841, 0x46, 0x2d},
758f29dbc25Smrg    {847, 0x46, 0x3f},
759f29dbc25Smrg    {853, 0x46, 0x10},
760f29dbc25Smrg    {859, 0x46, 0x86},
761f29dbc25Smrg    {865, 0x46, 0xc9},
762f29dbc25Smrg    {871, 0x46, 0x83},
763f29dbc25Smrg    {877, 0x46, 0xa8},
764f29dbc25Smrg    {883, 0x46, 0x81},
765f29dbc25Smrg    {889, 0x46, 0xa5},
766f29dbc25Smrg    {895, 0x46, 0xa9},
767f29dbc25Smrg    {901, 0x46, 0x81},
768f29dbc25Smrg    {907, 0x46, 0xa4},
769f29dbc25Smrg    {913, 0x46, 0xa5},
770f29dbc25Smrg    {919, 0x46, 0x7f},
771f29dbc25Smrg    {925, 0x46, 0xa2},
772f29dbc25Smrg    {931, 0x46, 0x9d},
773f29dbc25Smrg    {937, 0x46, 0xc1},
774f29dbc25Smrg    {943, 0x46, 0x96},
775f29dbc25Smrg    {949, 0x46, 0xb7},
776f29dbc25Smrg    {955, 0x46, 0xb1},
777f29dbc25Smrg    {961, 0x46, 0x8a},
778f29dbc25Smrg    {967, 0x46, 0xa9},
779f29dbc25Smrg    {973, 0x46, 0xa0},
780f29dbc25Smrg    {979, 0x46, 0x40},
781f29dbc25Smrg    {985, 0x46, 0x97},
782f29dbc25Smrg    {991, 0x46, 0xb5},
783f29dbc25Smrg    {997, 0x46, 0xaa},
784f29dbc25Smrg    {1003, 0x46, 0x83},
785f29dbc25Smrg    {1009, 0x46, 0x9f},
786f29dbc25Smrg    {1015, 0x47, 0x40},
787f29dbc25Smrg    {1021, 0x46, 0xad},
788f29dbc25Smrg    {1027, 0x46, 0x87},
789f29dbc25Smrg    {1033, 0x46, 0xa2},
790f29dbc25Smrg    {1039, 0x47, 0x40},
791f29dbc25Smrg    {1045, 0x46, 0xac},
792f29dbc25Smrg    {1051, 0x46, 0x86}
793f29dbc25Smrg};
794f29dbc25Smrg
795f29dbc25Smrg/*==========================================================================*/
796f29dbc25Smrg/*FS450 API Functions.														*/
797f29dbc25Smrg/*==========================================================================*/
798f29dbc25Smrg
799f29dbc25Smrg/* Initialize device settings */
800f29dbc25Smrgstatic void
801f29dbc25Smrginitialize_houston_static_registers(void)
802f29dbc25Smrg{
803f29dbc25Smrg    houston_WriteReg(HOUSTON_BYP, 0, 2);
804f29dbc25Smrg    houston_WriteReg(HOUSTON_APO, 0, 2);
805f29dbc25Smrg    houston_WriteReg(HOUSTON_ALO, 0, 2);
806f29dbc25Smrg    houston_WriteReg(HOUSTON_AFO, 0, 2);
807f29dbc25Smrg    houston_WriteReg(HOUSTON_BCONTL, 0, 2);
808f29dbc25Smrg    houston_WriteReg(HOUSTON_BCONTH, 0, 2);
809f29dbc25Smrg    houston_WriteReg(HOUSTON_BDONE, 0, 2);
810f29dbc25Smrg    houston_WriteReg(HOUSTON_BDIAGL, 0, 2);
811f29dbc25Smrg    houston_WriteReg(HOUSTON_BDIAGH, 0, 2);
812f29dbc25Smrg    houston_WriteReg(HOUSTON_MISC, 0, 2);
813f29dbc25Smrg}
814f29dbc25Smrg
815f29dbc25Smrgint
816f29dbc25SmrgFS450_init(void)
817f29dbc25Smrg{
818f29dbc25Smrg    int err;
819f29dbc25Smrg
820f29dbc25Smrg    TRACE(("FS450_Init()\n"))
821f29dbc25Smrg
822f29dbc25Smrg        err = houston_init();
823f29dbc25Smrg    if (err)
824f29dbc25Smrg        return err;
825f29dbc25Smrg
826f29dbc25Smrg    initialize_houston_static_registers();
827f29dbc25Smrg
828f29dbc25Smrg    d.tv_on = PLAL_IsTVOn()? 1 : 0;
829f29dbc25Smrg
830f29dbc25Smrg    /* get the current tv standard */
831f29dbc25Smrg    conget_tv_std(&d.tv_std);
832f29dbc25Smrg
833f29dbc25Smrg    d.vga_mode = 0;
834f29dbc25Smrg
835f29dbc25Smrg    /* default to VP_TVOUT_MODE_CVBS_YC */
836f29dbc25Smrg    d.tvout_mode = GFX_TVOUT_MODE_CVBS_YC;
837f29dbc25Smrg
838f29dbc25Smrg    /* default to 1000 out of 1000 */
839f29dbc25Smrg    d.sharpness = 1000;
840f29dbc25Smrg    config_sharpness(d.sharpness);
841f29dbc25Smrg
842f29dbc25Smrg    /* default to 800 out of 1000 */
843f29dbc25Smrg    d.flicker = 800;
844f29dbc25Smrg    config_flicker(d.flicker);
845f29dbc25Smrg
846f29dbc25Smrg    /* default to zeros */
847f29dbc25Smrg    d.overscan_x = 0;
848f29dbc25Smrg    d.overscan_y = 0;
849f29dbc25Smrg    d.position_x = 0;
850f29dbc25Smrg    d.position_y = 0;
851f29dbc25Smrg
852f29dbc25Smrg    d.color = 50;
853f29dbc25Smrg    /* d.color = tvsetup.color[k]; */
854f29dbc25Smrg    config_color(d.color);
855f29dbc25Smrg
856f29dbc25Smrg    /* default */
857f29dbc25Smrg    d.brightness = 50;
858f29dbc25Smrg    d.contrast = 60;
859f29dbc25Smrg    config_brightness_contrast(d.tv_std, d.aps_trigger_bits, d.brightness,
86004007ebaSmrg                               d.contrast);
861f29dbc25Smrg
862f29dbc25Smrg    /* get the current yc filtering */
863f29dbc25Smrg    {
864f29dbc25Smrg        int luma_filter, chroma_filter;
865f29dbc25Smrg
866f29dbc25Smrg        conget_yc_filter(&luma_filter, &chroma_filter);
867f29dbc25Smrg        d.yc_filter = 0;
868f29dbc25Smrg        if (luma_filter)
869f29dbc25Smrg            d.yc_filter |= GFX_LUMA_FILTER;
870f29dbc25Smrg        if (chroma_filter)
871f29dbc25Smrg            d.yc_filter |= GFX_CHROMA_FILTER;
872f29dbc25Smrg    }
873f29dbc25Smrg
874f29dbc25Smrg    d.aps_trigger_bits = 0;
875f29dbc25Smrg    config_macrovision(d.tv_std, d.aps_trigger_bits);
876f29dbc25Smrg
877f29dbc25Smrg    d.last_overscan_y = -10000;
878f29dbc25Smrg
879f29dbc25Smrg    return 0;
880f29dbc25Smrg}
881f29dbc25Smrg
882f29dbc25Smrgvoid
883f29dbc25SmrgFS450_cleanup(void)
884f29dbc25Smrg{
885f29dbc25Smrg}
886f29dbc25Smrg
887f29dbc25Smrg/*==========================================================================*/
888f29dbc25Smrg/* Required configuration calls to write new settings to the device			*/
889f29dbc25Smrg/*==========================================================================*/
890f29dbc25Smrg
891f29dbc25Smrg#define REQ_TV_STANDARD_BIT			0x0002
892f29dbc25Smrg#define REQ_VGA_MODE_BIT			0x0004
893f29dbc25Smrg#define REQ_TVOUT_MODE_BIT			0x0008
894f29dbc25Smrg#define REQ_SHARPNESS_BIT			0x0010
895f29dbc25Smrg#define REQ_FLICKER_BIT				0x0020
896f29dbc25Smrg#define REQ_OVERSCAN_POSITION_BIT	0x0040
897f29dbc25Smrg#define REQ_COLOR_BIT				0x0080
898f29dbc25Smrg#define REQ_BRIGHTNESS_CONTRAST_BIT 0x0100
899f29dbc25Smrg#define REQ_YC_FILTER_BIT			0x0200
900f29dbc25Smrg#define REQ_MACROVISION_BIT			0x0400
901f29dbc25Smrg#define REQ_NCO_BIT					0x1000
902f29dbc25Smrg
903f29dbc25Smrg#define REQ_TV_STANDARD			(REQ_TV_STANDARD_BIT | REQ_OVERSCAN_POSITION \
904f29dbc25Smrg									| REQ_BRIGHTNESS_CONTRAST 				 \
905f29dbc25Smrg									| REQ_MACROVISION_BIT | REQ_YC_FILTER)
906f29dbc25Smrg#define REQ_VGA_MODE			(REQ_VGA_MODE_BIT | REQ_OVERSCAN_POSITION)
907f29dbc25Smrg#define REQ_TVOUT_MODE			(REQ_TVOUT_MODE_BIT)
908f29dbc25Smrg#define REQ_SHARPNESS			(REQ_SHARPNESS_BIT)
909f29dbc25Smrg#define REQ_FLICKER				(REQ_FLICKER_BIT)
910f29dbc25Smrg#define REQ_OVERSCAN_POSITION	(REQ_OVERSCAN_POSITION_BIT | REQ_NCO)
911f29dbc25Smrg#define REQ_COLOR				(REQ_COLOR_BIT)
912f29dbc25Smrg#define REQ_BRIGHTNESS_CONTRAST	(REQ_BRIGHTNESS_CONTRAST_BIT)
913f29dbc25Smrg#define REQ_YC_FILTER			(REQ_YC_FILTER_BIT)
914f29dbc25Smrg#define REQ_MACROVISION			(REQ_TV_STANDARD_BIT | 						 \
915f29dbc25Smrg									REQ_BRIGHTNESS_CONTRAST_BIT | 			 \
916f29dbc25Smrg									REQ_MACROVISION_BIT)
917f29dbc25Smrg#define REQ_NCO					(REQ_NCO_BIT)
918f29dbc25Smrg#define REQ_ENCODER				(REQ_TV_STANDARD | REQ_COLOR | 				 \
919f29dbc25Smrg									REQ_BRIGHTNESS_CONTRAST | REQ_YC_FILTER)
920f29dbc25Smrg
921f29dbc25Smrgstatic int
922f29dbc25Smrgwrite_config(int req)
923f29dbc25Smrg{
924f29dbc25Smrg    unsigned long reg, reg_encoder_reset = 0;
925f29dbc25Smrg    int reset;
926f29dbc25Smrg
927f29dbc25Smrg    /*if we're changing the nco, and the vertical scaling has changed... */
928f29dbc25Smrg    reset = ((REQ_NCO_BIT & req) && (d.overscan_y != d.last_overscan_y));
929f29dbc25Smrg    if (reset) {
930f29dbc25Smrg        /*put the encoder into reset while making changes */
931f29dbc25Smrg        houston_ReadReg(ENC_RESET, &reg, 1);
932f29dbc25Smrg        houston_WriteReg(ENC_RESET, reg | 0x01, 1);
933f29dbc25Smrg        reg_encoder_reset = reg & 0x01;
934f29dbc25Smrg    }
935f29dbc25Smrg
936f29dbc25Smrg    if (REQ_TV_STANDARD_BIT & req)
937f29dbc25Smrg        config_tv_std(d.tv_std, d.aps_trigger_bits);
938f29dbc25Smrg
939f29dbc25Smrg    if (REQ_VGA_MODE_BIT & req)
940f29dbc25Smrg        config_vga_mode(d.vga_mode);
941f29dbc25Smrg
942f29dbc25Smrg    if (REQ_TVOUT_MODE_BIT & req)
943f29dbc25Smrg        config_tvout_mode(d.tvout_mode);
944f29dbc25Smrg
945f29dbc25Smrg    if (REQ_OVERSCAN_POSITION_BIT & req) {
946f29dbc25Smrg        config_overscan_xy(d.tv_std,
94704007ebaSmrg                           d.vga_mode,
94804007ebaSmrg                           d.overscan_x, d.overscan_y, d.position_x,
94904007ebaSmrg                           d.position_y);
950f29dbc25Smrg
951f29dbc25Smrg        /*h_timing and v_timing and syncs. */
952f29dbc25Smrg        if (PLAL_IsTVOn())
953f29dbc25Smrg            PLAL_SetTVTimingRegisters(p_specs());
954f29dbc25Smrg    }
955f29dbc25Smrg
956f29dbc25Smrg    if (REQ_NCO_BIT & req)
957f29dbc25Smrg        config_nco(d.tv_std, d.vga_mode);
958f29dbc25Smrg
959f29dbc25Smrg    if (REQ_SHARPNESS_BIT & req)
960f29dbc25Smrg        config_sharpness(d.sharpness);
961f29dbc25Smrg
962f29dbc25Smrg    if (REQ_FLICKER_BIT & req)
963f29dbc25Smrg        config_flicker(d.flicker);
964f29dbc25Smrg
965f29dbc25Smrg    if (REQ_COLOR_BIT & req)
966f29dbc25Smrg        config_color(d.color);
967f29dbc25Smrg
968f29dbc25Smrg    if (REQ_BRIGHTNESS_CONTRAST_BIT & req) {
969f29dbc25Smrg        config_brightness_contrast(d.tv_std,
97004007ebaSmrg                                   d.aps_trigger_bits, d.brightness,
97104007ebaSmrg                                   d.contrast);
972f29dbc25Smrg    }
973f29dbc25Smrg
974f29dbc25Smrg    if (REQ_YC_FILTER_BIT & req) {
975f29dbc25Smrg        config_yc_filter(d.tv_std,
97604007ebaSmrg                         (d.yc_filter & GFX_LUMA_FILTER),
97704007ebaSmrg                         (d.yc_filter & GFX_CHROMA_FILTER));
978f29dbc25Smrg    }
979f29dbc25Smrg
980f29dbc25Smrg    if (REQ_MACROVISION_BIT & req)
981f29dbc25Smrg        config_macrovision(d.tv_std, d.aps_trigger_bits);
982f29dbc25Smrg
983f29dbc25Smrg    /*if we decided to put the encoder into reset, put it back */
984f29dbc25Smrg    if (reset) {
985f29dbc25Smrg        houston_ReadReg(ENC_RESET, &reg, 1);
986f29dbc25Smrg        houston_WriteReg(ENC_RESET, reg_encoder_reset | (reg & ~0x01), 1);
987f29dbc25Smrg
988f29dbc25Smrg        d.last_overscan_y = d.overscan_y;
989f29dbc25Smrg    }
990f29dbc25Smrg    return 0;
991f29dbc25Smrg}
992f29dbc25Smrg
993f29dbc25Smrg/*==========================================================================*/
994f29dbc25Smrg/* TV On																	*/
995f29dbc25Smrg/*==========================================================================*/
996f29dbc25Smrg
997f29dbc25Smrg#if GFX_TV_DYNAMIC
998f29dbc25Smrgint
999f29dbc25Smrgfs450_get_tv_enable(unsigned int *p_on)
1000f29dbc25Smrg#else
1001f29dbc25Smrgint
1002f29dbc25Smrggfx_get_tv_enable(unsigned int *p_on)
1003f29dbc25Smrg#endif
1004f29dbc25Smrg{
1005f29dbc25Smrg    if (!p_on)
1006f29dbc25Smrg        return ERR_INVALID_PARAMETER;
1007f29dbc25Smrg
1008f29dbc25Smrg    *p_on = d.tv_on;
1009f29dbc25Smrg
1010f29dbc25Smrg    return 0;
1011f29dbc25Smrg}
1012f29dbc25Smrg
1013f29dbc25Smrg/*//int FS450_set_tv_on(unsigned int on)*/
1014f29dbc25Smrg#if GFX_TV_DYNAMIC
1015f29dbc25Smrgint
1016f29dbc25Smrgfs450_set_tv_enable(int on)
1017f29dbc25Smrg#else
1018f29dbc25Smrgint
1019f29dbc25Smrggfx_set_tv_enable(int on)
1020f29dbc25Smrg#endif
1021f29dbc25Smrg{
1022f29dbc25Smrg    unsigned long reg;
1023f29dbc25Smrg
1024f29dbc25Smrg    /*if not mode change, just return */
1025f29dbc25Smrg    if ((d.tv_on && on) || (!d.tv_on && !on))
1026f29dbc25Smrg        return 0;
1027f29dbc25Smrg
1028f29dbc25Smrg    /*if turning off... */
1029f29dbc25Smrg    if (!on) {
103079d5fcd7Smrg        /*re-enable vga. */
1031f29dbc25Smrg        PLAL_EnableVga();
1032f29dbc25Smrg
1033f29dbc25Smrg        /*power down houston */
1034f29dbc25Smrg        config_power(0);
1035f29dbc25Smrg
1036f29dbc25Smrg        d.tv_on = 0;
1037f29dbc25Smrg
1038f29dbc25Smrg        return 0;
1039f29dbc25Smrg    }
1040f29dbc25Smrg
1041f29dbc25Smrg    /*turning on... */
1042f29dbc25Smrg
1043f29dbc25Smrg    /*power up houston      */
1044f29dbc25Smrg    config_power(1);
1045f29dbc25Smrg
1046f29dbc25Smrg    /*assert encoder reset. */
1047f29dbc25Smrg    houston_WriteReg(ENC_RESET, 0x01, 1);
1048f29dbc25Smrg
1049f29dbc25Smrg    /*initial platform preparation */
1050f29dbc25Smrg    PLAL_PrepForTVout();
1051f29dbc25Smrg
1052f29dbc25Smrg    /*configure encoder and nco. */
1053f29dbc25Smrg    write_config(REQ_VGA_MODE |
105404007ebaSmrg                 REQ_TV_STANDARD |
105504007ebaSmrg                 REQ_TVOUT_MODE |
105604007ebaSmrg                 REQ_OVERSCAN_POSITION | REQ_YC_FILTER | REQ_MACROVISION);
1057f29dbc25Smrg
1058f29dbc25Smrg    /*set LP_EN and UIM */
1059f29dbc25Smrg    houston_ReadReg(HOUSTON_CR, &reg, 2);
1060f29dbc25Smrg    reg |= CR_LP_EN;
1061f29dbc25Smrg    reg &= ~(CR_UIM_MOD0 | CR_UIM_MOD1);
1062f29dbc25Smrg    reg |= (PLAL_FS450_UIM_mode() << 14);
1063f29dbc25Smrg    houston_WriteReg(HOUSTON_CR, reg, 2);
1064f29dbc25Smrg
1065f29dbc25Smrg    /*set platform timing registers */
1066f29dbc25Smrg    PLAL_SetTVTimingRegisters(p_specs());
1067f29dbc25Smrg
1068f29dbc25Smrg    PLAL_FinalEnableTVout(d.vga_mode);
1069f29dbc25Smrg
1070f29dbc25Smrg    /*sync bridge */
1071f29dbc25Smrg    {
1072f29dbc25Smrg        int retry_count = 0;
1073f29dbc25Smrg
1074f29dbc25Smrg        /*sync 50 times */
1075f29dbc25Smrg        while (retry_count++ < 50) {
1076f29dbc25Smrg            /*sync bridge. */
1077f29dbc25Smrg            houston_ReadReg(HOUSTON_MISC, &reg, 2);
1078f29dbc25Smrg            reg |= MISC_BRIDGE_SYNC;
1079f29dbc25Smrg            houston_WriteReg(HOUSTON_MISC, reg, 2);
1080f29dbc25Smrg            reg &= ~MISC_BRIDGE_SYNC;
1081f29dbc25Smrg            houston_WriteReg(HOUSTON_MISC, reg, 2);
1082f29dbc25Smrg        }
1083f29dbc25Smrg    }
1084f29dbc25Smrg
1085f29dbc25Smrg    /*deassert encoder reset. */
1086f29dbc25Smrg    houston_WriteReg(ENC_RESET, 0x00, 1);
1087f29dbc25Smrg
1088f29dbc25Smrg    d.tv_on = 1;
1089f29dbc25Smrg
1090f29dbc25Smrg    return 0;
1091f29dbc25Smrg}
1092f29dbc25Smrg
1093f29dbc25Smrg#if GFX_TV_DYNAMIC
1094f29dbc25Smrgint
1095f29dbc25Smrgfs450_set_tv_defaults(int format)
1096f29dbc25Smrg#else
1097f29dbc25Smrgint
1098f29dbc25Smrggfx_set_tv_defaults(int format)
1099f29dbc25Smrg#endif
1100f29dbc25Smrg{
1101f29dbc25Smrg    return 0;
1102f29dbc25Smrg}
1103f29dbc25Smrg
1104f29dbc25Smrg/*==========================================================================*/
1105f29dbc25Smrg/* TV standard																*/
1106f29dbc25Smrg/*==========================================================================*/
1107f29dbc25Smrg
1108f29dbc25Smrg#if GFX_TV_DYNAMIC
1109f29dbc25Smrgint
1110f29dbc25Smrgfs450_get_tv_standard(unsigned long *p_standard)
1111f29dbc25Smrg#else
1112f29dbc25Smrgint
1113f29dbc25Smrggfx_get_tv_standard(unsigned long *p_standard)
1114f29dbc25Smrg#endif
1115f29dbc25Smrg{
1116f29dbc25Smrg    if (!p_standard)
1117f29dbc25Smrg        return ERR_INVALID_PARAMETER;
1118f29dbc25Smrg
1119f29dbc25Smrg    *p_standard = d.tv_std;
1120f29dbc25Smrg
1121f29dbc25Smrg    return 0;
1122f29dbc25Smrg}
1123f29dbc25Smrg
1124f29dbc25Smrg#if GFX_TV_DYNAMIC
1125f29dbc25Smrgint
1126f29dbc25Smrgfs450_get_available_tv_standards(unsigned long *p_standards)
1127f29dbc25Smrg#else
1128f29dbc25Smrgint
1129f29dbc25Smrggfx_get_available_tv_standards(unsigned long *p_standards)
1130f29dbc25Smrg#endif
1131f29dbc25Smrg{
1132f29dbc25Smrg    if (!p_standards)
1133f29dbc25Smrg        return ERR_INVALID_PARAMETER;
1134f29dbc25Smrg
1135f29dbc25Smrg    *p_standards = supported_standards();
1136f29dbc25Smrg
1137f29dbc25Smrg    return 0;
1138f29dbc25Smrg}
1139f29dbc25Smrg
1140f29dbc25Smrg#if GFX_TV_DYNAMIC
1141f29dbc25Smrgint
1142f29dbc25Smrgfs450_set_tv_standard(unsigned long standard)
1143f29dbc25Smrg#else
1144f29dbc25Smrgint
1145f29dbc25Smrggfx_set_tv_standard(unsigned long standard)
1146f29dbc25Smrg#endif
1147f29dbc25Smrg{
1148f29dbc25Smrg    /* verify supported standard. */
1149f29dbc25Smrg    if (!(standard & supported_standards()))
1150f29dbc25Smrg        return ERR_INVALID_PARAMETER;
1151f29dbc25Smrg
1152f29dbc25Smrg    /* disallow if tv is on */
1153f29dbc25Smrg    if (d.tv_on)
1154f29dbc25Smrg        return ERR_CANNOT_CHANGE_WHILE_TV_ON;
1155f29dbc25Smrg
1156f29dbc25Smrg    d.tv_std = standard;
1157f29dbc25Smrg    /* d.color = tvsetup.color[k]; */
1158f29dbc25Smrg
1159f29dbc25Smrg    return write_config(REQ_TV_STANDARD);
1160f29dbc25Smrg}
1161f29dbc25Smrg
1162f29dbc25Smrg/*==========================================================================*/
1163f29dbc25Smrg/* vga mode as known by the driver											*/
1164f29dbc25Smrg/*==========================================================================*/
1165f29dbc25Smrg
1166f29dbc25Smrg#if GFX_TV_DYNAMIC
1167f29dbc25Smrgint
1168f29dbc25Smrgfs450_get_tv_vga_mode(unsigned long *p_vga_mode)
1169f29dbc25Smrg#else
1170f29dbc25Smrgint
1171f29dbc25Smrggfx_get_tv_vga_mode(unsigned long *p_vga_mode)
1172f29dbc25Smrg#endif
1173f29dbc25Smrg{
1174f29dbc25Smrg    if (!p_vga_mode)
1175f29dbc25Smrg        return ERR_INVALID_PARAMETER;
1176f29dbc25Smrg
1177f29dbc25Smrg    *p_vga_mode = d.vga_mode;
1178f29dbc25Smrg
1179f29dbc25Smrg    return 0;
1180f29dbc25Smrg}
1181f29dbc25Smrg
1182f29dbc25Smrg#if GFX_TV_DYNAMIC
1183f29dbc25Smrgint
1184f29dbc25Smrgfs450_get_available_tv_vga_modes(unsigned long *p_vga_modes)
1185f29dbc25Smrg#else
1186f29dbc25Smrgint
1187f29dbc25Smrggfx_get_available_tv_vga_modes(unsigned long *p_vga_modes)
1188f29dbc25Smrg#endif
1189f29dbc25Smrg{
1190f29dbc25Smrg    if (!p_vga_modes)
1191f29dbc25Smrg        return ERR_INVALID_PARAMETER;
1192f29dbc25Smrg
1193f29dbc25Smrg    *p_vga_modes =
1194f29dbc25Smrg        GFX_VGA_MODE_640X480 |
1195f29dbc25Smrg        GFX_VGA_MODE_720X487 | GFX_VGA_MODE_720X576 | GFX_VGA_MODE_800X600;
1196f29dbc25Smrg    if (houston_Rev() >= HOUSTON_REV_B)
1197f29dbc25Smrg        *p_vga_modes |= GFX_VGA_MODE_1024X768;
1198f29dbc25Smrg
1199f29dbc25Smrg    return 0;
1200f29dbc25Smrg}
1201f29dbc25Smrg
1202f29dbc25Smrg#if GFX_TV_DYNAMIC
1203f29dbc25Smrgint
1204f29dbc25Smrgfs450_set_tv_vga_mode(unsigned long vga_mode)
1205f29dbc25Smrg#else
1206f29dbc25Smrgint
1207f29dbc25Smrggfx_set_tv_vga_mode(unsigned long vga_mode)
1208f29dbc25Smrg#endif
1209f29dbc25Smrg{
1210f29dbc25Smrg    /*reject if not a single valid VGA mode */
1211f29dbc25Smrg    switch (vga_mode) {
1212f29dbc25Smrg    default:
1213f29dbc25Smrg        return ERR_INVALID_PARAMETER;
1214f29dbc25Smrg    case GFX_VGA_MODE_640X480:
1215f29dbc25Smrg    case GFX_VGA_MODE_720X487:
1216f29dbc25Smrg    case GFX_VGA_MODE_720X576:
1217f29dbc25Smrg    case GFX_VGA_MODE_800X600:
1218f29dbc25Smrg        break;
1219f29dbc25Smrg    case GFX_VGA_MODE_1024X768:
1220f29dbc25Smrg        if (houston_Rev() >= HOUSTON_REV_B)
1221f29dbc25Smrg            break;
1222f29dbc25Smrg        return ERR_INVALID_PARAMETER;
1223f29dbc25Smrg    }
1224f29dbc25Smrg
1225f29dbc25Smrg    /*if the mode has changed... */
1226f29dbc25Smrg    if (vga_mode != d.vga_mode) {
1227f29dbc25Smrg        d.vga_mode = vga_mode;
1228f29dbc25Smrg
1229f29dbc25Smrg        return write_config(REQ_VGA_MODE);
1230f29dbc25Smrg    }
1231f29dbc25Smrg
1232f29dbc25Smrg    return 0;
1233f29dbc25Smrg}
1234f29dbc25Smrg
1235f29dbc25Smrg/*==========================================================================*/
1236f29dbc25Smrg/* tvout mode																*/
1237f29dbc25Smrg/*==========================================================================*/
1238f29dbc25Smrg
1239f29dbc25Smrg#if GFX_TV_DYNAMIC
1240f29dbc25Smrgint
1241f29dbc25Smrgfs450_get_tvout_mode(unsigned long *p_tvout_mode)
1242f29dbc25Smrg#else
1243f29dbc25Smrgint
1244f29dbc25Smrggfx_get_tvout_mode(unsigned long *p_tvout_mode)
1245f29dbc25Smrg#endif
1246f29dbc25Smrg{
1247f29dbc25Smrg    if (!p_tvout_mode)
1248f29dbc25Smrg        return ERR_INVALID_PARAMETER;
1249f29dbc25Smrg
1250f29dbc25Smrg    *p_tvout_mode = d.tvout_mode;
1251f29dbc25Smrg
1252f29dbc25Smrg    return 0;
1253f29dbc25Smrg}
1254f29dbc25Smrg
1255f29dbc25Smrg#if GFX_TV_DYNAMIC
1256f29dbc25Smrgint
1257f29dbc25Smrgfs450_set_tvout_mode(unsigned long tvout_mode)
1258f29dbc25Smrg#else
1259f29dbc25Smrgint
1260f29dbc25Smrggfx_set_tvout_mode(unsigned long tvout_mode)
1261f29dbc25Smrg#endif
1262f29dbc25Smrg{
1263f29dbc25Smrg    d.tvout_mode = tvout_mode;
1264f29dbc25Smrg
1265f29dbc25Smrg    return write_config(REQ_TVOUT_MODE);
1266f29dbc25Smrg}
1267f29dbc25Smrg
1268f29dbc25Smrg/*==========================================================================*/
1269f29dbc25Smrg/* Sharpness																*/
1270f29dbc25Smrg/*==========================================================================*/
1271f29dbc25Smrg
1272f29dbc25Smrg#if GFX_TV_DYNAMIC
1273f29dbc25Smrgint
1274f29dbc25Smrgfs450_get_sharpness(int *p_sharpness)
1275f29dbc25Smrg#else
1276f29dbc25Smrgint
1277f29dbc25Smrggfx_get_sharpness(int *p_sharpness)
1278f29dbc25Smrg#endif
1279f29dbc25Smrg{
1280f29dbc25Smrg    if (!p_sharpness)
1281f29dbc25Smrg        return ERR_INVALID_PARAMETER;
1282f29dbc25Smrg
1283f29dbc25Smrg    *p_sharpness = d.sharpness;
1284f29dbc25Smrg
1285f29dbc25Smrg    return 0;
1286f29dbc25Smrg}
1287f29dbc25Smrg
1288f29dbc25Smrg#if GFX_TV_DYNAMIC
1289f29dbc25Smrgint
1290f29dbc25Smrgfs450_set_sharpness(int sharpness)
1291f29dbc25Smrg#else
1292f29dbc25Smrgint
1293f29dbc25Smrggfx_set_sharpness(int sharpness)
1294f29dbc25Smrg#endif
1295f29dbc25Smrg{
1296f29dbc25Smrg    d.sharpness = range_limit(sharpness, 0, 1000);
1297f29dbc25Smrg
1298f29dbc25Smrg    return write_config(REQ_SHARPNESS);
1299f29dbc25Smrg}
1300f29dbc25Smrg
1301f29dbc25Smrg/*==========================================================================*/
1302f29dbc25Smrg/* flicker filter control.													*/
1303f29dbc25Smrg/*==========================================================================*/
1304f29dbc25Smrg
1305f29dbc25Smrg#if GFX_TV_DYNAMIC
1306f29dbc25Smrgint
1307f29dbc25Smrgfs450_get_flicker_filter(int *p_flicker)
1308f29dbc25Smrg#else
1309f29dbc25Smrgint
1310f29dbc25Smrggfx_get_flicker_filter(int *p_flicker)
1311f29dbc25Smrg#endif
1312f29dbc25Smrg{
1313f29dbc25Smrg    if (!p_flicker)
1314f29dbc25Smrg        return ERR_INVALID_PARAMETER;
1315f29dbc25Smrg
1316f29dbc25Smrg    *p_flicker = d.flicker;
1317f29dbc25Smrg
1318f29dbc25Smrg    return 0;
1319f29dbc25Smrg}
1320f29dbc25Smrg
1321f29dbc25Smrg#if GFX_TV_DYNAMIC
1322f29dbc25Smrgint
1323f29dbc25Smrgfs450_set_flicker_filter(int flicker)
1324f29dbc25Smrg#else
1325f29dbc25Smrgint
1326f29dbc25Smrggfx_set_flicker_filter(int flicker)
1327f29dbc25Smrg#endif
1328f29dbc25Smrg{
1329f29dbc25Smrg    d.flicker = range_limit(flicker, 0, 1000);
1330f29dbc25Smrg
1331f29dbc25Smrg    return write_config(REQ_FLICKER);
1332f29dbc25Smrg}
1333f29dbc25Smrg
1334f29dbc25Smrg/*==========================================================================*/
1335f29dbc25Smrg/* Overscan and Position													*/
1336f29dbc25Smrg/*==========================================================================*/
1337f29dbc25Smrg
1338f29dbc25Smrg#if GFX_TV_DYNAMIC
1339f29dbc25Smrgint
1340f29dbc25Smrgfs450_get_overscan(int *p_x, int *p_y)
1341f29dbc25Smrg#else
1342f29dbc25Smrgint
1343f29dbc25Smrggfx_get_overscan(int *p_x, int *p_y)
1344f29dbc25Smrg#endif
1345f29dbc25Smrg{
1346f29dbc25Smrg    if (!p_x || !p_y)
1347f29dbc25Smrg        return ERR_INVALID_PARAMETER;
1348f29dbc25Smrg
1349f29dbc25Smrg    *p_x = d.overscan_x;
1350f29dbc25Smrg    *p_y = d.overscan_y;
1351f29dbc25Smrg
1352f29dbc25Smrg    return 0;
1353f29dbc25Smrg}
1354f29dbc25Smrg
1355f29dbc25Smrg#if GFX_TV_DYNAMIC
1356f29dbc25Smrgint
1357f29dbc25Smrgfs450_set_overscan(int x, int y)
1358f29dbc25Smrg#else
1359f29dbc25Smrgint
1360f29dbc25Smrggfx_set_overscan(int x, int y)
1361f29dbc25Smrg#endif
1362f29dbc25Smrg{
1363f29dbc25Smrg    d.overscan_x = range_limit(x, -1000, 1000);
1364f29dbc25Smrg    d.overscan_y = range_limit(y, -1000, 1000);
1365f29dbc25Smrg
1366f29dbc25Smrg    return write_config(REQ_OVERSCAN_POSITION);
1367f29dbc25Smrg}
1368f29dbc25Smrg
1369f29dbc25Smrg#if GFX_TV_DYNAMIC
1370f29dbc25Smrgint
1371f29dbc25Smrgfs450_get_position(int *p_x, int *p_y)
1372f29dbc25Smrg#else
1373f29dbc25Smrgint
1374f29dbc25Smrggfx_get_position(int *p_x, int *p_y)
1375f29dbc25Smrg#endif
1376f29dbc25Smrg{
1377f29dbc25Smrg    if (!p_x || !p_y)
1378f29dbc25Smrg        return ERR_INVALID_PARAMETER;
1379f29dbc25Smrg
1380f29dbc25Smrg    *p_x = d.position_x;
1381f29dbc25Smrg    *p_y = d.position_y;
1382f29dbc25Smrg
1383f29dbc25Smrg    return 0;
1384f29dbc25Smrg}
1385f29dbc25Smrg
1386f29dbc25Smrg#if GFX_TV_DYNAMIC
1387f29dbc25Smrgint
1388f29dbc25Smrgfs450_set_position(int x, int y)
1389f29dbc25Smrg#else
1390f29dbc25Smrgint
1391f29dbc25Smrggfx_set_position(int x, int y)
1392f29dbc25Smrg#endif
1393f29dbc25Smrg{
1394f29dbc25Smrg    d.position_x = range_limit(x, -1000, 1000);
1395f29dbc25Smrg    d.position_y = range_limit(y, -1000, 1000);
1396f29dbc25Smrg
1397f29dbc25Smrg    return write_config(REQ_OVERSCAN_POSITION);
1398f29dbc25Smrg}
1399f29dbc25Smrg
1400f29dbc25Smrg/*==========================================================================*/
1401f29dbc25Smrg/* Color, Brightness, and Contrast											*/
1402f29dbc25Smrg/*==========================================================================*/
1403f29dbc25Smrg
1404f29dbc25Smrg#if GFX_TV_DYNAMIC
1405f29dbc25Smrgint
1406f29dbc25Smrgfs450_get_color(int *p_color)
1407f29dbc25Smrg#else
1408f29dbc25Smrgint
1409f29dbc25Smrggfx_get_color(int *p_color)
1410f29dbc25Smrg#endif
1411f29dbc25Smrg{
1412f29dbc25Smrg    if (!p_color)
1413f29dbc25Smrg        return ERR_INVALID_PARAMETER;
1414f29dbc25Smrg
1415f29dbc25Smrg    *p_color = d.color;
1416f29dbc25Smrg
1417f29dbc25Smrg    return 0;
1418f29dbc25Smrg}
1419f29dbc25Smrg
1420f29dbc25Smrg#if GFX_TV_DYNAMIC
1421f29dbc25Smrgint
1422f29dbc25Smrgfs450_set_color(int color)
1423f29dbc25Smrg#else
1424f29dbc25Smrgint
1425f29dbc25Smrggfx_set_color(int color)
1426f29dbc25Smrg#endif
1427f29dbc25Smrg{
1428f29dbc25Smrg    d.color = range_limit(color, 0, 100);
1429f29dbc25Smrg
1430f29dbc25Smrg    return write_config(REQ_COLOR);
1431f29dbc25Smrg}
1432f29dbc25Smrg
1433f29dbc25Smrg#if GFX_TV_DYNAMIC
1434f29dbc25Smrgint
1435f29dbc25Smrgfs450_get_brightness(int *p_brightness)
1436f29dbc25Smrg#else
1437f29dbc25Smrgint
1438f29dbc25Smrggfx_get_brightness(int *p_brightness)
1439f29dbc25Smrg#endif
1440f29dbc25Smrg{
1441f29dbc25Smrg    if (!p_brightness)
1442f29dbc25Smrg        return ERR_INVALID_PARAMETER;
1443f29dbc25Smrg
1444f29dbc25Smrg    *p_brightness = d.brightness;
1445f29dbc25Smrg
1446f29dbc25Smrg    return 0;
1447f29dbc25Smrg}
1448f29dbc25Smrg
1449f29dbc25Smrg#if GFX_TV_DYNAMIC
1450f29dbc25Smrgint
1451f29dbc25Smrgfs450_set_brightness(int brightness)
1452f29dbc25Smrg#else
1453f29dbc25Smrgint
1454f29dbc25Smrggfx_set_brightness(int brightness)
1455f29dbc25Smrg#endif
1456f29dbc25Smrg{
1457f29dbc25Smrg    d.brightness = range_limit(brightness, 0, 100);
1458f29dbc25Smrg
1459f29dbc25Smrg    return write_config(REQ_BRIGHTNESS_CONTRAST);
1460f29dbc25Smrg}
1461f29dbc25Smrg
1462f29dbc25Smrg#if GFX_TV_DYNAMIC
1463f29dbc25Smrgint
1464f29dbc25Smrgfs450_get_contrast(int *p_contrast)
1465f29dbc25Smrg#else
1466f29dbc25Smrgint
1467f29dbc25Smrggfx_get_contrast(int *p_contrast)
1468f29dbc25Smrg#endif
1469f29dbc25Smrg{
1470f29dbc25Smrg    if (!p_contrast)
1471f29dbc25Smrg        return ERR_INVALID_PARAMETER;
1472f29dbc25Smrg
1473f29dbc25Smrg    *p_contrast = d.contrast;
1474f29dbc25Smrg
1475f29dbc25Smrg    return 0;
1476f29dbc25Smrg}
1477f29dbc25Smrg
1478f29dbc25Smrg#if GFX_TV_DYNAMIC
1479f29dbc25Smrgint
148079d5fcd7Smrgfs450_set_contrast(int contrast)
1481f29dbc25Smrg#else
1482f29dbc25Smrgint
148379d5fcd7Smrggfx_set_contrast(int contrast)
1484f29dbc25Smrg#endif
1485f29dbc25Smrg{
148679d5fcd7Smrg    d.contrast = range_limit(contrast, 0, 100);
1487f29dbc25Smrg
1488f29dbc25Smrg    return write_config(REQ_BRIGHTNESS_CONTRAST);
1489f29dbc25Smrg}
1490f29dbc25Smrg
1491f29dbc25Smrg/*==========================================================================*/
1492f29dbc25Smrg/* YC filters																*/
1493f29dbc25Smrg/*==========================================================================*/
1494f29dbc25Smrg
1495f29dbc25Smrg#if GFX_TV_DYNAMIC
1496f29dbc25Smrgint
1497f29dbc25Smrgfs450_get_yc_filter(unsigned int *p_yc_filter)
1498f29dbc25Smrg#else
1499f29dbc25Smrgint
1500f29dbc25Smrggfx_get_yc_filter(unsigned int *p_yc_filter)
1501f29dbc25Smrg#endif
1502f29dbc25Smrg{
1503f29dbc25Smrg    if (!p_yc_filter)
1504f29dbc25Smrg        return ERR_INVALID_PARAMETER;
1505f29dbc25Smrg
1506f29dbc25Smrg    if (houston_Rev() < HOUSTON_REV_B)
1507f29dbc25Smrg        return ERR_NOT_SUPPORTED;
1508f29dbc25Smrg
1509f29dbc25Smrg    *p_yc_filter = d.yc_filter;
1510f29dbc25Smrg
1511f29dbc25Smrg    return 0;
1512f29dbc25Smrg}
1513f29dbc25Smrg
1514f29dbc25Smrg#if GFX_TV_DYNAMIC
1515f29dbc25Smrgint
1516f29dbc25Smrgfs450_set_yc_filter(unsigned int yc_filter)
1517f29dbc25Smrg#else
1518f29dbc25Smrgint
1519f29dbc25Smrggfx_set_yc_filter(unsigned int yc_filter)
1520f29dbc25Smrg#endif
1521f29dbc25Smrg{
1522f29dbc25Smrg    if (houston_Rev() < HOUSTON_REV_B)
1523f29dbc25Smrg        return ERR_NOT_SUPPORTED;
1524f29dbc25Smrg
1525f29dbc25Smrg    /*luma filter. */
1526f29dbc25Smrg    if (yc_filter & GFX_LUMA_FILTER)
1527f29dbc25Smrg        d.yc_filter |= GFX_LUMA_FILTER;
1528f29dbc25Smrg    else
1529f29dbc25Smrg        d.yc_filter &= ~GFX_LUMA_FILTER;
1530f29dbc25Smrg
1531f29dbc25Smrg    /*chroma filter. */
1532f29dbc25Smrg    if (yc_filter & GFX_CHROMA_FILTER)
1533f29dbc25Smrg        d.yc_filter |= GFX_CHROMA_FILTER;
1534f29dbc25Smrg    else
1535f29dbc25Smrg        d.yc_filter &= ~GFX_CHROMA_FILTER;
1536f29dbc25Smrg
1537f29dbc25Smrg    return write_config(REQ_YC_FILTER);
1538f29dbc25Smrg}
1539f29dbc25Smrg
1540f29dbc25Smrg#if GFX_TV_DYNAMIC
1541f29dbc25Smrgint
1542f29dbc25Smrgfs450_get_aps_trigger_bits(unsigned int *p_trigger_bits)
1543f29dbc25Smrg#else
1544f29dbc25Smrgint
1545f29dbc25Smrggfx_get_aps_trigger_bits(unsigned int *p_trigger_bits)
1546f29dbc25Smrg#endif
1547f29dbc25Smrg{
1548f29dbc25Smrg    if (!p_trigger_bits)
1549f29dbc25Smrg        return ERR_INVALID_PARAMETER;
1550f29dbc25Smrg
1551f29dbc25Smrg    *p_trigger_bits = d.aps_trigger_bits;
1552f29dbc25Smrg
1553f29dbc25Smrg    return 0;
1554f29dbc25Smrg}
1555f29dbc25Smrg
1556f29dbc25Smrg#if GFX_TV_DYNAMIC
1557f29dbc25Smrgint
1558f29dbc25Smrgfs450_set_aps_trigger_bits(unsigned int trigger_bits)
1559f29dbc25Smrg#else
1560f29dbc25Smrgint
1561f29dbc25Smrggfx_set_aps_trigger_bits(unsigned int trigger_bits)
1562f29dbc25Smrg#endif
1563f29dbc25Smrg{
1564f29dbc25Smrg    d.aps_trigger_bits = trigger_bits;
1565f29dbc25Smrg
1566f29dbc25Smrg    return write_config(REQ_MACROVISION);
1567f29dbc25Smrg}
1568f29dbc25Smrg
1569f29dbc25Smrg/*----------------------------------------------------------------------------
1570f29dbc25Smrg * gfx_set_tv_format
1571f29dbc25Smrg *
1572f29dbc25Smrg * This routine sets the TV encoder registers to the specified format
1573f29dbc25Smrg * and resolution.
1574f29dbc25Smrg * Currently only NTSC 640x480 is supported.
1575f29dbc25Smrg *----------------------------------------------------------------------------
1576f29dbc25Smrg */
1577f29dbc25Smrg#if GFX_TV_DYNAMIC
1578f29dbc25Smrgint
1579f29dbc25Smrgfs450_set_tv_format(TVStandardType format, GfxOnTVType resolution)
1580f29dbc25Smrg#else
1581f29dbc25Smrgint
1582f29dbc25Smrggfx_set_tv_format(TVStandardType format, GfxOnTVType resolution)
1583f29dbc25Smrg#endif
1584f29dbc25Smrg{
1585f29dbc25Smrg    /* ### ADD ### IMPLEMENTATION */
1586f29dbc25Smrg    return (0);
1587f29dbc25Smrg}
1588f29dbc25Smrg
1589f29dbc25Smrg/*----------------------------------------------------------------------------
1590f29dbc25Smrg * gfx_set_tv_output
1591f29dbc25Smrg *
1592f29dbc25Smrg * This routine sets the TV encoder registers to the specified output type.
1593f29dbc25Smrg * Supported output types are : S-VIDEO and Composite.
1594f29dbc25Smrg *----------------------------------------------------------------------------
1595f29dbc25Smrg */
1596f29dbc25Smrg#if GFX_TV_DYNAMIC
1597f29dbc25Smrgint
1598f29dbc25Smrgfs450_set_tv_output(int output)
1599f29dbc25Smrg#else
1600f29dbc25Smrgint
1601f29dbc25Smrggfx_set_tv_output(int output)
1602f29dbc25Smrg#endif
1603f29dbc25Smrg{
1604f29dbc25Smrg    /* ### ADD ### IMPLEMENTATION */
1605f29dbc25Smrg    return (0);
1606f29dbc25Smrg}
1607f29dbc25Smrg
1608f29dbc25Smrg/*----------------------------------------------------------------------------
1609f29dbc25Smrg * gfx_set_tv_cc_enable
1610f29dbc25Smrg *
1611f29dbc25Smrg * This routine enables or disables the use of the hardware CC registers
1612f29dbc25Smrg * in the TV encoder.
1613f29dbc25Smrg *----------------------------------------------------------------------------
1614f29dbc25Smrg */
1615f29dbc25Smrg#if GFX_TV_DYNAMIC
1616f29dbc25Smrgint
1617f29dbc25Smrgfs450_set_tv_cc_enable(int enable)
1618f29dbc25Smrg#else
1619f29dbc25Smrgint
1620f29dbc25Smrggfx_set_tv_cc_enable(int enable)
1621f29dbc25Smrg#endif
1622f29dbc25Smrg{
1623f29dbc25Smrg    /* ### ADD ### IMPLEMENTATION */
1624f29dbc25Smrg    return (0);
1625f29dbc25Smrg}
1626f29dbc25Smrg
1627f29dbc25Smrg/*----------------------------------------------------------------------------
1628f29dbc25Smrg * gfx_set_tv_cc_data
1629f29dbc25Smrg *
1630f29dbc25Smrg * This routine writes the two specified characters to the CC data register
1631f29dbc25Smrg * of the TV encoder.
1632f29dbc25Smrg *----------------------------------------------------------------------------
1633f29dbc25Smrg */
1634f29dbc25Smrg#if GFX_TV_DYNAMIC
1635f29dbc25Smrgint
1636f29dbc25Smrgfs450_set_tv_cc_data(unsigned char data1, unsigned char data2)
1637f29dbc25Smrg#else
1638f29dbc25Smrgint
1639f29dbc25Smrggfx_set_tv_cc_data(unsigned char data1, unsigned char data2)
1640f29dbc25Smrg#endif
1641f29dbc25Smrg{
1642f29dbc25Smrg    /* ### ADD ### IMPLEMENTATION */
1643f29dbc25Smrg    return (0);
1644f29dbc25Smrg}
1645f29dbc25Smrg
1646f29dbc25Smrg#ifdef FS450_DIRECTREG
1647f29dbc25Smrg
1648f29dbc25Smrg/*==========================================================================*/
1649f29dbc25Smrg/* Direct Read and Write registers											*/
1650f29dbc25Smrg/*==========================================================================*/
1651f29dbc25Smrg
1652f29dbc25Smrgint
1653f29dbc25SmrgFS450_ReadRegister(S_REG_INFO * p_reg)
1654f29dbc25Smrg{
1655f29dbc25Smrg    unsigned long tmp;
1656f29dbc25Smrg
1657f29dbc25Smrg    if (PLAL_ReadRegister(p_reg))
1658f29dbc25Smrg        return 0;
1659f29dbc25Smrg
1660f29dbc25Smrg    if (SOURCE_HOUSTON == p_reg->source) {
1661f29dbc25Smrg        switch (p_reg->size) {
1662f29dbc25Smrg        case 1:
1663f29dbc25Smrg        case 2:
166404007ebaSmrg        {
166504007ebaSmrg            houston_ReadReg((int) p_reg->offset, &tmp, (int) p_reg->size);
166604007ebaSmrg            p_reg->value = tmp;
166704007ebaSmrg        }
1668f29dbc25Smrg            return 0;
1669f29dbc25Smrg
1670f29dbc25Smrg        case 4:
167104007ebaSmrg        {
167204007ebaSmrg            houston_ReadReg((unsigned int) p_reg->offset, &tmp, 2);
167304007ebaSmrg            p_reg->value = (tmp << 16);
167404007ebaSmrg            houston_ReadReg((unsigned int) (p_reg->offset + 2), &tmp, 2);
167504007ebaSmrg            p_reg->value |= tmp;
167604007ebaSmrg        }
1677f29dbc25Smrg            return 0;
1678f29dbc25Smrg        }
1679f29dbc25Smrg    }
1680f29dbc25Smrg
1681f29dbc25Smrg    return ERR_INVALID_PARAMETER;
1682f29dbc25Smrg}
1683f29dbc25Smrg
1684f29dbc25Smrgint
1685f29dbc25SmrgFS450_WriteRegister(S_REG_INFO * p_reg)
1686f29dbc25Smrg{
1687f29dbc25Smrg    if (PLAL_WriteRegister(p_reg))
1688f29dbc25Smrg        return 0;
1689f29dbc25Smrg
1690f29dbc25Smrg    if (SOURCE_HOUSTON == p_reg->source) {
169104007ebaSmrg        houston_WriteReg((unsigned int) p_reg->offset, p_reg->value,
169204007ebaSmrg                         p_reg->size);
1693f29dbc25Smrg
1694f29dbc25Smrg        return 0;
1695f29dbc25Smrg    }
1696f29dbc25Smrg
1697f29dbc25Smrg    return ERR_INVALID_PARAMETER;
1698f29dbc25Smrg}
1699f29dbc25Smrg
1700f29dbc25Smrg#endif
1701f29dbc25Smrg
1702f29dbc25Smrg/* Houston initialization function. */
1703f29dbc25Smrgstatic int g_houston_rev = -1;
1704f29dbc25Smrg
1705f29dbc25Smrgstatic int
1706f29dbc25Smrghouston_init(void)
1707f29dbc25Smrg{
1708f29dbc25Smrg    /*//int errc; */
1709f29dbc25Smrg    unsigned long write, read;
1710f29dbc25Smrg
1711f29dbc25Smrg    TRACE(("houston_init()\n"))
1712f29dbc25Smrg
1713f29dbc25Smrg        /*Before we begin, we must enable power to the TFT */
1714f29dbc25Smrg        read = READ_VID32(CS5530_DISPLAY_CONFIG);
1715f29dbc25Smrg    read |= CS5530_DCFG_FP_PWR_EN | CS5530_DCFG_FP_DATA_EN;
1716f29dbc25Smrg    WRITE_VID32(CS5530_DISPLAY_CONFIG, read);
1717f29dbc25Smrg
1718f29dbc25Smrg    /*simple w/r test. */
1719f29dbc25Smrg    write = 0x0055;
1720f29dbc25Smrg    read = 0;
1721f29dbc25Smrg
1722f29dbc25Smrg    houston_WriteReg(HOUSTON_IHO, write, 2);
1723f29dbc25Smrg    houston_ReadReg(HOUSTON_IHO, &read, 2);
1724f29dbc25Smrg    if (read != write) {
1725f29dbc25Smrg        houston_WriteReg(HOUSTON_IHO, write, 2);
1726f29dbc25Smrg        houston_ReadReg(HOUSTON_IHO, &read, 2);
1727f29dbc25Smrg        if (read != write) {
1728f29dbc25Smrg            /*chip is not there, do something appropriate? */
1729f29dbc25Smrg            TRACE(("wrote HOUSTON_IHO=0x0055, read 0x%04x\n", read))
1730f29dbc25Smrg                return ERR_DEVICE_NOT_FOUND;
1731f29dbc25Smrg        }
1732f29dbc25Smrg    }
1733f29dbc25Smrg
1734f29dbc25Smrg    /*read chip revision. */
1735f29dbc25Smrg    houston_ReadReg(HOUSTON_REV, &read, 2);
173604007ebaSmrg    g_houston_rev = (int) read;
1737f29dbc25Smrg
1738f29dbc25Smrg    /*ok. */
1739f29dbc25Smrg    return 0;
1740f29dbc25Smrg}
1741f29dbc25Smrg
1742f29dbc25Smrgstatic int
1743f29dbc25Smrghouston_Rev(void)
1744f29dbc25Smrg{
1745f29dbc25Smrg    return g_houston_rev;
1746f29dbc25Smrg}
1747f29dbc25Smrg
1748f29dbc25Smrgstatic S_TIMING_SPECS g_specs;
1749f29dbc25Smrg
1750f29dbc25Smrgstatic const S_TIMING_SPECS *
1751f29dbc25Smrgp_specs(void)
1752f29dbc25Smrg{
1753f29dbc25Smrg    return &g_specs;
1754f29dbc25Smrg}
1755f29dbc25Smrg
1756f29dbc25Smrg/*==========================================================================*/
1757f29dbc25Smrg/* FS450 configuration functions.											*/
1758f29dbc25Smrg/*==========================================================================*/
1759f29dbc25Smrgstatic int
1760f29dbc25Smrgconfig_init(void)
1761f29dbc25Smrg{
1762f29dbc25Smrg    int err;
1763f29dbc25Smrg
1764f29dbc25Smrg    TRACE(("config_init()\n"))
1765f29dbc25Smrg
1766f29dbc25Smrg        err = houston_init();
1767f29dbc25Smrg    if (err)
1768f29dbc25Smrg        return err;
1769f29dbc25Smrg
1770f29dbc25Smrg    return 0;
1771f29dbc25Smrg}
1772f29dbc25Smrg
1773f29dbc25Smrg/*==========================================================================*/
1774f29dbc25Smrg/* convert word to encoder 10 bit value.									*/
1775f29dbc25Smrg/*==========================================================================*/
1776f29dbc25Smrg
1777f29dbc25Smrgstatic unsigned short
1778f29dbc25Smrgw10bit2z(unsigned short w)
1779f29dbc25Smrg{
1780f29dbc25Smrg    return (w >> 2) | ((w & 0x03) << 8);
1781f29dbc25Smrg}
1782f29dbc25Smrg
1783f29dbc25Smrgstatic unsigned short
1784f29dbc25Smrgz2w10bit(unsigned short z)
1785f29dbc25Smrg{
1786f29dbc25Smrg    return (0x03 & (z >> 8)) | ((0xFF & z) << 2);
1787f29dbc25Smrg}
1788f29dbc25Smrg
1789f29dbc25Smrg/*==========================================================================*/
1790f29dbc25Smrg/* TV Standards																*/
1791f29dbc25Smrg/*==========================================================================*/
1792f29dbc25Smrg
179304007ebaSmrgstatic const struct {
1794f29dbc25Smrg    unsigned long standard;
1795f29dbc25Smrg    int tvsetup_index;
1796f29dbc25Smrg} g_tv_standards[] = {
1797f29dbc25Smrg    {
1798f29dbc25Smrg    GFX_TV_STANDARD_NTSC_M, 0}, {
1799f29dbc25Smrg    GFX_TV_STANDARD_NTSC_M_J, 2}, {
1800f29dbc25Smrg    GFX_TV_STANDARD_PAL_B, 1}, {
1801f29dbc25Smrg    GFX_TV_STANDARD_PAL_D, 1}, {
1802f29dbc25Smrg    GFX_TV_STANDARD_PAL_H, 1}, {
1803f29dbc25Smrg    GFX_TV_STANDARD_PAL_I, 1}, {
1804f29dbc25Smrg    GFX_TV_STANDARD_PAL_M, 3}, {
1805f29dbc25Smrg    GFX_TV_STANDARD_PAL_N, 4}, {
1806f29dbc25SmrgGFX_TV_STANDARD_PAL_G, 1},};
1807f29dbc25Smrg
1808f29dbc25Smrgstatic int
1809f29dbc25Smrgmap_tvstd_to_index(unsigned long tv_std)
1810f29dbc25Smrg{
1811f29dbc25Smrg    unsigned int i;
1812f29dbc25Smrg
1813f29dbc25Smrg    for (i = 0; i < sizeof(g_tv_standards) / sizeof(*g_tv_standards); i++) {
1814f29dbc25Smrg        if (tv_std == g_tv_standards[i].standard)
1815f29dbc25Smrg            return g_tv_standards[i].tvsetup_index;
1816f29dbc25Smrg    }
1817f29dbc25Smrg
1818f29dbc25Smrg    return -1;
1819f29dbc25Smrg}
1820f29dbc25Smrg
1821f29dbc25Smrgstatic unsigned long
1822f29dbc25Smrgsupported_standards(void)
1823f29dbc25Smrg{
1824f29dbc25Smrg    unsigned long standards = 0;
1825f29dbc25Smrg    unsigned int i;
1826f29dbc25Smrg
1827f29dbc25Smrg    for (i = 0; i < sizeof(g_tv_standards) / sizeof(*g_tv_standards); i++) {
1828f29dbc25Smrg        if (g_tv_standards[i].tvsetup_index >= 0)
1829f29dbc25Smrg            standards |= g_tv_standards[i].standard;
1830f29dbc25Smrg    }
1831f29dbc25Smrg
1832f29dbc25Smrg    return standards;
1833f29dbc25Smrg}
1834f29dbc25Smrg
1835f29dbc25Smrg/*==========================================================================*/
1836f29dbc25Smrg
1837f29dbc25Smrgstatic void
1838f29dbc25Smrgconfig_power(int on)
1839f29dbc25Smrg{
1840f29dbc25Smrg    unsigned long reg;
1841f29dbc25Smrg
1842f29dbc25Smrg    if (houston_Rev() < HOUSTON_REV_B) {
1843f29dbc25Smrg        /* no power down supported, but still turn of clock in off mode */
1844f29dbc25Smrg        if (on) {
1845f29dbc25Smrg            houston_ReadReg(HOUSTON_CR, &reg, 2);
1846f29dbc25Smrg            reg &= ~(CR_CLKOFF | CR_RESET);
1847f29dbc25Smrg            houston_WriteReg(HOUSTON_CR, reg, 2);
1848f29dbc25Smrg            reg |= CR_RESET;
1849f29dbc25Smrg            houston_WriteReg(HOUSTON_CR, reg, 2);
1850f29dbc25Smrg            reg &= ~CR_RESET;
1851f29dbc25Smrg            houston_WriteReg(HOUSTON_CR, reg, 2);
185204007ebaSmrg        }
185304007ebaSmrg        else {
1854f29dbc25Smrg            houston_ReadReg(HOUSTON_CR, &reg, 2);
1855f29dbc25Smrg            reg |= CR_CLKOFF;
1856f29dbc25Smrg            houston_WriteReg(HOUSTON_CR, reg, 2);
1857f29dbc25Smrg        }
1858f29dbc25Smrg
1859f29dbc25Smrg        return;
1860f29dbc25Smrg    }
1861f29dbc25Smrg
1862f29dbc25Smrg    if (on) {
1863f29dbc25Smrg        /* !CLKOFF, !COMPOFF, !YCOFF */
1864f29dbc25Smrg        /* and reset Houston */
1865f29dbc25Smrg        houston_ReadReg(HOUSTON_CR, &reg, 2);
1866f29dbc25Smrg        reg &= ~(CR_CLKOFF | CR_RESET | CR_COMPOFF | CR_YCOFF);
1867f29dbc25Smrg        houston_WriteReg(HOUSTON_CR, reg, 2);
1868f29dbc25Smrg        reg |= CR_RESET;
1869f29dbc25Smrg        houston_WriteReg(HOUSTON_CR, reg, 2);
1870f29dbc25Smrg        reg &= ~CR_RESET;
1871f29dbc25Smrg        houston_WriteReg(HOUSTON_CR, reg, 2);
1872f29dbc25Smrg
1873f29dbc25Smrg        /* !GTLIO_PD */
1874f29dbc25Smrg        houston_ReadReg(HOUSTON_MISC, &reg, 2);
1875f29dbc25Smrg        reg &= ~MISC_GTLIO_PD;
1876f29dbc25Smrg        houston_WriteReg(HOUSTON_MISC, reg, 2);
187704007ebaSmrg    }
187804007ebaSmrg    else {
1879f29dbc25Smrg        /* CLKOFF, COMPOFF, YCOFF */
1880f29dbc25Smrg        houston_ReadReg(HOUSTON_CR, &reg, 2);
1881f29dbc25Smrg        reg |= (CR_CLKOFF | CR_COMPOFF | CR_YCOFF);
1882f29dbc25Smrg        houston_WriteReg(HOUSTON_CR, reg, 2);
1883f29dbc25Smrg
1884f29dbc25Smrg        /* GTLIO_PD */
1885f29dbc25Smrg        houston_ReadReg(HOUSTON_MISC, &reg, 2);
1886f29dbc25Smrg        reg |= MISC_GTLIO_PD;
1887f29dbc25Smrg        houston_WriteReg(HOUSTON_MISC, reg, 2);
1888f29dbc25Smrg    }
1889f29dbc25Smrg}
1890f29dbc25Smrg
1891f29dbc25Smrg/*==========================================================================*/
1892f29dbc25Smrg/* VGA mode																	*/
1893f29dbc25Smrg/*==========================================================================*/
1894f29dbc25Smrg
1895f29dbc25Smrgstatic void
1896f29dbc25Smrgconfig_vga_mode(unsigned long vga_mode)
1897f29dbc25Smrg{
1898f29dbc25Smrg    /*h_total must be evenly divisible by 32? */
1899f29dbc25Smrg
190004007ebaSmrg    static struct {
1901f29dbc25Smrg        unsigned long mode;
1902f29dbc25Smrg        int width;
1903f29dbc25Smrg        int lines;
1904f29dbc25Smrg        int h_total;
1905f29dbc25Smrg    } vgaparams[] = {
1906f29dbc25Smrg        {
1907f29dbc25Smrg        GFX_VGA_MODE_640X480, 640, 480, 1056}, {
1908f29dbc25Smrg        GFX_VGA_MODE_720X487, 720, 487, 1056}, {
1909f29dbc25Smrg        GFX_VGA_MODE_720X576, 720, 576, 1056}, {
1910f29dbc25Smrg        GFX_VGA_MODE_800X600, 800, 600, 1056}, {
1911f29dbc25Smrg    GFX_VGA_MODE_1024X768, 1024, 768, 1344},};
1912f29dbc25Smrg
1913f29dbc25Smrg    unsigned long cr, misc, byp;
1914f29dbc25Smrg    unsigned int i;
1915f29dbc25Smrg
1916f29dbc25Smrg    g_specs.vga_width = 0;
1917f29dbc25Smrg    g_specs.vga_lines = 0;
1918f29dbc25Smrg    g_specs.h_total = 0;
1919f29dbc25Smrg
1920f29dbc25Smrg    for (i = 0; i < sizeof(vgaparams) / sizeof(*vgaparams); i++) {
1921f29dbc25Smrg        if (vga_mode == vgaparams[i].mode) {
1922f29dbc25Smrg            g_specs.vga_width = vgaparams[i].width;
1923f29dbc25Smrg            g_specs.vga_lines = vgaparams[i].lines;
1924f29dbc25Smrg            g_specs.h_total = vgaparams[i].h_total;
1925f29dbc25Smrg            break;
1926f29dbc25Smrg        }
1927f29dbc25Smrg    }
1928f29dbc25Smrg    if (!g_specs.h_total)
1929f29dbc25Smrg        return;
1930f29dbc25Smrg
1931f29dbc25Smrg    /*clock mux decimator and vga dual. */
1932f29dbc25Smrg    houston_ReadReg(HOUSTON_CR, &cr, 2);
1933f29dbc25Smrg    houston_ReadReg(HOUSTON_MISC, &misc, 2);
1934f29dbc25Smrg    houston_ReadReg(HOUSTON_BYP, &byp, 2);
1935f29dbc25Smrg
1936f29dbc25Smrg    if (vga_mode == GFX_VGA_MODE_1024X768) {
1937f29dbc25Smrg         /*XGA*/ cr |= CR_UIM_DEC;
1938f29dbc25Smrg        misc |= MISC_VGACKDIV;
1939f29dbc25Smrg        byp |= (BYP_HDS_BYPASS | BYP_CAC_BYPASS);
194004007ebaSmrg    }
194104007ebaSmrg    else {
1942f29dbc25Smrg        /*VGA,SVGA */
1943f29dbc25Smrg        cr &= ~CR_UIM_DEC;
1944f29dbc25Smrg        misc &= ~MISC_VGACKDIV;
1945f29dbc25Smrg        byp &= ~(BYP_HDS_BYPASS | BYP_CAC_BYPASS);
1946f29dbc25Smrg    }
1947f29dbc25Smrg
1948f29dbc25Smrg    houston_WriteReg(HOUSTON_CR, cr, 2);
1949f29dbc25Smrg    houston_WriteReg(HOUSTON_MISC, misc, 2);
1950f29dbc25Smrg    houston_WriteReg(HOUSTON_BYP, byp, 2);
1951f29dbc25Smrg}
1952f29dbc25Smrg
1953f29dbc25Smrg/*==========================================================================*/
1954f29dbc25Smrg/* Write settings for TV standard to device									*/
1955f29dbc25Smrg/*==========================================================================*/
1956f29dbc25Smrg
1957f29dbc25Smrgstatic void
1958f29dbc25Smrgconfig_tv_std(unsigned long tv_std, unsigned int trigger_bits)
1959f29dbc25Smrg{
1960f29dbc25Smrg    int k;
1961f29dbc25Smrg    unsigned short reg34;
1962f29dbc25Smrg    unsigned long cr, w;
1963f29dbc25Smrg    unsigned long l;
1964f29dbc25Smrg
1965f29dbc25Smrg    /*verify supported standard. */
1966f29dbc25Smrg    k = map_tvstd_to_index(tv_std);
1967f29dbc25Smrg    if (k < 0)
1968f29dbc25Smrg        return;
1969f29dbc25Smrg
1970f29dbc25Smrg    /*store tv width and lines */
1971f29dbc25Smrg    g_specs.tv_width = tvsetup.tv_width[k];
1972f29dbc25Smrg    g_specs.tv_lines = tvsetup.tv_lines[k];
1973f29dbc25Smrg
1974f29dbc25Smrg    /*houston CR register. */
1975f29dbc25Smrg    houston_ReadReg(HOUSTON_CR, &cr, 2);
1976f29dbc25Smrg    cr &= ~CR_656_PAL_NTSC;
1977f29dbc25Smrg    cr |= tvsetup.houston_cr[k];
1978f29dbc25Smrg    houston_WriteReg(HOUSTON_CR, cr, 2);
1979f29dbc25Smrg
1980f29dbc25Smrg    /*setup the encoder. */
1981f29dbc25Smrg    l = tvsetup.chroma_freq[k];
198204007ebaSmrg    houston_WriteReg(ENC_CHROMA_FREQ, (int) (l & 0x00ff), 1);
198304007ebaSmrg    houston_WriteReg(ENC_CHROMA_FREQ + 1, (int) ((l >> 8) & 0x00ff), 1);
198404007ebaSmrg    houston_WriteReg(ENC_CHROMA_FREQ + 2, (int) ((l >> 16) & 0x00ff), 1);
198504007ebaSmrg    houston_WriteReg(ENC_CHROMA_FREQ + 3, (int) ((l >> 24) & 0x00ff), 1);
1986f29dbc25Smrg
1987f29dbc25Smrg    houston_WriteReg(ENC_CHROMA_PHASE, tvsetup.chroma_phase[k], 1);
1988f29dbc25Smrg    houston_WriteReg(ENC_REG05, 0x00, 1);       /*reg 0x05 */
1989f29dbc25Smrg    houston_WriteReg(ENC_REG06, 0x89, 1);       /*reg 0x06 */
1990f29dbc25Smrg    houston_WriteReg(ENC_REG07, 0x00, 1);       /*reg 0x07 */
1991f29dbc25Smrg    houston_WriteReg(ENC_HSYNC_WIDTH, tvsetup.hsync_width[k], 1);
1992f29dbc25Smrg    houston_WriteReg(ENC_BURST_WIDTH, tvsetup.burst_width[k], 1);
1993f29dbc25Smrg    houston_WriteReg(ENC_BACK_PORCH, tvsetup.back_porch[k], 1);
1994f29dbc25Smrg    houston_WriteReg(ENC_CB_BURST_LEVEL, tvsetup.cb_burst_level[k], 1);
1995f29dbc25Smrg    houston_WriteReg(ENC_CR_BURST_LEVEL, tvsetup.cr_burst_level[k], 1);
1996f29dbc25Smrg    houston_WriteReg(ENC_SLAVE_MODE, 0x01, 1);  /*slave mode */
1997f29dbc25Smrg    if (trigger_bits == 0)
1998f29dbc25Smrg        w = w10bit2z(tvsetup.blank_level[k]);   /*blank level */
1999f29dbc25Smrg    else
200004007ebaSmrg        w = w10bit2z((unsigned short) (tvsetup.blank_level[k] -
200104007ebaSmrg                                       tvsetup.hamp_offset[k]));
2002f29dbc25Smrg    houston_WriteReg(ENC_BLANK_LEVEL, w & 0x00ff, 1);
2003f29dbc25Smrg    houston_WriteReg(ENC_BLANK_LEVEL + 1, w >> 8, 1);
200404007ebaSmrg    w = w10bit2z(tvsetup.tv_lines[k]);  /*num_lines */
2005f29dbc25Smrg    houston_WriteReg(ENC_NUM_LINES, w & 0x00ff, 1);
2006f29dbc25Smrg    houston_WriteReg(ENC_NUM_LINES + 1, w >> 8, 1);
2007f29dbc25Smrg
2008f29dbc25Smrg    houston_WriteReg(ENC_TINT, 0x00, 1);        /*tint */
2009f29dbc25Smrg    houston_WriteReg(ENC_BREEZE_WAY, tvsetup.breeze_way[k], 1);
2010f29dbc25Smrg    houston_WriteReg(ENC_FRONT_PORCH, tvsetup.front_porch[k], 1);
2011f29dbc25Smrg    houston_WriteReg(ENC_ACTIVELINE, tvsetup.activeline[k], 1);
2012f29dbc25Smrg    houston_WriteReg(ENC_FIRST_LINE, 0x15, 1);  /*firstvideoline */
2013f29dbc25Smrg    reg34 =
2014f29dbc25Smrg        0x80 |
2015f29dbc25Smrg        (tvsetup.pal_mode[k] << 6) |
2016f29dbc25Smrg        (tvsetup.sys625_50[k] << 3) |
2017f29dbc25Smrg        (tvsetup.cphase_rst[k] << 1) | (tvsetup.vsync5[k]);
2018f29dbc25Smrg    houston_WriteReg(ENC_REG34, reg34, 1);      /*reg 0x34 */
2019f29dbc25Smrg    houston_WriteReg(ENC_SYNC_LEVEL, tvsetup.sync_level[k], 1);
2020f29dbc25Smrg    if (trigger_bits == 0)
2021f29dbc25Smrg        w = w10bit2z(tvsetup.vbi_blank_level[k]);       /*blank level */
2022f29dbc25Smrg    else
202304007ebaSmrg        w = w10bit2z((unsigned short) (tvsetup.vbi_blank_level[k] - 1));
2024f29dbc25Smrg    houston_WriteReg(ENC_VBI_BLANK_LEVEL, w & 0x00ff, 1);
2025f29dbc25Smrg    houston_WriteReg(ENC_VBI_BLANK_LEVEL + 1, w >> 8, 1);
2026f29dbc25Smrg}
2027f29dbc25Smrg
2028f29dbc25Smrgstatic void
2029f29dbc25Smrgconget_tv_std(unsigned long *p_tv_standard)
2030f29dbc25Smrg{
2031f29dbc25Smrg    unsigned long cr;
2032f29dbc25Smrg
2033f29dbc25Smrg    if (!p_tv_standard)
2034f29dbc25Smrg        return;
2035f29dbc25Smrg
2036f29dbc25Smrg    /*just pick between NTSC and PAL */
2037f29dbc25Smrg    houston_ReadReg(HOUSTON_CR, &cr, 2);
2038f29dbc25Smrg    if (CR_656_PAL_NTSC & cr)
2039f29dbc25Smrg        *p_tv_standard = GFX_TV_STANDARD_PAL_B;
2040f29dbc25Smrg    else
2041f29dbc25Smrg        *p_tv_standard = GFX_TV_STANDARD_NTSC_M;
2042f29dbc25Smrg}
2043f29dbc25Smrg
2044f29dbc25Smrg/*==========================================================================*/
2045f29dbc25Smrg/* TVout mode																*/
2046f29dbc25Smrg/*==========================================================================*/
2047f29dbc25Smrg
2048f29dbc25Smrgstatic void
2049f29dbc25Smrgconfig_tvout_mode(unsigned long tvout_mode)
2050f29dbc25Smrg{
2051f29dbc25Smrg    unsigned long cr;
2052f29dbc25Smrg
2053f29dbc25Smrg    houston_ReadReg(HOUSTON_CR, &cr, 2);
2054f29dbc25Smrg
2055f29dbc25Smrg    /*all dacs off */
2056f29dbc25Smrg    cr |= (CR_COMPOFF | CR_YCOFF);
2057f29dbc25Smrg    /*not rgb */
2058f29dbc25Smrg    cr &= ~CR_OFMT;
2059f29dbc25Smrg
2060f29dbc25Smrg    /*turn on requested output */
2061f29dbc25Smrg    if (GFX_TVOUT_MODE_CVBS & tvout_mode)
2062f29dbc25Smrg        cr &= ~CR_COMPOFF;
2063f29dbc25Smrg    if (GFX_TVOUT_MODE_YC & tvout_mode)
2064f29dbc25Smrg        cr &= ~CR_YCOFF;
2065f29dbc25Smrg    if (GFX_TVOUT_MODE_RGB & tvout_mode) {
2066f29dbc25Smrg        cr &= ~(CR_COMPOFF | CR_YCOFF);
2067f29dbc25Smrg        cr |= CR_OFMT;
2068f29dbc25Smrg    }
2069f29dbc25Smrg
2070f29dbc25Smrg    houston_WriteReg(HOUSTON_CR, cr, 2);
2071f29dbc25Smrg}
2072f29dbc25Smrg
2073f29dbc25Smrgstatic void
2074f29dbc25Smrgconget_tvout_mode(unsigned long *p_tvout_mode)
2075f29dbc25Smrg{
2076f29dbc25Smrg    unsigned long cr;
2077f29dbc25Smrg
2078f29dbc25Smrg    if (!p_tvout_mode)
2079f29dbc25Smrg        return;
2080f29dbc25Smrg
2081f29dbc25Smrg    houston_ReadReg(HOUSTON_CR, &cr, 2);
2082f29dbc25Smrg
2083f29dbc25Smrg    if (CR_OFMT & cr)
2084f29dbc25Smrg        *p_tvout_mode = GFX_TVOUT_MODE_RGB;
2085f29dbc25Smrg    else {
2086f29dbc25Smrg        *p_tvout_mode = 0;
2087f29dbc25Smrg        if (!(CR_YCOFF & cr))
2088f29dbc25Smrg            *p_tvout_mode |= GFX_TVOUT_MODE_YC;
2089f29dbc25Smrg        if (!(CR_COMPOFF & cr))
2090f29dbc25Smrg            *p_tvout_mode |= GFX_TVOUT_MODE_CVBS;
2091f29dbc25Smrg    }
2092f29dbc25Smrg}
2093f29dbc25Smrg
2094f29dbc25Smrg/*==========================================================================*/
2095f29dbc25Smrg/* Size & Position															*/
2096f29dbc25Smrg/*==========================================================================*/
2097f29dbc25Smrg
2098f29dbc25Smrg#define IS_NTSC(tv_std) 		\
2099f29dbc25Smrg	(tv_std & ( 				\
2100f29dbc25Smrg	GFX_TV_STANDARD_NTSC_M |   	\
2101f29dbc25Smrg	GFX_TV_STANDARD_NTSC_M_J | 	\
2102f29dbc25Smrg	GFX_TV_STANDARD_PAL_M))
2103f29dbc25Smrg#define IS_PAL(tv_std) 			\
2104f29dbc25Smrg	(tv_std & ( 				\
2105f29dbc25Smrg	GFX_TV_STANDARD_PAL_B | 	\
2106f29dbc25Smrg	GFX_TV_STANDARD_PAL_D | 	\
2107f29dbc25Smrg	GFX_TV_STANDARD_PAL_H | 	\
2108f29dbc25Smrg	GFX_TV_STANDARD_PAL_I | 	\
2109f29dbc25Smrg	GFX_TV_STANDARD_PAL_N | 	\
2110f29dbc25Smrg	GFX_TV_STANDARD_PAL_G))
2111f29dbc25Smrg
2112f29dbc25Smrg/*return fifo delay setting for mode, std, and total lines.*/
2113f29dbc25Smrg
2114f29dbc25Smrgstatic void
2115f29dbc25Smrgget_ffolat_ivo(unsigned long vga_mode,
211604007ebaSmrg               unsigned long tv_std, long i, unsigned short *ffolat,
211704007ebaSmrg               unsigned short *ivo)
2118f29dbc25Smrg{
2119f29dbc25Smrg    switch (vga_mode) {
2120f29dbc25Smrg    case GFX_VGA_MODE_640X480:
2121f29dbc25Smrg        if (IS_NTSC(tv_std)) {
2122f29dbc25Smrg            if (i > SIZE6X4NTSC - 1)
2123f29dbc25Smrg                i = SIZE6X4NTSC - 1;
2124f29dbc25Smrg            *ffolat = ffo6x4ntsc[i].ffolat;
2125f29dbc25Smrg            *ivo = 0x20;
212604007ebaSmrg        }
212704007ebaSmrg        else {
2128f29dbc25Smrg            if (i > SIZE6X4PAL - 1)
2129f29dbc25Smrg                i = SIZE6X4PAL - 1;
2130f29dbc25Smrg            *ffolat = ffo6x4pal[i].ffolat;
2131f29dbc25Smrg            *ivo = 0x28;
2132f29dbc25Smrg        }
2133f29dbc25Smrg        break;
2134f29dbc25Smrg
2135f29dbc25Smrg    case GFX_VGA_MODE_800X600:
2136f29dbc25Smrg        if (IS_NTSC(tv_std)) {
2137f29dbc25Smrg            if (i > SIZE8X6NTSC - 1)
2138f29dbc25Smrg                i = SIZE8X6NTSC - 1;
2139f29dbc25Smrg            *ffolat = ffo8x6ntsc[i].ffolat;
2140f29dbc25Smrg            *ivo = 0x3a;
214104007ebaSmrg        }
214204007ebaSmrg        else {
2143f29dbc25Smrg            if (i > SIZE8X6PAL - 1)
2144f29dbc25Smrg                i = SIZE8X6PAL - 1;
2145f29dbc25Smrg            *ffolat = ffo8x6pal[i].ffolat;
2146f29dbc25Smrg            *ivo = 0x39;
2147f29dbc25Smrg        }
2148f29dbc25Smrg        break;
2149f29dbc25Smrg
2150f29dbc25Smrg    case GFX_VGA_MODE_720X487:
215104007ebaSmrg        *ffolat = 0x40;         /*FFO7x4; */
2152f29dbc25Smrg        *ivo = 0x1a;
2153f29dbc25Smrg        break;
2154f29dbc25Smrg
2155f29dbc25Smrg    case GFX_VGA_MODE_720X576:
215604007ebaSmrg        *ffolat = 0x40;         /*FFO7x5; */
2157f29dbc25Smrg        *ivo = 0x1a;
2158f29dbc25Smrg        break;
2159f29dbc25Smrg
2160f29dbc25Smrg    case GFX_VGA_MODE_1024X768:
2161f29dbc25Smrg    default:
2162f29dbc25Smrg        if (IS_NTSC(tv_std)) {
2163f29dbc25Smrg            if (i > SIZE10X7NTSC - 1)
2164f29dbc25Smrg                i = SIZE10X7NTSC - 1;
2165f29dbc25Smrg            *ffolat = ffo10x7ntsc[i].ffolat;
2166f29dbc25Smrg            *ivo = ffo10x7ntsc[i].ivo;
216704007ebaSmrg        }
216804007ebaSmrg        else {
2169f29dbc25Smrg            if (i > SIZE10X7PAL - 1)
2170f29dbc25Smrg                i = SIZE10X7PAL - 1;
2171f29dbc25Smrg            *ffolat = ffo10x7pal[i].ffolat;
2172f29dbc25Smrg            *ivo = ffo10x7pal[i].ivo;
2173f29dbc25Smrg        }
2174f29dbc25Smrg        break;
2175f29dbc25Smrg    }
2176f29dbc25Smrg}
2177f29dbc25Smrg
2178f29dbc25Smrg/*get vertical line min and max for mode and std.*/
2179f29dbc25Smrg
2180f29dbc25Smrgstatic void
2181f29dbc25Smrgget_vtotal_min_max(unsigned long vga_mode,
218204007ebaSmrg                   unsigned long tv_std, int *v_total_min, int *v_total_max,
218304007ebaSmrg                   int *v_step)
2184f29dbc25Smrg{
2185f29dbc25Smrg    int k = map_tvstd_to_index(tv_std);
2186f29dbc25Smrg
2187f29dbc25Smrg    switch (vga_mode) {
2188f29dbc25Smrg    case GFX_VGA_MODE_640X480:
2189f29dbc25Smrg        if (IS_NTSC(tv_std)) {
2190f29dbc25Smrg            *v_total_min = ffo6x4ntsc[0].v_total;
2191f29dbc25Smrg            *v_total_max = ffo6x4ntsc[SIZE6X4NTSC - 1].v_total;
219204007ebaSmrg        }
219304007ebaSmrg        else {
2194f29dbc25Smrg            *v_total_min = ffo6x4pal[0].v_total;
2195f29dbc25Smrg            *v_total_max = ffo6x4pal[SIZE6X4PAL - 1].v_total;
2196f29dbc25Smrg        }
2197f29dbc25Smrg        *v_step = 4;
2198f29dbc25Smrg        break;
2199f29dbc25Smrg
2200f29dbc25Smrg    case GFX_VGA_MODE_800X600:
2201f29dbc25Smrg        if (IS_NTSC(tv_std)) {
2202f29dbc25Smrg            *v_total_min = ffo8x6ntsc[0].v_total;
2203f29dbc25Smrg            *v_total_max = ffo8x6ntsc[SIZE8X6NTSC - 1].v_total;
220404007ebaSmrg        }
220504007ebaSmrg        else {
2206f29dbc25Smrg            *v_total_min = ffo8x6pal[0].v_total;
2207f29dbc25Smrg            *v_total_max = ffo8x6pal[SIZE8X6PAL - 1].v_total;
2208f29dbc25Smrg        }
2209f29dbc25Smrg        *v_step = 5;
2210f29dbc25Smrg        break;
2211f29dbc25Smrg
2212f29dbc25Smrg    case GFX_VGA_MODE_720X487:
2213f29dbc25Smrg    case GFX_VGA_MODE_720X576:
2214f29dbc25Smrg        *v_total_min = tvsetup.tv_lines[k];
2215f29dbc25Smrg        *v_total_max = tvsetup.tv_lines[k];
2216f29dbc25Smrg        *v_step = 4;
2217f29dbc25Smrg        break;
2218f29dbc25Smrg
2219f29dbc25Smrg    case GFX_VGA_MODE_1024X768:
2220f29dbc25Smrg        if (IS_NTSC(tv_std)) {
2221f29dbc25Smrg            *v_total_min = ffo10x7ntsc[0].v_total;
2222f29dbc25Smrg            *v_total_max = ffo10x7ntsc[SIZE10X7NTSC - 1].v_total;
222304007ebaSmrg        }
222404007ebaSmrg        else {
2225f29dbc25Smrg            *v_total_min = ffo10x7pal[0].v_total;
2226f29dbc25Smrg            *v_total_max = ffo10x7pal[SIZE10X7PAL - 1].v_total;
2227f29dbc25Smrg        }
2228f29dbc25Smrg        *v_step = 6;
2229f29dbc25Smrg        break;
2230f29dbc25Smrg    }
2231f29dbc25Smrg}
2232f29dbc25Smrg
2233f29dbc25Smrgstatic void
2234f29dbc25Smrgconfig_overscan_xy(unsigned long tv_std,
223504007ebaSmrg                   unsigned long vga_mode,
223604007ebaSmrg                   int overscan_x, int overscan_y, int pos_x, int pos_y)
2237f29dbc25Smrg{
2238f29dbc25Smrg    unsigned int vga_index;
2239f29dbc25Smrg    unsigned long reg;
2240f29dbc25Smrg    double vsc;
2241f29dbc25Smrg    int k;
2242f29dbc25Smrg    unsigned short ffolat, ivo;
2243f29dbc25Smrg    int base_v_total, range, v_offset;
2244f29dbc25Smrg    int v_total_min, v_total_max, v_step;
2245f29dbc25Smrg    float r, f;
2246f29dbc25Smrg    int vga_pixels, pre_pixels;
2247f29dbc25Smrg    float hscale, hscale_min, hscale_max;
2248f29dbc25Smrg    int hsc;
2249f29dbc25Smrg    int iho, iho_max, ihw;
2250f29dbc25Smrg
2251f29dbc25Smrg    /*tv_std is valid. */
2252f29dbc25Smrg    k = map_tvstd_to_index(tv_std);
2253f29dbc25Smrg
2254f29dbc25Smrg    /*store tv width and lines */
2255f29dbc25Smrg    g_specs.tv_width = tvsetup.tv_width[k];
2256f29dbc25Smrg    g_specs.tv_lines = tvsetup.tv_lines[k];
2257f29dbc25Smrg
2258f29dbc25Smrg    /*determine vga mode index */
2259f29dbc25Smrg    for (vga_index = 0; vga_index < SCANTABLE_ENTRIES; vga_index++) {
2260f29dbc25Smrg        if (scantable[vga_index].mode == vga_mode)
2261f29dbc25Smrg            break;
2262f29dbc25Smrg    }
2263f29dbc25Smrg    if (vga_index >= SCANTABLE_ENTRIES)
2264f29dbc25Smrg        return;
2265f29dbc25Smrg
2266f29dbc25Smrg    /*vertical scaling (v_total setup). */
2267f29dbc25Smrg    /*calculate vertical range. */
2268f29dbc25Smrg    get_vtotal_min_max(vga_mode, tv_std, &v_total_min, &v_total_max, &v_step);
2269f29dbc25Smrg    TRACE(("v_total min=%d, max=%d\n", v_total_min, v_total_max))
2270f29dbc25Smrg        base_v_total = scantable[vga_index].v_total[k];
2271f29dbc25Smrg    range = fsmax(base_v_total - v_total_min, v_total_max - base_v_total);
2272f29dbc25Smrg    TRACE(("v_total range = %d\n", range))
2273f29dbc25Smrg
2274f29dbc25Smrg        /*map +/-1000 overscan y into +/-range. */
227504007ebaSmrg        v_offset = (int) ((((float) overscan_y * range) / 1000.f) + .5f);
2276f29dbc25Smrg    TRACE(("v_offset = %d\n", v_offset))
2277f29dbc25Smrg
2278f29dbc25Smrg        /*range limit v_total. */
2279f29dbc25Smrg        g_specs.v_total =
2280f29dbc25Smrg        range_limit(base_v_total + v_offset, v_total_min, v_total_max);
2281f29dbc25Smrg
2282f29dbc25Smrg    /*round to calibrated value. */
2283f29dbc25Smrg    v_offset = (g_specs.v_total - v_total_min + (v_step / 2)) / v_step;
2284f29dbc25Smrg    g_specs.v_total = v_total_min + v_offset * v_step;
2285f29dbc25Smrg    TRACE(("desired v_total=%d\n", g_specs.v_total))
2286f29dbc25Smrg
2287f29dbc25Smrg        /*vertical positioning (vsync setup). */
2288f29dbc25Smrg        get_ffolat_ivo(vga_mode, tv_std, v_offset, &ffolat, &ivo);
2289f29dbc25Smrg    houston_WriteReg(HOUSTON_IVO, ivo, 2);
2290f29dbc25Smrg
2291f29dbc25Smrg    /*scale base sync offset by scaling ratio. */
229204007ebaSmrg    r = (float) g_specs.v_total / (float) base_v_total;
229304007ebaSmrg    v_offset = (int) (r * (float) scantable[vga_index].v_sync[k]);
2294f29dbc25Smrg
2295f29dbc25Smrg    /*scale ivo. */
229604007ebaSmrg    f = (float) ivo;
229704007ebaSmrg    v_offset -= (int) (f - f / r);
2298f29dbc25Smrg
2299f29dbc25Smrg    /*compensate for center screen. */
230004007ebaSmrg    f = (float) tvsetup.tv_active_lines[k] / 2.f;
230104007ebaSmrg    v_offset += (int) (f * r - f);
2302f29dbc25Smrg
2303f29dbc25Smrg    /*calculate vsync. */
2304f29dbc25Smrg    g_specs.v_sync = g_specs.v_total - v_offset + pos_y;
2305f29dbc25Smrg    TRACE(("desired v_total=%d, desired v_sync=%d\n", g_specs.v_total,
230604007ebaSmrg           g_specs.v_sync))
2307f29dbc25Smrg        if (g_specs.v_sync < g_specs.vga_lines + 10) {
2308f29dbc25Smrg        TRACE(("vsync too low\n"))
2309f29dbc25Smrg            /*d.v_total += d.vga_lines+10-d.v_sync; */
2310f29dbc25Smrg            g_specs.v_sync = g_specs.vga_lines + 10;
231104007ebaSmrg    }
231204007ebaSmrg    else if (g_specs.v_sync > g_specs.v_total - 10) {
2313f29dbc25Smrg        TRACE(("vsync too high\n"))
2314f29dbc25Smrg            g_specs.v_sync = g_specs.v_total - 10;
2315f29dbc25Smrg    }
2316f29dbc25Smrg    TRACE(("v_total=%d v_sync=%d\n", g_specs.v_total, g_specs.v_sync))
2317f29dbc25Smrg
2318f29dbc25Smrg        /* FFOLAT. */
2319f29dbc25Smrg        houston_WriteReg(HOUSTON_FFO_LAT, ffolat, 2);
2320f29dbc25Smrg
2321f29dbc25Smrg    /* VSC. */
2322f29dbc25Smrg    vsc =
2323f29dbc25Smrg        (65536.0f * (1.0f -
232404007ebaSmrg                     (double) g_specs.tv_lines / (double) g_specs.v_total)) +
232504007ebaSmrg        0.5f;
232604007ebaSmrg    reg = ((unsigned long) -vsc) & 0xffff;
2327f29dbc25Smrg    TRACE(("vsc=%04x, tv_lines=%d, v_total=%d\n", reg, g_specs.tv_lines,
232804007ebaSmrg           g_specs.v_total))
232904007ebaSmrg        houston_WriteReg(HOUSTON_VSC, (int) reg, 2);
2330f29dbc25Smrg
2331f29dbc25Smrg    /* horizontal scaling. */
2332f29dbc25Smrg
2333f29dbc25Smrg    /* vga pixels is vga width, except in 1024x768, where it's half that. */
2334f29dbc25Smrg    vga_pixels = g_specs.vga_width;
2335f29dbc25Smrg    if (1024 == vga_pixels)
2336f29dbc25Smrg        vga_pixels /= 2;
2337f29dbc25Smrg
2338f29dbc25Smrg    /* maximum scaling coefficient is tv_width / vga_pixels */
2339f29dbc25Smrg    /* minimum is about 1/2, but that is quite small.  arbitrarily set
2340f29dbc25Smrg     * minimum at 75% maximum. */
2341f29dbc25Smrg    hscale_max = (720.0f / vga_pixels);
2342f29dbc25Smrg    hscale_min = fsmax((0.75f * hscale_max), (1.0f - (63.0f / 128.0f)));
2343f29dbc25Smrg    TRACE(("hscale_min = %u.%u, hscale_max = %u.%u\n",
234404007ebaSmrg           (int) hscale_min,
234504007ebaSmrg           (int) ((hscale_min - (int) hscale_min) * 1000),
234604007ebaSmrg           (int) hscale_max, (int) ((hscale_max - (int) hscale_max) * 1000)))
2347f29dbc25Smrg
2348f29dbc25Smrg        /* map overscan_x into min to max. */
2349f29dbc25Smrg        hscale =
2350f29dbc25Smrg        hscale_min + ((overscan_x + 1000.0f) / 2000.0f) * (hscale_max -
235104007ebaSmrg                                                           hscale_min);
235204007ebaSmrg    TRACE(("hscale = %u.%u\n", (int) hscale,
235304007ebaSmrg           (int) ((hscale - (int) hscale) * 1000)))
2354f29dbc25Smrg
2355f29dbc25Smrg        /* determine hsc where hscale = (1 + hsc/128) */
2356f29dbc25Smrg        if (hscale >= 1.0f)
235704007ebaSmrg        hsc = (int) (128.f * (hscale - 1.0f) + .5f);
2358f29dbc25Smrg    else
235904007ebaSmrg        hsc = (int) (128.f * (hscale - 1.0f) - .5f);
2360f29dbc25Smrg
2361f29dbc25Smrg    TRACE(("hsc = %d\n", hsc))
2362f29dbc25Smrg        if (hsc >= 0)
2363f29dbc25Smrg        houston_WriteReg(HOUSTON_HSC, hsc << 8, 2);
2364f29dbc25Smrg    else
2365f29dbc25Smrg        houston_WriteReg(HOUSTON_HSC, hsc & 0xFF, 2);
2366f29dbc25Smrg
2367f29dbc25Smrg    /* recalculate hscale for future formulas */
2368f29dbc25Smrg    hscale = 1.0f + (hsc / 128.0f);
236904007ebaSmrg    TRACE(("recalculated hscale = %u.%u\n", (int) hscale,
237004007ebaSmrg           (int) ((hscale - (int) hscale) * 1000)))
2371f29dbc25Smrg
2372f29dbc25Smrg        /* horizontal offset. */
2373f29dbc25Smrg        /* place hsync 40 before halfway from vga_width to htotal */
2374f29dbc25Smrg        /* but not less than vga_width + 10 */
2375f29dbc25Smrg        g_specs.h_sync =
2376f29dbc25Smrg        fsmax((g_specs.h_total + g_specs.vga_width) / 2 - 40,
237704007ebaSmrg              g_specs.vga_width + 10);
2378f29dbc25Smrg    /* also, make it even */
2379f29dbc25Smrg    g_specs.h_sync &= ~1;
2380f29dbc25Smrg    TRACE(("hsync = %u\n", g_specs.h_sync))
2381f29dbc25Smrg
2382f29dbc25Smrg        /* iho range is 0 to iho_max. */
2383f29dbc25Smrg        /* iho_max is 2 * iho_center. */
2384f29dbc25Smrg        /* iho_center is pre_pixels - (tvwidth / hscale - vga pixels) / 2. */
2385f29dbc25Smrg        /* pre_pixels = (htotal - hsync) * (vga_pixels / vga_width) */
2386f29dbc25Smrg        /* note that the range is inverted also, because it specifies the number
2387f29dbc25Smrg         * of pixels */
2388f29dbc25Smrg        /* to skip, or subtract.  iho=0 maps to farthest right. */
2389f29dbc25Smrg        /* map -pos_x = +/-1000 into (0 to iho_max) */
2390f29dbc25Smrg        pre_pixels =
239104007ebaSmrg        (int) ((long) (g_specs.h_total -
239204007ebaSmrg                       g_specs.h_sync) * vga_pixels / g_specs.vga_width);
239304007ebaSmrg    iho_max = (2 * pre_pixels) - ((int) (720.0f / hscale + 0.5f) - vga_pixels);
2394f29dbc25Smrg    TRACE(("iho_max = %u\n", iho_max))
2395f29dbc25Smrg        iho =
239604007ebaSmrg        (int) range_limit(((long) (1000 - pos_x) * iho_max / 2000) +
239704007ebaSmrg                          scantable[vga_index].iho[k], 0, iho_max);
2398f29dbc25Smrg    TRACE(("iho = %u\n", iho))
2399f29dbc25Smrg        houston_WriteReg(HOUSTON_IHO, iho, 2);
2400f29dbc25Smrg
2401f29dbc25Smrg    /* input horizontal width. */
2402f29dbc25Smrg
2403f29dbc25Smrg    /* input horizontal width is vga pixels + pre_pixels - iho */
2404f29dbc25Smrg    /* additionally, ihw cannot exceed tv width / hscale */
2405f29dbc25Smrg    /* and if hsc is negative, (ihw)(-hsc/128) cannot exceed ~250. */
2406f29dbc25Smrg    /* and ihw should be even. */
240704007ebaSmrg    ihw = fsmin(vga_pixels + pre_pixels - iho, (int) (720.0f / hscale));
2408f29dbc25Smrg    if (hsc < 0)
240904007ebaSmrg        ihw = (int) fsmin(ihw, 253L * 128 / (-hsc));
2410f29dbc25Smrg    ihw &= ~1;
2411f29dbc25Smrg    TRACE(("ihw = %u\n", ihw))
2412f29dbc25Smrg        houston_WriteReg(HOUSTON_IHA, ihw, 2);
2413f29dbc25Smrg
241404007ebaSmrg    f = (((float) g_specs.h_total * g_specs.v_total) * 27.f) /
241504007ebaSmrg        ((float) g_specs.tv_width * g_specs.tv_lines);
2416f29dbc25Smrg
241704007ebaSmrg    TRACE(("freq=%u.%uMHz\n", (int) f, (int) ((f - (int) f) * 1000)))
2418f29dbc25Smrg}
2419f29dbc25Smrg
2420f29dbc25Smrg/*==========================================================================*/
2421f29dbc25Smrg/* configure houston nco.													*/
2422f29dbc25Smrg/*==========================================================================*/
2423f29dbc25Smrg
2424f29dbc25Smrgstatic void
2425f29dbc25Smrgconfig_nco(unsigned long tv_std, unsigned long vga_mode)
2426f29dbc25Smrg{
2427f29dbc25Smrg    unsigned long cr, misc;
2428f29dbc25Smrg    unsigned long reg;
2429f29dbc25Smrg    int k = map_tvstd_to_index(tv_std);
2430f29dbc25Smrg
2431f29dbc25Smrg    /*read and store CR. */
2432f29dbc25Smrg    houston_ReadReg(HOUSTON_CR, &cr, 2);
2433f29dbc25Smrg
2434f29dbc25Smrg    /*make sure NCO_EN (enable latch) bit is clear */
2435f29dbc25Smrg    cr &= ~CR_NCO_EN;
2436f29dbc25Smrg    houston_WriteReg(HOUSTON_CR, cr, 2);
2437f29dbc25Smrg
2438f29dbc25Smrg    /*clear NCO_LOADX. */
2439f29dbc25Smrg    houston_ReadReg(HOUSTON_MISC, &misc, 2);
2440f29dbc25Smrg    misc &= ~(MISC_NCO_LOAD1 + MISC_NCO_LOAD0);
2441f29dbc25Smrg    houston_WriteReg(HOUSTON_MISC, misc, 2);
2442f29dbc25Smrg
2443f29dbc25Smrg    if (vga_mode == GFX_VGA_MODE_1024X768) {
2444f29dbc25Smrg        /*setup for M and N load (Nco_load=1). */
2445f29dbc25Smrg        misc |= (MISC_NCO_LOAD0);
2446f29dbc25Smrg        houston_WriteReg(HOUSTON_MISC, misc, 2);
2447f29dbc25Smrg
2448f29dbc25Smrg        /*M and N. */
2449f29dbc25Smrg        houston_WriteReg(HOUSTON_NCONL, 1024 - 2, 2);
2450f29dbc25Smrg        houston_WriteReg(HOUSTON_NCODL, 128 - 1, 2);
2451f29dbc25Smrg
2452f29dbc25Smrg        /*latch M/N in. */
2453f29dbc25Smrg        cr |= CR_NCO_EN;
2454f29dbc25Smrg        houston_WriteReg(HOUSTON_CR, cr, 2);
2455f29dbc25Smrg        cr &= ~CR_NCO_EN;
2456f29dbc25Smrg        houston_WriteReg(HOUSTON_CR, cr, 2);
2457f29dbc25Smrg
2458f29dbc25Smrg        /*setup ncon and ncod load (Nco_load=0). */
2459f29dbc25Smrg        misc &= ~(MISC_NCO_LOAD1 + MISC_NCO_LOAD0);
2460f29dbc25Smrg        houston_WriteReg(HOUSTON_MISC, misc, 2);
2461f29dbc25Smrg
2462f29dbc25Smrg        /*NCON. */
246304007ebaSmrg        reg = ((unsigned long) g_specs.v_total * g_specs.h_total) / 2;
2464f29dbc25Smrg        houston_WriteReg(HOUSTON_NCONH, reg >> 16, 2);
2465f29dbc25Smrg        houston_WriteReg(HOUSTON_NCONL, reg & 0xffff, 2);
2466f29dbc25Smrg
2467f29dbc25Smrg        /*NCOD. */
2468f29dbc25Smrg        houston_WriteReg(HOUSTON_NCODL, tvsetup.houston_ncodl[k], 2);
2469f29dbc25Smrg        houston_WriteReg(HOUSTON_NCODH, tvsetup.houston_ncodh[k], 2);
247004007ebaSmrg    }
247104007ebaSmrg    else {
2472f29dbc25Smrg        /*setup for M and N load (Nco_load=2). */
2473f29dbc25Smrg        misc |= (MISC_NCO_LOAD1);
2474f29dbc25Smrg        houston_WriteReg(HOUSTON_MISC, misc, 2);
2475f29dbc25Smrg
2476f29dbc25Smrg        /*NCON. */
247704007ebaSmrg        reg = (unsigned long) g_specs.v_total * g_specs.h_total;
2478f29dbc25Smrg        houston_WriteReg(HOUSTON_NCONH, reg >> 16, 2);
2479f29dbc25Smrg        houston_WriteReg(HOUSTON_NCONL, reg & 0xffff, 2);
2480f29dbc25Smrg
2481f29dbc25Smrg        /*NCOD. */
2482f29dbc25Smrg        houston_WriteReg(HOUSTON_NCODL, tvsetup.houston_ncodl[k], 2);
2483f29dbc25Smrg        houston_WriteReg(HOUSTON_NCODH, tvsetup.houston_ncodh[k], 2);
2484f29dbc25Smrg
2485f29dbc25Smrg        TRACE(("NCON = %lu (0x%08lx), NCOD = %lu (0x%08lx)\n",
248604007ebaSmrg               reg,
248704007ebaSmrg               reg,
248804007ebaSmrg               ((unsigned long) tvsetup.houston_ncodh[k] << 16) +
248904007ebaSmrg               tvsetup.houston_ncodl[k],
249004007ebaSmrg               ((unsigned long) tvsetup.houston_ncodh[k] << 16) +
249104007ebaSmrg               tvsetup.houston_ncodl[k]))
2492f29dbc25Smrg    }
2493f29dbc25Smrg
2494f29dbc25Smrg    /*latch M/N and NCON/NCOD in. */
2495f29dbc25Smrg    cr |= CR_NCO_EN;
2496f29dbc25Smrg    houston_WriteReg(HOUSTON_CR, cr, 2);
2497f29dbc25Smrg    cr &= ~CR_NCO_EN;
2498f29dbc25Smrg    houston_WriteReg(HOUSTON_CR, cr, 2);
2499f29dbc25Smrg}
2500f29dbc25Smrg
2501f29dbc25Smrg/*==========================================================================*/
2502f29dbc25Smrg/* Write sharpness settings to device										*/
2503f29dbc25Smrg/*==========================================================================*/
2504f29dbc25Smrg
2505f29dbc25Smrgstatic void
2506f29dbc25Smrgconfig_sharpness(int sharpness)
2507f29dbc25Smrg{
2508f29dbc25Smrg    unsigned int shp;
2509f29dbc25Smrg
2510f29dbc25Smrg    /*map 0-1000 to 0-20. */
251104007ebaSmrg    shp = (unsigned int) (0.5f + ((float) sharpness * 20.0f / 1000.0f));
2512f29dbc25Smrg    shp = range_limit(shp, 0, 20);
2513f29dbc25Smrg
2514f29dbc25Smrg    houston_WriteReg(HOUSTON_SHP, shp, 2);
2515f29dbc25Smrg}
2516f29dbc25Smrg
2517f29dbc25Smrgstatic void
2518f29dbc25Smrgconget_sharpness(int *p_sharpness)
2519f29dbc25Smrg{
2520f29dbc25Smrg    unsigned long shp;
2521f29dbc25Smrg
2522f29dbc25Smrg    if (!p_sharpness)
2523f29dbc25Smrg        return;
2524f29dbc25Smrg
2525f29dbc25Smrg    houston_ReadReg(HOUSTON_SHP, &shp, 2);
2526f29dbc25Smrg
2527f29dbc25Smrg    /*map 0-20 to 0-1000. */
252804007ebaSmrg    *p_sharpness = (int) (0.5f + ((float) shp * 1000.0f / 20.0f));
2529f29dbc25Smrg}
2530f29dbc25Smrg
2531f29dbc25Smrg/*==========================================================================*/
2532f29dbc25Smrg/* Write flicker settings to device											*/
2533f29dbc25Smrg/*==========================================================================*/
2534f29dbc25Smrg
2535f29dbc25Smrgstatic void
2536f29dbc25Smrgconfig_flicker(int flicker)
2537f29dbc25Smrg{
2538f29dbc25Smrg    unsigned int flk;
2539f29dbc25Smrg
2540f29dbc25Smrg    /*map 0-1000 to 0-16. */
254104007ebaSmrg    flk = (unsigned int) (0.5f + ((float) flicker * 16.0f / 1000.0f));
2542f29dbc25Smrg    flk = range_limit(flk, 0, 16);
2543f29dbc25Smrg
2544f29dbc25Smrg    houston_WriteReg(HOUSTON_FLK, flk, 2);
2545f29dbc25Smrg}
2546f29dbc25Smrg
2547f29dbc25Smrgstatic void
2548f29dbc25Smrgconget_flicker(int *p_flicker)
2549f29dbc25Smrg{
2550f29dbc25Smrg    unsigned long flk;
2551f29dbc25Smrg
2552f29dbc25Smrg    if (!p_flicker)
2553f29dbc25Smrg        return;
2554f29dbc25Smrg
2555f29dbc25Smrg    houston_ReadReg(HOUSTON_FLK, &flk, 2);
2556f29dbc25Smrg
2557f29dbc25Smrg    /*map 0-16 to 0-1000. */
255804007ebaSmrg    *p_flicker = (int) (0.5f + ((float) flk * 1000.0f / 16.0f));
2559f29dbc25Smrg}
2560f29dbc25Smrg
2561f29dbc25Smrg/*==========================================================================*/
2562f29dbc25Smrg/* Write color settings to device											*/
2563f29dbc25Smrg/*==========================================================================*/
2564f29dbc25Smrg
2565f29dbc25Smrgstatic void
2566f29dbc25Smrgconfig_color(int color)
2567f29dbc25Smrg{
2568f29dbc25Smrg    unsigned long clr;
2569f29dbc25Smrg
2570f29dbc25Smrg    /*map 0-100 to 0-255. */
2571f29dbc25Smrg    /*montreal production test needs 169 to be mappable, so */
2572f29dbc25Smrg    /*use .8 rounding factor, 169=(int)(66.*2.55+.8). */
257304007ebaSmrg    clr = (unsigned long) (0.8f + ((float) color * 255.0f / 100.0f));
2574f29dbc25Smrg    clr = range_limit(clr, 0, 255);
2575f29dbc25Smrg
2576f29dbc25Smrg    houston_WriteReg(ENC_CR_GAIN, clr, 1);
2577f29dbc25Smrg    houston_WriteReg(ENC_CB_GAIN, clr, 1);
2578f29dbc25Smrg}
2579f29dbc25Smrg
2580f29dbc25Smrgstatic void
2581f29dbc25Smrgconget_color(int *p_color)
2582f29dbc25Smrg{
2583f29dbc25Smrg    unsigned long cr_gain;
2584f29dbc25Smrg
2585f29dbc25Smrg    if (!p_color)
2586f29dbc25Smrg        return;
2587f29dbc25Smrg
2588f29dbc25Smrg    /*just get CR GAIN, CB GAIN should match. */
2589f29dbc25Smrg    houston_ReadReg(ENC_CR_GAIN, &cr_gain, 1);
2590f29dbc25Smrg
2591f29dbc25Smrg    /*map 0-255 to 0-100. */
259204007ebaSmrg    *p_color = (int) (0.5f + ((float) cr_gain * 100.0f / 255.0f));
2593f29dbc25Smrg}
2594f29dbc25Smrg
2595f29dbc25Smrg/*==========================================================================*/
2596f29dbc25Smrg/* Write brightness and contrast settings to device							*/
2597f29dbc25Smrg/*==========================================================================*/
2598f29dbc25Smrg
2599f29dbc25Smrg#define	NTSC_BLANK_LEVEL	240
2600f29dbc25Smrg
2601f29dbc25Smrgstatic const int min_black_level = NTSC_BLANK_LEVEL + 1;
2602f29dbc25Smrgstatic const int max_white_level = 1023;
2603f29dbc25Smrg
2604f29dbc25Smrgstatic void
2605f29dbc25Smrgconfig_brightness_contrast(unsigned long tv_std, unsigned int trigger_bits,
260604007ebaSmrg                           int brightness, int contrast)
2607f29dbc25Smrg{
2608f29dbc25Smrg    int brightness_off;
2609f29dbc25Smrg    float contrast_mult;
2610f29dbc25Smrg    int black, white;
2611f29dbc25Smrg    unsigned short w;
2612f29dbc25Smrg    int k = map_tvstd_to_index(tv_std);
2613f29dbc25Smrg
2614f29dbc25Smrg    /*0-100 maps to +/-220. */
2615f29dbc25Smrg    brightness_off =
261604007ebaSmrg        (int) (0.5f + ((float) brightness * 440.0f / 100.0f)) - 220;
2617f29dbc25Smrg
2618f29dbc25Smrg    /*0-100 maps to .75-1.25. */
261904007ebaSmrg    contrast_mult = ((float) contrast * 0.5f / 100.0f) + 0.75f;
2620f29dbc25Smrg
2621f29dbc25Smrg    black = tvsetup.black_level[k];
2622f29dbc25Smrg    if (trigger_bits != 0)
2623f29dbc25Smrg        black -= tvsetup.hamp_offset[k];
2624f29dbc25Smrg
2625f29dbc25Smrg    white = tvsetup.white_level[k];
2626f29dbc25Smrg    if (trigger_bits != 0)
2627f29dbc25Smrg        white -= tvsetup.hamp_offset[k];
2628f29dbc25Smrg
262904007ebaSmrg    black = (int) ((float) (black + brightness_off) * contrast_mult);
263004007ebaSmrg    white = (int) ((float) (white + brightness_off) * contrast_mult);
2631f29dbc25Smrg    if (black < min_black_level)
2632f29dbc25Smrg        black = min_black_level;
2633f29dbc25Smrg    if (white > max_white_level)
2634f29dbc25Smrg        white = max_white_level;
2635f29dbc25Smrg
263604007ebaSmrg    w = w10bit2z((unsigned short) black);
2637f29dbc25Smrg    houston_WriteReg(ENC_BLACK_LEVEL, w & 0x00ff, 1);
2638f29dbc25Smrg    houston_WriteReg(ENC_BLACK_LEVEL + 1, w >> 8, 1);
263904007ebaSmrg    w = w10bit2z((unsigned short) white);
2640f29dbc25Smrg    houston_WriteReg(ENC_WHITE_LEVEL, w & 0x00ff, 1);
2641f29dbc25Smrg    houston_WriteReg(ENC_WHITE_LEVEL + 1, w >> 8, 1);
2642f29dbc25Smrg}
2643f29dbc25Smrg
2644f29dbc25Smrgstatic void
2645f29dbc25Smrgconget_brightness_contrast(unsigned long tv_std, unsigned int trigger_bits,
264604007ebaSmrg                           int *p_brightness, int *p_contrast)
2647f29dbc25Smrg{
2648f29dbc25Smrg    int brightness_off;
2649f29dbc25Smrg    float contrast_mult;
2650f29dbc25Smrg    unsigned short black, white;
2651f29dbc25Smrg    unsigned long zh, zl;
2652f29dbc25Smrg    int k;
2653f29dbc25Smrg
2654f29dbc25Smrg    if (!p_brightness || !p_contrast)
2655f29dbc25Smrg        return;
2656f29dbc25Smrg
2657f29dbc25Smrg    k = map_tvstd_to_index(tv_std);
2658f29dbc25Smrg
2659f29dbc25Smrg    houston_ReadReg(ENC_BLACK_LEVEL, &zl, 1);
2660f29dbc25Smrg    houston_ReadReg(ENC_BLACK_LEVEL + 1, &zh, 1);
266104007ebaSmrg    black = z2w10bit((unsigned short) (zl + (zh << 8)));
2662f29dbc25Smrg    if (trigger_bits != 0)
2663f29dbc25Smrg        black += tvsetup.hamp_offset[k];
2664f29dbc25Smrg    houston_ReadReg(ENC_WHITE_LEVEL, &zl, 1);
2665f29dbc25Smrg    houston_ReadReg(ENC_WHITE_LEVEL + 1, &zh, 1);
266604007ebaSmrg    white = z2w10bit((unsigned short) (zl + (zh << 8)));
2667f29dbc25Smrg    if (trigger_bits != 0)
2668f29dbc25Smrg        white += tvsetup.hamp_offset[k];
2669f29dbc25Smrg
2670f29dbc25Smrg    /*this reverse computation does not account for clipping, but should */
2671f29dbc25Smrg    /*provide somewhat reasonable numbers */
2672f29dbc25Smrg    contrast_mult =
267304007ebaSmrg        ((float) white - (float) black) / ((float) tvsetup.white_level[k] -
267404007ebaSmrg                                           (float) tvsetup.black_level[k]);
2675f29dbc25Smrg    brightness_off =
267604007ebaSmrg        (int) (((float) black / contrast_mult) - tvsetup.black_level[k]);
2677f29dbc25Smrg
2678f29dbc25Smrg    /*+/-220 maps to 0-100. */
2679f29dbc25Smrg    *p_brightness =
268004007ebaSmrg        range_limit((int) (0.5f + ((float) (brightness_off +
268104007ebaSmrg                                            220) * 100.0f / 440.0f)), 0, 100);
2682f29dbc25Smrg
2683f29dbc25Smrg    /*.75-1.25 maps to 0-100. */
2684f29dbc25Smrg    *p_contrast =
268504007ebaSmrg        range_limit((int) (0.5f + ((float) (contrast_mult -
268604007ebaSmrg                                            0.75f) * 100.0f / 0.5f)), 0, 100);
2687f29dbc25Smrg}
2688f29dbc25Smrg
2689f29dbc25Smrg/*==========================================================================*/
2690f29dbc25Smrg/* configure luma/chroma filters.											*/
2691f29dbc25Smrg/*==========================================================================*/
2692f29dbc25Smrg
2693f29dbc25Smrgstatic void
2694f29dbc25Smrgconfig_yc_filter(unsigned long tv_std, int luma_filter, int chroma_filter)
2695f29dbc25Smrg{
2696f29dbc25Smrg    unsigned long reg, reg07, reg34;
2697f29dbc25Smrg
2698f29dbc25Smrg    if (houston_Rev() < HOUSTON_REV_B)
2699f29dbc25Smrg        return;
2700f29dbc25Smrg
2701f29dbc25Smrg    /*luma filter. */
2702f29dbc25Smrg    if (luma_filter)
2703f29dbc25Smrg        reg = tvsetup.notch_filter[map_tvstd_to_index(tv_std)];
2704f29dbc25Smrg    else
2705f29dbc25Smrg        reg = 0;
2706f29dbc25Smrg    houston_WriteReg(ENC_NOTCH_FILTER, reg, 1);
2707f29dbc25Smrg
2708f29dbc25Smrg    /*chroma filter. */
2709f29dbc25Smrg    houston_ReadReg(ENC_REG07, &reg07, 1);
2710f29dbc25Smrg    houston_ReadReg(ENC_REG34, &reg34, 1);
2711f29dbc25Smrg    if (chroma_filter) {
2712f29dbc25Smrg        reg07 &= ~0x08;
2713f29dbc25Smrg        reg34 &= ~0x20;
271404007ebaSmrg    }
271504007ebaSmrg    else {
2716f29dbc25Smrg        reg07 |= 0x08;
2717f29dbc25Smrg        reg34 |= 0x20;
2718f29dbc25Smrg    }
2719f29dbc25Smrg    houston_WriteReg(ENC_REG07, reg07, 1);
2720f29dbc25Smrg    houston_WriteReg(ENC_REG34, reg34, 1);
2721f29dbc25Smrg}
2722f29dbc25Smrg
2723f29dbc25Smrgstatic void
2724f29dbc25Smrgconget_yc_filter(int *p_luma_filter, int *p_chroma_filter)
2725f29dbc25Smrg{
2726f29dbc25Smrg    unsigned long reg, reg07, reg34;
2727f29dbc25Smrg
2728f29dbc25Smrg    if (!p_luma_filter || !p_chroma_filter)
2729f29dbc25Smrg        return;
2730f29dbc25Smrg
2731f29dbc25Smrg    if (houston_Rev() < HOUSTON_REV_B) {
2732f29dbc25Smrg        *p_luma_filter = 0;
2733f29dbc25Smrg        *p_chroma_filter = 0;
2734f29dbc25Smrg        return;
2735f29dbc25Smrg    }
2736f29dbc25Smrg
2737f29dbc25Smrg    /*luma filter. */
2738f29dbc25Smrg    houston_ReadReg(ENC_NOTCH_FILTER, &reg, 1);
2739f29dbc25Smrg    *p_luma_filter = (reg ? 1 : 0);
2740f29dbc25Smrg
2741f29dbc25Smrg    /*chroma filter. */
2742f29dbc25Smrg    houston_ReadReg(ENC_REG07, &reg07, 1);
2743f29dbc25Smrg    houston_ReadReg(ENC_REG34, &reg34, 1);
2744f29dbc25Smrg    *p_chroma_filter = !((0x08 & reg07) || (0x20 & reg34));
2745f29dbc25Smrg}
2746f29dbc25Smrg
2747f29dbc25Smrg/*==========================================================================*/
2748f29dbc25Smrg/* Macrovision																*/
2749f29dbc25Smrg/*==========================================================================*/
2750f29dbc25Smrg
2751f29dbc25Smrgstatic void
2752f29dbc25Smrgconfig_macrovision(unsigned long tv_std, unsigned int trigger_bits)
2753f29dbc25Smrg{
2754f29dbc25Smrg/*Constants to index into mvsetup columns.*/
275504007ebaSmrg#define	nNTSC_APS00		0       /*ntsc mv off.                   */
275604007ebaSmrg#define	nNTSC_APS01		1       /*ntsc AGC only.                 */
275704007ebaSmrg#define	nNTSC_APS10		2       /*ntsc AGC + 2-line CS.  */
275804007ebaSmrg#define	nNTSC_APS11		3       /*ntsc AGC + 4-line CS.  */
275904007ebaSmrg#define	nPAL_APS00		4       /*pal mv off.                    */
276004007ebaSmrg#define	nPAL_APSXX		5       /*pal mv on.                     */
2761f29dbc25Smrg#define	nMVModes		6
2762f29dbc25Smrg
2763f29dbc25Smrg    /*Macrovision setup table. */
276404007ebaSmrg    static const struct mvparms {
2765f29dbc25Smrg        unsigned short n0[nMVModes];
2766f29dbc25Smrg        unsigned short n1[nMVModes];
2767f29dbc25Smrg        unsigned short n2[nMVModes];
2768f29dbc25Smrg        unsigned short n3[nMVModes];
2769f29dbc25Smrg        unsigned short n4[nMVModes];
2770f29dbc25Smrg        unsigned short n5[nMVModes];
2771f29dbc25Smrg        unsigned short n6[nMVModes];
2772f29dbc25Smrg        unsigned short n7[nMVModes];
2773f29dbc25Smrg        unsigned short n8[nMVModes];
2774f29dbc25Smrg        unsigned short n9[nMVModes];
2775f29dbc25Smrg        unsigned short n10[nMVModes];
2776f29dbc25Smrg        unsigned short n11[nMVModes];
2777f29dbc25Smrg        unsigned short n12[nMVModes];
2778f29dbc25Smrg        unsigned short n13[nMVModes];
2779f29dbc25Smrg        unsigned short n14[nMVModes];
2780f29dbc25Smrg        unsigned short n15[nMVModes];
2781f29dbc25Smrg        unsigned short n16[nMVModes];
2782f29dbc25Smrg        unsigned short n17[nMVModes];
2783f29dbc25Smrg        unsigned short n18[nMVModes];
2784f29dbc25Smrg        unsigned short n19[nMVModes];
2785f29dbc25Smrg        unsigned short n20[nMVModes];
2786f29dbc25Smrg        unsigned short n21[nMVModes];
2787f29dbc25Smrg        unsigned short n22[nMVModes];
2788f29dbc25Smrg        unsigned short agc_pulse_level[nMVModes];
2789f29dbc25Smrg        unsigned short bp_pulse_level[nMVModes];
279004007ebaSmrg    } mvsetup = {
2791f29dbc25Smrg        /*    ntsc    ntsc    ntsc    ntsc    pal             pal */
2792f29dbc25Smrg        /*    MV      AGC     AGC +   AGC +   MV              MV */
2793f29dbc25Smrg        /*    off.    only    2-line  4-line  off.    on. */
2794f29dbc25Smrg        /*    CS.             CS. */
2795f29dbc25Smrg        {
2796f29dbc25Smrg        0x00, 0x36, 0x3e, 0x3e, 0x00, 0x3e},    /*n0 */
2797f29dbc25Smrg        {
2798f29dbc25Smrg        0x1d, 0x1d, 0x1d, 0x17, 0x1a, 0x1a},    /*n1 */
2799f29dbc25Smrg        {
2800f29dbc25Smrg        0x11, 0x11, 0x11, 0x15, 0x22, 0x22},    /*n2 */
2801f29dbc25Smrg        {
2802f29dbc25Smrg        0x25, 0x25, 0x25, 0x21, 0x2a, 0x2a},    /*n3 */
2803f29dbc25Smrg        {
2804f29dbc25Smrg        0x11, 0x11, 0x11, 0x15, 0x22, 0x22},    /*n4 */
2805f29dbc25Smrg        {
2806f29dbc25Smrg        0x01, 0x01, 0x01, 0x05, 0x05, 0x05},    /*n5 */
2807f29dbc25Smrg        {
2808f29dbc25Smrg        0x07, 0x07, 0x07, 0x05, 0x02, 0x02},    /*n6 */
2809f29dbc25Smrg        {
2810f29dbc25Smrg        0x00, 0x00, 0x00, 0x02, 0x00, 0x00},    /*n7 */
2811f29dbc25Smrg        {
2812f29dbc25Smrg        0x1b, 0x1b, 0x1b, 0x1b, 0x1c, 0x1c},    /*n8 */
2813f29dbc25Smrg        {
2814f29dbc25Smrg        0x1b, 0x1b, 0x1b, 0x1b, 0x3d, 0x3d},    /*n9 */
2815f29dbc25Smrg        {
2816f29dbc25Smrg        0x24, 0x24, 0x24, 0x24, 0x14, 0x14},    /*n10 */
2817f29dbc25Smrg        {
2818f29dbc25Smrg        0x780f, 0x780f, 0x780f, 0x780f, 0x7e07, 0x7e07},        /*n11 */
2819f29dbc25Smrg        {
2820f29dbc25Smrg        0x0000, 0x0000, 0x0000, 0x0000, 0x5402, 0x5402},        /*n12 */
2821f29dbc25Smrg        {
2822f29dbc25Smrg        0x0f, 0x0f, 0x0f, 0x0f, 0xfe, 0xfe},    /*n13 */
2823f29dbc25Smrg        {
2824f29dbc25Smrg        0x0f, 0x0f, 0x0f, 0x0f, 0x7e, 0x7e},    /*n14 */
2825f29dbc25Smrg        {
2826f29dbc25Smrg        0x60, 0x60, 0x60, 0x60, 0x60, 0x60},    /*n15 */
2827f29dbc25Smrg        {
2828f29dbc25Smrg        0x01, 0x01, 0x01, 0x01, 0x00, 0x00},    /*n16 */
2829f29dbc25Smrg        {
2830f29dbc25Smrg        0x0a, 0x0a, 0x0a, 0x0a, 0x08, 0x08},    /*n17 */
2831f29dbc25Smrg        {
2832f29dbc25Smrg        0x00, 0x00, 0x00, 0x00, 0x00, 0x00},    /*n18 */
2833f29dbc25Smrg        {
2834f29dbc25Smrg        0x05, 0x05, 0x05, 0x05, 0x04, 0x04},    /*n19 */
2835f29dbc25Smrg        {
2836f29dbc25Smrg        0x04, 0x04, 0x04, 0x04, 0x07, 0x07},    /*n20 */
2837f29dbc25Smrg        {
2838f29dbc25Smrg        0x03ff, 0x03ff, 0x03ff, 0x03ff, 0x0155, 0x0155},        /*n21 */
2839f29dbc25Smrg        {
2840f29dbc25Smrg        0x00, 0x00, 0x00, 0x00, 0x00, 0x00},    /*n22 */
2841f29dbc25Smrg        {
2842f29dbc25Smrg        0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3},    /*agc_pulse_level */
2843f29dbc25Smrg        {
2844f29dbc25Smrg        0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8},    /*bp_pulse_level */
2845f29dbc25Smrg    };
2846f29dbc25Smrg
2847f29dbc25Smrg    int nMode;
2848f29dbc25Smrg    unsigned long misc;
2849f29dbc25Smrg    unsigned short n0;
2850f29dbc25Smrg
2851f29dbc25Smrg    trigger_bits &= 0x3;
2852f29dbc25Smrg
2853f29dbc25Smrg    /*Determine the OEM Macrovision Program Mode and Register 0 Data. */
2854f29dbc25Smrg    if (IS_NTSC(tv_std)) {
2855f29dbc25Smrg        /*NTSC TV Standard. */
2856f29dbc25Smrg        if (trigger_bits == 0) {
2857f29dbc25Smrg            /*turn Macrovision OFF. */
2858f29dbc25Smrg            nMode = nNTSC_APS00;
285904007ebaSmrg        }
286004007ebaSmrg        else if (trigger_bits == 1) {
2861f29dbc25Smrg            /*AGC Only. */
2862f29dbc25Smrg            nMode = nNTSC_APS01;
286304007ebaSmrg        }
286404007ebaSmrg        else if (trigger_bits == 2) {
2865f29dbc25Smrg            /*AGC + 2-line CS. */
2866f29dbc25Smrg            nMode = nNTSC_APS10;
286704007ebaSmrg        }
286804007ebaSmrg        else {
2869f29dbc25Smrg            /*AGC + 4-line CS. */
2870f29dbc25Smrg            nMode = nNTSC_APS11;
2871f29dbc25Smrg        }
287204007ebaSmrg    }
287304007ebaSmrg    else {
2874f29dbc25Smrg        /*PAL TV Standard. */
2875f29dbc25Smrg        if (trigger_bits == 0) {
2876f29dbc25Smrg            /*turn Macrovision OFF. */
2877f29dbc25Smrg            nMode = nPAL_APS00;
287804007ebaSmrg        }
287904007ebaSmrg        else {
2880f29dbc25Smrg            /*APS 01, 10, or 11. */
2881f29dbc25Smrg            nMode = nPAL_APSXX;
2882f29dbc25Smrg        }
2883f29dbc25Smrg    }
2884f29dbc25Smrg
2885f29dbc25Smrg    /*Retrieve the Macrovision Program Mode Data */
2886f29dbc25Smrg    if (tv_std != GFX_TV_STANDARD_PAL_M)
2887f29dbc25Smrg        n0 = mvsetup.n0[nMode];
2888f29dbc25Smrg    else {
2889f29dbc25Smrg        /*PAL-M sets up like NTSC except for n0. */
2890f29dbc25Smrg        if ((trigger_bits & 0x03) == 0)
2891f29dbc25Smrg            n0 = mvsetup.n0[nPAL_APS00];
2892f29dbc25Smrg        else
2893f29dbc25Smrg            n0 = mvsetup.n0[nPAL_APSXX];
2894f29dbc25Smrg    }
2895f29dbc25Smrg
2896f29dbc25Smrg    /*download settings now. */
2897f29dbc25Smrg    houston_WriteReg(MV_N0, n0, 1);
2898f29dbc25Smrg    houston_WriteReg(MV_N1, mvsetup.n1[nMode], 1);
2899f29dbc25Smrg    houston_WriteReg(MV_N2, mvsetup.n2[nMode], 1);
2900f29dbc25Smrg    houston_WriteReg(MV_N3, mvsetup.n3[nMode], 1);
2901f29dbc25Smrg    houston_WriteReg(MV_N4, mvsetup.n4[nMode], 1);
2902f29dbc25Smrg    houston_WriteReg(MV_N5, mvsetup.n5[nMode], 1);
2903f29dbc25Smrg    houston_WriteReg(MV_N6, mvsetup.n6[nMode], 1);
2904f29dbc25Smrg    houston_WriteReg(MV_N7, mvsetup.n7[nMode], 1);
2905f29dbc25Smrg    houston_WriteReg(MV_N8, mvsetup.n8[nMode], 1);
2906f29dbc25Smrg    houston_WriteReg(MV_N9, mvsetup.n9[nMode], 1);
2907f29dbc25Smrg    houston_WriteReg(MV_N10, mvsetup.n10[nMode], 1);
2908f29dbc25Smrg    houston_WriteReg(MV_N11, mvsetup.n11[nMode] & 0xff, 1);
2909f29dbc25Smrg    houston_WriteReg(MV_N11 + 1, mvsetup.n11[nMode] >> 8, 1);
2910f29dbc25Smrg    houston_WriteReg(MV_N12, mvsetup.n12[nMode] & 0xff, 1);
2911f29dbc25Smrg    houston_WriteReg(MV_N12 + 1, mvsetup.n12[nMode] >> 8, 1);
2912f29dbc25Smrg    houston_WriteReg(MV_N13, mvsetup.n13[nMode], 1);
2913f29dbc25Smrg    houston_WriteReg(MV_N14, mvsetup.n14[nMode], 1);
2914f29dbc25Smrg    houston_WriteReg(MV_N15, mvsetup.n15[nMode], 1);
2915f29dbc25Smrg    houston_WriteReg(MV_N16, mvsetup.n16[nMode], 1);
2916f29dbc25Smrg    houston_WriteReg(MV_N17, mvsetup.n17[nMode], 1);
2917f29dbc25Smrg    houston_WriteReg(MV_N18, mvsetup.n18[nMode], 1);
2918f29dbc25Smrg    houston_WriteReg(MV_N19, mvsetup.n19[nMode], 1);
2919f29dbc25Smrg    houston_WriteReg(MV_N20, mvsetup.n20[nMode], 1);
2920f29dbc25Smrg    houston_WriteReg(MV_N21, mvsetup.n21[nMode] & 0xff, 1);
2921f29dbc25Smrg    houston_WriteReg(MV_N21 + 1, mvsetup.n21[nMode] >> 8, 1);
2922f29dbc25Smrg    houston_WriteReg(MV_N22, mvsetup.n22[nMode], 1);
2923f29dbc25Smrg    houston_WriteReg(MV_AGC_PULSE_LEVEL, mvsetup.agc_pulse_level[nMode], 1);
2924f29dbc25Smrg    houston_WriteReg(MV_BP_PULSE_LEVEL, mvsetup.bp_pulse_level[nMode], 1);
2925f29dbc25Smrg
2926f29dbc25Smrg    houston_ReadReg(HOUSTON_MISC, &misc, 2);
2927f29dbc25Smrg    if (trigger_bits == 0)
2928f29dbc25Smrg        misc &= ~MISC_MV_SOFT_EN;
2929f29dbc25Smrg    else
2930f29dbc25Smrg        misc |= MISC_MV_SOFT_EN;
2931f29dbc25Smrg    houston_WriteReg(HOUSTON_MISC, misc, 2);
2932f29dbc25Smrg}
2933f29dbc25Smrg
2934f29dbc25Smrgstatic void
2935f29dbc25Smrgconget_macrovision(unsigned long tv_std, unsigned int *p_cp_trigger_bits)
2936f29dbc25Smrg{
2937f29dbc25Smrg    unsigned long n0, n1;
2938f29dbc25Smrg
2939f29dbc25Smrg    if (!p_cp_trigger_bits)
2940f29dbc25Smrg        return;
2941f29dbc25Smrg
2942f29dbc25Smrg    houston_ReadReg(MV_N0, &n0, 1);
2943f29dbc25Smrg    houston_ReadReg(MV_N1, &n1, 1);
2944f29dbc25Smrg
2945f29dbc25Smrg    *p_cp_trigger_bits = 0;
2946f29dbc25Smrg
2947f29dbc25Smrg    if (IS_NTSC(tv_std)) {
2948f29dbc25Smrg        switch (n0) {
2949f29dbc25Smrg        case 0:
2950f29dbc25Smrg            *p_cp_trigger_bits = 0;
2951f29dbc25Smrg            break;
2952f29dbc25Smrg
2953f29dbc25Smrg        case 0x36:
2954f29dbc25Smrg            *p_cp_trigger_bits = 1;
2955f29dbc25Smrg            break;
2956f29dbc25Smrg
2957f29dbc25Smrg        case 0x3E:
295804007ebaSmrg        {
295904007ebaSmrg            if (0x1D == n1)
296004007ebaSmrg                *p_cp_trigger_bits = 2;
296104007ebaSmrg            else
296204007ebaSmrg                *p_cp_trigger_bits = 3;
296304007ebaSmrg        }
2964f29dbc25Smrg            break;
2965f29dbc25Smrg        }
296604007ebaSmrg    }
296704007ebaSmrg    else if (IS_PAL(tv_std)) {
2968f29dbc25Smrg        if (0 == n0)
2969f29dbc25Smrg            *p_cp_trigger_bits = 0;
2970f29dbc25Smrg        else {
2971f29dbc25Smrg            /*don't know here what the non-zero trigger bits were */
2972f29dbc25Smrg            *p_cp_trigger_bits = 1;
2973f29dbc25Smrg        }
2974f29dbc25Smrg    }
2975f29dbc25Smrg}
2976f29dbc25Smrg
2977f29dbc25Smrg/* PLAL_MediaGX.cpp															*/
2978f29dbc25Smrg/*==========================================================================*/
2979f29dbc25Smrg/* These functions provides implementation of platform-specific functions	*/
2980f29dbc25Smrg/* MediaGX platform.														*/
2981f29dbc25Smrg/*==========================================================================*/
2982f29dbc25Smrg
2983f29dbc25Smrg/*MediaGX control registers.*/
2984f29dbc25Smrg#define CCR3	0xC3
2985f29dbc25Smrg#define	GCR		0xb8
2986f29dbc25Smrg
2987f29dbc25Smrg/*Media GX general config register.*/
2988f29dbc25Smrg#define	GX_DCLK_MUL			0x00c0
2989f29dbc25Smrg#define	GX_DCLKx1			0x0040
2990f29dbc25Smrg#define	GX_DCLKx2			0x0080
2991f29dbc25Smrg#define GX_DCLKx4			0x00c0
2992f29dbc25Smrg
2993f29dbc25Smrg/*Media GX timing config register.*/
2994f29dbc25Smrg#define	GX_TGEN				0x0020
2995f29dbc25Smrg
2996f29dbc25Smrg/*Cx5530 register offsets (from GX_BASE).*/
2997f29dbc25Smrg#define	CX_DISPLAY_CONFIG	0x10004
2998f29dbc25Smrg#define	CX_DOT_CLK			0x10024
2999f29dbc25Smrg#define	CX_TV_CONFIG		0x10028
3000f29dbc25Smrg
3001f29dbc25Smrg/*Cx5530 display configuration register.*/
3002f29dbc25Smrg#define	CX_FPVSYNC_POL		0x0800
3003f29dbc25Smrg#define	CX_FPHSYNC_POL		0x0400
3004f29dbc25Smrg#define	CX_FPDATA_ENB		0x0080
3005f29dbc25Smrg#define	CX_FPPOWER_ENB		0x0040
3006f29dbc25Smrg#define CX_CRTVSYNC_POL		0x0200
3007f29dbc25Smrg#define CX_CRTHSYNC_POL		0x0100
3008f29dbc25Smrg
3009f29dbc25Smrg/*Cx5530 dot clock configuration register.*/
3010f29dbc25Smrg#define	CX_TVCLK_SELECT		0x0400
3011f29dbc25Smrg
3012f29dbc25Smrg/*Cx5530 tv configuration register*/
3013f29dbc25Smrg#define CX_INVERT_FPCLK (1 << 6)
3014f29dbc25Smrg
3015f29dbc25Smrg/*==========================================================================
3016f29dbc25Smrg *	FS450 I2C Address
3017f29dbc25Smrg *	There are two possible 7-bit addresses, 0x4A and 0x6A.
3018f29dbc25Smrg *	The address if selectable via pins on the FS450.
3019f29dbc25Smrg *	There are also two possible 10-bit addresses, 0x224 and 0x276, but this
3020f29dbc25Smrg *	source is not designed to use them.
3021f29dbc25Smrg *==========================================================================*/
3022f29dbc25Smrg
3023f29dbc25Smrg#define	FS450_I2C_ADDRESS (0x4A)
3024f29dbc25Smrg
3025f29dbc25Smrgstatic unsigned char
3026f29dbc25SmrgPLAL_FS450_i2c_address(void)
3027f29dbc25Smrg{
3028f29dbc25Smrg    return FS450_I2C_ADDRESS;
3029f29dbc25Smrg}
3030f29dbc25Smrg
3031f29dbc25Smrg/*==========================================================================
3032f29dbc25Smrg *	FS450 UIM mode
3033f29dbc25Smrg *	This mode is programmed in the FS450 command register when enabling TV
3034f29dbc25Smrg *	out.
3035f29dbc25Smrg *==========================================================================
3036f29dbc25Smrg */
3037f29dbc25Smrgstatic int
3038f29dbc25SmrgPLAL_FS450_UIM_mode(void)
3039f29dbc25Smrg{
3040f29dbc25Smrg    return 3;
3041f29dbc25Smrg}
3042f29dbc25Smrg
3043f29dbc25Smrg/*==========================================================================*/
3044f29dbc25Smrg/* Read and Write MediaGX registers											*/
3045f29dbc25Smrg/*==========================================================================*/
3046f29dbc25Smrgstatic unsigned long
3047f29dbc25SmrgReadGx(unsigned long inRegAddr)
3048f29dbc25Smrg{
3049f29dbc25Smrg    unsigned long data;
3050f29dbc25Smrg
3051f29dbc25Smrg    DMAL_ReadUInt32(inRegAddr, &data);
3052f29dbc25Smrg
3053f29dbc25Smrg    return data;
3054f29dbc25Smrg}
3055f29dbc25Smrg
3056f29dbc25Smrgstatic void
3057f29dbc25SmrgWriteGx(unsigned long inRegAddr, unsigned long inData)
3058f29dbc25Smrg{
3059f29dbc25Smrg    int is_timing_register;
3060f29dbc25Smrg    unsigned long reg_timing_cfg;
3061f29dbc25Smrg
3062f29dbc25Smrg    /*because the unlock register for the MediaGx video registers may not */
3063f29dbc25Smrg    /*persist, we will write the unlock code before every write. */
3064f29dbc25Smrg    DMAL_WriteUInt32(DC_UNLOCK, 0x4758);
3065f29dbc25Smrg
3066f29dbc25Smrg    /*see if register is a timing register */
3067f29dbc25Smrg    is_timing_register =
3068f29dbc25Smrg        (DC_H_TIMING_1 == inRegAddr) ||
3069f29dbc25Smrg        (DC_H_TIMING_2 == inRegAddr) ||
3070f29dbc25Smrg        (DC_H_TIMING_3 == inRegAddr) ||
3071f29dbc25Smrg        (DC_FP_H_TIMING == inRegAddr) ||
3072f29dbc25Smrg        (DC_V_TIMING_1 == inRegAddr) ||
3073f29dbc25Smrg        (DC_V_TIMING_2 == inRegAddr) ||
3074f29dbc25Smrg        (DC_V_TIMING_3 == inRegAddr) || (DC_FP_V_TIMING == inRegAddr);
3075f29dbc25Smrg
3076f29dbc25Smrg    /*if the register is a timing register, clear the TGEN bit to allow
3077f29dbc25Smrg     * modification */
3078f29dbc25Smrg    if (is_timing_register) {
3079f29dbc25Smrg        DMAL_ReadUInt32(DC_TIMING_CFG, &reg_timing_cfg);
3080f29dbc25Smrg        DMAL_WriteUInt32(DC_TIMING_CFG, reg_timing_cfg & ~GX_TGEN);
3081f29dbc25Smrg    }
3082f29dbc25Smrg
3083f29dbc25Smrg    /*write the requested register */
3084f29dbc25Smrg    DMAL_WriteUInt32(inRegAddr, inData);
3085f29dbc25Smrg
3086f29dbc25Smrg    /*reset the TGEN bit to previous state */
3087f29dbc25Smrg    if (is_timing_register) {
3088f29dbc25Smrg        DMAL_WriteUInt32(DC_TIMING_CFG, reg_timing_cfg);
3089f29dbc25Smrg    }
3090f29dbc25Smrg}
3091f29dbc25Smrg
3092f29dbc25Smrg#ifdef FS450_DIRECTREG
3093f29dbc25Smrg
3094f29dbc25Smrg/*==========================================================================*/
3095f29dbc25Smrg/*	Platform-specific processing for a Read or Write Register calls.		*/
3096f29dbc25Smrg/*	The functions should return true if the specified register belongs to	*/
3097f29dbc25Smrg/*	this platform.															*/
3098f29dbc25Smrg/*==========================================================================*/
3099f29dbc25Smrg
3100f29dbc25Smrgstatic int
3101f29dbc25SmrgPLAL_ReadRegister(S_REG_INFO * p_reg)
3102f29dbc25Smrg{
3103f29dbc25Smrg    if (!p_reg)
3104f29dbc25Smrg        return 0;
3105f29dbc25Smrg
3106f29dbc25Smrg    if (SOURCE_GCC == p_reg->source) {
3107f29dbc25Smrg        p_reg->value = ReadGx(p_reg->offset);
3108f29dbc25Smrg
3109f29dbc25Smrg        return 1;
3110f29dbc25Smrg    }
3111f29dbc25Smrg
3112f29dbc25Smrg    return 0;
3113f29dbc25Smrg}
3114f29dbc25Smrg
3115f29dbc25Smrgstatic int
3116f29dbc25SmrgPLAL_WriteRegister(const S_REG_INFO * p_reg)
3117f29dbc25Smrg{
3118f29dbc25Smrg    if (!p_reg)
3119f29dbc25Smrg        return 0;
3120f29dbc25Smrg
3121f29dbc25Smrg    if (SOURCE_GCC == p_reg->source) {
3122f29dbc25Smrg        WriteGx(p_reg->offset, p_reg->value);
3123f29dbc25Smrg
3124f29dbc25Smrg        return 1;
3125f29dbc25Smrg    }
3126f29dbc25Smrg
3127f29dbc25Smrg    return 0;
3128f29dbc25Smrg}
3129f29dbc25Smrg
3130f29dbc25Smrg#endif
3131f29dbc25Smrg
3132f29dbc25Smrg/*==========================================================================
3133f29dbc25Smrg *	Determine if TV is on
3134f29dbc25Smrg *==========================================================================*/
3135f29dbc25Smrgstatic int
3136f29dbc25SmrgPLAL_IsTVOn(void)
3137f29dbc25Smrg{
3138f29dbc25Smrg    unsigned long reg;
3139f29dbc25Smrg
3140f29dbc25Smrg    /*check Cx5530 dot clock */
3141f29dbc25Smrg    reg = ReadGx(CX_DOT_CLK);
3142f29dbc25Smrg    return (reg & CX_TVCLK_SELECT) ? 1 : 0;
3143f29dbc25Smrg}
3144f29dbc25Smrg
3145f29dbc25Smrg/*==========================================================================
3146f29dbc25Smrg * Platform-specific actions to reset to VGA mode
3147f29dbc25Smrg *==========================================================================*/
3148f29dbc25Smrg
3149f29dbc25Smrgstatic int
3150f29dbc25SmrgPLAL_EnableVga(void)
3151f29dbc25Smrg{
3152f29dbc25Smrg    unsigned long reg;
3153f29dbc25Smrg
3154f29dbc25Smrg    /*2 x dclk */
3155f29dbc25Smrg    reg = ReadGx(DC_GENERAL_CFG);
3156f29dbc25Smrg    reg &= ~GX_DCLK_MUL;
3157f29dbc25Smrg    reg |= GX_DCLKx2;
3158f29dbc25Smrg    WriteGx(DC_GENERAL_CFG, reg);
3159f29dbc25Smrg
3160f29dbc25Smrg    /*select pll dot clock. */
3161f29dbc25Smrg    reg = ReadGx(CX_DOT_CLK);
3162f29dbc25Smrg    reg &= ~CX_TVCLK_SELECT;
3163f29dbc25Smrg    WriteGx(CX_DOT_CLK, reg);
3164f29dbc25Smrg
3165f29dbc25Smrg    /*timing config, reset everything on dclk. */
3166f29dbc25Smrg    reg = ReadGx(DC_TIMING_CFG);
3167f29dbc25Smrg    reg &= ~GX_TGEN;
3168f29dbc25Smrg    WriteGx(DC_TIMING_CFG, reg);
3169f29dbc25Smrg    reg |= GX_TGEN;
3170f29dbc25Smrg    WriteGx(DC_TIMING_CFG, reg);
3171f29dbc25Smrg
3172f29dbc25Smrg    /*un-invert FP clock */
3173f29dbc25Smrg    reg = ReadGx(CX_TV_CONFIG);
3174f29dbc25Smrg    reg &= ~CX_INVERT_FPCLK;
3175f29dbc25Smrg    WriteGx(CX_TV_CONFIG, reg);
3176f29dbc25Smrg
3177f29dbc25Smrg    return 0;
3178f29dbc25Smrg}
3179f29dbc25Smrg
3180f29dbc25Smrg/*==========================================================================*/
3181f29dbc25Smrg/*Platform-specific actions to enter TVout mode								*/
3182f29dbc25Smrg/*==========================================================================*/
3183f29dbc25Smrg
3184f29dbc25Smrgstatic int
3185f29dbc25SmrgPLAL_PrepForTVout(void)
3186f29dbc25Smrg{
3187f29dbc25Smrg    unsigned int reg;
3188f29dbc25Smrg
3189f29dbc25Smrg    /*Cx5530 tv config. */
3190f29dbc25Smrg    reg = 0;
3191f29dbc25Smrg    WriteGx(CX_TV_CONFIG, reg);
3192f29dbc25Smrg
3193f29dbc25Smrg    /*invert FP clock */
319404007ebaSmrg    reg = (int) ReadGx(CX_TV_CONFIG);
3195f29dbc25Smrg    reg |= CX_INVERT_FPCLK;
3196f29dbc25Smrg    WriteGx(CX_TV_CONFIG, reg);
3197f29dbc25Smrg
3198f29dbc25Smrg    return 0;
3199f29dbc25Smrg}
3200f29dbc25Smrg
3201f29dbc25Smrgstatic int
3202f29dbc25SmrgPLAL_SetTVTimingRegisters(const S_TIMING_SPECS * p_specs)
3203f29dbc25Smrg{
3204f29dbc25Smrg    unsigned long reg;
3205f29dbc25Smrg
3206f29dbc25Smrg    /*timing config, reset everything on dclk. */
3207f29dbc25Smrg    reg = ReadGx(DC_TIMING_CFG);
3208f29dbc25Smrg    reg &= ~GX_TGEN;
3209f29dbc25Smrg    WriteGx(DC_TIMING_CFG, reg);
3210f29dbc25Smrg
3211f29dbc25Smrg    /*htotal and hactive. */
3212f29dbc25Smrg    reg = ((p_specs->h_total - 1) << 16) | (p_specs->vga_width - 1);
3213f29dbc25Smrg    WriteGx(DC_H_TIMING_1, reg);
3214f29dbc25Smrg
3215f29dbc25Smrg    /*hblank. */
3216f29dbc25Smrg    reg = ((p_specs->h_total - 1) << 16) | (p_specs->vga_width - 1);
3217f29dbc25Smrg    WriteGx(DC_H_TIMING_2, reg);
3218f29dbc25Smrg
3219f29dbc25Smrg    /*hsync. */
3220f29dbc25Smrg    reg = ((p_specs->h_sync + 63) << 16) | p_specs->h_sync;
3221f29dbc25Smrg    WriteGx(DC_H_TIMING_3, reg);
3222f29dbc25Smrg
3223f29dbc25Smrg    /*fp hsync. */
3224f29dbc25Smrg    WriteGx(DC_FP_H_TIMING, reg);
3225f29dbc25Smrg
3226f29dbc25Smrg    /*vtotal and vactive. */
3227f29dbc25Smrg    reg = ((p_specs->v_total - 1) << 16) | (p_specs->vga_lines - 1);
3228f29dbc25Smrg    WriteGx(DC_V_TIMING_1, reg);
3229f29dbc25Smrg
3230f29dbc25Smrg    /*vblank. */
3231f29dbc25Smrg    reg = ((p_specs->v_total - 1) << 16) | (p_specs->vga_lines - 1);
3232f29dbc25Smrg    WriteGx(DC_V_TIMING_2, reg);
3233f29dbc25Smrg
3234f29dbc25Smrg    /*vsync. */
3235f29dbc25Smrg    reg = ((p_specs->v_sync) << 16) | (p_specs->v_sync - 1);
3236f29dbc25Smrg    WriteGx(DC_V_TIMING_3, reg);
3237f29dbc25Smrg
3238f29dbc25Smrg    /*fp vsync. */
3239f29dbc25Smrg    reg = ((p_specs->v_sync - 1) << 16) | (p_specs->v_sync - 2);
3240f29dbc25Smrg    WriteGx(DC_FP_V_TIMING, reg);
3241f29dbc25Smrg
324279d5fcd7Smrg    /*timing config, re-enable all dclk stuff. */
3243f29dbc25Smrg    reg = ReadGx(DC_TIMING_CFG);
3244f29dbc25Smrg    reg |= GX_TGEN;
3245f29dbc25Smrg    WriteGx(DC_TIMING_CFG, reg);
3246f29dbc25Smrg
3247f29dbc25Smrg    return 0;
3248f29dbc25Smrg}
3249f29dbc25Smrg
3250f29dbc25Smrgstatic int
3251f29dbc25SmrgPLAL_FinalEnableTVout(unsigned long vga_mode)
3252f29dbc25Smrg{
3253f29dbc25Smrg    unsigned int reg;
3254f29dbc25Smrg
3255f29dbc25Smrg    /*Cx5530 select tv dot clock. */
325604007ebaSmrg    reg = (int) ReadGx(CX_DOT_CLK);
3257f29dbc25Smrg    reg |= CX_TVCLK_SELECT;
3258f29dbc25Smrg    WriteGx(CX_DOT_CLK, reg);
3259f29dbc25Smrg
3260f29dbc25Smrg    /*2 x dclk (actually 1x) */
326104007ebaSmrg    reg = (int) ReadGx(DC_GENERAL_CFG);
3262f29dbc25Smrg    reg &= ~GX_DCLK_MUL;
3263f29dbc25Smrg    WriteGx(DC_GENERAL_CFG, reg);
3264f29dbc25Smrg
3265f29dbc25Smrg    reg |= GX_DCLKx2;
3266f29dbc25Smrg    WriteGx(DC_GENERAL_CFG, reg);
3267f29dbc25Smrg
3268f29dbc25Smrg    /*Cx5530 display configuration register. */
326904007ebaSmrg    reg = (int) ReadGx(CX_DISPLAY_CONFIG);
3270f29dbc25Smrg    reg |= (CX_FPVSYNC_POL | CX_FPHSYNC_POL | CX_FPDATA_ENB | CX_FPPOWER_ENB);
3271f29dbc25Smrg    WriteGx(CX_DISPLAY_CONFIG, reg);
3272f29dbc25Smrg
3273f29dbc25Smrg    return 0;
3274f29dbc25Smrg}
3275