1
/* Copyright (c) 2005 Advanced Micro Devices, Inc.
3
* Permission is hereby granted, free of charge, to any person obtaining a copy
4
* of this software and associated documentation files (the "Software"), to
5
* deal in the Software without restriction, including without limitation the
6
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7
* sell copies of the Software, and to permit persons to whom the Software is
8
* furnished to do so, subject to the following conditions:
10
* The above copyright notice and this permission notice shall be included in
11
* all copies or substantial portions of the Software.
13
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21
* Neither the name of the Advanced Micro Devices, Inc. nor the names of its
22
* contributors may be used to endorse or promote products derived from this
23
* software without specific prior written permission.
26
#define FS450_DIRECTREG 0
30
/*==========================================================================
32
*==========================================================================
36
#define fsmax(a, b) ((a) > (b) ? (a) : (b))
37
#define fsmin(a, b) ((a) < (b) ? (a) : (b))
40
#define range_limit(val,min_val,max_val) (fsmax((min_val),fsmin((val),(max_val))))
42
/*==========================================================================
44
*==========================================================================
47
#define MAX_REGISTERS 32
52
#define READ_WRITE (READ | WRITE)
57
unsigned char bit_length;
58
unsigned char valid_bits;
59
unsigned char read_write;
60
char *bitfield_names[MAX_BITS];
66
S_REGISTER_DESCRIP registers[MAX_REGISTERS];
69
const S_SET_DESCRIP *houston_regs(void);
70
const S_SET_DESCRIP *encoder_regs(void);
71
const S_SET_DESCRIP *macrovision_regs(void);
72
const S_SET_DESCRIP *gcc_regs(void);
74
/*==========================================================================
75
* Houston Register Addresses & Bit Definitions
76
*==========================================================================
78
#define HOUSTON_IHO 0x00 /* Input Horizontal Offset */
79
#define HOUSTON_IVO 0x02 /* Input Vertical Offset */
80
#define HOUSTON_IHA 0x04 /* Input Horizontal Active Width */
81
#define HOUSTON_VSC 0x06 /* Vertical Scaling Coeficient */
82
#define HOUSTON_HSC 0x08 /* Horizontal Scaling Coeficient */
83
#define HOUSTON_BYP 0x0A /* Bypass Register */
84
#define HOUSTON_CR 0x0C /* Control Register */
85
#define HOUSTON_SP 0x0E /* Status */
86
#define HOUSTON_NCONL 0x10 /* NCO numerator low word */
87
#define HOUSTON_NCONH 0x12 /* NCO numerator high word */
88
#define HOUSTON_NCODL 0x14 /* NCO denominator low word */
89
#define HOUSTON_NCODH 0x16 /* NCO denominator high word */
90
#define HOUSTON_APO 0x18
91
#define HOUSTON_ALO 0x1A
92
#define HOUSTON_AFO 0x1C
93
#define HOUSTON_HSOUTWID 0x1E
94
#define HOUSTON_HSOUTST 0x20
95
#define HOUSTON_HSOUTEND 0x22
96
#define HOUSTON_SHP 0x24 /* Sharpness */
97
#define HOUSTON_FLK 0x26 /* Flicker Filter */
98
#define HOUSTON_BCONTL 0x28
99
#define HOUSTON_BCONTH 0x2A
100
#define HOUSTON_BDONE 0x2C
101
#define HOUSTON_BDIAGL 0x2E
102
#define HOUSTON_BDIAGH 0x30
103
#define HOUSTON_REV 0x32
104
#define HOUSTON_MISC 0x34
105
#define HOUSTON_FFO 0x36
106
#define HOUSTON_FFO_LAT 0x38
107
#define HOUSTON_VSOUTWID 0x3A
108
#define HOUSTON_VSOUTST 0x3C
109
#define HOUSTON_VSOUTEND 0x3E
110
/* BYP Register Bits */
111
#define BYP_RGB_BYPASS 0x0001
112
#define BYP_HDS_BYPASS 0x0002
113
#define BYP_HDS_TBYPASS 0x0004
114
#define BYP_CAC_BYPASS 0x0008
115
#define BYP_R2V_SBYPASS 0x0010
116
#define BYP_R2V_BYPASS 0x0020
117
#define BYP_VDS_BYPASS 0x0040
118
#define BYP_FFT_BYPASS 0x0080
119
#define BYP_FIF_BYPASS 0x0100
120
#define BYP_FIF_TBYPASS 0x0200
121
#define BYP_HUS_BYPASS 0x0400
122
#define BYP_HUS_TBYPASS 0x0800
123
#define BYP_CCR_BYPASS 0x1000
124
#define BYP_PLL_BYPASS 0x2000
125
#define BYP_NCO_BYPASS 0x4000
126
#define BYP_ENC_BYPASS 0x8000
127
/* CR Register Bits */
128
#define CR_RESET 0x0001
129
#define CR_CLKOFF 0x0002
130
#define CR_NCO_EN 0x0004
131
#define CR_COMPOFF 0x0008
132
#define CR_YCOFF 0x0010
133
#define CR_LP_EN 0x0020
134
#define CR_CACQ_CLR 0x0040
135
#define CR_FFO_CLR 0x0080
136
#define CR_656_PAL_NTSC 0x0100
137
#define CR_656_STD_VMI 0x0200
138
#define CR_OFMT 0x0400
139
#define CR_UIM_CLK 0x0800
140
#define CR_UIM_DEC 0x1000
141
#define CR_BIPGEN_EN1 0x2000
142
#define CR_UIM_MOD0 0x4000
143
#define CR_UIM_MOD1 0x8000
144
/* Status Register Bits */
145
#define SP_CACQ_ST 0x0001
146
#define SP_FFO_ST 0x0002
147
#define SP_REVID_MASK 0x7FFC
148
#define SP_MV_EN 0x8000
149
/* BDONE Register Bits */
150
#define BDONE_BIST_DONE_A 0x0001
151
#define BDONE_BIST_DONE_B 0x0002
152
#define BDONE_BIST_DONE_C 0x0004
153
#define BDONE_BIST_DONE_D 0x0008
154
#define BDONE_BIST_DONE_E 0x0010
155
#define BDONE_BIST_DONE_F 0x0020
156
#define BDONE_BIST_DONE_G 0x0040
157
/* BDIAGL Register Bits */
158
#define BDIAGL_BIST_DIAG_A 0x000F
159
#define BDIAGL_BIST_DIAG_B 0x00F0
160
#define BDIAGL_BIST_DIAG_C 0x0F00
161
#define BDIAGL_BIST_DIAG_D 0xF000
162
/* BDIAGH Register Bits */
163
#define BDIAGH_BIST_DIAG_E 0x000F
164
#define BDIAGH_BIST_DIAG_F 0x000F
165
#define BDIAGH_BIST_DIAG_G 0x000F
166
/* MISC Register Bits */
167
#define MISC_TV_SHORT_FLD 0x0001
168
#define MISC_ENC_TEST 0x0002
169
#define MISC_DAC_TEST 0x0004
170
#define MISC_MV_SOFT_EN 0x0008
171
#define MISC_NCO_LOAD0 0x0010
172
#define MISC_NCO_LOAD1 0x0020
173
#define MISC_VGACKDIV 0x0200
174
#define MISC_BRIDGE_SYNC 0x0400
175
#define MISC_GTLIO_PD 0x8000
176
/*==========================================================================
177
* Encoder Registers & Bit Definitions
178
*==========================================================================
180
#define ENC_CHROMA_FREQ 0x40
181
#define ENC_CHROMA_PHASE 0x44
182
#define ENC_REG05 0x45
183
#define ENC_REG06 0x46
184
#define ENC_REG07 0x47
185
#define ENC_HSYNC_WIDTH 0x48
186
#define ENC_BURST_WIDTH 0x49
187
#define ENC_BACK_PORCH 0x4A
188
#define ENC_CB_BURST_LEVEL 0x4B
189
#define ENC_CR_BURST_LEVEL 0x4C
190
#define ENC_SLAVE_MODE 0x4D
191
#define ENC_BLACK_LEVEL 0x4e
192
#define ENC_BLANK_LEVEL 0x50
193
#define ENC_NUM_LINES 0x57
194
#define ENC_WHITE_LEVEL 0x5e
195
#define ENC_CB_GAIN 0x60
196
#define ENC_CR_GAIN 0x62
197
#define ENC_TINT 0x65
198
#define ENC_BREEZE_WAY 0x69
199
#define ENC_FRONT_PORCH 0x6C
200
#define ENC_ACTIVELINE 0x71
201
#define ENC_FIRST_LINE 0x73
202
#define ENC_REG34 0x74
203
#define ENC_SYNC_LEVEL 0x75
204
#define ENC_VBI_BLANK_LEVEL 0x7C
205
#define ENC_RESET 0x7e
206
#define ENC_NOTCH_FILTER 0x8d
207
/*==========================================================================
208
* Macrovision Registers & Bit Definitions
209
*==========================================================================
234
#define MV_AGC_PULSE_LEVEL 0x77
235
#define MV_BP_PULSE_LEVEL 0x78
236
/*==========================================================================
237
* The TRACE macro can be used to display debug information. It can display
238
* one or more parameters in a formatted string like printf. No code will be
239
* generated for a release build. Use double parentheses for compatibility
240
* with C #define statements. Newline characters are not added
241
* automatically. Usage example:
243
* TRACE(("Number is %d, Name is %s.\n",iNumber,lpszName))
244
*==========================================================================
246
#define TRACE(parameters) {}
247
/* GCC timing structure */
248
typedef struct _S_TIMING_SPECS {
259
/* Revision of Houston chip */
260
#define HOUSTON_REV_A 0
261
#define HOUSTON_REV_B 1
262
static int houston_Rev(void);
264
/*==========================================================================
266
*==========================================================================
268
static int houston_init(void);
270
static unsigned char PLAL_FS450_i2c_address(void);
271
static int PLAL_FS450_UIM_mode(void);
272
static int PLAL_ReadRegister(S_REG_INFO * p_reg);
273
static int PLAL_WriteRegister(const S_REG_INFO * p_reg);
274
static int PLAL_IsTVOn(void);
275
static int PLAL_EnableVga(void);
276
static int PLAL_PrepForTVout(void);
277
static int PLAL_SetTVTimingRegisters(const S_TIMING_SPECS * p_specs);
278
static int PLAL_FinalEnableTVout(unsigned long vga_mode);
280
/* Direct Memory Access Functions */
281
/* NOTE: Cx5530 is assumed hardcoded at 0x10000 offset from MediaGX base.
282
* F4Bar is bogus as described in the Cx5530 datasheet (actually points to GX
285
DMAL_ReadUInt32(unsigned long phys_addr, unsigned long *p_data)
287
*p_data = READ_REG32(phys_addr);
292
DMAL_WriteUInt32(unsigned long phys_addr, unsigned long data)
294
WRITE_REG32(phys_addr, data);
298
/* Houston register access functions. */
300
houston_ReadReg(unsigned int reg, unsigned long *p_value, unsigned int bytes)
302
return gfx_i2c_read(1, PLAL_FS450_i2c_address(), (unsigned char) reg,
303
(unsigned char) bytes, (unsigned char *) p_value);
307
houston_WriteReg(unsigned int reg, unsigned long value, unsigned int bytes)
309
return gfx_i2c_write(1, PLAL_FS450_i2c_address(), (unsigned char) reg,
310
(unsigned char) bytes, (unsigned char *) &value);
313
/* TV configuration functions. */
314
static int config_init(void);
315
static const S_TIMING_SPECS *p_specs(void);
316
static void config_power(int on);
317
static void config_vga_mode(unsigned long vga_mode);
318
static void config_tv_std(unsigned long tv_std, unsigned int trigger_bits);
319
static void conget_tv_std(unsigned long *p_tv_std);
320
static unsigned long supported_standards(void);
321
static void config_tvout_mode(unsigned long tvout_mode);
322
static void conget_tvout_mode(unsigned long *p_tvout_mode);
323
static void config_overscan_xy(unsigned long tv_std, unsigned long vga_mode,
324
int overscan_x, int overscan_y, int pos_x,
326
static void config_nco(unsigned long tv_std, unsigned long vga_mode);
327
static void config_sharpness(int sharpness);
328
static void conget_sharpness(int *p_sharpness);
329
static void config_flicker(int flicker);
330
static void conget_flicker(int *p_flicker);
331
static void config_color(int color);
332
static void conget_color(int *p_color);
333
static void config_brightness_contrast(unsigned long tv_std,
334
unsigned int trigger_bits,
335
int brightness, int contrast);
336
static void conget_brightness_contrast(unsigned long tv_std,
337
unsigned int trigger_bits,
338
int *p_brightness, int *p_contrast);
339
static void config_yc_filter(unsigned long tv_std, int luma_filter,
341
static void conget_yc_filter(int *p_luma_filter, int *p_chroma_filter);
342
static void config_macrovision(unsigned long tv_std,
343
unsigned int cp_trigger_bits);
344
static void conget_macrovision(unsigned long tv_std,
345
unsigned int *p_cp_trigger_bits);
347
/* Device settings. */
348
typedef struct _S_DEVICE_SETTINGS {
350
unsigned long vga_mode;
351
unsigned long tv_std;
352
unsigned long tvout_mode;
362
unsigned char yc_filter;
363
unsigned int aps_trigger_bits;
367
static S_DEVICE_SETTINGS d;
369
/*==========================================================================
370
* TV Setup Parameters
371
*==========================================================================
374
static const struct {
375
unsigned long chroma_freq[5];
376
unsigned short chroma_phase[5];
377
unsigned short cphase_rst[5];
378
unsigned short color[5];
379
unsigned short cr_burst_level[5];
380
unsigned short cb_burst_level[5];
381
unsigned short sys625_50[5];
382
unsigned short vsync5[5];
383
unsigned short pal_mode[5];
384
unsigned short hsync_width[5];
385
unsigned short burst_width[5];
386
unsigned short back_porch[5];
387
unsigned short front_porch[5];
388
unsigned short breeze_way[5];
389
unsigned short activeline[5];
390
unsigned short blank_level[5];
391
unsigned short vbi_blank_level[5];
392
unsigned short black_level[5];
393
unsigned short white_level[5];
394
unsigned short hamp_offset[5];
395
unsigned short sync_level[5];
396
unsigned short tv_lines[5];
397
unsigned short tv_width[5];
398
unsigned short tv_active_lines[5];
399
unsigned short tv_active_width[5];
400
unsigned char notch_filter[5];
401
unsigned short houston_cr[5];
402
unsigned short houston_ncodl[5];
403
unsigned short houston_ncodh[5];
405
/* ntsc, pal, ntsc-eij, pal-m, pal-n */
407
0x1f7cf021, 0xcb8a092a, 0x1f7cf021, 0xe3efe621, 0xcb8a092a},
434
0x7a, 0x7a, 0x7a, 0x7a, 0x7a},
437
0x40, 0x3c, 0x40, 0x40, 0x3c},
440
0x80, 0x9a, 0x80, 0x80, 0x9a},
443
0x24, 0x1e, 0x24, 0x24, 0x1e},
446
0x19, 0x1a, 0x19, 0x12, 0x1a},
449
0xb4, 0xb4, 0xb4, 0xb4, 0xb4},
452
240, 251, 240, 240, 240},
455
240, 251, 240, 240, 240},
456
/* vbi_blank_level */
458
284, 252, 240, 252, 252},
461
823, 821, 823, 821, 821},
467
0x08, 0x08, 0x08, 0x08, 0x08},
470
525, 625, 525, 525, 625},
473
858, 864, 858, 858, 864},
476
487, 576, 487, 487, 576},
477
/* tv_active_lines */
479
800, 800, 800, 800, 800},
480
/* tv_active_width */
482
0x1a, 0x1d, 0x1a, 0x1d, 0x1d},
483
/* notch filter enabled */
485
0x0000, 0x0100, 0x0000, 0x0000, 0x0100},
488
0x7e48, 0xf580, 0x7e48, 0x7e48, 0xf580},
491
0x001b, 0x0020, 0x001b, 0x001b, 0x0020}
495
/* MediaGX default underscan and centered position setups. */
496
#define SCANTABLE_ENTRIES 5
499
unsigned short v_total[5];
500
unsigned short v_sync[5];
501
unsigned short iha[5];
506
static struct _scantable scantable[SCANTABLE_ENTRIES] = {
508
GFX_VGA_MODE_640X480,
509
{617, 624, 617, 624, 624}, /* v_total */
510
{69, 88, 69, 88, 88}, /* v_sync */
511
{720, 720, 720, 720, 720}, /* iha */
512
{0, 0, 0, 0, 0}, /* iho */
513
{-12, 0, -6, 0, 0} /* hsc */
516
GFX_VGA_MODE_800X600,
517
{740, 740, 740, 740, 740}, /* v_total */
518
{90, 88, 90, 88, 88}, /* v_sync */
519
{720, 720, 508, 720, 720}, /* iha */
520
{-8, 11, -8, -8, 11}, /* iho */
521
{-27, -27, -27, -27, -27} /* hsc */
524
GFX_VGA_MODE_720X487,
525
{525, 720, 525, 720, 720}, /* v_total */
526
{23, 230, 23, 230, 230}, /* v_sync */
527
{720, 720, 720, 720, 720}, /* iha */
528
{0xa2, 0xa2, 0xa2, 0xa2, 0xa2}, /* iho */
529
{0, 0, 0, 0, 0} /* hsc */
532
GFX_VGA_MODE_720X576,
533
{720, 625, 720, 625, 625}, /* v_total */
534
{129, 25, 129, 25, 25}, /* v_sync */
535
{720, 720, 720, 720, 720}, /* iha */
536
{0xaa, 0xaa, 0xaa, 0xaa, 0xaa}, /* iho */
537
{0, 0, 0, 0, 0} /* hsc */
540
GFX_VGA_MODE_1024X768,
541
{933, 942, 933, 806, 806}, /* v_total */
542
{121, 112, 121, 88, 88}, /* v_sync */
543
{600, 600, 600, 600, 600}, /* iha */
544
{0x3c, 0x23, 0x3c, 0x65, 0x65}, /* iho */
545
{35, 26, 35, 26, 26} /* hsc */
549
/* Houston fifo configuration constants. */
552
unsigned short ffolat;
558
unsigned short ffolat;
561
/* h_total=832, ivo=40, tv_width=858, tv_lines=525, vga_lines=480 */
562
#define SIZE6X4NTSC 66
563
static struct _ffolat ffo6x4ntsc[SIZE6X4NTSC + 1] = {
564
{541, 0x40}, {545, 0x40}, {549, 0x40}, {553, 0x40},
565
{557, 0x58}, {561, 0x40}, {565, 0x40}, {569, 0x40},
566
{573, 0x48}, {577, 0x40}, {581, 0x40}, {585, 0x40},
567
{589, 0x40}, {593, 0x48}, {597, 0x40}, {601, 0x40},
568
{605, 0x40}, {609, 0x40}, {613, 0x5b}, {617, 0x48},
569
{621, 0x60}, {625, 0x48}, {629, 0x48}, {633, 0x40},
570
{637, 0x5e}, {641, 0x40}, {645, 0x50}, {649, 0x56},
571
{653, 0x58}, {657, 0x6c}, {661, 0x40}, {665, 0x40},
572
{669, 0x40}, {673, 0x40}, {677, 0x40}, {681, 0x40},
573
{685, 0x40}, {689, 0x40}, {693, 0x40}, {697, 0x40},
574
{701, 0x40}, {705, 0x40}, {709, 0x40}, {713, 0x40},
575
{717, 0x40}, {721, 0x40}, {725, 0x40}, {729, 0x40},
576
{733, 0x40}, {737, 0x40}, {741, 0x40}, {745, 0x40},
577
{749, 0x40}, {753, 0x40}, {757, 0x40}, {761, 0x40},
578
{765, 0x40}, {769, 0x40}, {773, 0x40}, {777, 0x40},
579
{781, 0x40}, {785, 0x40}, {789, 0x40}, {793, 0x40},
580
{797, 0x30}, {801, 0x40},
584
#define SIZE6X4PAL 45
585
static struct _ffolat ffo6x4pal[SIZE6X4PAL + 1] = {
586
{625, 0x60}, {629, 0x60}, {633, 0x60}, {637, 0x60},
587
{641, 0x50}, {645, 0x60}, {649, 0x60}, {653, 0x60},
588
{657, 0x60}, {661, 0x60}, {665, 0x60}, {669, 0x60},
589
{673, 0x60}, {677, 0x60}, {681, 0x60}, {685, 0x60},
590
{689, 0x60}, {693, 0x60}, {697, 0x60}, {701, 0x60},
591
{705, 0x60}, {709, 0x60}, {713, 0x60}, {717, 0x60},
592
{721, 0x60}, {725, 0x60}, {729, 0x60}, {733, 0x60},
593
{737, 0x60}, {741, 0x60}, {745, 0x60}, {749, 0x60},
594
{753, 0x60}, {757, 0x60}, {761, 0x60}, {765, 0x60},
595
{769, 0x60}, {773, 0x60}, {777, 0x60}, {781, 0x60},
596
{785, 0x60}, {789, 0x60}, {793, 0x60}, {797, 0x60},
601
#define SIZE7X4NTSC 40
602
static struct _ffolat ffo7x4ntsc[SIZE7X4NTSC + 1] = {
603
{525, 0x52}, {529, 0x52}, {533, 0x52}, {537, 0x52},
604
{541, 0x52}, {545, 0x40}, {549, 0x40}, {553, 0x40},
605
{557, 0x58}, {561, 0x40}, {565, 0x58}, {569, 0x40},
606
{573, 0x48}, {577, 0x40}, {581, 0x40}, {585, 0x40},
607
{589, 0x40}, {593, 0x48}, {597, 0x40}, {601, 0x40},
608
{605, 0x40}, {609, 0x40}, {613, 0x5b}, {617, 0x48},
609
{621, 0x60}, {625, 0x48}, {629, 0x48}, {633, 0x40},
610
{637, 0x5e}, {641, 0x40}, {645, 0x50}, {649, 0x56},
611
{653, 0x58}, {657, 0x6c}, {661, 0x40}, {665, 0x40},
612
{669, 0x40}, {673, 0x40}, {677, 0x40}, {681, 0x40},
616
#define SIZE7X4PAL 24
617
static struct _ffolat ffo7x4pal[SIZE7X4PAL + 1] = {
618
{625, 0x60}, {629, 0x60}, {633, 0x60}, {637, 0x60},
619
{641, 0x50}, {645, 0x60}, {649, 0x60}, {653, 0x60},
620
{657, 0x60}, {661, 0x60}, {665, 0x60}, {669, 0x60},
621
{673, 0x60}, {677, 0x60}, {681, 0x60}, {685, 0x60},
622
{689, 0x60}, {693, 0x60}, {697, 0x60}, {701, 0x60},
623
{705, 0x60}, {709, 0x60}, {713, 0x60}, {717, 0x60},
627
#define SIZE7X5NTSC 54
628
static struct _ffolat ffo7x5ntsc[SIZE7X5NTSC + 1] = {
629
{590, 0x40}, {594, 0x48}, {598, 0x40}, {602, 0x40},
630
{606, 0x40}, {610, 0x40}, {614, 0x5b}, {618, 0x48},
631
{622, 0x60}, {626, 0x48}, {630, 0x48}, {634, 0x40},
632
{638, 0x5e}, {642, 0x40}, {646, 0x50}, {650, 0x56},
633
{654, 0x58}, {658, 0x6c}, {662, 0x40}, {666, 0x40},
634
{670, 0x40}, {674, 0x40}, {678, 0x40}, {682, 0x40},
635
{686, 0x40}, {690, 0x40}, {694, 0x40}, {698, 0x40},
636
{702, 0x40}, {706, 0x40}, {710, 0x40}, {714, 0x40},
637
{718, 0x40}, {722, 0x40}, {726, 0x40}, {730, 0x40},
638
{734, 0x40}, {738, 0x40}, {742, 0x40}, {746, 0x40},
639
{750, 0x40}, {754, 0x40}, {758, 0x40}, {762, 0x40},
640
{766, 0x40}, {770, 0x40}, {774, 0x40}, {778, 0x40},
641
{782, 0x40}, {786, 0x40}, {790, 0x40}, {794, 0x40},
642
{798, 0x30}, {802, 0x40},
646
#define SIZE7X5PAL 45
647
static struct _ffolat ffo7x5pal[SIZE7X5PAL + 1] = {
648
{625, 0x60}, {629, 0x60}, {633, 0x60}, {637, 0x60},
649
{641, 0x50}, {645, 0x60}, {649, 0x60}, {653, 0x60},
650
{657, 0x60}, {661, 0x60}, {665, 0x60}, {669, 0x60},
651
{673, 0x60}, {677, 0x60}, {681, 0x60}, {685, 0x60},
652
{689, 0x60}, {693, 0x60}, {697, 0x60}, {701, 0x60},
653
{705, 0x60}, {709, 0x60}, {713, 0x60}, {717, 0x60},
654
{721, 0x60}, {725, 0x60}, {729, 0x60}, {733, 0x60},
655
{737, 0x60}, {741, 0x60}, {745, 0x60}, {749, 0x60},
656
{753, 0x60}, {757, 0x60}, {761, 0x60}, {765, 0x60},
657
{769, 0x60}, {773, 0x60}, {777, 0x60}, {781, 0x60},
658
{785, 0x60}, {789, 0x60}, {793, 0x60}, {797, 0x60},
663
/* h_total=1056, vga_lines=600 */
664
#define SIZE8X6NTSC 37
665
static struct _ffolat ffo8x6ntsc[SIZE8X6NTSC + 1] = {
666
{620, 0x40}, /* v_total_min >= vsync+10 >= vga_lines+10 = 610 */
667
{625, 0x58}, {630, 0x40}, {635, 0x40}, {640, 0x40},
668
{645, 0x46}, {650, 0x46}, {655, 0x4f}, {660, 0x4c},
669
{665, 0x4a}, {670, 0x50}, {675, 0x2f}, {680, 0x48},
670
{685, 0x38}, {690, 0x31}, {695, 0x40}, {700, 0x21},
671
{705, 0x25}, {710, 0x40}, {715, 0x48}, {720, 0x50},
672
{725, 0x30}, {730, 0x50}, {735, 0x50}, {740, 0x50},
673
{745, 0x40}, {750, 0x38}, {755, 0x50}, {760, 0x50},
674
{765, 0x40}, {770, 0x38}, {775, 0x40}, {780, 0x40},
675
{785, 0x40}, {790, 0x38}, {795, 0x50}, {800, 0x50},
679
/* h_total=1056, vga_lines=600 */
680
#define SIZE8X6PAL 36
681
static struct _ffolat ffo8x6pal[SIZE8X6PAL + 1] = {
682
{625, 0x80}, {630, 0x80}, {635, 0x5a}, {640, 0x55},
683
{645, 0x48}, {650, 0x65}, {655, 0x65}, {660, 0x50},
684
{665, 0x80}, {670, 0x70}, {675, 0x56}, {680, 0x80},
685
{685, 0x58}, {690, 0x31}, {695, 0x80}, {700, 0x60},
686
{705, 0x45}, {710, 0x4a}, {715, 0x50}, {720, 0x50},
687
{725, 0x50}, {730, 0x45}, {735, 0x50}, {740, 0x50},
688
{745, 0x50}, {750, 0x50}, {755, 0x50}, {760, 0x50},
689
{765, 0x50}, {770, 0x50}, {775, 0x50}, {780, 0x50},
690
{785, 0x50}, {790, 0x50}, {795, 0x50}, {800, 0x50},
694
/* h_total=1344, vga_lines=768 */
695
#define SIZE10X7NTSC 45
696
static struct _ffolativo ffo10x7ntsc[SIZE10X7NTSC] = {
744
/* h_total=1344, vga_lines=768 */
745
#define SIZE10X7PAL 46
746
static struct _ffolativo ffo10x7pal[SIZE10X7PAL] = {
795
/*==========================================================================*/
796
/*FS450 API Functions. */
797
/*==========================================================================*/
799
/* Initialize device settings */
801
initialize_houston_static_registers(void)
803
houston_WriteReg(HOUSTON_BYP, 0, 2);
804
houston_WriteReg(HOUSTON_APO, 0, 2);
805
houston_WriteReg(HOUSTON_ALO, 0, 2);
806
houston_WriteReg(HOUSTON_AFO, 0, 2);
807
houston_WriteReg(HOUSTON_BCONTL, 0, 2);
808
houston_WriteReg(HOUSTON_BCONTH, 0, 2);
809
houston_WriteReg(HOUSTON_BDONE, 0, 2);
810
houston_WriteReg(HOUSTON_BDIAGL, 0, 2);
811
houston_WriteReg(HOUSTON_BDIAGH, 0, 2);
812
houston_WriteReg(HOUSTON_MISC, 0, 2);
820
TRACE(("FS450_Init()\n"))
822
err = houston_init();
826
initialize_houston_static_registers();
828
d.tv_on = PLAL_IsTVOn()? 1 : 0;
830
/* get the current tv standard */
831
conget_tv_std(&d.tv_std);
835
/* default to VP_TVOUT_MODE_CVBS_YC */
836
d.tvout_mode = GFX_TVOUT_MODE_CVBS_YC;
838
/* default to 1000 out of 1000 */
840
config_sharpness(d.sharpness);
842
/* default to 800 out of 1000 */
844
config_flicker(d.flicker);
846
/* default to zeros */
853
/* d.color = tvsetup.color[k]; */
854
config_color(d.color);
859
config_brightness_contrast(d.tv_std, d.aps_trigger_bits, d.brightness,
862
/* get the current yc filtering */
864
int luma_filter, chroma_filter;
866
conget_yc_filter(&luma_filter, &chroma_filter);
869
d.yc_filter |= GFX_LUMA_FILTER;
871
d.yc_filter |= GFX_CHROMA_FILTER;
874
d.aps_trigger_bits = 0;
875
config_macrovision(d.tv_std, d.aps_trigger_bits);
877
d.last_overscan_y = -10000;
887
/*==========================================================================*/
888
/* Required configuration calls to write new settings to the device */
889
/*==========================================================================*/
891
#define REQ_TV_STANDARD_BIT 0x0002
892
#define REQ_VGA_MODE_BIT 0x0004
893
#define REQ_TVOUT_MODE_BIT 0x0008
894
#define REQ_SHARPNESS_BIT 0x0010
895
#define REQ_FLICKER_BIT 0x0020
896
#define REQ_OVERSCAN_POSITION_BIT 0x0040
897
#define REQ_COLOR_BIT 0x0080
898
#define REQ_BRIGHTNESS_CONTRAST_BIT 0x0100
899
#define REQ_YC_FILTER_BIT 0x0200
900
#define REQ_MACROVISION_BIT 0x0400
901
#define REQ_NCO_BIT 0x1000
903
#define REQ_TV_STANDARD (REQ_TV_STANDARD_BIT | REQ_OVERSCAN_POSITION \
904
| REQ_BRIGHTNESS_CONTRAST \
905
| REQ_MACROVISION_BIT | REQ_YC_FILTER)
906
#define REQ_VGA_MODE (REQ_VGA_MODE_BIT | REQ_OVERSCAN_POSITION)
907
#define REQ_TVOUT_MODE (REQ_TVOUT_MODE_BIT)
908
#define REQ_SHARPNESS (REQ_SHARPNESS_BIT)
909
#define REQ_FLICKER (REQ_FLICKER_BIT)
910
#define REQ_OVERSCAN_POSITION (REQ_OVERSCAN_POSITION_BIT | REQ_NCO)
911
#define REQ_COLOR (REQ_COLOR_BIT)
912
#define REQ_BRIGHTNESS_CONTRAST (REQ_BRIGHTNESS_CONTRAST_BIT)
913
#define REQ_YC_FILTER (REQ_YC_FILTER_BIT)
914
#define REQ_MACROVISION (REQ_TV_STANDARD_BIT | \
915
REQ_BRIGHTNESS_CONTRAST_BIT | \
917
#define REQ_NCO (REQ_NCO_BIT)
918
#define REQ_ENCODER (REQ_TV_STANDARD | REQ_COLOR | \
919
REQ_BRIGHTNESS_CONTRAST | REQ_YC_FILTER)
922
write_config(int req)
924
unsigned long reg, reg_encoder_reset = 0;
927
/*if we're changing the nco, and the vertical scaling has changed... */
928
reset = ((REQ_NCO_BIT & req) && (d.overscan_y != d.last_overscan_y));
930
/*put the encoder into reset while making changes */
931
houston_ReadReg(ENC_RESET, ®, 1);
932
houston_WriteReg(ENC_RESET, reg | 0x01, 1);
933
reg_encoder_reset = reg & 0x01;
936
if (REQ_TV_STANDARD_BIT & req)
937
config_tv_std(d.tv_std, d.aps_trigger_bits);
939
if (REQ_VGA_MODE_BIT & req)
940
config_vga_mode(d.vga_mode);
942
if (REQ_TVOUT_MODE_BIT & req)
943
config_tvout_mode(d.tvout_mode);
945
if (REQ_OVERSCAN_POSITION_BIT & req) {
946
config_overscan_xy(d.tv_std,
948
d.overscan_x, d.overscan_y, d.position_x,
951
/*h_timing and v_timing and syncs. */
953
PLAL_SetTVTimingRegisters(p_specs());
956
if (REQ_NCO_BIT & req)
957
config_nco(d.tv_std, d.vga_mode);
959
if (REQ_SHARPNESS_BIT & req)
960
config_sharpness(d.sharpness);
962
if (REQ_FLICKER_BIT & req)
963
config_flicker(d.flicker);
965
if (REQ_COLOR_BIT & req)
966
config_color(d.color);
968
if (REQ_BRIGHTNESS_CONTRAST_BIT & req) {
969
config_brightness_contrast(d.tv_std,
970
d.aps_trigger_bits, d.brightness,
974
if (REQ_YC_FILTER_BIT & req) {
975
config_yc_filter(d.tv_std,
976
(d.yc_filter & GFX_LUMA_FILTER),
977
(d.yc_filter & GFX_CHROMA_FILTER));
980
if (REQ_MACROVISION_BIT & req)
981
config_macrovision(d.tv_std, d.aps_trigger_bits);
983
/*if we decided to put the encoder into reset, put it back */
985
houston_ReadReg(ENC_RESET, ®, 1);
986
houston_WriteReg(ENC_RESET, reg_encoder_reset | (reg & ~0x01), 1);
988
d.last_overscan_y = d.overscan_y;
993
/*==========================================================================*/
995
/*==========================================================================*/
999
fs450_get_tv_enable(unsigned int *p_on)
1002
gfx_get_tv_enable(unsigned int *p_on)
1006
return ERR_INVALID_PARAMETER;
1013
/*//int FS450_set_tv_on(unsigned int on)*/
1016
fs450_set_tv_enable(int on)
1019
gfx_set_tv_enable(int on)
1024
/*if not mode change, just return */
1025
if ((d.tv_on && on) || (!d.tv_on && !on))
1028
/*if turning off... */
1033
/*power down houston */
1043
/*power up houston */
1046
/*assert encoder reset. */
1047
houston_WriteReg(ENC_RESET, 0x01, 1);
1049
/*initial platform preparation */
1050
PLAL_PrepForTVout();
1052
/*configure encoder and nco. */
1053
write_config(REQ_VGA_MODE |
1056
REQ_OVERSCAN_POSITION | REQ_YC_FILTER | REQ_MACROVISION);
1058
/*set LP_EN and UIM */
1059
houston_ReadReg(HOUSTON_CR, ®, 2);
1061
reg &= ~(CR_UIM_MOD0 | CR_UIM_MOD1);
1062
reg |= (PLAL_FS450_UIM_mode() << 14);
1063
houston_WriteReg(HOUSTON_CR, reg, 2);
1065
/*set platform timing registers */
1066
PLAL_SetTVTimingRegisters(p_specs());
1068
PLAL_FinalEnableTVout(d.vga_mode);
1072
int retry_count = 0;
1075
while (retry_count++ < 50) {
1077
houston_ReadReg(HOUSTON_MISC, ®, 2);
1078
reg |= MISC_BRIDGE_SYNC;
1079
houston_WriteReg(HOUSTON_MISC, reg, 2);
1080
reg &= ~MISC_BRIDGE_SYNC;
1081
houston_WriteReg(HOUSTON_MISC, reg, 2);
1085
/*deassert encoder reset. */
1086
houston_WriteReg(ENC_RESET, 0x00, 1);
1095
fs450_set_tv_defaults(int format)
1098
gfx_set_tv_defaults(int format)
1104
/*==========================================================================*/
1106
/*==========================================================================*/
1110
fs450_get_tv_standard(unsigned long *p_standard)
1113
gfx_get_tv_standard(unsigned long *p_standard)
1117
return ERR_INVALID_PARAMETER;
1119
*p_standard = d.tv_std;
1126
fs450_get_available_tv_standards(unsigned long *p_standards)
1129
gfx_get_available_tv_standards(unsigned long *p_standards)
1133
return ERR_INVALID_PARAMETER;
1135
*p_standards = supported_standards();
1142
fs450_set_tv_standard(unsigned long standard)
1145
gfx_set_tv_standard(unsigned long standard)
1148
/* verify supported standard. */
1149
if (!(standard & supported_standards()))
1150
return ERR_INVALID_PARAMETER;
1152
/* disallow if tv is on */
1154
return ERR_CANNOT_CHANGE_WHILE_TV_ON;
1156
d.tv_std = standard;
1157
/* d.color = tvsetup.color[k]; */
1159
return write_config(REQ_TV_STANDARD);
1162
/*==========================================================================*/
1163
/* vga mode as known by the driver */
1164
/*==========================================================================*/
1168
fs450_get_tv_vga_mode(unsigned long *p_vga_mode)
1171
gfx_get_tv_vga_mode(unsigned long *p_vga_mode)
1175
return ERR_INVALID_PARAMETER;
1177
*p_vga_mode = d.vga_mode;
1184
fs450_get_available_tv_vga_modes(unsigned long *p_vga_modes)
1187
gfx_get_available_tv_vga_modes(unsigned long *p_vga_modes)
1191
return ERR_INVALID_PARAMETER;
1194
GFX_VGA_MODE_640X480 |
1195
GFX_VGA_MODE_720X487 | GFX_VGA_MODE_720X576 | GFX_VGA_MODE_800X600;
1196
if (houston_Rev() >= HOUSTON_REV_B)
1197
*p_vga_modes |= GFX_VGA_MODE_1024X768;
1204
fs450_set_tv_vga_mode(unsigned long vga_mode)
1207
gfx_set_tv_vga_mode(unsigned long vga_mode)
1210
/*reject if not a single valid VGA mode */
1213
return ERR_INVALID_PARAMETER;
1214
case GFX_VGA_MODE_640X480:
1215
case GFX_VGA_MODE_720X487:
1216
case GFX_VGA_MODE_720X576:
1217
case GFX_VGA_MODE_800X600:
1219
case GFX_VGA_MODE_1024X768:
1220
if (houston_Rev() >= HOUSTON_REV_B)
1222
return ERR_INVALID_PARAMETER;
1225
/*if the mode has changed... */
1226
if (vga_mode != d.vga_mode) {
1227
d.vga_mode = vga_mode;
1229
return write_config(REQ_VGA_MODE);
1235
/*==========================================================================*/
1237
/*==========================================================================*/
1241
fs450_get_tvout_mode(unsigned long *p_tvout_mode)
1244
gfx_get_tvout_mode(unsigned long *p_tvout_mode)
1248
return ERR_INVALID_PARAMETER;
1250
*p_tvout_mode = d.tvout_mode;
1257
fs450_set_tvout_mode(unsigned long tvout_mode)
1260
gfx_set_tvout_mode(unsigned long tvout_mode)
1263
d.tvout_mode = tvout_mode;
1265
return write_config(REQ_TVOUT_MODE);
1268
/*==========================================================================*/
1270
/*==========================================================================*/
1274
fs450_get_sharpness(int *p_sharpness)
1277
gfx_get_sharpness(int *p_sharpness)
1281
return ERR_INVALID_PARAMETER;
1283
*p_sharpness = d.sharpness;
1290
fs450_set_sharpness(int sharpness)
1293
gfx_set_sharpness(int sharpness)
1296
d.sharpness = range_limit(sharpness, 0, 1000);
1298
return write_config(REQ_SHARPNESS);
1301
/*==========================================================================*/
1302
/* flicker filter control. */
1303
/*==========================================================================*/
1307
fs450_get_flicker_filter(int *p_flicker)
1310
gfx_get_flicker_filter(int *p_flicker)
1314
return ERR_INVALID_PARAMETER;
1316
*p_flicker = d.flicker;
1323
fs450_set_flicker_filter(int flicker)
1326
gfx_set_flicker_filter(int flicker)
1329
d.flicker = range_limit(flicker, 0, 1000);
1331
return write_config(REQ_FLICKER);
1334
/*==========================================================================*/
1335
/* Overscan and Position */
1336
/*==========================================================================*/
1340
fs450_get_overscan(int *p_x, int *p_y)
1343
gfx_get_overscan(int *p_x, int *p_y)
1347
return ERR_INVALID_PARAMETER;
1349
*p_x = d.overscan_x;
1350
*p_y = d.overscan_y;
1357
fs450_set_overscan(int x, int y)
1360
gfx_set_overscan(int x, int y)
1363
d.overscan_x = range_limit(x, -1000, 1000);
1364
d.overscan_y = range_limit(y, -1000, 1000);
1366
return write_config(REQ_OVERSCAN_POSITION);
1371
fs450_get_position(int *p_x, int *p_y)
1374
gfx_get_position(int *p_x, int *p_y)
1378
return ERR_INVALID_PARAMETER;
1380
*p_x = d.position_x;
1381
*p_y = d.position_y;
1388
fs450_set_position(int x, int y)
1391
gfx_set_position(int x, int y)
1394
d.position_x = range_limit(x, -1000, 1000);
1395
d.position_y = range_limit(y, -1000, 1000);
1397
return write_config(REQ_OVERSCAN_POSITION);
1400
/*==========================================================================*/
1401
/* Color, Brightness, and Contrast */
1402
/*==========================================================================*/
1406
fs450_get_color(int *p_color)
1409
gfx_get_color(int *p_color)
1413
return ERR_INVALID_PARAMETER;
1422
fs450_set_color(int color)
1425
gfx_set_color(int color)
1428
d.color = range_limit(color, 0, 100);
1430
return write_config(REQ_COLOR);
1435
fs450_get_brightness(int *p_brightness)
1438
gfx_get_brightness(int *p_brightness)
1442
return ERR_INVALID_PARAMETER;
1444
*p_brightness = d.brightness;
1451
fs450_set_brightness(int brightness)
1454
gfx_set_brightness(int brightness)
1457
d.brightness = range_limit(brightness, 0, 100);
1459
return write_config(REQ_BRIGHTNESS_CONTRAST);
1464
fs450_get_contrast(int *p_contrast)
1467
gfx_get_contrast(int *p_contrast)
1471
return ERR_INVALID_PARAMETER;
1473
*p_contrast = d.contrast;
1480
fs450_set_contrast(int constrast)
1483
gfx_set_contrast(int constrast)
1486
d.contrast = range_limit(constrast, 0, 100);
1488
return write_config(REQ_BRIGHTNESS_CONTRAST);
1491
/*==========================================================================*/
1493
/*==========================================================================*/
1497
fs450_get_yc_filter(unsigned int *p_yc_filter)
1500
gfx_get_yc_filter(unsigned int *p_yc_filter)
1504
return ERR_INVALID_PARAMETER;
1506
if (houston_Rev() < HOUSTON_REV_B)
1507
return ERR_NOT_SUPPORTED;
1509
*p_yc_filter = d.yc_filter;
1516
fs450_set_yc_filter(unsigned int yc_filter)
1519
gfx_set_yc_filter(unsigned int yc_filter)
1522
if (houston_Rev() < HOUSTON_REV_B)
1523
return ERR_NOT_SUPPORTED;
1526
if (yc_filter & GFX_LUMA_FILTER)
1527
d.yc_filter |= GFX_LUMA_FILTER;
1529
d.yc_filter &= ~GFX_LUMA_FILTER;
1532
if (yc_filter & GFX_CHROMA_FILTER)
1533
d.yc_filter |= GFX_CHROMA_FILTER;
1535
d.yc_filter &= ~GFX_CHROMA_FILTER;
1537
return write_config(REQ_YC_FILTER);
1542
fs450_get_aps_trigger_bits(unsigned int *p_trigger_bits)
1545
gfx_get_aps_trigger_bits(unsigned int *p_trigger_bits)
1548
if (!p_trigger_bits)
1549
return ERR_INVALID_PARAMETER;
1551
*p_trigger_bits = d.aps_trigger_bits;
1558
fs450_set_aps_trigger_bits(unsigned int trigger_bits)
1561
gfx_set_aps_trigger_bits(unsigned int trigger_bits)
1564
d.aps_trigger_bits = trigger_bits;
1566
return write_config(REQ_MACROVISION);
1569
/*----------------------------------------------------------------------------
1572
* This routine sets the TV encoder registers to the specified format
1574
* Currently only NTSC 640x480 is supported.
1575
*----------------------------------------------------------------------------
1579
fs450_set_tv_format(TVStandardType format, GfxOnTVType resolution)
1582
gfx_set_tv_format(TVStandardType format, GfxOnTVType resolution)
1585
/* ### ADD ### IMPLEMENTATION */
1589
/*----------------------------------------------------------------------------
1592
* This routine sets the TV encoder registers to the specified output type.
1593
* Supported output types are : S-VIDEO and Composite.
1594
*----------------------------------------------------------------------------
1598
fs450_set_tv_output(int output)
1601
gfx_set_tv_output(int output)
1604
/* ### ADD ### IMPLEMENTATION */
1608
/*----------------------------------------------------------------------------
1609
* gfx_set_tv_cc_enable
1611
* This routine enables or disables the use of the hardware CC registers
1612
* in the TV encoder.
1613
*----------------------------------------------------------------------------
1617
fs450_set_tv_cc_enable(int enable)
1620
gfx_set_tv_cc_enable(int enable)
1623
/* ### ADD ### IMPLEMENTATION */
1627
/*----------------------------------------------------------------------------
1628
* gfx_set_tv_cc_data
1630
* This routine writes the two specified characters to the CC data register
1631
* of the TV encoder.
1632
*----------------------------------------------------------------------------
1636
fs450_set_tv_cc_data(unsigned char data1, unsigned char data2)
1639
gfx_set_tv_cc_data(unsigned char data1, unsigned char data2)
1642
/* ### ADD ### IMPLEMENTATION */
1646
#ifdef FS450_DIRECTREG
1648
/*==========================================================================*/
1649
/* Direct Read and Write registers */
1650
/*==========================================================================*/
1653
FS450_ReadRegister(S_REG_INFO * p_reg)
1657
if (PLAL_ReadRegister(p_reg))
1660
if (SOURCE_HOUSTON == p_reg->source) {
1661
switch (p_reg->size) {
1665
houston_ReadReg((int) p_reg->offset, &tmp, (int) p_reg->size);
1672
houston_ReadReg((unsigned int) p_reg->offset, &tmp, 2);
1673
p_reg->value = (tmp << 16);
1674
houston_ReadReg((unsigned int) (p_reg->offset + 2), &tmp, 2);
1675
p_reg->value |= tmp;
1681
return ERR_INVALID_PARAMETER;
1685
FS450_WriteRegister(S_REG_INFO * p_reg)
1687
if (PLAL_WriteRegister(p_reg))
1690
if (SOURCE_HOUSTON == p_reg->source) {
1691
houston_WriteReg((unsigned int) p_reg->offset, p_reg->value,
1697
return ERR_INVALID_PARAMETER;
1702
/* Houston initialization function. */
1703
static int g_houston_rev = -1;
1709
unsigned long write, read;
1711
TRACE(("houston_init()\n"))
1713
/*Before we begin, we must enable power to the TFT */
1714
read = READ_VID32(CS5530_DISPLAY_CONFIG);
1715
read |= CS5530_DCFG_FP_PWR_EN | CS5530_DCFG_FP_DATA_EN;
1716
WRITE_VID32(CS5530_DISPLAY_CONFIG, read);
1718
/*simple w/r test. */
1722
houston_WriteReg(HOUSTON_IHO, write, 2);
1723
houston_ReadReg(HOUSTON_IHO, &read, 2);
1724
if (read != write) {
1725
houston_WriteReg(HOUSTON_IHO, write, 2);
1726
houston_ReadReg(HOUSTON_IHO, &read, 2);
1727
if (read != write) {
1728
/*chip is not there, do something appropriate? */
1729
TRACE(("wrote HOUSTON_IHO=0x0055, read 0x%04x\n", read))
1730
return ERR_DEVICE_NOT_FOUND;
1734
/*read chip revision. */
1735
houston_ReadReg(HOUSTON_REV, &read, 2);
1736
g_houston_rev = (int) read;
1745
return g_houston_rev;
1748
static S_TIMING_SPECS g_specs;
1750
static const S_TIMING_SPECS *
1756
/*==========================================================================*/
1757
/* FS450 configuration functions. */
1758
/*==========================================================================*/
1764
TRACE(("config_init()\n"))
1766
err = houston_init();
1773
/*==========================================================================*/
1774
/* convert word to encoder 10 bit value. */
1775
/*==========================================================================*/
1777
static unsigned short
1778
w10bit2z(unsigned short w)
1780
return (w >> 2) | ((w & 0x03) << 8);
1783
static unsigned short
1784
z2w10bit(unsigned short z)
1786
return (0x03 & (z >> 8)) | ((0xFF & z) << 2);
1789
/*==========================================================================*/
1791
/*==========================================================================*/
1793
static const struct {
1794
unsigned long standard;
1796
} g_tv_standards[] = {
1798
GFX_TV_STANDARD_NTSC_M, 0}, {
1799
GFX_TV_STANDARD_NTSC_M_J, 2}, {
1800
GFX_TV_STANDARD_PAL_B, 1}, {
1801
GFX_TV_STANDARD_PAL_D, 1}, {
1802
GFX_TV_STANDARD_PAL_H, 1}, {
1803
GFX_TV_STANDARD_PAL_I, 1}, {
1804
GFX_TV_STANDARD_PAL_M, 3}, {
1805
GFX_TV_STANDARD_PAL_N, 4}, {
1806
GFX_TV_STANDARD_PAL_G, 1},};
1809
map_tvstd_to_index(unsigned long tv_std)
1813
for (i = 0; i < sizeof(g_tv_standards) / sizeof(*g_tv_standards); i++) {
1814
if (tv_std == g_tv_standards[i].standard)
1815
return g_tv_standards[i].tvsetup_index;
1821
static unsigned long
1822
supported_standards(void)
1824
unsigned long standards = 0;
1827
for (i = 0; i < sizeof(g_tv_standards) / sizeof(*g_tv_standards); i++) {
1828
if (g_tv_standards[i].tvsetup_index >= 0)
1829
standards |= g_tv_standards[i].standard;
1835
/*==========================================================================*/
1838
config_power(int on)
1842
if (houston_Rev() < HOUSTON_REV_B) {
1843
/* no power down supported, but still turn of clock in off mode */
1845
houston_ReadReg(HOUSTON_CR, ®, 2);
1846
reg &= ~(CR_CLKOFF | CR_RESET);
1847
houston_WriteReg(HOUSTON_CR, reg, 2);
1849
houston_WriteReg(HOUSTON_CR, reg, 2);
1851
houston_WriteReg(HOUSTON_CR, reg, 2);
1854
houston_ReadReg(HOUSTON_CR, ®, 2);
1856
houston_WriteReg(HOUSTON_CR, reg, 2);
1863
/* !CLKOFF, !COMPOFF, !YCOFF */
1864
/* and reset Houston */
1865
houston_ReadReg(HOUSTON_CR, ®, 2);
1866
reg &= ~(CR_CLKOFF | CR_RESET | CR_COMPOFF | CR_YCOFF);
1867
houston_WriteReg(HOUSTON_CR, reg, 2);
1869
houston_WriteReg(HOUSTON_CR, reg, 2);
1871
houston_WriteReg(HOUSTON_CR, reg, 2);
1874
houston_ReadReg(HOUSTON_MISC, ®, 2);
1875
reg &= ~MISC_GTLIO_PD;
1876
houston_WriteReg(HOUSTON_MISC, reg, 2);
1879
/* CLKOFF, COMPOFF, YCOFF */
1880
houston_ReadReg(HOUSTON_CR, ®, 2);
1881
reg |= (CR_CLKOFF | CR_COMPOFF | CR_YCOFF);
1882
houston_WriteReg(HOUSTON_CR, reg, 2);
1885
houston_ReadReg(HOUSTON_MISC, ®, 2);
1886
reg |= MISC_GTLIO_PD;
1887
houston_WriteReg(HOUSTON_MISC, reg, 2);
1891
/*==========================================================================*/
1893
/*==========================================================================*/
1896
config_vga_mode(unsigned long vga_mode)
1898
/*h_total must be evenly divisible by 32? */
1907
GFX_VGA_MODE_640X480, 640, 480, 1056}, {
1908
GFX_VGA_MODE_720X487, 720, 487, 1056}, {
1909
GFX_VGA_MODE_720X576, 720, 576, 1056}, {
1910
GFX_VGA_MODE_800X600, 800, 600, 1056}, {
1911
GFX_VGA_MODE_1024X768, 1024, 768, 1344},};
1913
unsigned long cr, misc, byp;
1916
g_specs.vga_width = 0;
1917
g_specs.vga_lines = 0;
1918
g_specs.h_total = 0;
1920
for (i = 0; i < sizeof(vgaparams) / sizeof(*vgaparams); i++) {
1921
if (vga_mode == vgaparams[i].mode) {
1922
g_specs.vga_width = vgaparams[i].width;
1923
g_specs.vga_lines = vgaparams[i].lines;
1924
g_specs.h_total = vgaparams[i].h_total;
1928
if (!g_specs.h_total)
1931
/*clock mux decimator and vga dual. */
1932
houston_ReadReg(HOUSTON_CR, &cr, 2);
1933
houston_ReadReg(HOUSTON_MISC, &misc, 2);
1934
houston_ReadReg(HOUSTON_BYP, &byp, 2);
1936
if (vga_mode == GFX_VGA_MODE_1024X768) {
1937
/*XGA*/ cr |= CR_UIM_DEC;
1938
misc |= MISC_VGACKDIV;
1939
byp |= (BYP_HDS_BYPASS | BYP_CAC_BYPASS);
1944
misc &= ~MISC_VGACKDIV;
1945
byp &= ~(BYP_HDS_BYPASS | BYP_CAC_BYPASS);
1948
houston_WriteReg(HOUSTON_CR, cr, 2);
1949
houston_WriteReg(HOUSTON_MISC, misc, 2);
1950
houston_WriteReg(HOUSTON_BYP, byp, 2);
1953
/*==========================================================================*/
1954
/* Write settings for TV standard to device */
1955
/*==========================================================================*/
1958
config_tv_std(unsigned long tv_std, unsigned int trigger_bits)
1961
unsigned short reg34;
1962
unsigned long cr, w;
1965
/*verify supported standard. */
1966
k = map_tvstd_to_index(tv_std);
1970
/*store tv width and lines */
1971
g_specs.tv_width = tvsetup.tv_width[k];
1972
g_specs.tv_lines = tvsetup.tv_lines[k];
1974
/*houston CR register. */
1975
houston_ReadReg(HOUSTON_CR, &cr, 2);
1976
cr &= ~CR_656_PAL_NTSC;
1977
cr |= tvsetup.houston_cr[k];
1978
houston_WriteReg(HOUSTON_CR, cr, 2);
1980
/*setup the encoder. */
1981
l = tvsetup.chroma_freq[k];
1982
houston_WriteReg(ENC_CHROMA_FREQ, (int) (l & 0x00ff), 1);
1983
houston_WriteReg(ENC_CHROMA_FREQ + 1, (int) ((l >> 8) & 0x00ff), 1);
1984
houston_WriteReg(ENC_CHROMA_FREQ + 2, (int) ((l >> 16) & 0x00ff), 1);
1985
houston_WriteReg(ENC_CHROMA_FREQ + 3, (int) ((l >> 24) & 0x00ff), 1);
1987
houston_WriteReg(ENC_CHROMA_PHASE, tvsetup.chroma_phase[k], 1);
1988
houston_WriteReg(ENC_REG05, 0x00, 1); /*reg 0x05 */
1989
houston_WriteReg(ENC_REG06, 0x89, 1); /*reg 0x06 */
1990
houston_WriteReg(ENC_REG07, 0x00, 1); /*reg 0x07 */
1991
houston_WriteReg(ENC_HSYNC_WIDTH, tvsetup.hsync_width[k], 1);
1992
houston_WriteReg(ENC_BURST_WIDTH, tvsetup.burst_width[k], 1);
1993
houston_WriteReg(ENC_BACK_PORCH, tvsetup.back_porch[k], 1);
1994
houston_WriteReg(ENC_CB_BURST_LEVEL, tvsetup.cb_burst_level[k], 1);
1995
houston_WriteReg(ENC_CR_BURST_LEVEL, tvsetup.cr_burst_level[k], 1);
1996
houston_WriteReg(ENC_SLAVE_MODE, 0x01, 1); /*slave mode */
1997
if (trigger_bits == 0)
1998
w = w10bit2z(tvsetup.blank_level[k]); /*blank level */
2000
w = w10bit2z((unsigned short) (tvsetup.blank_level[k] -
2001
tvsetup.hamp_offset[k]));
2002
houston_WriteReg(ENC_BLANK_LEVEL, w & 0x00ff, 1);
2003
houston_WriteReg(ENC_BLANK_LEVEL + 1, w >> 8, 1);
2004
w = w10bit2z(tvsetup.tv_lines[k]); /*num_lines */
2005
houston_WriteReg(ENC_NUM_LINES, w & 0x00ff, 1);
2006
houston_WriteReg(ENC_NUM_LINES + 1, w >> 8, 1);
2008
houston_WriteReg(ENC_TINT, 0x00, 1); /*tint */
2009
houston_WriteReg(ENC_BREEZE_WAY, tvsetup.breeze_way[k], 1);
2010
houston_WriteReg(ENC_FRONT_PORCH, tvsetup.front_porch[k], 1);
2011
houston_WriteReg(ENC_ACTIVELINE, tvsetup.activeline[k], 1);
2012
houston_WriteReg(ENC_FIRST_LINE, 0x15, 1); /*firstvideoline */
2015
(tvsetup.pal_mode[k] << 6) |
2016
(tvsetup.sys625_50[k] << 3) |
2017
(tvsetup.cphase_rst[k] << 1) | (tvsetup.vsync5[k]);
2018
houston_WriteReg(ENC_REG34, reg34, 1); /*reg 0x34 */
2019
houston_WriteReg(ENC_SYNC_LEVEL, tvsetup.sync_level[k], 1);
2020
if (trigger_bits == 0)
2021
w = w10bit2z(tvsetup.vbi_blank_level[k]); /*blank level */
2023
w = w10bit2z((unsigned short) (tvsetup.vbi_blank_level[k] - 1));
2024
houston_WriteReg(ENC_VBI_BLANK_LEVEL, w & 0x00ff, 1);
2025
houston_WriteReg(ENC_VBI_BLANK_LEVEL + 1, w >> 8, 1);
2029
conget_tv_std(unsigned long *p_tv_standard)
2036
/*just pick between NTSC and PAL */
2037
houston_ReadReg(HOUSTON_CR, &cr, 2);
2038
if (CR_656_PAL_NTSC & cr)
2039
*p_tv_standard = GFX_TV_STANDARD_PAL_B;
2041
*p_tv_standard = GFX_TV_STANDARD_NTSC_M;
2044
/*==========================================================================*/
2046
/*==========================================================================*/
2049
config_tvout_mode(unsigned long tvout_mode)
2053
houston_ReadReg(HOUSTON_CR, &cr, 2);
2056
cr |= (CR_COMPOFF | CR_YCOFF);
2060
/*turn on requested output */
2061
if (GFX_TVOUT_MODE_CVBS & tvout_mode)
2063
if (GFX_TVOUT_MODE_YC & tvout_mode)
2065
if (GFX_TVOUT_MODE_RGB & tvout_mode) {
2066
cr &= ~(CR_COMPOFF | CR_YCOFF);
2070
houston_WriteReg(HOUSTON_CR, cr, 2);
2074
conget_tvout_mode(unsigned long *p_tvout_mode)
2081
houston_ReadReg(HOUSTON_CR, &cr, 2);
2084
*p_tvout_mode = GFX_TVOUT_MODE_RGB;
2087
if (!(CR_YCOFF & cr))
2088
*p_tvout_mode |= GFX_TVOUT_MODE_YC;
2089
if (!(CR_COMPOFF & cr))
2090
*p_tvout_mode |= GFX_TVOUT_MODE_CVBS;
2094
/*==========================================================================*/
2095
/* Size & Position */
2096
/*==========================================================================*/
2098
#define IS_NTSC(tv_std) \
2100
GFX_TV_STANDARD_NTSC_M | \
2101
GFX_TV_STANDARD_NTSC_M_J | \
2102
GFX_TV_STANDARD_PAL_M))
2103
#define IS_PAL(tv_std) \
2105
GFX_TV_STANDARD_PAL_B | \
2106
GFX_TV_STANDARD_PAL_D | \
2107
GFX_TV_STANDARD_PAL_H | \
2108
GFX_TV_STANDARD_PAL_I | \
2109
GFX_TV_STANDARD_PAL_N | \
2110
GFX_TV_STANDARD_PAL_G))
2112
/*return fifo delay setting for mode, std, and total lines.*/
2115
get_ffolat_ivo(unsigned long vga_mode,
2116
unsigned long tv_std, long i, unsigned short *ffolat,
2117
unsigned short *ivo)
2120
case GFX_VGA_MODE_640X480:
2121
if (IS_NTSC(tv_std)) {
2122
if (i > SIZE6X4NTSC - 1)
2123
i = SIZE6X4NTSC - 1;
2124
*ffolat = ffo6x4ntsc[i].ffolat;
2128
if (i > SIZE6X4PAL - 1)
2130
*ffolat = ffo6x4pal[i].ffolat;
2135
case GFX_VGA_MODE_800X600:
2136
if (IS_NTSC(tv_std)) {
2137
if (i > SIZE8X6NTSC - 1)
2138
i = SIZE8X6NTSC - 1;
2139
*ffolat = ffo8x6ntsc[i].ffolat;
2143
if (i > SIZE8X6PAL - 1)
2145
*ffolat = ffo8x6pal[i].ffolat;
2150
case GFX_VGA_MODE_720X487:
2151
*ffolat = 0x40; /*FFO7x4; */
2155
case GFX_VGA_MODE_720X576:
2156
*ffolat = 0x40; /*FFO7x5; */
2160
case GFX_VGA_MODE_1024X768:
2162
if (IS_NTSC(tv_std)) {
2163
if (i > SIZE10X7NTSC - 1)
2164
i = SIZE10X7NTSC - 1;
2165
*ffolat = ffo10x7ntsc[i].ffolat;
2166
*ivo = ffo10x7ntsc[i].ivo;
2169
if (i > SIZE10X7PAL - 1)
2170
i = SIZE10X7PAL - 1;
2171
*ffolat = ffo10x7pal[i].ffolat;
2172
*ivo = ffo10x7pal[i].ivo;
2178
/*get vertical line min and max for mode and std.*/
2181
get_vtotal_min_max(unsigned long vga_mode,
2182
unsigned long tv_std, int *v_total_min, int *v_total_max,
2185
int k = map_tvstd_to_index(tv_std);
2188
case GFX_VGA_MODE_640X480:
2189
if (IS_NTSC(tv_std)) {
2190
*v_total_min = ffo6x4ntsc[0].v_total;
2191
*v_total_max = ffo6x4ntsc[SIZE6X4NTSC - 1].v_total;
2194
*v_total_min = ffo6x4pal[0].v_total;
2195
*v_total_max = ffo6x4pal[SIZE6X4PAL - 1].v_total;
2200
case GFX_VGA_MODE_800X600:
2201
if (IS_NTSC(tv_std)) {
2202
*v_total_min = ffo8x6ntsc[0].v_total;
2203
*v_total_max = ffo8x6ntsc[SIZE8X6NTSC - 1].v_total;
2206
*v_total_min = ffo8x6pal[0].v_total;
2207
*v_total_max = ffo8x6pal[SIZE8X6PAL - 1].v_total;
2212
case GFX_VGA_MODE_720X487:
2213
case GFX_VGA_MODE_720X576:
2214
*v_total_min = tvsetup.tv_lines[k];
2215
*v_total_max = tvsetup.tv_lines[k];
2219
case GFX_VGA_MODE_1024X768:
2220
if (IS_NTSC(tv_std)) {
2221
*v_total_min = ffo10x7ntsc[0].v_total;
2222
*v_total_max = ffo10x7ntsc[SIZE10X7NTSC - 1].v_total;
2225
*v_total_min = ffo10x7pal[0].v_total;
2226
*v_total_max = ffo10x7pal[SIZE10X7PAL - 1].v_total;
2234
config_overscan_xy(unsigned long tv_std,
2235
unsigned long vga_mode,
2236
int overscan_x, int overscan_y, int pos_x, int pos_y)
2238
unsigned int vga_index;
2242
unsigned short ffolat, ivo;
2243
int base_v_total, range, v_offset;
2244
int v_total_min, v_total_max, v_step;
2246
int vga_pixels, pre_pixels;
2247
float hscale, hscale_min, hscale_max;
2249
int iho, iho_max, ihw;
2251
/*tv_std is valid. */
2252
k = map_tvstd_to_index(tv_std);
2254
/*store tv width and lines */
2255
g_specs.tv_width = tvsetup.tv_width[k];
2256
g_specs.tv_lines = tvsetup.tv_lines[k];
2258
/*determine vga mode index */
2259
for (vga_index = 0; vga_index < SCANTABLE_ENTRIES; vga_index++) {
2260
if (scantable[vga_index].mode == vga_mode)
2263
if (vga_index >= SCANTABLE_ENTRIES)
2266
/*vertical scaling (v_total setup). */
2267
/*calculate vertical range. */
2268
get_vtotal_min_max(vga_mode, tv_std, &v_total_min, &v_total_max, &v_step);
2269
TRACE(("v_total min=%d, max=%d\n", v_total_min, v_total_max))
2270
base_v_total = scantable[vga_index].v_total[k];
2271
range = fsmax(base_v_total - v_total_min, v_total_max - base_v_total);
2272
TRACE(("v_total range = %d\n", range))
2274
/*map +/-1000 overscan y into +/-range. */
2275
v_offset = (int) ((((float) overscan_y * range) / 1000.f) + .5f);
2276
TRACE(("v_offset = %d\n", v_offset))
2278
/*range limit v_total. */
2280
range_limit(base_v_total + v_offset, v_total_min, v_total_max);
2282
/*round to calibrated value. */
2283
v_offset = (g_specs.v_total - v_total_min + (v_step / 2)) / v_step;
2284
g_specs.v_total = v_total_min + v_offset * v_step;
2285
TRACE(("desired v_total=%d\n", g_specs.v_total))
2287
/*vertical positioning (vsync setup). */
2288
get_ffolat_ivo(vga_mode, tv_std, v_offset, &ffolat, &ivo);
2289
houston_WriteReg(HOUSTON_IVO, ivo, 2);
2291
/*scale base sync offset by scaling ratio. */
2292
r = (float) g_specs.v_total / (float) base_v_total;
2293
v_offset = (int) (r * (float) scantable[vga_index].v_sync[k]);
2297
v_offset -= (int) (f - f / r);
2299
/*compensate for center screen. */
2300
f = (float) tvsetup.tv_active_lines[k] / 2.f;
2301
v_offset += (int) (f * r - f);
2303
/*calculate vsync. */
2304
g_specs.v_sync = g_specs.v_total - v_offset + pos_y;
2305
TRACE(("desired v_total=%d, desired v_sync=%d\n", g_specs.v_total,
2307
if (g_specs.v_sync < g_specs.vga_lines + 10) {
2308
TRACE(("vsync too low\n"))
2309
/*d.v_total += d.vga_lines+10-d.v_sync; */
2310
g_specs.v_sync = g_specs.vga_lines + 10;
2312
else if (g_specs.v_sync > g_specs.v_total - 10) {
2313
TRACE(("vsync too high\n"))
2314
g_specs.v_sync = g_specs.v_total - 10;
2316
TRACE(("v_total=%d v_sync=%d\n", g_specs.v_total, g_specs.v_sync))
2319
houston_WriteReg(HOUSTON_FFO_LAT, ffolat, 2);
2324
(double) g_specs.tv_lines / (double) g_specs.v_total)) +
2326
reg = ((unsigned long) -vsc) & 0xffff;
2327
TRACE(("vsc=%04x, tv_lines=%d, v_total=%d\n", reg, g_specs.tv_lines,
2329
houston_WriteReg(HOUSTON_VSC, (int) reg, 2);
2331
/* horizontal scaling. */
2333
/* vga pixels is vga width, except in 1024x768, where it's half that. */
2334
vga_pixels = g_specs.vga_width;
2335
if (1024 == vga_pixels)
2338
/* maximum scaling coefficient is tv_width / vga_pixels */
2339
/* minimum is about 1/2, but that is quite small. arbitrarily set
2340
* minimum at 75% maximum. */
2341
hscale_max = (720.0f / vga_pixels);
2342
hscale_min = fsmax((0.75f * hscale_max), (1.0f - (63.0f / 128.0f)));
2343
TRACE(("hscale_min = %u.%u, hscale_max = %u.%u\n",
2345
(int) ((hscale_min - (int) hscale_min) * 1000),
2346
(int) hscale_max, (int) ((hscale_max - (int) hscale_max) * 1000)))
2348
/* map overscan_x into min to max. */
2350
hscale_min + ((overscan_x + 1000.0f) / 2000.0f) * (hscale_max -
2352
TRACE(("hscale = %u.%u\n", (int) hscale,
2353
(int) ((hscale - (int) hscale) * 1000)))
2355
/* determine hsc where hscale = (1 + hsc/128) */
2357
hsc = (int) (128.f * (hscale - 1.0f) + .5f);
2359
hsc = (int) (128.f * (hscale - 1.0f) - .5f);
2361
TRACE(("hsc = %d\n", hsc))
2363
houston_WriteReg(HOUSTON_HSC, hsc << 8, 2);
2365
houston_WriteReg(HOUSTON_HSC, hsc & 0xFF, 2);
2367
/* recalculate hscale for future formulas */
2368
hscale = 1.0f + (hsc / 128.0f);
2369
TRACE(("recalculated hscale = %u.%u\n", (int) hscale,
2370
(int) ((hscale - (int) hscale) * 1000)))
2372
/* horizontal offset. */
2373
/* place hsync 40 before halfway from vga_width to htotal */
2374
/* but not less than vga_width + 10 */
2376
fsmax((g_specs.h_total + g_specs.vga_width) / 2 - 40,
2377
g_specs.vga_width + 10);
2378
/* also, make it even */
2379
g_specs.h_sync &= ~1;
2380
TRACE(("hsync = %u\n", g_specs.h_sync))
2382
/* iho range is 0 to iho_max. */
2383
/* iho_max is 2 * iho_center. */
2384
/* iho_center is pre_pixels - (tvwidth / hscale - vga pixels) / 2. */
2385
/* pre_pixels = (htotal - hsync) * (vga_pixels / vga_width) */
2386
/* note that the range is inverted also, because it specifies the number
2388
/* to skip, or subtract. iho=0 maps to farthest right. */
2389
/* map -pos_x = +/-1000 into (0 to iho_max) */
2391
(int) ((long) (g_specs.h_total -
2392
g_specs.h_sync) * vga_pixels / g_specs.vga_width);
2393
iho_max = (2 * pre_pixels) - ((int) (720.0f / hscale + 0.5f) - vga_pixels);
2394
TRACE(("iho_max = %u\n", iho_max))
2396
(int) range_limit(((long) (1000 - pos_x) * iho_max / 2000) +
2397
scantable[vga_index].iho[k], 0, iho_max);
2398
TRACE(("iho = %u\n", iho))
2399
houston_WriteReg(HOUSTON_IHO, iho, 2);
2401
/* input horizontal width. */
2403
/* input horizontal width is vga pixels + pre_pixels - iho */
2404
/* additionally, ihw cannot exceed tv width / hscale */
2405
/* and if hsc is negative, (ihw)(-hsc/128) cannot exceed ~250. */
2406
/* and ihw should be even. */
2407
ihw = fsmin(vga_pixels + pre_pixels - iho, (int) (720.0f / hscale));
2409
ihw = (int) fsmin(ihw, 253L * 128 / (-hsc));
2411
TRACE(("ihw = %u\n", ihw))
2412
houston_WriteReg(HOUSTON_IHA, ihw, 2);
2414
f = (((float) g_specs.h_total * g_specs.v_total) * 27.f) /
2415
((float) g_specs.tv_width * g_specs.tv_lines);
2417
TRACE(("freq=%u.%uMHz\n", (int) f, (int) ((f - (int) f) * 1000)))
2420
/*==========================================================================*/
2421
/* configure houston nco. */
2422
/*==========================================================================*/
2425
config_nco(unsigned long tv_std, unsigned long vga_mode)
2427
unsigned long cr, misc;
2429
int k = map_tvstd_to_index(tv_std);
2431
/*read and store CR. */
2432
houston_ReadReg(HOUSTON_CR, &cr, 2);
2434
/*make sure NCO_EN (enable latch) bit is clear */
2436
houston_WriteReg(HOUSTON_CR, cr, 2);
2438
/*clear NCO_LOADX. */
2439
houston_ReadReg(HOUSTON_MISC, &misc, 2);
2440
misc &= ~(MISC_NCO_LOAD1 + MISC_NCO_LOAD0);
2441
houston_WriteReg(HOUSTON_MISC, misc, 2);
2443
if (vga_mode == GFX_VGA_MODE_1024X768) {
2444
/*setup for M and N load (Nco_load=1). */
2445
misc |= (MISC_NCO_LOAD0);
2446
houston_WriteReg(HOUSTON_MISC, misc, 2);
2449
houston_WriteReg(HOUSTON_NCONL, 1024 - 2, 2);
2450
houston_WriteReg(HOUSTON_NCODL, 128 - 1, 2);
2454
houston_WriteReg(HOUSTON_CR, cr, 2);
2456
houston_WriteReg(HOUSTON_CR, cr, 2);
2458
/*setup ncon and ncod load (Nco_load=0). */
2459
misc &= ~(MISC_NCO_LOAD1 + MISC_NCO_LOAD0);
2460
houston_WriteReg(HOUSTON_MISC, misc, 2);
2463
reg = ((unsigned long) g_specs.v_total * g_specs.h_total) / 2;
2464
houston_WriteReg(HOUSTON_NCONH, reg >> 16, 2);
2465
houston_WriteReg(HOUSTON_NCONL, reg & 0xffff, 2);
2468
houston_WriteReg(HOUSTON_NCODL, tvsetup.houston_ncodl[k], 2);
2469
houston_WriteReg(HOUSTON_NCODH, tvsetup.houston_ncodh[k], 2);
2472
/*setup for M and N load (Nco_load=2). */
2473
misc |= (MISC_NCO_LOAD1);
2474
houston_WriteReg(HOUSTON_MISC, misc, 2);
2477
reg = (unsigned long) g_specs.v_total * g_specs.h_total;
2478
houston_WriteReg(HOUSTON_NCONH, reg >> 16, 2);
2479
houston_WriteReg(HOUSTON_NCONL, reg & 0xffff, 2);
2482
houston_WriteReg(HOUSTON_NCODL, tvsetup.houston_ncodl[k], 2);
2483
houston_WriteReg(HOUSTON_NCODH, tvsetup.houston_ncodh[k], 2);
2485
TRACE(("NCON = %lu (0x%08lx), NCOD = %lu (0x%08lx)\n",
2488
((unsigned long) tvsetup.houston_ncodh[k] << 16) +
2489
tvsetup.houston_ncodl[k],
2490
((unsigned long) tvsetup.houston_ncodh[k] << 16) +
2491
tvsetup.houston_ncodl[k]))
2494
/*latch M/N and NCON/NCOD in. */
2496
houston_WriteReg(HOUSTON_CR, cr, 2);
2498
houston_WriteReg(HOUSTON_CR, cr, 2);
2501
/*==========================================================================*/
2502
/* Write sharpness settings to device */
2503
/*==========================================================================*/
2506
config_sharpness(int sharpness)
2510
/*map 0-1000 to 0-20. */
2511
shp = (unsigned int) (0.5f + ((float) sharpness * 20.0f / 1000.0f));
2512
shp = range_limit(shp, 0, 20);
2514
houston_WriteReg(HOUSTON_SHP, shp, 2);
2518
conget_sharpness(int *p_sharpness)
2525
houston_ReadReg(HOUSTON_SHP, &shp, 2);
2527
/*map 0-20 to 0-1000. */
2528
*p_sharpness = (int) (0.5f + ((float) shp * 1000.0f / 20.0f));
2531
/*==========================================================================*/
2532
/* Write flicker settings to device */
2533
/*==========================================================================*/
2536
config_flicker(int flicker)
2540
/*map 0-1000 to 0-16. */
2541
flk = (unsigned int) (0.5f + ((float) flicker * 16.0f / 1000.0f));
2542
flk = range_limit(flk, 0, 16);
2544
houston_WriteReg(HOUSTON_FLK, flk, 2);
2548
conget_flicker(int *p_flicker)
2555
houston_ReadReg(HOUSTON_FLK, &flk, 2);
2557
/*map 0-16 to 0-1000. */
2558
*p_flicker = (int) (0.5f + ((float) flk * 1000.0f / 16.0f));
2561
/*==========================================================================*/
2562
/* Write color settings to device */
2563
/*==========================================================================*/
2566
config_color(int color)
2570
/*map 0-100 to 0-255. */
2571
/*montreal production test needs 169 to be mappable, so */
2572
/*use .8 rounding factor, 169=(int)(66.*2.55+.8). */
2573
clr = (unsigned long) (0.8f + ((float) color * 255.0f / 100.0f));
2574
clr = range_limit(clr, 0, 255);
2576
houston_WriteReg(ENC_CR_GAIN, clr, 1);
2577
houston_WriteReg(ENC_CB_GAIN, clr, 1);
2581
conget_color(int *p_color)
2583
unsigned long cr_gain;
2588
/*just get CR GAIN, CB GAIN should match. */
2589
houston_ReadReg(ENC_CR_GAIN, &cr_gain, 1);
2591
/*map 0-255 to 0-100. */
2592
*p_color = (int) (0.5f + ((float) cr_gain * 100.0f / 255.0f));
2595
/*==========================================================================*/
2596
/* Write brightness and contrast settings to device */
2597
/*==========================================================================*/
2599
#define NTSC_BLANK_LEVEL 240
2601
static const int min_black_level = NTSC_BLANK_LEVEL + 1;
2602
static const int max_white_level = 1023;
2605
config_brightness_contrast(unsigned long tv_std, unsigned int trigger_bits,
2606
int brightness, int contrast)
2609
float contrast_mult;
2612
int k = map_tvstd_to_index(tv_std);
2614
/*0-100 maps to +/-220. */
2616
(int) (0.5f + ((float) brightness * 440.0f / 100.0f)) - 220;
2618
/*0-100 maps to .75-1.25. */
2619
contrast_mult = ((float) contrast * 0.5f / 100.0f) + 0.75f;
2621
black = tvsetup.black_level[k];
2622
if (trigger_bits != 0)
2623
black -= tvsetup.hamp_offset[k];
2625
white = tvsetup.white_level[k];
2626
if (trigger_bits != 0)
2627
white -= tvsetup.hamp_offset[k];
2629
black = (int) ((float) (black + brightness_off) * contrast_mult);
2630
white = (int) ((float) (white + brightness_off) * contrast_mult);
2631
if (black < min_black_level)
2632
black = min_black_level;
2633
if (white > max_white_level)
2634
white = max_white_level;
2636
w = w10bit2z((unsigned short) black);
2637
houston_WriteReg(ENC_BLACK_LEVEL, w & 0x00ff, 1);
2638
houston_WriteReg(ENC_BLACK_LEVEL + 1, w >> 8, 1);
2639
w = w10bit2z((unsigned short) white);
2640
houston_WriteReg(ENC_WHITE_LEVEL, w & 0x00ff, 1);
2641
houston_WriteReg(ENC_WHITE_LEVEL + 1, w >> 8, 1);
2645
conget_brightness_contrast(unsigned long tv_std, unsigned int trigger_bits,
2646
int *p_brightness, int *p_contrast)
2649
float contrast_mult;
2650
unsigned short black, white;
2651
unsigned long zh, zl;
2654
if (!p_brightness || !p_contrast)
2657
k = map_tvstd_to_index(tv_std);
2659
houston_ReadReg(ENC_BLACK_LEVEL, &zl, 1);
2660
houston_ReadReg(ENC_BLACK_LEVEL + 1, &zh, 1);
2661
black = z2w10bit((unsigned short) (zl + (zh << 8)));
2662
if (trigger_bits != 0)
2663
black += tvsetup.hamp_offset[k];
2664
houston_ReadReg(ENC_WHITE_LEVEL, &zl, 1);
2665
houston_ReadReg(ENC_WHITE_LEVEL + 1, &zh, 1);
2666
white = z2w10bit((unsigned short) (zl + (zh << 8)));
2667
if (trigger_bits != 0)
2668
white += tvsetup.hamp_offset[k];
2670
/*this reverse computation does not account for clipping, but should */
2671
/*provide somewhat reasonable numbers */
2673
((float) white - (float) black) / ((float) tvsetup.white_level[k] -
2674
(float) tvsetup.black_level[k]);
2676
(int) (((float) black / contrast_mult) - tvsetup.black_level[k]);
2678
/*+/-220 maps to 0-100. */
2680
range_limit((int) (0.5f + ((float) (brightness_off +
2681
220) * 100.0f / 440.0f)), 0, 100);
2683
/*.75-1.25 maps to 0-100. */
2685
range_limit((int) (0.5f + ((float) (contrast_mult -
2686
0.75f) * 100.0f / 0.5f)), 0, 100);
2689
/*==========================================================================*/
2690
/* configure luma/chroma filters. */
2691
/*==========================================================================*/
2694
config_yc_filter(unsigned long tv_std, int luma_filter, int chroma_filter)
2696
unsigned long reg, reg07, reg34;
2698
if (houston_Rev() < HOUSTON_REV_B)
2703
reg = tvsetup.notch_filter[map_tvstd_to_index(tv_std)];
2706
houston_WriteReg(ENC_NOTCH_FILTER, reg, 1);
2709
houston_ReadReg(ENC_REG07, ®07, 1);
2710
houston_ReadReg(ENC_REG34, ®34, 1);
2711
if (chroma_filter) {
2719
houston_WriteReg(ENC_REG07, reg07, 1);
2720
houston_WriteReg(ENC_REG34, reg34, 1);
2724
conget_yc_filter(int *p_luma_filter, int *p_chroma_filter)
2726
unsigned long reg, reg07, reg34;
2728
if (!p_luma_filter || !p_chroma_filter)
2731
if (houston_Rev() < HOUSTON_REV_B) {
2733
*p_chroma_filter = 0;
2738
houston_ReadReg(ENC_NOTCH_FILTER, ®, 1);
2739
*p_luma_filter = (reg ? 1 : 0);
2742
houston_ReadReg(ENC_REG07, ®07, 1);
2743
houston_ReadReg(ENC_REG34, ®34, 1);
2744
*p_chroma_filter = !((0x08 & reg07) || (0x20 & reg34));
2747
/*==========================================================================*/
2749
/*==========================================================================*/
2752
config_macrovision(unsigned long tv_std, unsigned int trigger_bits)
2754
/*Constants to index into mvsetup columns.*/
2755
#define nNTSC_APS00 0 /*ntsc mv off. */
2756
#define nNTSC_APS01 1 /*ntsc AGC only. */
2757
#define nNTSC_APS10 2 /*ntsc AGC + 2-line CS. */
2758
#define nNTSC_APS11 3 /*ntsc AGC + 4-line CS. */
2759
#define nPAL_APS00 4 /*pal mv off. */
2760
#define nPAL_APSXX 5 /*pal mv on. */
2763
/*Macrovision setup table. */
2764
static const struct mvparms {
2765
unsigned short n0[nMVModes];
2766
unsigned short n1[nMVModes];
2767
unsigned short n2[nMVModes];
2768
unsigned short n3[nMVModes];
2769
unsigned short n4[nMVModes];
2770
unsigned short n5[nMVModes];
2771
unsigned short n6[nMVModes];
2772
unsigned short n7[nMVModes];
2773
unsigned short n8[nMVModes];
2774
unsigned short n9[nMVModes];
2775
unsigned short n10[nMVModes];
2776
unsigned short n11[nMVModes];
2777
unsigned short n12[nMVModes];
2778
unsigned short n13[nMVModes];
2779
unsigned short n14[nMVModes];
2780
unsigned short n15[nMVModes];
2781
unsigned short n16[nMVModes];
2782
unsigned short n17[nMVModes];
2783
unsigned short n18[nMVModes];
2784
unsigned short n19[nMVModes];
2785
unsigned short n20[nMVModes];
2786
unsigned short n21[nMVModes];
2787
unsigned short n22[nMVModes];
2788
unsigned short agc_pulse_level[nMVModes];
2789
unsigned short bp_pulse_level[nMVModes];
2791
/* ntsc ntsc ntsc ntsc pal pal */
2792
/* MV AGC AGC + AGC + MV MV */
2793
/* off. only 2-line 4-line off. on. */
2796
0x00, 0x36, 0x3e, 0x3e, 0x00, 0x3e}, /*n0 */
2798
0x1d, 0x1d, 0x1d, 0x17, 0x1a, 0x1a}, /*n1 */
2800
0x11, 0x11, 0x11, 0x15, 0x22, 0x22}, /*n2 */
2802
0x25, 0x25, 0x25, 0x21, 0x2a, 0x2a}, /*n3 */
2804
0x11, 0x11, 0x11, 0x15, 0x22, 0x22}, /*n4 */
2806
0x01, 0x01, 0x01, 0x05, 0x05, 0x05}, /*n5 */
2808
0x07, 0x07, 0x07, 0x05, 0x02, 0x02}, /*n6 */
2810
0x00, 0x00, 0x00, 0x02, 0x00, 0x00}, /*n7 */
2812
0x1b, 0x1b, 0x1b, 0x1b, 0x1c, 0x1c}, /*n8 */
2814
0x1b, 0x1b, 0x1b, 0x1b, 0x3d, 0x3d}, /*n9 */
2816
0x24, 0x24, 0x24, 0x24, 0x14, 0x14}, /*n10 */
2818
0x780f, 0x780f, 0x780f, 0x780f, 0x7e07, 0x7e07}, /*n11 */
2820
0x0000, 0x0000, 0x0000, 0x0000, 0x5402, 0x5402}, /*n12 */
2822
0x0f, 0x0f, 0x0f, 0x0f, 0xfe, 0xfe}, /*n13 */
2824
0x0f, 0x0f, 0x0f, 0x0f, 0x7e, 0x7e}, /*n14 */
2826
0x60, 0x60, 0x60, 0x60, 0x60, 0x60}, /*n15 */
2828
0x01, 0x01, 0x01, 0x01, 0x00, 0x00}, /*n16 */
2830
0x0a, 0x0a, 0x0a, 0x0a, 0x08, 0x08}, /*n17 */
2832
0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*n18 */
2834
0x05, 0x05, 0x05, 0x05, 0x04, 0x04}, /*n19 */
2836
0x04, 0x04, 0x04, 0x04, 0x07, 0x07}, /*n20 */
2838
0x03ff, 0x03ff, 0x03ff, 0x03ff, 0x0155, 0x0155}, /*n21 */
2840
0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*n22 */
2842
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3}, /*agc_pulse_level */
2844
0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8}, /*bp_pulse_level */
2851
trigger_bits &= 0x3;
2853
/*Determine the OEM Macrovision Program Mode and Register 0 Data. */
2854
if (IS_NTSC(tv_std)) {
2855
/*NTSC TV Standard. */
2856
if (trigger_bits == 0) {
2857
/*turn Macrovision OFF. */
2858
nMode = nNTSC_APS00;
2860
else if (trigger_bits == 1) {
2862
nMode = nNTSC_APS01;
2864
else if (trigger_bits == 2) {
2865
/*AGC + 2-line CS. */
2866
nMode = nNTSC_APS10;
2869
/*AGC + 4-line CS. */
2870
nMode = nNTSC_APS11;
2874
/*PAL TV Standard. */
2875
if (trigger_bits == 0) {
2876
/*turn Macrovision OFF. */
2880
/*APS 01, 10, or 11. */
2885
/*Retrieve the Macrovision Program Mode Data */
2886
if (tv_std != GFX_TV_STANDARD_PAL_M)
2887
n0 = mvsetup.n0[nMode];
2889
/*PAL-M sets up like NTSC except for n0. */
2890
if ((trigger_bits & 0x03) == 0)
2891
n0 = mvsetup.n0[nPAL_APS00];
2893
n0 = mvsetup.n0[nPAL_APSXX];
2896
/*download settings now. */
2897
houston_WriteReg(MV_N0, n0, 1);
2898
houston_WriteReg(MV_N1, mvsetup.n1[nMode], 1);
2899
houston_WriteReg(MV_N2, mvsetup.n2[nMode], 1);
2900
houston_WriteReg(MV_N3, mvsetup.n3[nMode], 1);
2901
houston_WriteReg(MV_N4, mvsetup.n4[nMode], 1);
2902
houston_WriteReg(MV_N5, mvsetup.n5[nMode], 1);
2903
houston_WriteReg(MV_N6, mvsetup.n6[nMode], 1);
2904
houston_WriteReg(MV_N7, mvsetup.n7[nMode], 1);
2905
houston_WriteReg(MV_N8, mvsetup.n8[nMode], 1);
2906
houston_WriteReg(MV_N9, mvsetup.n9[nMode], 1);
2907
houston_WriteReg(MV_N10, mvsetup.n10[nMode], 1);
2908
houston_WriteReg(MV_N11, mvsetup.n11[nMode] & 0xff, 1);
2909
houston_WriteReg(MV_N11 + 1, mvsetup.n11[nMode] >> 8, 1);
2910
houston_WriteReg(MV_N12, mvsetup.n12[nMode] & 0xff, 1);
2911
houston_WriteReg(MV_N12 + 1, mvsetup.n12[nMode] >> 8, 1);
2912
houston_WriteReg(MV_N13, mvsetup.n13[nMode], 1);
2913
houston_WriteReg(MV_N14, mvsetup.n14[nMode], 1);
2914
houston_WriteReg(MV_N15, mvsetup.n15[nMode], 1);
2915
houston_WriteReg(MV_N16, mvsetup.n16[nMode], 1);
2916
houston_WriteReg(MV_N17, mvsetup.n17[nMode], 1);
2917
houston_WriteReg(MV_N18, mvsetup.n18[nMode], 1);
2918
houston_WriteReg(MV_N19, mvsetup.n19[nMode], 1);
2919
houston_WriteReg(MV_N20, mvsetup.n20[nMode], 1);
2920
houston_WriteReg(MV_N21, mvsetup.n21[nMode] & 0xff, 1);
2921
houston_WriteReg(MV_N21 + 1, mvsetup.n21[nMode] >> 8, 1);
2922
houston_WriteReg(MV_N22, mvsetup.n22[nMode], 1);
2923
houston_WriteReg(MV_AGC_PULSE_LEVEL, mvsetup.agc_pulse_level[nMode], 1);
2924
houston_WriteReg(MV_BP_PULSE_LEVEL, mvsetup.bp_pulse_level[nMode], 1);
2926
houston_ReadReg(HOUSTON_MISC, &misc, 2);
2927
if (trigger_bits == 0)
2928
misc &= ~MISC_MV_SOFT_EN;
2930
misc |= MISC_MV_SOFT_EN;
2931
houston_WriteReg(HOUSTON_MISC, misc, 2);
2935
conget_macrovision(unsigned long tv_std, unsigned int *p_cp_trigger_bits)
2937
unsigned long n0, n1;
2939
if (!p_cp_trigger_bits)
2942
houston_ReadReg(MV_N0, &n0, 1);
2943
houston_ReadReg(MV_N1, &n1, 1);
2945
*p_cp_trigger_bits = 0;
2947
if (IS_NTSC(tv_std)) {
2950
*p_cp_trigger_bits = 0;
2954
*p_cp_trigger_bits = 1;
2960
*p_cp_trigger_bits = 2;
2962
*p_cp_trigger_bits = 3;
2967
else if (IS_PAL(tv_std)) {
2969
*p_cp_trigger_bits = 0;
2971
/*don't know here what the non-zero trigger bits were */
2972
*p_cp_trigger_bits = 1;
2977
/* PLAL_MediaGX.cpp */
2978
/*==========================================================================*/
2979
/* These functions provides implementation of platform-specific functions */
2980
/* MediaGX platform. */
2981
/*==========================================================================*/
2983
/*MediaGX control registers.*/
2987
/*Media GX general config register.*/
2988
#define GX_DCLK_MUL 0x00c0
2989
#define GX_DCLKx1 0x0040
2990
#define GX_DCLKx2 0x0080
2991
#define GX_DCLKx4 0x00c0
2993
/*Media GX timing config register.*/
2994
#define GX_TGEN 0x0020
2996
/*Cx5530 register offsets (from GX_BASE).*/
2997
#define CX_DISPLAY_CONFIG 0x10004
2998
#define CX_DOT_CLK 0x10024
2999
#define CX_TV_CONFIG 0x10028
3001
/*Cx5530 display configuration register.*/
3002
#define CX_FPVSYNC_POL 0x0800
3003
#define CX_FPHSYNC_POL 0x0400
3004
#define CX_FPDATA_ENB 0x0080
3005
#define CX_FPPOWER_ENB 0x0040
3006
#define CX_CRTVSYNC_POL 0x0200
3007
#define CX_CRTHSYNC_POL 0x0100
3009
/*Cx5530 dot clock configuration register.*/
3010
#define CX_TVCLK_SELECT 0x0400
3012
/*Cx5530 tv configuration register*/
3013
#define CX_INVERT_FPCLK (1 << 6)
3015
/*==========================================================================
3017
* There are two possible 7-bit addresses, 0x4A and 0x6A.
3018
* The address if selectable via pins on the FS450.
3019
* There are also two possible 10-bit addresses, 0x224 and 0x276, but this
3020
* source is not designed to use them.
3021
*==========================================================================*/
3023
#define FS450_I2C_ADDRESS (0x4A)
3025
static unsigned char
3026
PLAL_FS450_i2c_address(void)
3028
return FS450_I2C_ADDRESS;
3031
/*==========================================================================
3033
* This mode is programmed in the FS450 command register when enabling TV
3035
*==========================================================================
3038
PLAL_FS450_UIM_mode(void)
3043
/*==========================================================================*/
3044
/* Read and Write MediaGX registers */
3045
/*==========================================================================*/
3046
static unsigned long
3047
ReadGx(unsigned long inRegAddr)
3051
DMAL_ReadUInt32(inRegAddr, &data);
3057
WriteGx(unsigned long inRegAddr, unsigned long inData)
3059
int is_timing_register;
3060
unsigned long reg_timing_cfg;
3062
/*because the unlock register for the MediaGx video registers may not */
3063
/*persist, we will write the unlock code before every write. */
3064
DMAL_WriteUInt32(DC_UNLOCK, 0x4758);
3066
/*see if register is a timing register */
3067
is_timing_register =
3068
(DC_H_TIMING_1 == inRegAddr) ||
3069
(DC_H_TIMING_2 == inRegAddr) ||
3070
(DC_H_TIMING_3 == inRegAddr) ||
3071
(DC_FP_H_TIMING == inRegAddr) ||
3072
(DC_V_TIMING_1 == inRegAddr) ||
3073
(DC_V_TIMING_2 == inRegAddr) ||
3074
(DC_V_TIMING_3 == inRegAddr) || (DC_FP_V_TIMING == inRegAddr);
3076
/*if the register is a timing register, clear the TGEN bit to allow
3078
if (is_timing_register) {
3079
DMAL_ReadUInt32(DC_TIMING_CFG, ®_timing_cfg);
3080
DMAL_WriteUInt32(DC_TIMING_CFG, reg_timing_cfg & ~GX_TGEN);
3083
/*write the requested register */
3084
DMAL_WriteUInt32(inRegAddr, inData);
3086
/*reset the TGEN bit to previous state */
3087
if (is_timing_register) {
3088
DMAL_WriteUInt32(DC_TIMING_CFG, reg_timing_cfg);
3092
#ifdef FS450_DIRECTREG
3094
/*==========================================================================*/
3095
/* Platform-specific processing for a Read or Write Register calls. */
3096
/* The functions should return true if the specified register belongs to */
3097
/* this platform. */
3098
/*==========================================================================*/
3101
PLAL_ReadRegister(S_REG_INFO * p_reg)
3106
if (SOURCE_GCC == p_reg->source) {
3107
p_reg->value = ReadGx(p_reg->offset);
3116
PLAL_WriteRegister(const S_REG_INFO * p_reg)
3121
if (SOURCE_GCC == p_reg->source) {
3122
WriteGx(p_reg->offset, p_reg->value);
3132
/*==========================================================================
3133
* Determine if TV is on
3134
*==========================================================================*/
3140
/*check Cx5530 dot clock */
3141
reg = ReadGx(CX_DOT_CLK);
3142
return (reg & CX_TVCLK_SELECT) ? 1 : 0;
3145
/*==========================================================================
3146
* Platform-specific actions to reset to VGA mode
3147
*==========================================================================*/
3150
PLAL_EnableVga(void)
3155
reg = ReadGx(DC_GENERAL_CFG);
3156
reg &= ~GX_DCLK_MUL;
3158
WriteGx(DC_GENERAL_CFG, reg);
3160
/*select pll dot clock. */
3161
reg = ReadGx(CX_DOT_CLK);
3162
reg &= ~CX_TVCLK_SELECT;
3163
WriteGx(CX_DOT_CLK, reg);
3165
/*timing config, reset everything on dclk. */
3166
reg = ReadGx(DC_TIMING_CFG);
3168
WriteGx(DC_TIMING_CFG, reg);
3170
WriteGx(DC_TIMING_CFG, reg);
3172
/*un-invert FP clock */
3173
reg = ReadGx(CX_TV_CONFIG);
3174
reg &= ~CX_INVERT_FPCLK;
3175
WriteGx(CX_TV_CONFIG, reg);
3180
/*==========================================================================*/
3181
/*Platform-specific actions to enter TVout mode */
3182
/*==========================================================================*/
3185
PLAL_PrepForTVout(void)
3189
/*Cx5530 tv config. */
3191
WriteGx(CX_TV_CONFIG, reg);
3193
/*invert FP clock */
3194
reg = (int) ReadGx(CX_TV_CONFIG);
3195
reg |= CX_INVERT_FPCLK;
3196
WriteGx(CX_TV_CONFIG, reg);
3202
PLAL_SetTVTimingRegisters(const S_TIMING_SPECS * p_specs)
3206
/*timing config, reset everything on dclk. */
3207
reg = ReadGx(DC_TIMING_CFG);
3209
WriteGx(DC_TIMING_CFG, reg);
3211
/*htotal and hactive. */
3212
reg = ((p_specs->h_total - 1) << 16) | (p_specs->vga_width - 1);
3213
WriteGx(DC_H_TIMING_1, reg);
3216
reg = ((p_specs->h_total - 1) << 16) | (p_specs->vga_width - 1);
3217
WriteGx(DC_H_TIMING_2, reg);
3220
reg = ((p_specs->h_sync + 63) << 16) | p_specs->h_sync;
3221
WriteGx(DC_H_TIMING_3, reg);
3224
WriteGx(DC_FP_H_TIMING, reg);
3226
/*vtotal and vactive. */
3227
reg = ((p_specs->v_total - 1) << 16) | (p_specs->vga_lines - 1);
3228
WriteGx(DC_V_TIMING_1, reg);
3231
reg = ((p_specs->v_total - 1) << 16) | (p_specs->vga_lines - 1);
3232
WriteGx(DC_V_TIMING_2, reg);
3235
reg = ((p_specs->v_sync) << 16) | (p_specs->v_sync - 1);
3236
WriteGx(DC_V_TIMING_3, reg);
3239
reg = ((p_specs->v_sync - 1) << 16) | (p_specs->v_sync - 2);
3240
WriteGx(DC_FP_V_TIMING, reg);
3242
/*timing config, reenable all dclk stuff. */
3243
reg = ReadGx(DC_TIMING_CFG);
3245
WriteGx(DC_TIMING_CFG, reg);
3251
PLAL_FinalEnableTVout(unsigned long vga_mode)
3255
/*Cx5530 select tv dot clock. */
3256
reg = (int) ReadGx(CX_DOT_CLK);
3257
reg |= CX_TVCLK_SELECT;
3258
WriteGx(CX_DOT_CLK, reg);
3260
/*2 x dclk (actually 1x) */
3261
reg = (int) ReadGx(DC_GENERAL_CFG);
3262
reg &= ~GX_DCLK_MUL;
3263
WriteGx(DC_GENERAL_CFG, reg);
3266
WriteGx(DC_GENERAL_CFG, reg);
3268
/*Cx5530 display configuration register. */
3269
reg = (int) ReadGx(CX_DISPLAY_CONFIG);
3270
reg |= (CX_FPVSYNC_POL | CX_FPHSYNC_POL | CX_FPDATA_ENB | CX_FPPOWER_ENB);
3271
WriteGx(CX_DISPLAY_CONFIG, reg);