~ubuntu-branches/ubuntu/trusty/xserver-xorg-video-geode-lts-utopic/trusty-proposed

« back to all changes in this revision

Viewing changes to src/gfx/tv_fs450.c

  • Committer: Package Import Robot
  • Author(s): Maarten Lankhorst
  • Date: 2015-01-06 10:39:17 UTC
  • Revision ID: package-import@ubuntu.com-20150106103917-bumwel1243pseqs6
Tags: upstream-2.11.16
ImportĀ upstreamĀ versionĀ 2.11.16

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (c) 2005 Advanced Micro Devices, Inc.
 
2
 *
 
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:
 
9
 *
 
10
 * The above copyright notice and this permission notice shall be included in
 
11
 * all copies or substantial portions of the Software.
 
12
 *
 
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
 
19
 * IN THE SOFTWARE.
 
20
 *
 
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.
 
24
 * */
 
25
 
 
26
#define FS450_DIRECTREG 0
 
27
 
 
28
#include "tv_fs450.h"
 
29
 
 
30
/*==========================================================================
 
31
 *      Macros
 
32
 *==========================================================================
 
33
 */
 
34
#undef          fsmax
 
35
#undef          fsmin
 
36
#define         fsmax(a, b)             ((a) > (b) ? (a) : (b))
 
37
#define         fsmin(a, b)             ((a) < (b) ? (a) : (b))
 
38
 
 
39
#undef range_limit
 
40
#define range_limit(val,min_val,max_val) (fsmax((min_val),fsmin((val),(max_val))))
 
41
 
 
42
/*==========================================================================
 
43
 *      Registers
 
44
 *==========================================================================
 
45
 */
 
46
 
 
47
#define MAX_REGISTERS   32
 
48
#define MAX_BITS                32
 
49
 
 
50
#define READ    1
 
51
#define WRITE   2
 
52
#define READ_WRITE (READ | WRITE)
 
53
 
 
54
typedef struct {
 
55
    char *name;
 
56
    unsigned long offset;
 
57
    unsigned char bit_length;
 
58
    unsigned char valid_bits;
 
59
    unsigned char read_write;
 
60
    char *bitfield_names[MAX_BITS];
 
61
} S_REGISTER_DESCRIP;
 
62
 
 
63
typedef struct {
 
64
    int source;
 
65
    char *name;
 
66
    S_REGISTER_DESCRIP registers[MAX_REGISTERS];
 
67
} S_SET_DESCRIP;
 
68
 
 
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);
 
73
 
 
74
/*==========================================================================
 
75
 *      Houston Register Addresses & Bit Definitions
 
76
 *==========================================================================
 
77
 */
 
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
 *==========================================================================
 
179
 */
 
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
 *==========================================================================
 
210
 */
 
211
#define         MV_N0                   0x59
 
212
#define         MV_N1                   0x52
 
213
#define         MV_N2                   0x7b
 
214
#define         MV_N3                   0x53
 
215
#define         MV_N4                   0x79
 
216
#define         MV_N5                   0x5d
 
217
#define         MV_N6                   0x7a
 
218
#define         MV_N7                   0x64
 
219
#define         MV_N8                   0x54
 
220
#define         MV_N9                   0x55
 
221
#define         MV_N10                  0x56
 
222
#define         MV_N11                  0x6d
 
223
#define         MV_N12                  0x6f
 
224
#define         MV_N13                  0x5a
 
225
#define         MV_N14                  0x5b
 
226
#define         MV_N15                  0x5c
 
227
#define         MV_N16                  0x63
 
228
#define         MV_N17                  0x66
 
229
#define         MV_N18                  0x68
 
230
#define         MV_N19                  0x67
 
231
#define         MV_N20                  0x61
 
232
#define         MV_N21                  0x6a
 
233
#define         MV_N22                  0x76
 
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:
 
242
 *
 
243
 *      TRACE(("Number is %d, Name is %s.\n",iNumber,lpszName))
 
244
 *==========================================================================
 
245
 */
 
246
#define TRACE(parameters) {}
 
247
/*              GCC timing structure            */
 
248
typedef struct _S_TIMING_SPECS {
 
249
    int vga_width;
 
250
    int vga_lines;
 
251
    int tv_width;
 
252
    int tv_lines;
 
253
    int h_total;
 
254
    int h_sync;
 
255
    int v_total;
 
256
    int v_sync;
 
257
} S_TIMING_SPECS;
 
258
 
 
259
/*              Revision of Houston chip        */
 
260
#define HOUSTON_REV_A 0
 
261
#define HOUSTON_REV_B 1
 
262
static int houston_Rev(void);
 
263
 
 
264
/*==========================================================================
 
265
 *      Functions
 
266
 *==========================================================================
 
267
 */
 
268
static int houston_init(void);
 
269
 
 
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);
 
279
 
 
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
 
283
 * frame buffer).                                       */
 
284
static int
 
285
DMAL_ReadUInt32(unsigned long phys_addr, unsigned long *p_data)
 
286
{
 
287
    *p_data = READ_REG32(phys_addr);
 
288
    return 0;
 
289
}
 
290
 
 
291
static int
 
292
DMAL_WriteUInt32(unsigned long phys_addr, unsigned long data)
 
293
{
 
294
    WRITE_REG32(phys_addr, data);
 
295
    return 0;
 
296
}
 
297
 
 
298
/* Houston register access functions.   */
 
299
static int
 
300
houston_ReadReg(unsigned int reg, unsigned long *p_value, unsigned int bytes)
 
301
{
 
302
    return gfx_i2c_read(1, PLAL_FS450_i2c_address(), (unsigned char) reg,
 
303
                        (unsigned char) bytes, (unsigned char *) p_value);
 
304
}
 
305
 
 
306
static int
 
307
houston_WriteReg(unsigned int reg, unsigned long value, unsigned int bytes)
 
308
{
 
309
    return gfx_i2c_write(1, PLAL_FS450_i2c_address(), (unsigned char) reg,
 
310
                         (unsigned char) bytes, (unsigned char *) &value);
 
311
}
 
312
 
 
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,
 
325
                               int pos_y);
 
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,
 
340
                             int chroma_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);
 
346
 
 
347
/* Device settings.                     */
 
348
typedef struct _S_DEVICE_SETTINGS {
 
349
    int tv_on;
 
350
    unsigned long vga_mode;
 
351
    unsigned long tv_std;
 
352
    unsigned long tvout_mode;
 
353
    int overscan_x;
 
354
    int overscan_y;
 
355
    int position_x;
 
356
    int position_y;
 
357
    int sharpness;
 
358
    int flicker;
 
359
    int color;
 
360
    int brightness;
 
361
    int contrast;
 
362
    unsigned char yc_filter;
 
363
    unsigned int aps_trigger_bits;
 
364
    int last_overscan_y;
 
365
} S_DEVICE_SETTINGS;
 
366
 
 
367
static S_DEVICE_SETTINGS d;
 
368
 
 
369
/*==========================================================================
 
370
 * TV Setup Parameters
 
371
 *==========================================================================
 
372
 * */
 
373
 
 
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];
 
404
} tvsetup = {
 
405
    /*     ntsc,    pal,                ntsc-eij,   pal-m,      pal-n */
 
406
    {
 
407
    0x1f7cf021, 0xcb8a092a, 0x1f7cf021, 0xe3efe621, 0xcb8a092a},
 
408
        /* chroma_freq                  */
 
409
    {
 
410
    0, 0, 0, 0, 0},
 
411
        /* chroma_phase                 */
 
412
    {
 
413
    2, 0, 2, 0, 0},
 
414
        /* cphase_rst                   */
 
415
    {
 
416
    54, 43, 54, 43, 43},
 
417
        /* color                                */
 
418
    {
 
419
    0, 31, 0, 29, 29},
 
420
        /* cr_burst_level               */
 
421
    {
 
422
    59, 44, 59, 41, 41},
 
423
        /* cb_burst_level               */
 
424
    {
 
425
    0, 1, 0, 0, 1},
 
426
        /* sys625_50                    */
 
427
    {
 
428
    0, 1, 0, 0, 0},
 
429
        /* vsync5                               */
 
430
    {
 
431
    0, 1, 0, 1, 1},
 
432
        /* pal_mode                     */
 
433
    {
 
434
    0x7a, 0x7a, 0x7a, 0x7a, 0x7a},
 
435
        /* hsync_width                  */
 
436
    {
 
437
    0x40, 0x3c, 0x40, 0x40, 0x3c},
 
438
        /* burst_width                  */
 
439
    {
 
440
    0x80, 0x9a, 0x80, 0x80, 0x9a},
 
441
        /* back_porch                   */
 
442
    {
 
443
    0x24, 0x1e, 0x24, 0x24, 0x1e},
 
444
        /* front_porch                  */
 
445
    {
 
446
    0x19, 0x1a, 0x19, 0x12, 0x1a},
 
447
        /* breeze_way                   */
 
448
    {
 
449
    0xb4, 0xb4, 0xb4, 0xb4, 0xb4},
 
450
        /* active_line                  */
 
451
    {
 
452
    240, 251, 240, 240, 240},
 
453
        /* blank_level                  */
 
454
    {
 
455
    240, 251, 240, 240, 240},
 
456
        /* vbi_blank_level              */
 
457
    {
 
458
    284, 252, 240, 252, 252},
 
459
        /* black_level                  */
 
460
    {
 
461
    823, 821, 823, 821, 821},
 
462
        /* white_level                  */
 
463
    {
 
464
    60, 48, 60, 48, 48},
 
465
        /* hamp_offset                  */
 
466
    {
 
467
    0x08, 0x08, 0x08, 0x08, 0x08},
 
468
        /* sync_level                   */
 
469
    {
 
470
    525, 625, 525, 525, 625},
 
471
        /* tv_lines                     */
 
472
    {
 
473
    858, 864, 858, 858, 864},
 
474
        /* tv_width                     */
 
475
    {
 
476
    487, 576, 487, 487, 576},
 
477
        /* tv_active_lines              */
 
478
    {
 
479
    800, 800, 800, 800, 800},
 
480
        /* tv_active_width              */
 
481
    {
 
482
    0x1a, 0x1d, 0x1a, 0x1d, 0x1d},
 
483
        /* notch filter enabled */
 
484
    {
 
485
    0x0000, 0x0100, 0x0000, 0x0000, 0x0100},
 
486
        /* houston cr pal               */
 
487
    {
 
488
    0x7e48, 0xf580, 0x7e48, 0x7e48, 0xf580},
 
489
        /* houston ncodl                */
 
490
    {
 
491
    0x001b, 0x0020, 0x001b, 0x001b, 0x0020}
 
492
    /* houston ncodh                */
 
493
};
 
494
 
 
495
/* MediaGX default underscan and centered position setups. */
 
496
#define SCANTABLE_ENTRIES       5
 
497
struct _scantable {
 
498
    unsigned long mode;
 
499
    unsigned short v_total[5];
 
500
    unsigned short v_sync[5];
 
501
    unsigned short iha[5];
 
502
    signed short iho[5];
 
503
    signed short hsc[5];
 
504
};
 
505
 
 
506
static struct _scantable scantable[SCANTABLE_ENTRIES] = {
 
507
    {
 
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          */
 
514
     },
 
515
    {
 
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          */
 
522
     },
 
523
    {
 
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          */
 
530
     },
 
531
    {
 
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          */
 
538
     },
 
539
    {
 
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          */
 
546
     },
 
547
};
 
548
 
 
549
/* Houston fifo configuration constants. */
 
550
struct _ffolat {
 
551
    int v_total;
 
552
    unsigned short ffolat;
 
553
};
 
554
 
 
555
struct _ffolativo {
 
556
    int v_total;
 
557
    unsigned short ivo;
 
558
    unsigned short ffolat;
 
559
};
 
560
 
 
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},
 
581
    {-1, 0}
 
582
};
 
583
 
 
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},
 
597
    {801, 0x60},
 
598
    {-1, 0}
 
599
};
 
600
 
 
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},
 
613
    {-1, 0}
 
614
};
 
615
 
 
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},
 
624
    {-1, 0}
 
625
};
 
626
 
 
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},
 
643
    {-1, 0}
 
644
};
 
645
 
 
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},
 
659
    {801, 0x60},
 
660
    {-1, 0}
 
661
};
 
662
 
 
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},
 
676
    {-1, 0}
 
677
};
 
678
 
 
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},
 
691
    {-1, 0}
 
692
};
 
