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