693
 
 
694
/* h_total=1344, vga_lines=768 */
 
695
#define SIZE10X7NTSC            45
 
696
static struct _ffolativo ffo10x7ntsc[SIZE10X7NTSC] = {
 
697
    {783, 0x4d, 0x40},
 
698
    {789, 0x47, 0x14},
 
699
    {795, 0x47, 0x7f},
 
700
    {801, 0x47, 0x53},
 
701
    {807, 0x47, 0x11},
 
702
    {813, 0x47, 0x78},
 
703
    {819, 0x47, 0x54},
 
704
    {825, 0x47, 0x40},
 
705
    {831, 0x47, 0x0f},
 
706
    {837, 0x4d, 0x40},
 
707
    {843, 0x47, 0x5a},
 
708
    {849, 0x4d, 0x40},
 
709
    {855, 0x47, 0x4b},
 
710
    {861, 0x4d, 0x40},
 
711
    {867, 0x47, 0x4b},
 
712
    {873, 0x4d, 0x40},
 
713
    {879, 0x47, 0x07},
 
714
    {885, 0x48, 0x20},
 
715
    {891, 0x47, 0x82},
 
716
    {897, 0x47, 0x60},
 
717
    {903, 0x47, 0x7f},
 
718
    {909, 0x4d, 0x40},
 
719
    {915, 0x48, 0x40},
 
720
    {921, 0x4c, 0x40},
 
721
    {927, 0x49, 0x40},
 
722
    {933, 0x48, 0x40},
 
723
    {939, 0x4a, 0x40},
 
724
    {945, 0x46, 0x40},
 
725
    {951, 0x4a, 0x40},
 
726
    {957, 0x4a, 0x40},
 
727
    {963, 0x4b, 0x40},
 
728
    {969, 0x4b, 0x40},
 
729
    {975, 0x48, 0x40},
 
730
    {981, 0x47, 0x40},
 
731
    {987, 0x47, 0x40},
 
732
    {993, 0x47, 0x40},
 
733
    {999, 0x48, 0x40},
 
734
    {1005, 0x48, 0x40},
 
735
    {1011, 0x47, 0x40},
 
736
    {1017, 0x47, 0x40},
 
737
    {1023, 0x48, 0x40},
 
738
    {1029, 0x48, 0x40},
 
739
    {1035, 0x46, 0x40},
 
740
    {1041, 0x47, 0x40},
 
741
    {1047, 0x47, 0x40}
 
742
};
 
743
 
 
744
/* h_total=1344, vga_lines=768 */
 
745
#define SIZE10X7PAL             46
 
746
static struct _ffolativo ffo10x7pal[SIZE10X7PAL] = {
 
747
    {781, 0x49, 0x40},
 
748
    {787, 0x46, 0x40},
 
749
    {793, 0x48, 0x40},
 
750
    {799, 0x46, 0x40},
 
751
    {805, 0x49, 0x40},
 
752
    {811, 0x47, 0x40},
 
753
    {817, 0x46, 0x40},
 
754
    {823, 0x46, 0x56},
 
755
    {829, 0x46, 0x2d},
 
756
    {835, 0x46, 0x40},
 
757
    {841, 0x46, 0x2d},
 
758
    {847, 0x46, 0x3f},
 
759
    {853, 0x46, 0x10},
 
760
    {859, 0x46, 0x86},
 
761
    {865, 0x46, 0xc9},
 
762
    {871, 0x46, 0x83},
 
763
    {877, 0x46, 0xa8},
 
764
    {883, 0x46, 0x81},
 
765
    {889, 0x46, 0xa5},
 
766
    {895, 0x46, 0xa9},
 
767
    {901, 0x46, 0x81},
 
768
    {907, 0x46, 0xa4},
 
769
    {913, 0x46, 0xa5},
 
770
    {919, 0x46, 0x7f},
 
771
    {925, 0x46, 0xa2},
 
772
    {931, 0x46, 0x9d},
 
773
    {937, 0x46, 0xc1},
 
774
    {943, 0x46, 0x96},
 
775
    {949, 0x46, 0xb7},
 
776
    {955, 0x46, 0xb1},
 
777
    {961, 0x46, 0x8a},
 
778
    {967, 0x46, 0xa9},
 
779
    {973, 0x46, 0xa0},
 
780
    {979, 0x46, 0x40},
 
781
    {985, 0x46, 0x97},
 
782
    {991, 0x46, 0xb5},
 
783
    {997, 0x46, 0xaa},
 
784
    {1003, 0x46, 0x83},
 
785
    {1009, 0x46, 0x9f},
 
786
    {1015, 0x47, 0x40},
 
787
    {1021, 0x46, 0xad},
 
788
    {1027, 0x46, 0x87},
 
789
    {1033, 0x46, 0xa2},
 
790
    {1039, 0x47, 0x40},
 
791
    {1045, 0x46, 0xac},
 
792
    {1051, 0x46, 0x86}
 
793
};
 
794
 
 
795
/*==========================================================================*/
 
796
/*FS450 API Functions.                                                                                                          */
 
797
/*==========================================================================*/
 
798
 
 
799
/* Initialize device settings */
 
800
static void
 
801
initialize_houston_static_registers(void)
 
802
{
 
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);
 
813
}
 
814
 
 
815
int
 
816
FS450_init(void)
 
817
{
 
818
    int err;
 
819
 
 
820
    TRACE(("FS450_Init()\n"))
 
821
 
 
822
        err = houston_init();
 
823
    if (err)
 
824
        return err;
 
825
 
 
826
    initialize_houston_static_registers();
 
827
 
 
828
    d.tv_on = PLAL_IsTVOn()? 1 : 0;
 
829
 
 
830
    /* get the current tv standard */
 
831
    conget_tv_std(&d.tv_std);
 
832
 
 
833
    d.vga_mode = 0;
 
834
 
 
835
    /* default to VP_TVOUT_MODE_CVBS_YC */
 
836
    d.tvout_mode = GFX_TVOUT_MODE_CVBS_YC;
 
837
 
 
838
    /* default to 1000 out of 1000 */
 
839
    d.sharpness = 1000;
 
840
    config_sharpness(d.sharpness);
 
841
 
 
842
    /* default to 800 out of 1000 */
 
843
    d.flicker = 800;
 
844
    config_flicker(d.flicker);
 
845
 
 
846
    /* default to zeros */
 
847
    d.overscan_x = 0;
 
848
    d.overscan_y = 0;
 
849
    d.position_x = 0;
 
850
    d.position_y = 0;
 
851
 
 
852
    d.color = 50;
 
853
    /* d.color = tvsetup.color[k]; */
 
854
    config_color(d.color);
 
855
 
 
856
    /* default */
 
857
    d.brightness = 50;
 
858
    d.contrast = 60;
 
859
    config_brightness_contrast(d.tv_std, d.aps_trigger_bits, d.brightness,
 
860
                               d.contrast);
 
861
 
 
862
    /* get the current yc filtering */
 
863
    {
 
864
        int luma_filter, chroma_filter;
 
865
 
 
866
        conget_yc_filter(&luma_filter, &chroma_filter);
 
867
        d.yc_filter = 0;
 
868
        if (luma_filter)
 
869
            d.yc_filter |= GFX_LUMA_FILTER;
 
870
        if (chroma_filter)
 
871
            d.yc_filter |= GFX_CHROMA_FILTER;
 
872
    }
 
873
 
 
874
    d.aps_trigger_bits = 0;
 
875
    config_macrovision(d.tv_std, d.aps_trigger_bits);
 
876
 
 
877
    d.last_overscan_y = -10000;
 
878
 
 
879
    return 0;
 
880
}
 
881
 
 
882
void
 
883
FS450_cleanup(void)
 
884
{
 
885
}
 
886
 
 
887
/*==========================================================================*/
 
888
/* Required configuration calls to write new settings to the device                     */
 
889
/*==========================================================================*/
 
890
 
 
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
 
902
 
 
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 |                    \
 
916
                                                                        REQ_MACROVISION_BIT)
 
917
#define REQ_NCO                                 (REQ_NCO_BIT)
 
918
#define REQ_ENCODER                             (REQ_TV_STANDARD | REQ_COLOR |                           \
 
919
                                                                        REQ_BRIGHTNESS_CONTRAST | REQ_YC_FILTER)
 
920
 
 
921
static int
 
922
write_config(int req)
 
923
{
 
924
    unsigned long reg, reg_encoder_reset = 0;
 
925
    int reset;
 
926
 
 
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));
 
929
    if (reset) {
 
930
        /*put the encoder into reset while making changes */
 
931
        houston_ReadReg(ENC_RESET, &reg, 1);
 
932
        houston_WriteReg(ENC_RESET, reg | 0x01, 1);
 
933
        reg_encoder_reset = reg & 0x01;
 
934
    }
 
935
 
 
936
    if (REQ_TV_STANDARD_BIT & req)
 
937
        config_tv_std(d.tv_std, d.aps_trigger_bits);
 
938
 
 
939
    if (REQ_VGA_MODE_BIT & req)
 
940
        config_vga_mode(d.vga_mode);
 
941
 
 
942
    if (REQ_TVOUT_MODE_BIT & req)
 
943
        config_tvout_mode(d.tvout_mode);
 
944
 
 
945
    if (REQ_OVERSCAN_POSITION_BIT & req) {
 
946
        config_overscan_xy(d.tv_std,
 
947
                           d.vga_mode,
 
948
                           d.overscan_x, d.overscan_y, d.position_x,
 
949
                           d.position_y);
 
950
 
 
951
        /*h_timing and v_timing and syncs. */
 
952
        if (PLAL_IsTVOn())
 
953
            PLAL_SetTVTimingRegisters(p_specs());
 
954
    }
 
955
 
 
956
    if (REQ_NCO_BIT & req)
 
957
        config_nco(d.tv_std, d.vga_mode);
 
958
 
 
959
    if (REQ_SHARPNESS_BIT & req)
 
960
        config_sharpness(d.sharpness);
 
961
 
 
962
    if (REQ_FLICKER_BIT & req)
 
963
        config_flicker(d.flicker);
 
964
 
 
965
    if (REQ_COLOR_BIT & req)
 
966
        config_color(d.color);
 
967
 
 
968
    if (REQ_BRIGHTNESS_CONTRAST_BIT & req) {
 
969
        config_brightness_contrast(d.tv_std,
 
970
                                   d.aps_trigger_bits, d.brightness,
 
971
                                   d.contrast);
 
972
    }
 
973
 
 
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));
 
978
    }
 
979
 
 
980
    if (REQ_MACROVISION_BIT & req)
 
981
        config_macrovision(d.tv_std, d.aps_trigger_bits);
 
982
 
 
983
    /*if we decided to put the encoder into reset, put it back */
 
984
    if (reset) {
 
985
        houston_ReadReg(ENC_RESET, &reg, 1);
 
986
        houston_WriteReg(ENC_RESET, reg_encoder_reset | (reg & ~0x01), 1);
 
987
 
 
988
        d.last_overscan_y = d.overscan_y;
 
989
    }
 
990
    return 0;
 
991
}
 
992
 
 
993
/*==========================================================================*/
 
994
/* TV On                                                                                                                                        */
 
995
/*==========================================================================*/
 
996
 
 
997
#if GFX_TV_DYNAMIC
 
998
int
 
999
fs450_get_tv_enable(unsigned int *p_on)
 
1000
#else
 
1001
int
 
1002
gfx_get_tv_enable(unsigned int *p_on)
 
1003
#endif
 
1004
{
 
1005
    if (!p_on)
 
1006
        return ERR_INVALID_PARAMETER;
 
1007
 
 
1008
    *p_on = d.tv_on;
 
1009
 
 
1010
    return 0;
 
1011
}
 
1012
 
 
1013
/*//int FS450_set_tv_on(unsigned int on)*/
 
1014
#if GFX_TV_DYNAMIC
 
1015
int
 
1016
fs450_set_tv_enable(int on)
 
1017
#else
 
1018
int
 
1019
gfx_set_tv_enable(int on)
 
1020
#endif
 
1021
{
 
1022
    unsigned long reg;
 
1023
 
 
1024
    /*if not mode change, just return */
 
1025
    if ((d.tv_on && on) || (!d.tv_on && !on))
 
1026
        return 0;
 
1027
 
 
1028
    /*if turning off... */
 
1029
    if (!on) {
 
1030
        /*reenable vga. */
 
1031
        PLAL_EnableVga();
 
1032
 
 
1033
        /*power down houston */
 
1034
        config_power(0);
 
1035
 
 
1036
        d.tv_on = 0;
 
1037
 
 
1038
        return 0;
 
1039
    }
 
1040
 
 
1041
    /*turning on... */
 
1042
 
 
1043
    /*power up houston      */
 
1044
    config_power(1);
 
1045
 
 
1046
    /*assert encoder reset. */
 
1047
    houston_WriteReg(ENC_RESET, 0x01, 1);
 
1048
 
 
1049
    /*initial platform preparation */
 
1050
    PLAL_PrepForTVout();
 
1051
 
 
1052
    /*configure encoder and nco. */
 
1053
    write_config(REQ_VGA_MODE |
 
1054
                 REQ_TV_STANDARD |
 
1055
                 REQ_TVOUT_MODE |
 
1056
                 REQ_OVERSCAN_POSITION | REQ_YC_FILTER | REQ_MACROVISION);
 
1057
 
 
1058
    /*set LP_EN and UIM */
 
1059
    houston_ReadReg(HOUSTON_CR, &reg, 2);
 
1060
    reg |= CR_LP_EN;
 
1061
    reg &= ~(CR_UIM_MOD0 | CR_UIM_MOD1);
 
1062
    reg |= (PLAL_FS450_UIM_mode() << 14);
 
1063
    houston_WriteReg(HOUSTON_CR, reg, 2);
 
1064
 
 
1065
    /*set platform timing registers */
 
1066
    PLAL_SetTVTimingRegisters(p_specs());
 
1067
 
 
1068
    PLAL_FinalEnableTVout(d.vga_mode);
 
1069
 
 
1070
    /*sync bridge */
 
1071
    {
 
1072
        int retry_count = 0;
 
1073
 
 
1074
        /*sync 50 times */
 
1075
        while (retry_count++ < 50) {
 
1076
            /*sync bridge. */
 
1077
            houston_ReadReg(HOUSTON_MISC, &reg, 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);
 
1082
        }
 
1083
    }
 
1084
 
 
1085
    /*deassert encoder reset. */
 
1086
    houston_WriteReg(ENC_RESET, 0x00, 1);
 
1087
 
 
1088
    d.tv_on = 1;
 
1089
 
 
1090
    return 0;
 
1091
}
 
1092
 
 
1093
#if GFX_TV_DYNAMIC
 
1094
int
 
1095
fs450_set_tv_defaults(int format)
 
1096
#else
 
1097
int
 
1098
gfx_set_tv_defaults(int format)
 
1099
#endif
 
1100
{
 
1101
    return 0;
 
1102
}
 
1103
 
 
1104
/*==========================================================================*/
 
1105
/* TV standard                                                                                                                          */
 
1106
/*==========================================================================*/
 
1107
 
 
1108
#if GFX_TV_DYNAMIC
 
1109
int
 
1110
fs450_get_tv_standard(unsigned long *p_standard)
 
1111
#else
 
1112
int
 
1113
gfx_get_tv_standard(unsigned long *p_standard)
 
1114
#endif
 
1115
{
 
1116
    if (!p_standard)
 
1117
        return ERR_INVALID_PARAMETER;
 
1118
 
 
1119
    *p_standard = d.tv_std;
 
1120
 
 
1121
    return 0;
 
1122
}
 
1123
 
 
1124
#if GFX_TV_DYNAMIC
 
1125
int
 
1126
fs450_get_available_tv_standards(unsigned long *p_standards)
 
1127
#else
 
1128
int
 
1129
gfx_get_available_tv_standards(unsigned long *p_standards)
 
1130
#endif
 
1131
{
 
1132
    if (!p_standards)
 
1133
        return ERR_INVALID_PARAMETER;
 
1134
 
 
1135
    *p_standards = supported_standards();
 
1136
 
 
1137
    return 0;
 
1138
}
 
1139
 
 
1140
#if GFX_TV_DYNAMIC
 
1141
int
 
1142
fs450_set_tv_standard(unsigned long standard)
 
1143
#else
 
1144
int
 
1145
gfx_set_tv_standard(unsigned long standard)
 
1146
#endif
 
1147
{
 
1148
    /* verify supported standard. */
 
1149
    if (!(standard & supported_standards()))
 
1150
        return ERR_INVALID_PARAMETER;
 
1151
 
 
1152
    /* disallow if tv is on */
 
1153
    if (d.tv_on)
 
1154
        return ERR_CANNOT_CHANGE_WHILE_TV_ON;
 
1155
 
 
1156
    d.tv_std = standard;
 
1157
    /* d.color = tvsetup.color[k]; */
 
1158
 
 
1159
    return write_config(REQ_TV_STANDARD);
 
1160
}
 
1161
 
 
1162
/*==========================================================================*/
 
1163
/* vga mode as known by the driver                                                                                      */
 
1164
/*==========================================================================*/
 
1165
 
 
1166
#if GFX_TV_DYNAMIC
 
1167
int
 
1168
fs450_get_tv_vga_mode(unsigned long *p_vga_mode)
 
1169
#else
 
1170
int
 
1171
gfx_get_tv_vga_mode(unsigned long *p_vga_mode)
 
1172
#endif
 
1173
{
 
1174
    if (!p_vga_mode)
 
1175
        return ERR_INVALID_PARAMETER;
 
1176
 
 
1177
    *p_vga_mode = d.vga_mode;
 
1178
 
 
1179
    return 0;
 
1180
}
 
1181
 
 
1182
#if GFX_TV_DYNAMIC
 
1183
int
 
1184
fs450_get_available_tv_vga_modes(unsigned long *p_vga_modes)
 
1185
#else
 
1186
int
 
1187
gfx_get_available_tv_vga_modes(unsigned long *p_vga_modes)
 
1188
#endif
 
1189
{
 
1190
    if (!p_vga_modes)
 
1191
        return ERR_INVALID_PARAMETER;
 
1192
 
 
1193
    *p_vga_modes =
 
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;
 
1198
 
 
1199
    return 0;
 
1200
}
 
1201
 
 
1202
#if GFX_TV_DYNAMIC
 
1203
int
 
1204
fs450_set_tv_vga_mode(unsigned long vga_mode)
 
1205
#else
 
1206
int
 
1207
gfx_set_tv_vga_mode(unsigned long vga_mode)
 
1208
#endif
 
1209
{
 
1210
    /*reject if not a single valid VGA mode */
 
1211
    switch (vga_mode) {
 
1212
    default:
 
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:
 
1218
        break;
 
1219
    case GFX_VGA_MODE_1024X768:
 
1220
        if (houston_Rev() >= HOUSTON_REV_B)
 
1221
            break;
 
1222
        return ERR_INVALID_PARAMETER;
 
1223
    }
 
1224
 
 
1225
    /*if the mode has changed... */
 
1226
    if (vga_mode != d.vga_mode) {
 
1227
        d.vga_mode = vga_mode;
 
1228
 
 
1229
        return write_config(REQ_VGA_MODE);
 
1230
    }
 
1231
 
 
1232
    return 0;
 
1233
}
 
1234
 
 
1235
/*==========================================================================*/
 
1236
/* tvout mode                                                                                                                           */
 
1237
/*==========================================================================*/
 
1238
 
 
1239
#if GFX_TV_DYNAMIC
 
1240
int
 
1241
fs450_get_tvout_mode(unsigned long *p_tvout_mode)
 
1242
#else
 
1243
int
 
1244
gfx_get_tvout_mode(unsigned long *p_tvout_mode)
 
1245
#endif
 
1246
{
 
1247
    if (!p_tvout_mode)
 
1248
        return ERR_INVALID_PARAMETER;
 
1249
 
 
1250
    *p_tvout_mode = d.tvout_mode;
 
1251
 
 
1252
    return 0;
 
1253
}
 
1254
 
 
1255
#if GFX_TV_DYNAMIC
 
1256
int
 
1257
fs450_set_tvout_mode(unsigned long tvout_mode)
 
1258
#else
 
1259
int
 
1260
gfx_set_tvout_mode(unsigned long tvout_mode)
 
1261
#endif
 
1262
{
 
1263
    d.tvout_mode = tvout_mode;
 
1264
 
 
1265
    return write_config(REQ_TVOUT_MODE);
 
1266
}
 
1267
 
 
1268
/*==========================================================================*/
 
1269
/* Sharpness                                                                                                                            */
 
1270
/*==========================================================================*/
 
1271
 
 
1272
#if GFX_TV_DYNAMIC
 
1273
int
 
1274
fs450_get_sharpness(int *p_sharpness)
 
1275
#else
 
1276
int
 
1277
gfx_get_sharpness(int *p_sharpness)
 
1278
#endif
 
1279
{
 
1280
    if (!p_sharpness)
 
1281
        return ERR_INVALID_PARAMETER;
 
1282
 
 
1283
    *p_sharpness = d.sharpness;
 
1284
 
 
1285
    return 0;
 
1286
}
 
1287
 
 
1288
#if GFX_TV_DYNAMIC
 
1289
int
 
1290
fs450_set_sharpness(int sharpness)
 
1291
#else
 
1292
int
 
1293
gfx_set_sharpness(int sharpness)
 
1294
#endif
 
1295
{
 
1296
    d.sharpness = range_limit(sharpness, 0, 1000);
 
1297
 
 
1298
    return write_config(REQ_SHARPNESS);
 
1299
}
 
1300
 
 
1301
/*==========================================================================*/
 
1302
/* flicker filter control.                                                                                                      */
 
1303
/*==========================================================================*/
 
1304
 
 
1305
#if GFX_TV_DYNAMIC
 
1306
int
 
1307
fs450_get_flicker_filter(int *p_flicker)
 
1308
#else
 
1309
int
 
1310
gfx_get_flicker_filter(int *p_flicker)
 
1311
#endif
 
1312
{
 
1313
    if (!p_flicker)
 
1314
        return ERR_INVALID_PARAMETER;
 
1315
 
 
1316
    *p_flicker = d.flicker;
 
1317
 
 
1318
    return 0;
 
1319
}
 
1320
 
 
1321
#if GFX_TV_DYNAMIC
 
1322
int
 
1323
fs450_set_flicker_filter(int flicker)
 
1324
#else
 
1325
int
 
1326
gfx_set_flicker_filter(int flicker)
 
1327
#endif
 
1328
{
 
1329
    d.flicker = range_limit(flicker, 0, 1000);
 
1330
 
 
1331
    return write_config(REQ_FLICKER);
 
1332
}
 
1333
 
 
1334
/*==========================================================================*/
 
1335
/* Overscan and Position                                                                                                        */
 
1336
/*==========================================================================*/
 
1337
 
 
1338
#if GFX_TV_DYNAMIC
 
1339
int
 
1340
fs450_get_overscan(int *p_x, int *p_y)
 
1341
#else
 
1342
int
 
1343
gfx_get_overscan(int *p_x, int *p_y)
 
1344
#endif
 
1345
{
 
1346
    if (!p_x || !p_y)
 
1347
        return ERR_INVALID_PARAMETER;
 
1348
 
 
1349
    *p_x = d.overscan_x;
 
1350
    *p_y = d.overscan_y;
 
1351
 
 
1352
    return 0;
 
1353
}
 
1354
 
 
1355
#if GFX_TV_DYNAMIC
 
1356
int
 
1357
fs450_set_overscan(int x, int y)
 
1358
#else
 
1359
int
 
1360
gfx_set_overscan(int x, int y)
 
1361
#endif
 
1362
{
 
1363
    d.overscan_x = range_limit(x, -1000, 1000);
 
1364
    d.overscan_y = range_limit(y, -1000, 1000);
 
1365
 
 
1366
    return write_config(REQ_OVERSCAN_POSITION);
 
1367
}
 
1368
 
 
1369
#if GFX_TV_DYNAMIC
 
1370
int
 
1371
fs450_get_position(int *p_x, int *p_y)
 
1372
#else
 
1373
int
 
1374
gfx_get_position(int *p_x, int *p_y)
 
1375
#endif
 
1376
{
 
1377
    if (!p_x || !p_y)
 
1378
        return ERR_INVALID_PARAMETER;
 
1379
 
 
1380
    *p_x = d.position_x;
 
1381
    *p_y = d.position_y;
 
1382
 
 
1383
    return 0;
 
1384
}
 
1385
 
 
1386
#if GFX_TV_DYNAMIC
 
1387
int
 
1388
fs450_set_position(int x, int y)
 
1389
#else
 
1390
int
 
1391
gfx_set_position(int x, int y)
 
1392
#endif
 
1393
{
 
1394
    d.position_x = range_limit(x, -1000, 1000);
 
1395
    d.position_y = range_limit(y, -1000, 1000);
 
1396
 
 
1397
    return write_config(REQ_OVERSCAN_POSITION);
 
1398
}
 
1399
 
 
1400
/*==========================================================================*/
 
1401
/* Color, Brightness, and Contrast                                                                                      */
 
1402
/*==========================================================================*/
 
1403
 
 
1404
#if GFX_TV_DYNAMIC
 
1405
int
 
1406
fs450_get_color(int *p_color)
 
1407
#else
 
1408
int
 
1409
gfx_get_color(int *p_color)
 
1410
#endif
 
1411
{
 
1412
    if (!p_color)
 
1413
        return ERR_INVALID_PARAMETER;
 
1414
 
 
1415
    *p_color = d.color;
 
1416
 
 
1417
    return 0;
 
1418
}
 
1419
 
 
1420
#if GFX_TV_DYNAMIC
 
1421
int
 
1422
fs450_set_color(int color)
 
1423
#else
 
1424
int
 
1425
gfx_set_color(int color)
 
1426
#endif
 
1427
{
 
1428
    d.color = range_limit(color, 0, 100);
 
1429
 
 
1430
    return write_config(REQ_COLOR);
 
1431
}
 
1432
 
 
1433
#if GFX_TV_DYNAMIC
 
1434
int
 
1435
fs450_get_brightness(int *p_brightness)
 
1436
#else
 
1437
int
 
1438
gfx_get_brightness(int *p_brightness)
 
1439
#endif
 
1440
{
 
1441
    if (!p_brightness)
 
1442
        return ERR_INVALID_PARAMETER;
 
1443
 
 
1444
    *p_brightness = d.brightness;
 
1445
 
 
1446
    return 0;
 
1447
}
 
1448
 
 
1449
#if GFX_TV_DYNAMIC
 
1450
int
 
1451
fs450_set_brightness(int brightness)
 
1452
#else
 
1453
int
 
1454
gfx_set_brightness(int brightness)
 
1455
#endif
 
1456
{
 
1457
    d.brightness = range_limit(brightness, 0, 100);
 
1458
 
 
1459
    return write_config(REQ_BRIGHTNESS_CONTRAST);
 
1460
}
 
1461
 
 
1462
#if GFX_TV_DYNAMIC
 
1463
int
 
1464
fs450_get_contrast(int *p_contrast)
 
1465
#else
 
1466
int
 
1467
gfx_get_contrast(int *p_contrast)
 
1468
#endif
 
1469
{
 
1470
    if (!p_contrast)
 
1471
        return ERR_INVALID_PARAMETER;
 
1472
 
 
1473
    *p_contrast = d.contrast;
 
1474
 
 
1475
    return 0;
 
1476
}
 
1477
 
 
1478
#if GFX_TV_DYNAMIC
 
1479
int
 
1480
fs450_set_contrast(int constrast)
 
1481
#else
 
1482
int
 
1483
gfx_set_contrast(int constrast)
 
1484
#endif
 
1485
{
 
1486
    d.contrast = range_limit(constrast, 0, 100);
 
1487
 
 
1488
    return write_config(REQ_BRIGHTNESS_CONTRAST);
 
1489
}
 
1490
 
 
1491
/*==========================================================================*/
 
1492
/* YC filters                                                                                                                           */
 
1493
/*==========================================================================*/
 
1494
 
 
1495
#if GFX_TV_DYNAMIC
 
1496
int
 
1497
fs450_get_yc_filter(unsigned int *p_yc_filter)
 
1498
#else
 
1499
int
 
1500
gfx_get_yc_filter(unsigned int *p_yc_filter)
 
1501
#endif
 
1502
{
 
1503
    if (!p_yc_filter)
 
1504
        return ERR_INVALID_PARAMETER;
 
1505
 
 
1506
    if (houston_Rev() < HOUSTON_REV_B)
 
1507
        return ERR_NOT_SUPPORTED;
 
1508
 
 
1509
    *p_yc_filter = d.yc_filter;
 
1510
 
 
1511
    return 0;
 
1512
}
 
1513
 
 
1514
#if GFX_TV_DYNAMIC
 
1515
int
 
1516
fs450_set_yc_filter(unsigned int yc_filter)
 
1517
#else
 
1518
int
 
1519
gfx_set_yc_filter(unsigned int yc_filter)
 
1520
#endif
 
1521
{
 
1522
    if (houston_Rev() < HOUSTON_REV_B)
 
1523
        return ERR_NOT_SUPPORTED;
 
1524
 
 
1525
    /*luma filter. */
 
1526
    if (yc_filter & GFX_LUMA_FILTER)
 
1527
        d.yc_filter |= GFX_LUMA_FILTER;
 
1528
    else
 
1529
        d.yc_filter &= ~GFX_LUMA_FILTER;
 
1530
 
 
1531
    /*chroma filter. */
 
1532
    if (yc_filter & GFX_CHROMA_FILTER)
 
1533
        d.yc_filter |= GFX_CHROMA_FILTER;
 
1534
    else
 
1535
        d.yc_filter &= ~GFX_CHROMA_FILTER;
 
1536
 
 
1537
    return write_config(REQ_YC_FILTER);
 
1538
}
 
1539
 
 
1540
#if GFX_TV_DYNAMIC
 
1541
int
 
1542
fs450_get_aps_trigger_bits(unsigned int *p_trigger_bits)
 
1543
#else
 
1544
int
 
1545
gfx_get_aps_trigger_bits(unsigned int *p_trigger_bits)
 
1546
#endif
 
1547
{
 
1548
    if (!p_trigger_bits)
 
1549
        return ERR_INVALID_PARAMETER;
 
1550
 
 
1551
    *p_trigger_bits = d.aps_trigger_bits;
 
1552
 
 
1553
    return 0;
 
1554
}
 
1555
 
 
1556
#if GFX_TV_DYNAMIC
 
1557
int
 
1558
fs450_set_aps_trigger_bits(unsigned int trigger_bits)
 
1559
#else
 
1560
int
 
1561
gfx_set_aps_trigger_bits(unsigned int trigger_bits)
 
1562
#endif
 
1563
{
 
1564
    d.aps_trigger_bits = trigger_bits;
 
1565
 
 
1566
    return write_config(REQ_MACROVISION);
 
1567
}
 
1568
 
 
1569
/*----------------------------------------------------------------------------
 
1570
 * gfx_set_tv_format
 
1571
 *
 
1572
 * This routine sets the TV encoder registers to the specified format
 
1573
 * and resolution.
 
1574
 * Currently only NTSC 640x480 is supported.
 
1575
 *----------------------------------------------------------------------------
 
1576
 */
 
1577
#if GFX_TV_DYNAMIC
 
1578
int
 
1579
fs450_set_tv_format(TVStandardType format, GfxOnTVType resolution)
 
1580
#else
 
1581
int
 
1582
gfx_set_tv_format(TVStandardType format, GfxOnTVType resolution)
 
1583
#endif
 
1584
{
 
1585
    /* ### ADD ### IMPLEMENTATION */
 
1586
    return (0);
 
1587
}
 
1588
 
 
1589
/*----------------------------------------------------------------------------
 
1590
 * gfx_set_tv_output
 
1591
 *
 
1592
 * This routine sets the TV encoder registers to the specified output type.
 
1593
 * Supported output types are : S-VIDEO and Composite.
 
1594
 *----------------------------------------------------------------------------
 
1595
 */
 
1596
#if GFX_TV_DYNAMIC
 
1597
int
 
1598
fs450_set_tv_output(int output)
 
1599
#else
 
1600
int
 
1601
gfx_set_tv_output(int output)
 
1602
#endif
 
1603
{
 
1604
    /* ### ADD ### IMPLEMENTATION */
 
1605
    return (0);
 
1606
}
 
1607
 
 
1608
/*----------------------------------------------------------------------------
 
1609
 * gfx_set_tv_cc_enable
 
1610
 *
 
1611
 * This routine enables or disables the use of the hardware CC registers 
 
1612
 * in the TV encoder.
 
1613
 *----------------------------------------------------------------------------
 
1614
 */
 
1615
#if GFX_TV_DYNAMIC
 
1616
int
 
1617
fs450_set_tv_cc_enable(int enable)
 
1618
#else
 
1619
int
 
1620
gfx_set_tv_cc_enable(int enable)
 
1621
#endif
 
1622
{
 
1623
    /* ### ADD ### IMPLEMENTATION */
 
1624
    return (0);
 
1625
}
 
1626
 
 
1627
/*----------------------------------------------------------------------------
 
1628
 * gfx_set_tv_cc_data
 
1629
 *
 
1630
 * This routine writes the two specified characters to the CC data register 
 
1631
 * of the TV encoder.
 
1632
 *----------------------------------------------------------------------------
 
1633
 */
 
1634
#if GFX_TV_DYNAMIC
 
1635
int
 
1636
fs450_set_tv_cc_data(unsigned char data1, unsigned char data2)
 
1637
#else
 
1638
int
 
1639
gfx_set_tv_cc_data(unsigned char data1, unsigned char data2)
 
1640
#endif
 
1641
{
 
1642
    /* ### ADD ### IMPLEMENTATION */
 
1643
    return (0);
 
1644
}
 
1645
 
 
1646
#ifdef FS450_DIRECTREG
 
1647
 
 
1648
/*==========================================================================*/
 
1649
/* Direct Read and Write registers                                                                                      */
 
1650
/*==========================================================================*/
 
1651
 
 
1652
int
 
1653
FS450_ReadRegister(S_REG_INFO * p_reg)
 
1654
{
 
1655
    unsigned long tmp;
 
1656
 
 
1657
    if (PLAL_ReadRegister(p_reg))
 
1658
        return 0;
 
1659
 
 
1660
    if (SOURCE_HOUSTON == p_reg->source) {
 
1661
        switch (p_reg->size) {
 
1662
        case 1:
 
1663
        case 2:
 
1664
        {
 
1665
            houston_ReadReg((int) p_reg->offset, &tmp, (int) p_reg->size);
 
1666
            p_reg->value = tmp;
 
1667
        }
 
1668
            return 0;
 
1669
 
 
1670
        case 4:
 
1671
        {
 
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;
 
1676
        }
 
1677
            return 0;
 
1678
        }
 
1679
    }
 
1680
 
 
1681
    return ERR_INVALID_PARAMETER;
 
1682
}
 
1683
 
 
1684
int
 
1685
FS450_WriteRegister(S_REG_INFO * p_reg)
 
1686
{
 
1687
    if (PLAL_WriteRegister(p_reg))
 
1688
        return 0;
 
1689
 
 
1690
    if (SOURCE_HOUSTON == p_reg->source) {
 
1691
        houston_WriteReg((unsigned int) p_reg->offset, p_reg->value,
 
1692
                         p_reg->size);
 
1693
 
 
1694
        return 0;
 
1695
    }
 
1696
 
 
1697
    return ERR_INVALID_PARAMETER;
 
1698
}
 
1699
 
 
1700
#endif
 
1701
 
 
1702
/* Houston initialization function. */
 
1703
static int g_houston_rev = -1;
 
1704
 
 
1705
static int
 
1706
houston_init(void)
 
1707
{
 
1708
    /*//int errc; */
 
1709
    unsigned long write, read;
 
1710
 
 
1711
    TRACE(("houston_init()\n"))
 
1712
 
 
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);
 
1717
 
 
1718
    /*simple w/r test. */
 
1719
    write = 0x0055;
 
1720
    read = 0;
 
1721
 
 
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;
 
1731
        }
 
1732
    }
 
1733
 
 
1734
    /*read chip revision. */
 
1735
    houston_ReadReg(HOUSTON_REV, &read, 2);
 
1736
    g_houston_rev = (int) read;
 
1737
 
 
1738
    /*ok. */
 
1739
    return 0;
 
1740
}
 
1741
 
 
1742
static int
 
1743
houston_Rev(void)
 
1744
{
 
1745
    return g_houston_rev;
 
1746
}
 
1747
 
 
1748
static S_TIMING_SPECS g_specs;
 
1749
 
 
1750
static const S_TIMING_SPECS *
 
1751
p_specs(void)
 
1752
{
 
1753
    return &g_specs;
 
1754
}
 
1755
 
 
1756
/*==========================================================================*/
 
1757
/* FS450 configuration functions.                                                                                       */
 
1758
/*==========================================================================*/
 
1759
static int
 
1760
config_init(void)
 
1761
{
 
1762
    int err;
 
1763
 
 
1764
    TRACE(("config_init()\n"))
 
1765
 
 
1766
        err = houston_init();
 
1767
    if (err)
 
1768
        return err;
 
1769
 
 
1770
    return 0;
 
1771
}
 
1772
 
 
1773
/*==========================================================================*/
 
1774
/* convert word to encoder 10 bit value.                                                                        */
 
1775
/*==========================================================================*/
 
1776
 
 
1777
static unsigned short
 
1778
w10bit2z(unsigned short w)
 
1779
{
 
1780
    return (w >> 2) | ((w & 0x03) << 8);
 
1781
}
 
1782
 
 
1783
static unsigned short
 
1784
z2w10bit(unsigned short z)
 
1785
{
 
1786
    return (0x03 & (z >> 8)) | ((0xFF & z) << 2);
 
1787
}
 
1788
 
 
1789
/*==========================================================================*/
 
1790
/* TV Standards                                                                                                                         */
 
1791
/*==========================================================================*/
 
1792
 
 
1793
static const struct {
 
1794
    unsigned long standard;
 
1795
    int tvsetup_index;
 
1796
} g_tv_standards[] = {
 
1797
    {
 
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},};
 
1807
 
 
1808
static int
 
1809
map_tvstd_to_index(unsigned long tv_std)
 
1810
{
 
1811
    unsigned int i;
 
1812
 
 
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;
 
1816
    }
 
1817
 
 
1818
    return -1;
 
1819
}
 
1820
 
 
1821
static unsigned long
 
1822
supported_standards(void)
 
1823
{
 
1824
    unsigned long standards = 0;
 
1825
    unsigned int i;
 
1826
 
 
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;
 
1830
    }
 
1831
 
 
1832
    return standards;
 
1833
}
 
1834
 
 
1835
/*==========================================================================*/
 
1836
 
 
1837
static void
 
1838
config_power(int on)
 
1839
{
 
1840
    unsigned long reg;
 
1841
 
 
1842
    if (houston_Rev() < HOUSTON_REV_B) {
 
1843
        /* no power down supported, but still turn of clock in off mode */
 
1844
        if (on) {
 
1845
            houston_ReadReg(HOUSTON_CR, &reg, 2);
 
1846
            reg &= ~(CR_CLKOFF | CR_RESET);
 
1847
            houston_WriteReg(HOUSTON_CR, reg, 2);
 
1848
            reg |= CR_RESET;
 
1849
            houston_WriteReg(HOUSTON_CR, reg, 2);
 
1850
            reg &= ~CR_RESET;
 
1851
            houston_WriteReg(HOUSTON_CR, reg, 2);
 
1852
        }
 
1853
        else {
 
1854
            houston_ReadReg(HOUSTON_CR, &reg, 2);
 
1855
            reg |= CR_CLKOFF;
 
1856
            houston_WriteReg(HOUSTON_CR, reg, 2);
 
1857
        }
 
1858
 
 
1859
        return;
 
1860
    }
 
1861
 
 
1862
    if (on) {
 
1863
        /* !CLKOFF, !COMPOFF, !YCOFF */
 
1864
        /* and reset Houston */
 
1865
        houston_ReadReg(HOUSTON_CR, &reg, 2);
 
1866
        reg &= ~(CR_CLKOFF | CR_RESET | CR_COMPOFF | CR_YCOFF);
 
1867
        houston_WriteReg(HOUSTON_CR, reg, 2);
 
1868
        reg |= CR_RESET;
 
1869
        houston_WriteReg(HOUSTON_CR, reg, 2);
 
1870
        reg &= ~CR_RESET;
 
1871
        houston_WriteReg(HOUSTON_CR, reg, 2);
 
1872
 
 
1873
        /* !GTLIO_PD */
 
1874
        houston_ReadReg(HOUSTON_MISC, &reg, 2);
 
1875
        reg &= ~MISC_GTLIO_PD;
 
1876
        houston_WriteReg(HOUSTON_MISC, reg, 2);
 
1877
    }
 
1878
    else {
 
1879
        /* CLKOFF, COMPOFF, YCOFF */
 
1880
        houston_ReadReg(HOUSTON_CR, &reg, 2);
 
1881
        reg |= (CR_CLKOFF | CR_COMPOFF | CR_YCOFF);
 
1882
        houston_WriteReg(HOUSTON_CR, reg, 2);
 
1883
 
 
1884
        /* GTLIO_PD */
 
1885
        houston_ReadReg(HOUSTON_MISC, &reg, 2);
 
1886
        reg |= MISC_GTLIO_PD;
 
1887
        houston_WriteReg(HOUSTON_MISC, reg, 2);
 
1888
    }
 
1889
}
 
1890
 
 
1891
/*==========================================================================*/
 
1892
/* VGA mode                                                                                                                                     */
 
1893
/*==========================================================================*/
 
1894
 
 
1895
static void
 
1896
config_vga_mode(unsigned long vga_mode)
 
1897
{
 
1898
    /*h_total must be evenly divisible by 32? */
 
1899
 
 
1900
    static struct {
 
1901
        unsigned long mode;
 
1902
        int width;
 
1903
        int lines;
 
1904
        int h_total;
 
1905
    } vgaparams[] = {
 
1906
        {
 
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},};
 
1912
 
 
1913
    unsigned long cr, misc, byp;
 
1914
    unsigned int i;
 
1915
 
 
1916
    g_specs.vga_width = 0;
 
1917
    g_specs.vga_lines = 0;
 
1918
    g_specs.h_total = 0;
 
1919
 
 
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;
 
1925
            break;
 
1926
        }
 
1927
    }
 
1928
    if (!g_specs.h_total)
 
1929
        return;
 
1930
 
 
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);
 
1935
 
 
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);
 
1940
    }
 
1941
    else {
 
1942
        /*VGA,SVGA */
 
1943
        cr &= ~CR_UIM_DEC;
 
1944
        misc &= ~MISC_VGACKDIV;
 
1945
        byp &= ~(BYP_HDS_BYPASS | BYP_CAC_BYPASS);
 
1946
    }
 
1947
 
 
1948
    houston_WriteReg(HOUSTON_CR, cr, 2);
 
1949
    houston_WriteReg(HOUSTON_MISC, misc, 2);
 
1950
    houston_WriteReg(HOUSTON_BYP, byp, 2);
 
1951
}
 
1952
 
 
1953
/*==========================================================================*/
 
1954
/* Write settings for TV standard to device                                                                     */
 
1955
/*==========================================================================*/
 
1956
 
 
1957
static void
 
1958
config_tv_std(unsigned long tv_std, unsigned int trigger_bits)
 
1959
{
 
1960
    int k;
 
1961
    unsigned short reg34;
 
1962
    unsigned long cr, w;
 
1963
    unsigned long l;
 
1964
 
 
1965
    /*verify supported standard. */
 
1966
    k = map_tvstd_to_index(tv_std);
 
1967
    if (k < 0)
 
1968
        return;
 
1969
 
 
1970
    /*store tv width and lines */
 
1971
    g_specs.tv_width = tvsetup.tv_width[k];
 
1972
    g_specs.tv_lines = tvsetup.tv_lines[k];
 
1973
 
 
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);
 
1979
 
 
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);
 
1986
 
 
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 */
 
1999
    else
 
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);
 
2007
 
 
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 */
 
2013
    reg34 =
 
2014
        0x80 |
 
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 */
 
2022
    else
 
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);
 
2026
}
 
2027
 
 
2028
static void
 
2029
conget_tv_std(unsigned long *p_tv_standard)
 
2030
{
 
2031
    unsigned long cr;
 
2032
 
 
2033
    if (!p_tv_standard)
 
2034
        return;
 
2035
 
 
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;
 
2040
    else
 
2041
        *p_tv_standard = GFX_TV_STANDARD_NTSC_M;
 
2042
}
 
2043
 
 
2044
/*==========================================================================*/
 
2045
/* TVout mode                                                                                                                           */
 
2046
/*==========================================================================*/
 
2047
 
 
2048
static void
 
2049
config_tvout_mode(unsigned long tvout_mode)
 
2050
{
 
2051
    unsigned long cr;
 
2052
 
 
2053
    houston_ReadReg(HOUSTON_CR, &cr, 2);
 
2054
 
 
2055
    /*all dacs off */
 
2056
    cr |= (CR_COMPOFF | CR_YCOFF);
 
2057
    /*not rgb */
 
2058
    cr &= ~CR_OFMT;
 
2059
 
 
2060
    /*turn on requested output */
 
2061
    if (GFX_TVOUT_MODE_CVBS & tvout_mode)
 
2062
        cr &= ~CR_COMPOFF;
 
2063
    if (GFX_TVOUT_MODE_YC & tvout_mode)
 
2064
        cr &= ~CR_YCOFF;
 
2065
    if (GFX_TVOUT_MODE_RGB & tvout_mode) {
 
2066
        cr &= ~(CR_COMPOFF | CR_YCOFF);
 
2067
        cr |= CR_OFMT;
 
2068
    }
 
2069
 
 
2070
    houston_WriteReg(HOUSTON_CR, cr, 2);
 
2071
}
 
2072
 
 
2073
static void
 
2074
conget_tvout_mode(unsigned long *p_tvout_mode)
 
2075
{
 
2076
    unsigned long cr;
 
2077
 
 
2078
    if (!p_tvout_mode)
 
2079
        return;
 
2080
 
 
2081
    houston_ReadReg(HOUSTON_CR, &cr, 2);
 
2082
 
 
2083
    if (CR_OFMT & cr)
 
2084
        *p_tvout_mode = GFX_TVOUT_MODE_RGB;
 
2085
    else {
 
2086
        *p_tvout_mode = 0;
 
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;
 
2091
    }
 
2092
}
 
2093
 
 
2094
/*==========================================================================*/
 
2095
/* Size & Position                                                                                                                      */
 
2096
/*==========================================================================*/
 
2097
 
 
2098
#define IS_NTSC(tv_std)                 \
 
2099
        (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)                  \
 
2104
        (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))
 
2111
 
 
2112
/*return fifo delay setting for mode, std, and total lines.*/
 
2113
 
 
2114
static void
 
2115
get_ffolat_ivo(unsigned long vga_mode,
 
2116
               unsigned long tv_std, long i, unsigned short *ffolat,
 
2117
               unsigned short *ivo)
 
2118
{
 
2119
    switch (vga_mode) {
 
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;
 
2125
            *ivo = 0x20;
 
2126
        }
 
2127
        else {
 
2128
            if (i > SIZE6X4PAL - 1)
 
2129
                i = SIZE6X4PAL - 1;
 
2130
            *ffolat = ffo6x4pal[i].ffolat;
 
2131
            *ivo = 0x28;
 
2132
        }
 
2133
        break;
 
2134
 
 
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;
 
2140
            *ivo = 0x3a;
 
2141
        }
 
2142
        else {
 
2143
            if (i > SIZE8X6PAL - 1)
 
2144
                i = SIZE8X6PAL - 1;
 
2145
            *ffolat = ffo8x6pal[i].ffolat;
 
2146
            *ivo = 0x39;
 
2147
        }
 
2148
        break;
 
2149
 
 
2150
    case GFX_VGA_MODE_720X487:
 
2151
        *ffolat = 0x40;         /*FFO7x4; */
 
2152
        *ivo = 0x1a;
 
2153
        break;
 
2154
 
 
2155
    case GFX_VGA_MODE_720X576:
 
2156
        *ffolat = 0x40;         /*FFO7x5; */
 
2157
        *ivo = 0x1a;
 
2158
        break;
 
2159
 
 
2160
    case GFX_VGA_MODE_1024X768:
 
2161
    default:
 
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;
 
2167
        }
 
2168
        else {
 
2169
            if (i > SIZE10X7PAL - 1)
 
2170
                i = SIZE10X7PAL - 1;
 
2171
            *ffolat = ffo10x7pal[i].ffolat;
 
2172
            *ivo = ffo10x7pal[i].ivo;
 
2173
        }
 
2174
        break;
 
2175
    }
 
2176
}
 
2177
 
 
2178
/*get vertical line min and max for mode and std.*/
 
2179
 
 
2180
static void
 
2181
get_vtotal_min_max(unsigned long vga_mode,
 
2182
                   unsigned long tv_std, int *v_total_min, int *v_total_max,
 
2183
                   int *v_step)
 
2184
{
 
2185
    int k = map_tvstd_to_index(tv_std);
 
2186
 
 
2187
    switch (vga_mode) {
 
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;
 
2192
        }
 
2193
        else {
 
2194
            *v_total_min = ffo6x4pal[0].v_total;
 
2195
            *v_total_max = ffo6x4pal[SIZE6X4PAL - 1].v_total;
 
2196
        }
 
2197
        *v_step = 4;
 
2198
        break;
 
2199
 
 
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;
 
2204
        }
 
2205
        else {
 
2206
            *v_total_min = ffo8x6pal[0].v_total;
 
2207
            *v_total_max = ffo8x6pal[SIZE8X6PAL - 1].v_total;
 
2208
        }
 
2209
        *v_step = 5;
 
2210
        break;
 
2211
 
 
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];
 
2216
        *v_step = 4;
 
2217
        break;
 
2218
 
 
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;
 
2223
        }
 
2224
        else {
 
2225
            *v_total_min = ffo10x7pal[0].v_total;
 
2226
            *v_total_max = ffo10x7pal[SIZE10X7PAL - 1].v_total;
 
2227
        }
 
2228
        *v_step = 6;
 
2229
        break;
 
2230
    }
 
2231
}
 
2232
 
 
2233
static void
 
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)
 
2237
{
 
2238
    unsigned int vga_index;
 
2239
    unsigned long reg;
 
2240
    double vsc;
 
2241
    int k;
 
2242
    unsigned short ffolat, ivo;
 
2243
    int base_v_total, range, v_offset;
 
2244
    int v_total_min, v_total_max, v_step;
 
2245
    float r, f;
 
2246
    int vga_pixels, pre_pixels;
 
2247
    float hscale, hscale_min, hscale_max;
 
2248
    int hsc;
 
2249
    int iho, iho_max, ihw;
 
2250
 
 
2251
    /*tv_std is valid. */
 
2252
    k = map_tvstd_to_index(tv_std);
 
2253
 
 
2254
    /*store tv width and lines */
 
2255
    g_specs.tv_width = tvsetup.tv_width[k];
 
2256
    g_specs.tv_lines = tvsetup.tv_lines[k];
 
2257
 
 
2258
    /*determine vga mode index */
 
2259
    for (vga_index = 0; vga_index < SCANTABLE_ENTRIES; vga_index++) {
 
2260
        if (scantable[vga_index].mode == vga_mode)
 
2261
            break;
 
2262
    }
 
2263
    if (vga_index >= SCANTABLE_ENTRIES)
 
2264
        return;
 
2265
 
 
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))
 
2273
 
 
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))
 
2277
 
 
2278
        /*range limit v_total. */
 
2279
        g_specs.v_total =
 
2280
        range_limit(base_v_total + v_offset, v_total_min, v_total_max);
 
2281
 
 
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))
 
2286
 
 
2287
        /*vertical positioning (vsync setup). */
 
2288
        get_ffolat_ivo(vga_mode, tv_std, v_offset, &ffolat, &ivo);
 
2289
    houston_WriteReg(HOUSTON_IVO, ivo, 2);
 
2290
 
 
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]);
 
2294
 
 
2295
    /*scale ivo. */
 
2296
    f = (float) ivo;
 
2297
    v_offset -= (int) (f - f / r);
 
2298
 
 
2299
    /*compensate for center screen. */
 
2300
    f = (float) tvsetup.tv_active_lines[k] / 2.f;
 
2301
    v_offset += (int) (f * r - f);
 
2302
 
 
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,
 
2306
           g_specs.v_sync))
 
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;
 
2311
    }
 
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;
 
2315
    }
 
2316
    TRACE(("v_total=%d v_sync=%d\n", g_specs.v_total, g_specs.v_sync))
 
2317
 
 
2318
        /* FFOLAT. */
 
2319
        houston_WriteReg(HOUSTON_FFO_LAT, ffolat, 2);
 
2320
 
 
2321
    /* VSC. */
 
2322
    vsc =
 
2323
        (65536.0f * (1.0f -
 
2324
                     (double) g_specs.tv_lines / (double) g_specs.v_total)) +
 
2325
        0.5f;
 
2326
    reg = ((unsigned long) -vsc) & 0xffff;
 
2327
    TRACE(("vsc=%04x, tv_lines=%d, v_total=%d\n", reg, g_specs.tv_lines,
 
2328
           g_specs.v_total))
 
2329
        houston_WriteReg(HOUSTON_VSC, (int) reg, 2);
 
2330
 
 
2331
    /* horizontal scaling. */
 
2332
 
 
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)
 
2336
        vga_pixels /= 2;
 
2337
 
 
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",
 
2344
           (int) hscale_min,
 
2345
           (int) ((hscale_min - (int) hscale_min) * 1000),
 
2346
           (int) hscale_max, (int) ((hscale_max - (int) hscale_max) * 1000)))
 
2347
 
 
2348
        /* map overscan_x into min to max. */
 
2349
        hscale =
 
2350
        hscale_min + ((overscan_x + 1000.0f) / 2000.0f) * (hscale_max -
 
2351
                                                           hscale_min);
 
2352
    TRACE(("hscale = %u.%u\n", (int) hscale,
 
2353
           (int) ((hscale - (int) hscale) * 1000)))
 
2354
 
 
2355
        /* determine hsc where hscale = (1 + hsc/128) */
 
2356
        if (hscale >= 1.0f)
 
2357
        hsc = (int) (128.f * (hscale - 1.0f) + .5f);
 
2358
    else
 
2359
        hsc = (int) (128.f * (hscale - 1.0f) - .5f);
 
2360
 
 
2361
    TRACE(("hsc = %d\n", hsc))
 
2362
        if (hsc >= 0)
 
2363
        houston_WriteReg(HOUSTON_HSC, hsc << 8, 2);
 
2364
    else
 
2365
        houston_WriteReg(HOUSTON_HSC, hsc & 0xFF, 2);
 
2366
 
 
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)))
 
2371
 
 
2372
        /* horizontal offset. */
 
2373
        /* place hsync 40 before halfway from vga_width to htotal */
 
2374
        /* but not less than vga_width + 10 */
 
2375
        g_specs.h_sync =
 
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))
 
2381
 
 
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 
 
2387
         * of pixels */
 
2388
        /* to skip, or subtract.  iho=0 maps to farthest right. */
 
2389
        /* map -pos_x = +/-1000 into (0 to iho_max) */
 
2390
        pre_pixels =
 
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))
 
2395
        iho =
 
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);
 
2400
 
 
2401
    /* input horizontal width. */
 
2402
 
 
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));
 
2408
    if (hsc < 0)
 
2409
        ihw = (int) fsmin(ihw, 253L * 128 / (-hsc));
 
2410
    ihw &= ~1;
 
2411
    TRACE(("ihw = %u\n", ihw))
 
2412
        houston_WriteReg(HOUSTON_IHA, ihw, 2);
 
2413
 
 
2414
    f = (((float) g_specs.h_total * g_specs.v_total) * 27.f) /
 
2415
        ((float) g_specs.tv_width * g_specs.tv_lines);
 
2416
 
 
2417
    TRACE(("freq=%u.%uMHz\n", (int) f, (int) ((f - (int) f) * 1000)))
 
2418
}
 
2419
 
 
2420
/*==========================================================================*/
 
2421
/* configure houston nco.                                                                                                       */
 
2422
/*==========================================================================*/
 
2423
 
 
2424
static void
 
2425
config_nco(unsigned long tv_std, unsigned long vga_mode)
 
2426
{
 
2427
    unsigned long cr, misc;
 
2428
    unsigned long reg;
 
2429
    int k = map_tvstd_to_index(tv_std);
 
2430
 
 
2431
    /*read and store CR. */
 
2432
    houston_ReadReg(HOUSTON_CR, &cr, 2);
 
2433
 
 
2434
    /*make sure NCO_EN (enable latch) bit is clear */
 
2435
    cr &= ~CR_NCO_EN;
 
2436
    houston_WriteReg(HOUSTON_CR, cr, 2);
 
2437
 
 
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);
 
2442
 
 
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);
 
2447
 
 
2448
        /*M and N. */
 
2449
        houston_WriteReg(HOUSTON_NCONL, 1024 - 2, 2);
 
2450
        houston_WriteReg(HOUSTON_NCODL, 128 - 1, 2);
 
2451
 
 
2452
        /*latch M/N in. */
 
2453
        cr |= CR_NCO_EN;
 
2454
        houston_WriteReg(HOUSTON_CR, cr, 2);
 
2455
        cr &= ~CR_NCO_EN;
 
2456
        houston_WriteReg(HOUSTON_CR, cr, 2);
 
2457
 
 
2458
        /*setup ncon and ncod load (Nco_load=0). */
 
2459
        misc &= ~(MISC_NCO_LOAD1 + MISC_NCO_LOAD0);
 
2460
        houston_WriteReg(HOUSTON_MISC, misc, 2);
 
2461
 
 
2462
        /*NCON. */
 
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);
 
2466
 
 
2467
        /*NCOD. */
 
2468
        houston_WriteReg(HOUSTON_NCODL, tvsetup.houston_ncodl[k], 2);
 
2469
        houston_WriteReg(HOUSTON_NCODH, tvsetup.houston_ncodh[k], 2);
 
2470
    }
 
2471
    else {
 
2472
        /*setup for M and N load (Nco_load=2). */
 
2473
        misc |= (MISC_NCO_LOAD1);
 
2474
        houston_WriteReg(HOUSTON_MISC, misc, 2);
 
2475
 
 
2476
        /*NCON. */
 
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);
 
2480
 
 
2481
        /*NCOD. */
 
2482
        houston_WriteReg(HOUSTON_NCODL, tvsetup.houston_ncodl[k], 2);
 
2483
        houston_WriteReg(HOUSTON_NCODH, tvsetup.houston_ncodh[k], 2);
 
2484
 
 
2485
        TRACE(("NCON = %lu (0x%08lx), NCOD = %lu (0x%08lx)\n",
 
2486
               reg,
 
2487
               reg,
 
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]))
 
2492
    }
 
2493
 
 
2494
    /*latch M/N and NCON/NCOD in. */
 
2495
    cr |= CR_NCO_EN;
 
2496
    houston_WriteReg(HOUSTON_CR, cr, 2);
 
2497
    cr &= ~CR_NCO_EN;
 
2498
    houston_WriteReg(HOUSTON_CR, cr, 2);
 
2499
}
 
2500
 
 
2501
/*==========================================================================*/
 
2502
/* Write sharpness settings to device                                                                           */
 
2503
/*==========================================================================*/
 
2504
 
 
2505
static void
 
2506
config_sharpness(int sharpness)
 
2507
{
 
2508
    unsigned int shp;
 
2509
 
 
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);
 
2513
 
 
2514
    houston_WriteReg(HOUSTON_SHP, shp, 2);
 
2515
}
 
2516
 
 
2517
static void
 
2518
conget_sharpness(int *p_sharpness)
 
2519
{
 
2520
    unsigned long shp;
 
2521
 
 
2522
    if (!p_sharpness)
 
2523
        return;
 
2524
 
 
2525
    houston_ReadReg(HOUSTON_SHP, &shp, 2);
 
2526
 
 
2527
    /*map 0-20 to 0-1000. */
 
2528
    *p_sharpness = (int) (0.5f + ((float) shp * 1000.0f / 20.0f));
 
2529
}
 
2530
 
 
2531
/*==========================================================================*/
 
2532
/* Write flicker settings to device                                                                                     */
 
2533
/*==========================================================================*/
 
2534
 
 
2535
static void
 
2536
config_flicker(int flicker)
 
2537
{
 
2538
    unsigned int flk;
 
2539
 
 
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);
 
2543
 
 
2544
    houston_WriteReg(HOUSTON_FLK, flk, 2);
 
2545
}
 
2546
 
 
2547
static void
 
2548
conget_flicker(int *p_flicker)
 
2549
{
 
2550
    unsigned long flk;
 
2551
 
 
2552
    if (!p_flicker)
 
2553
        return;
 
2554
 
 
2555
    houston_ReadReg(HOUSTON_FLK, &flk, 2);
 
2556
 
 
2557
    /*map 0-16 to 0-1000. */
 
2558
    *p_flicker = (int) (0.5f + ((float) flk * 1000.0f / 16.0f));
 
2559
}
 
2560
 
 
2561
/*==========================================================================*/
 
2562
/* Write color settings to device                                                                                       */
 
2563
/*==========================================================================*/
 
2564
 
 
2565
static void
 
2566
config_color(int color)
 
2567
{
 
2568
    unsigned long clr;
 
2569
 
 
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);
 
2575
 
 
2576
    houston_WriteReg(ENC_CR_GAIN, clr, 1);
 
2577
    houston_WriteReg(ENC_CB_GAIN, clr, 1);
 
2578
}
 
2579
 
 
2580
static void
 
2581
conget_color(int *p_color)
 
2582
{
 
2583
    unsigned long cr_gain;
 
2584
 
 
2585
    if (!p_color)
 
2586
        return;
 
2587
 
 
2588
    /*just get CR GAIN, CB GAIN should match. */
 
2589
    houston_ReadReg(ENC_CR_GAIN, &cr_gain, 1);
 
2590
 
 
2591
    /*map 0-255 to 0-100. */
 
2592
    *p_color = (int) (0.5f + ((float) cr_gain * 100.0f / 255.0f));
 
2593
}
 
2594
 
 
2595
/*==========================================================================*/
 
2596
/* Write brightness and contrast settings to device                                                     */
 
2597
/*==========================================================================*/
 
2598
 
 
2599
#define NTSC_BLANK_LEVEL        240
 
2600
 
 
2601
static const int min_black_level = NTSC_BLANK_LEVEL + 1;
 
2602
static const int max_white_level = 1023;
 
2603
 
 
2604
static void
 
2605
config_brightness_contrast(unsigned long tv_std, unsigned int trigger_bits,
 
2606
                           int brightness, int contrast)
 
2607
{
 
2608
    int brightness_off;
 
2609
    float contrast_mult;
 
2610
    int black, white;
 
2611
    unsigned short w;
 
2612
    int k = map_tvstd_to_index(tv_std);
 
2613
 
 
2614
    /*0-100 maps to +/-220. */
 
2615
    brightness_off =
 
2616
        (int) (0.5f + ((float) brightness * 440.0f / 100.0f)) - 220;
 
2617
 
 
2618
    /*0-100 maps to .75-1.25. */
 
2619
    contrast_mult = ((float) contrast * 0.5f / 100.0f) + 0.75f;
 
2620
 
 
2621
    black = tvsetup.black_level[k];
 
2622
    if (trigger_bits != 0)
 
2623
        black -= tvsetup.hamp_offset[k];
 
2624
 
 
2625
    white = tvsetup.white_level[k];
 
2626
    if (trigger_bits != 0)
 
2627
        white -= tvsetup.hamp_offset[k];
 
2628
 
 
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;
 
2635
 
 
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);
 
2642
}
 
2643
 
 
2644
static void
 
2645
conget_brightness_contrast(unsigned long tv_std, unsigned int trigger_bits,
 
2646
                           int *p_brightness, int *p_contrast)
 
2647
{
 
2648
    int brightness_off;
 
2649
    float contrast_mult;
 
2650
    unsigned short black, white;
 
2651
    unsigned long zh, zl;
 
2652
    int k;
 
2653
 
 
2654
    if (!p_brightness || !p_contrast)
 
2655
        return;
 
2656
 
 
2657
    k = map_tvstd_to_index(tv_std);
 
2658
 
 
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];
 
2669
 
 
2670
    /*this reverse computation does not account for clipping, but should */
 
2671
    /*provide somewhat reasonable numbers */
 
2672
    contrast_mult =
 
2673
        ((float) white - (float) black) / ((float) tvsetup.white_level[k] -
 
2674
                                           (float) tvsetup.black_level[k]);
 
2675
    brightness_off =
 
2676
        (int) (((float) black / contrast_mult) - tvsetup.black_level[k]);
 
2677
 
 
2678
    /*+/-220 maps to 0-100. */
 
2679
    *p_brightness =
 
2680
        range_limit((int) (0.5f + ((float) (brightness_off +
 
2681
                                            220) * 100.0f / 440.0f)), 0, 100);
 
2682
 
 
2683
    /*.75-1.25 maps to 0-100. */
 
2684
    *p_contrast =
 
2685
        range_limit((int) (0.5f + ((float) (contrast_mult -
 
2686
                                            0.75f) * 100.0f / 0.5f)), 0, 100);
 
2687
}
 
2688
 
 
2689
/*==========================================================================*/
 
2690
/* configure luma/chroma filters.                                                                                       */
 
2691
/*==========================================================================*/
 
2692
 
 
2693
static void
 
2694
config_yc_filter(unsigned long tv_std, int luma_filter, int chroma_filter)
 
2695
{
 
2696
    unsigned long reg, reg07, reg34;
 
2697
 
 
2698
    if (houston_Rev() < HOUSTON_REV_B)
 
2699
        return;
 
2700
 
 
2701
    /*luma filter. */
 
2702
    if (luma_filter)
 
2703
        reg = tvsetup.notch_filter[map_tvstd_to_index(tv_std)];
 
2704
    else
 
2705
        reg = 0;
 
2706
    houston_WriteReg(ENC_NOTCH_FILTER, reg, 1);
 
2707
 
 
2708
    /*chroma filter. */
 
2709
    houston_ReadReg(ENC_REG07, &reg07, 1);
 
2710
    houston_ReadReg(ENC_REG34, &reg34, 1);
 
2711
    if (chroma_filter) {
 
2712
        reg07 &= ~0x08;
 
2713
        reg34 &= ~0x20;
 
2714
    }
 
2715
    else {
 
2716
        reg07 |= 0x08;
 
2717
        reg34 |= 0x20;
 
2718
    }
 
2719
    houston_WriteReg(ENC_REG07, reg07, 1);
 
2720
    houston_WriteReg(ENC_REG34, reg34, 1);
 
2721
}
 
2722
 
 
2723
static void
 
2724
conget_yc_filter(int *p_luma_filter, int *p_chroma_filter)
 
2725
{
 
2726
    unsigned long reg, reg07, reg34;
 
2727
 
 
2728
    if (!p_luma_filter || !p_chroma_filter)
 
2729
        return;
 
2730
 
 
2731
    if (houston_Rev() < HOUSTON_REV_B) {
 
2732
        *p_luma_filter = 0;
 
2733
        *p_chroma_filter = 0;
 
2734
        return;
 
2735
    }
 
2736
 
 
2737
    /*luma filter. */
 
2738
    houston_ReadReg(ENC_NOTCH_FILTER, &reg, 1);
 
2739
    *p_luma_filter = (reg ? 1 : 0);
 
2740
 
 
2741
    /*chroma filter. */
 
2742
    houston_ReadReg(ENC_REG07, &reg07, 1);
 
2743
    houston_ReadReg(ENC_REG34, &reg34, 1);
 
2744
    *p_chroma_filter = !((0x08 & reg07) || (0x20 & reg34));
 
2745
}
 
2746
 
 
2747
/*==========================================================================*/
 
2748
/* Macrovision                                                                                                                          */
 
2749
/*==========================================================================*/
 
2750
 
 
2751
static void
 
2752
config_macrovision(unsigned long tv_std, unsigned int trigger_bits)
 
2753
{
 
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.                     */
 
2761
#define nMVModes                6
 
2762
 
 
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];
 
2790
    } mvsetup = {
 
2791
        /*    ntsc    ntsc    ntsc    ntsc    pal             pal */
 
2792
        /*    MV      AGC     AGC +   AGC +   MV              MV */
 
2793
        /*    off.    only    2-line  4-line  off.    on. */
 
2794
        /*    CS.             CS. */
 
2795
        {
 
2796
        0x00, 0x36, 0x3e, 0x3e, 0x00, 0x3e},    /*n0 */
 
2797
        {
 
2798
        0x1d, 0x1d, 0x1d, 0x17, 0x1a, 0x1a},    /*n1 */
 
2799
        {
 
2800
        0x11, 0x11, 0x11, 0x15, 0x22, 0x22},    /*n2 */
 
2801
        {
 
2802
        0x25, 0x25, 0x25, 0x21, 0x2a, 0x2a},    /*n3 */
 
2803
        {
 
2804
        0x11, 0x11, 0x11, 0x15, 0x22, 0x22},    /*n4 */
 
2805
        {
 
2806
        0x01, 0x01, 0x01, 0x05, 0x05, 0x05},    /*n5 */
 
2807
        {
 
2808
        0x07, 0x07, 0x07, 0x05, 0x02, 0x02},    /*n6 */
 
2809
        {
 
2810
        0x00, 0x00, 0x00, 0x02, 0x00, 0x00},    /*n7 */
 
2811
        {
 
2812
        0x1b, 0x1b, 0x1b, 0x1b, 0x1c, 0x1c},    /*n8 */
 
2813
        {
 
2814
        0x1b, 0x1b, 0x1b, 0x1b, 0x3d, 0x3d},    /*n9 */
 
2815
        {
 
2816
        0x24, 0x24, 0x24, 0x24, 0x14, 0x14},    /*n10 */
 
2817
        {
 
2818
        0x780f, 0x780f, 0x780f, 0x780f, 0x7e07, 0x7e07},        /*n11 */
 
2819
        {
 
2820
        0x0000, 0x0000, 0x0000, 0x0000, 0x5402, 0x5402},        /*n12 */
 
2821
        {
 
2822
        0x0f, 0x0f, 0x0f, 0x0f, 0xfe, 0xfe},    /*n13 */
 
2823
        {
 
2824
        0x0f, 0x0f, 0x0f, 0x0f, 0x7e, 0x7e},    /*n14 */
 
2825
        {
 
2826
        0x60, 0x60, 0x60, 0x60, 0x60, 0x60},    /*n15 */
 
2827
        {
 
2828
        0x01, 0x01, 0x01, 0x01, 0x00, 0x00},    /*n16 */
 
2829
        {
 
2830
        0x0a, 0x0a, 0x0a, 0x0a, 0x08, 0x08},    /*n17 */
 
2831
        {
 
2832
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00},    /*n18 */
 
2833
        {
 
2834
        0x05, 0x05, 0x05, 0x05, 0x04, 0x04},    /*n19 */
 
2835
        {
 
2836
        0x04, 0x04, 0x04, 0x04, 0x07, 0x07},    /*n20 */
 
2837
        {
 
2838
        0x03ff, 0x03ff, 0x03ff, 0x03ff, 0x0155, 0x0155},        /*n21 */
 
2839
        {
 
2840
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00},    /*n22 */
 
2841
        {
 
2842
        0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3},    /*agc_pulse_level */
 
2843
        {
 
2844
        0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8},    /*bp_pulse_level */
 
2845
    };
 
2846
 
 
2847
    int nMode;
 
2848
    unsigned long misc;
 
2849
    unsigned short n0;
 
2850
 
 
2851
    trigger_bits &= 0x3;
 
2852
 
 
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;
 
2859
        }
 
2860
        else if (trigger_bits == 1) {
 
2861
            /*AGC Only. */
 
2862
            nMode = nNTSC_APS01;
 
2863
        }
 
2864
        else if (trigger_bits == 2) {
 
2865
            /*AGC + 2-line CS. */
 
2866
            nMode = nNTSC_APS10;
 
2867
        }
 
2868
        else {
 
2869
            /*AGC + 4-line CS. */
 
2870
            nMode = nNTSC_APS11;
 
2871
        }
 
2872
    }
 
2873
    else {
 
2874
        /*PAL TV Standard. */
 
2875
        if (trigger_bits == 0) {
 
2876
            /*turn Macrovision OFF. */
 
2877
            nMode = nPAL_APS00;
 
2878
        }
 
2879
        else {
 
2880
            /*APS 01, 10, or 11. */
 
2881
            nMode = nPAL_APSXX;
 
2882
        }
 
2883
    }
 
2884
 
 
2885
    /*Retrieve the Macrovision Program Mode Data */
 
2886
    if (tv_std != GFX_TV_STANDARD_PAL_M)
 
2887
        n0 = mvsetup.n0[nMode];
 
2888
    else {
 
2889
        /*PAL-M sets up like NTSC except for n0. */
 
2890
        if ((trigger_bits & 0x03) == 0)
 
2891
            n0 = mvsetup.n0[nPAL_APS00];
 
2892
        else
 
2893
            n0 = mvsetup.n0[nPAL_APSXX];
 
2894
    }
 
2895
 
 
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);
 
2925
 
 
2926
    houston_ReadReg(HOUSTON_MISC, &misc, 2);
 
2927
    if (trigger_bits == 0)
 
2928
        misc &= ~MISC_MV_SOFT_EN;
 
2929
    else
 
2930
        misc |= MISC_MV_SOFT_EN;
 
2931
    houston_WriteReg(HOUSTON_MISC, misc, 2);
 
2932
}
 
2933
 
 
2934
static void
 
2935
conget_macrovision(unsigned long tv_std, unsigned int *p_cp_trigger_bits)
 
2936
{
 
2937
    unsigned long n0, n1;
 
2938
 
 
2939
    if (!p_cp_trigger_bits)
 
2940
        return;
 
2941
 
 
2942
    houston_ReadReg(MV_N0, &n0, 1);
 
2943
    houston_ReadReg(MV_N1, &n1, 1);
 
2944
 
 
2945
    *p_cp_trigger_bits = 0;
 
2946
 
 
2947
    if (IS_NTSC(tv_std)) {
 
2948
        switch (n0) {
 
2949
        case 0:
 
2950
            *p_cp_trigger_bits = 0;
 
2951
            break;
 
2952
 
 
2953
        case 0x36:
 
2954
            *p_cp_trigger_bits = 1;
 
2955
            break;
 
2956
 
 
2957
        case 0x3E:
 
2958
        {
 
2959
            if (0x1D == n1)
 
2960
                *p_cp_trigger_bits = 2;
 
2961
            else
 
2962
                *p_cp_trigger_bits = 3;
 
2963
        }
 
2964
            break;
 
2965
        }
 
2966
    }
 
2967
    else if (IS_PAL(tv_std)) {
 
2968
        if (0 == n0)
 
2969
            *p_cp_trigger_bits = 0;
 
2970
        else {
 
2971
            /*don't know here what the non-zero trigger bits were */
 
2972
            *p_cp_trigger_bits = 1;
 
2973
        }
 
2974
    }
 
2975
}
 
2976
 
 
2977
/* PLAL_MediaGX.cpp                                                                                                                     */
 
2978
/*==========================================================================*/
 
2979
/* These functions provides implementation of platform-specific functions       */
 
2980
/* MediaGX platform.                                                                                                            */
 
2981
/*==========================================================================*/
 
2982
 
 
2983
/*MediaGX control registers.*/
 
2984
#define CCR3    0xC3
 
2985
#define GCR             0xb8
 
2986
 
 
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
 
2992
 
 
2993
/*Media GX timing config register.*/
 
2994
#define GX_TGEN                         0x0020
 
2995
 
 
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
 
3000
 
 
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
 
3008
 
 
3009
/*Cx5530 dot clock configuration register.*/
 
3010
#define CX_TVCLK_SELECT         0x0400
 
3011
 
 
3012
/*Cx5530 tv configuration register*/
 
3013
#define CX_INVERT_FPCLK (1 << 6)
 
3014
 
 
3015
/*==========================================================================
 
3016
 *      FS450 I2C Address
 
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
 *==========================================================================*/
 
3022
 
 
3023
#define FS450_I2C_ADDRESS (0x4A)
 
3024
 
 
3025
static unsigned char
 
3026
PLAL_FS450_i2c_address(void)
 
3027
{
 
3028
    return FS450_I2C_ADDRESS;
 
3029
}
 
3030
 
 
3031
/*==========================================================================
 
3032
 *      FS450 UIM mode
 
3033
 *      This mode is programmed in the FS450 command register when enabling TV
 
3034
 *      out.
 
3035
 *==========================================================================
 
3036
 */
 
3037
static int
 
3038
PLAL_FS450_UIM_mode(void)
 
3039
{
 
3040
    return 3;
 
3041
}
 
3042
 
 
3043
/*==========================================================================*/
 
3044
/* Read and Write MediaGX registers                                                                                     */
 
3045
/*==========================================================================*/
 
3046
static unsigned long
 
3047
ReadGx(unsigned long inRegAddr)
 
3048
{
 
3049
    unsigned long data;
 
3050
 
 
3051
    DMAL_ReadUInt32(inRegAddr, &data);
 
3052
 
 
3053
    return data;
 
3054
}
 
3055
 
 
3056
static void
 
3057
WriteGx(unsigned long inRegAddr, unsigned long inData)
 
3058
{
 
3059
    int is_timing_register;
 
3060
    unsigned long reg_timing_cfg;
 
3061
 
 
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);
 
3065
 
 
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);
 
3075
 
 
3076
    /*if the register is a timing register, clear the TGEN bit to allow 
 
3077
     * modification */
 
3078
    if (is_timing_register) {
 
3079
        DMAL_ReadUInt32(DC_TIMING_CFG, &reg_timing_cfg);
 
3080
        DMAL_WriteUInt32(DC_TIMING_CFG, reg_timing_cfg & ~GX_TGEN);
 
3081
    }
 
3082
 
 
3083
    /*write the requested register */
 
3084
    DMAL_WriteUInt32(inRegAddr, inData);
 
3085
 
 
3086
    /*reset the TGEN bit to previous state */
 
3087
    if (is_timing_register) {
 
3088
        DMAL_WriteUInt32(DC_TIMING_CFG, reg_timing_cfg);
 
3089
    }
 
3090
}
 
3091
 
 
3092
#ifdef FS450_DIRECTREG
 
3093
 
 
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
/*==========================================================================*/
 
3099
 
 
3100
static int
 
3101
PLAL_ReadRegister(S_REG_INFO * p_reg)
 
3102
{
 
3103
    if (!p_reg)
 
3104
        return 0;
 
3105
 
 
3106
    if (SOURCE_GCC == p_reg->source) {
 
3107
        p_reg->value = ReadGx(p_reg->offset);
 
3108
 
 
3109
        return 1;
 
3110
    }
 
3111
 
 
3112
    return 0;
 
3113
}
 
3114
 
 
3115
static int
 
3116
PLAL_WriteRegister(const S_REG_INFO * p_reg)
 
3117
{
 
3118
    if (!p_reg)
 
3119
        return 0;
 
3120
 
 
3121
    if (SOURCE_GCC == p_reg->source) {
 
3122
        WriteGx(p_reg->offset, p_reg->value);
 
3123
 
 
3124
        return 1;
 
3125
    }
 
3126
 
 
3127
    return 0;
 
3128
}
 
3129
 
 
3130
#endif
 
3131
 
 
3132
/*==========================================================================
 
3133
 *      Determine if TV is on
 
3134
 *==========================================================================*/
 
3135
static int
 
3136
PLAL_IsTVOn(void)
 
3137
{
 
3138
    unsigned long reg;
 
3139
 
 
3140
    /*check Cx5530 dot clock */
 
3141
    reg = ReadGx(CX_DOT_CLK);
 
3142
    return (reg & CX_TVCLK_SELECT) ? 1 : 0;
 
3143
}
 
3144
 
 
3145
/*==========================================================================
 
3146
 * Platform-specific actions to reset to VGA mode
 
3147
 *==========================================================================*/
 
3148
 
 
3149
static int
 
3150
PLAL_EnableVga(void)
 
3151
{
 
3152
    unsigned long reg;
 
3153
 
 
3154
    /*2 x dclk */
 
3155
    reg = ReadGx(DC_GENERAL_CFG);
 
3156
    reg &= ~GX_DCLK_MUL;
 
3157
    reg |= GX_DCLKx2;
 
3158
    WriteGx(DC_GENERAL_CFG, reg);
 
3159
 
 
3160
    /*select pll dot clock. */
 
3161
    reg = ReadGx(CX_DOT_CLK);
 
3162
    reg &= ~CX_TVCLK_SELECT;
 
3163
    WriteGx(CX_DOT_CLK, reg);
 
3164
 
 
3165
    /*timing config, reset everything on dclk. */
 
3166
    reg = ReadGx(DC_TIMING_CFG);
 
3167
    reg &= ~GX_TGEN;
 
3168
    WriteGx(DC_TIMING_CFG, reg);
 
3169
    reg |= GX_TGEN;
 
3170
    WriteGx(DC_TIMING_CFG, reg);
 
3171
 
 
3172
    /*un-invert FP clock */
 
3173
    reg = ReadGx(CX_TV_CONFIG);
 
3174
    reg &= ~CX_INVERT_FPCLK;
 
3175
    WriteGx(CX_TV_CONFIG, reg);
 
3176
 
 
3177
    return 0;
 
3178
}
 
3179
 
 
3180
/*==========================================================================*/
 
3181
/*Platform-specific actions to enter TVout mode                                                         */
 
3182
/*==========================================================================*/
 
3183
 
 
3184
static int
 
3185
PLAL_PrepForTVout(void)
 
3186
{
 
3187
    unsigned int reg;
 
3188
 
 
3189
    /*Cx5530 tv config. */
 
3190
    reg = 0;
 
3191
    WriteGx(CX_TV_CONFIG, reg);
 
3192
 
 
3193
    /*invert FP clock */
 
3194
    reg = (int) ReadGx(CX_TV_CONFIG);
 
3195
    reg |= CX_INVERT_FPCLK;
 
3196
    WriteGx(CX_TV_CONFIG, reg);
 
3197
 
 
3198
    return 0;
 
3199
}
 
3200
 
 
3201
static int
 
3202
PLAL_SetTVTimingRegisters(const S_TIMING_SPECS * p_specs)
 
3203
{
 
3204
    unsigned long reg;
 
3205
 
 
3206
    /*timing config, reset everything on dclk. */
 
3207
    reg = ReadGx(DC_TIMING_CFG);
 
3208
    reg &= ~GX_TGEN;
 
3209
    WriteGx(DC_TIMING_CFG, reg);
 
3210
 
 
3211
    /*htotal and hactive. */
 
3212
    reg = ((p_specs->h_total - 1) << 16) | (p_specs->vga_width - 1);
 
3213
    WriteGx(DC_H_TIMING_1, reg);
 
3214
 
 
3215
    /*hblank. */
 
3216
    reg = ((p_specs->h_total - 1) << 16) | (p_specs->vga_width - 1);
 
3217
    WriteGx(DC_H_TIMING_2, reg);
 
3218
 
 
3219
    /*hsync. */
 
3220
    reg = ((p_specs->h_sync + 63) << 16) | p_specs->h_sync;
 
3221
    WriteGx(DC_H_TIMING_3, reg);
 
3222
 
 
3223
    /*fp hsync. */
 
3224
    WriteGx(DC_FP_H_TIMING, reg);
 
3225
 
 
3226
    /*vtotal and vactive. */
 
3227
    reg = ((p_specs->v_total - 1) << 16) | (p_specs->vga_lines - 1);
 
3228
    WriteGx(DC_V_TIMING_1, reg);
 
3229
 
 
3230
    /*vblank. */
 
3231
    reg = ((p_specs->v_total - 1) << 16) | (p_specs->vga_lines - 1);
 
3232
    WriteGx(DC_V_TIMING_2, reg);
 
3233
 
 
3234
    /*vsync. */
 
3235
    reg = ((p_specs->v_sync) << 16) | (p_specs->v_sync - 1);
 
3236
    WriteGx(DC_V_TIMING_3, reg);
 
3237
 
 
3238
    /*fp vsync. */
 
3239
    reg = ((p_specs->v_sync - 1) << 16) | (p_specs->v_sync - 2);
 
3240
    WriteGx(DC_FP_V_TIMING, reg);
 
3241
 
 
3242
    /*timing config, reenable all dclk stuff. */
 
3243
    reg = ReadGx(DC_TIMING_CFG);
 
3244
    reg |= GX_TGEN;
 
3245
    WriteGx(DC_TIMING_CFG, reg);
 
3246
 
 
3247
    return 0;
 
3248
}
 
3249
 
 
3250
static int
 
3251
PLAL_FinalEnableTVout(unsigned long vga_mode)
 
3252
{
 
3253
    unsigned int reg;
 
3254
 
 
3255
    /*Cx5530 select tv dot clock. */
 
3256
    reg = (int) ReadGx(CX_DOT_CLK);
 
3257
    reg |= CX_TVCLK_SELECT;
 
3258
    WriteGx(CX_DOT_CLK, reg);
 
3259
 
 
3260
    /*2 x dclk (actually 1x) */
 
3261
    reg = (int) ReadGx(DC_GENERAL_CFG);
 
3262
    reg &= ~GX_DCLK_MUL;
 
3263
    WriteGx(DC_GENERAL_CFG, reg);
 
3264
 
 
3265
    reg |= GX_DCLKx2;
 
3266
    WriteGx(DC_GENERAL_CFG, reg);
 
3267
 
 
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);
 
3272
 
 
3273
    return 0;
 
3274
}