vid_1200.c revision 71d7fec4
1/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/vid_1200.c,v 1.2 2003/01/14 09:34:34 alanh Exp $ */
2/*
3 * $Workfile: vid_1200.c $
4 *
5 * This file contains routines to control the SC1200 video overlay hardware.
6 *
7 * NSC_LIC_ALTERNATIVE_PREAMBLE
8 *
9 * Revision 1.0
10 *
11 * National Semiconductor Alternative GPL-BSD License
12 *
13 * National Semiconductor Corporation licenses this software
14 * ("Software"):
15 *
16 *      Durango
17 *
18 * under one of the two following licenses, depending on how the
19 * Software is received by the Licensee.
20 *
21 * If this Software is received as part of the Linux Framebuffer or
22 * other GPL licensed software, then the GPL license designated
23 * NSC_LIC_GPL applies to this Software; in all other circumstances
24 * then the BSD-style license designated NSC_LIC_BSD shall apply.
25 *
26 * END_NSC_LIC_ALTERNATIVE_PREAMBLE */
27
28/* NSC_LIC_BSD
29 *
30 * National Semiconductor Corporation Open Source License for Durango
31 *
32 * (BSD License with Export Notice)
33 *
34 * Copyright (c) 1999-2001
35 * National Semiconductor Corporation.
36 * All rights reserved.
37 *
38 * Redistribution and use in source and binary forms, with or without
39 * modification, are permitted provided that the following conditions
40 * are met:
41 *
42 *   * Redistributions of source code must retain the above copyright
43 *     notice, this list of conditions and the following disclaimer.
44 *
45 *   * Redistributions in binary form must reproduce the above
46 *     copyright notice, this list of conditions and the following
47 *     disclaimer in the documentation and/or other materials provided
48 *     with the distribution.
49 *
50 *   * Neither the name of the National Semiconductor Corporation nor
51 *     the names of its contributors may be used to endorse or promote
52 *     products derived from this software without specific prior
53 *     written permission.
54 *
55 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
56 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
57 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
58 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
59 * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY
60 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
61 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
62 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
63 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
64 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE,
65 * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY
66 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
67 * OF SUCH DAMAGE.
68 *
69 * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF
70 * YOUR JURISDICTION. It is licensee's responsibility to comply with
71 * any export regulations applicable in licensee's jurisdiction. Under
72 * CURRENT (2001) U.S. export regulations this software
73 * is eligible for export from the U.S. and can be downloaded by or
74 * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed
75 * destinations which include Cuba, Iraq, Libya, North Korea, Iran,
76 * Syria, Sudan, Afghanistan and any other country to which the U.S.
77 * has embargoed goods and services.
78 *
79 * END_NSC_LIC_BSD */
80
81/* NSC_LIC_GPL
82 *
83 * National Semiconductor Corporation Gnu General Public License for Durango
84 *
85 * (GPL License with Export Notice)
86 *
87 * Copyright (c) 1999-2001
88 * National Semiconductor Corporation.
89 * All rights reserved.
90 *
91 * Redistribution and use in source and binary forms, with or without
92 * modification, are permitted under the terms of the GNU General
93 * Public License as published by the Free Software Foundation; either
94 * version 2 of the License, or (at your option) any later version
95 *
96 * In addition to the terms of the GNU General Public License, neither
97 * the name of the National Semiconductor Corporation nor the names of
98 * its contributors may be used to endorse or promote products derived
99 * from this software without specific prior written permission.
100 *
101 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
102 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
103 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
104 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
105 * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY
106 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
107 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
108 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
109 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
110 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE,
111 * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY
112 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
113 * OF SUCH DAMAGE. See the GNU General Public License for more details.
114 *
115 * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF
116 * YOUR JURISDICTION. It is licensee's responsibility to comply with
117 * any export regulations applicable in licensee's jurisdiction. Under
118 * CURRENT (2001) U.S. export regulations this software
119 * is eligible for export from the U.S. and can be downloaded by or
120 * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed
121 * destinations which include Cuba, Iraq, Libya, North Korea, Iran,
122 * Syria, Sudan, Afghanistan and any other country to which the U.S.
123 * has embargoed goods and services.
124 *
125 * You should have received a copy of the GNU General Public License
126 * along with this file; if not, write to the Free Software Foundation,
127 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
128 *
129 * END_NSC_LIC_GPL */
130
131/*----------------------------------------------------------------------------
132 * SC1200 PLL TABLE
133 *----------------------------------------------------------------------------
134 */
135
136typedef struct tagSC1200PLL
137{
138   long frequency;			/* 16.16 fixed point frequency */
139   unsigned long clock_select;		/* clock select register (0x2C) */
140}
141SC1200PLL;
142
143SC1200PLL gfx_sc1200_clock_table[] = {
144   {(25L << 16) | ((1750L * 65536L) / 10000L), 0x0070E00C},	/* 25.1750 (sc=24.9231) */
145   {(27L << 16) | ((0000L * 65536L) / 10000L), 0x00300100},	/* 27.0000 */
146   {(28L << 16) | ((3220L * 65536L) / 10000L), 0x0070EC0C},	/* 28.3220 (SC=27.000) */
147   {(31L << 16) | ((5000L * 65536L) / 10000L), 0x00500D02},	/* 31.5000 */
148   {(36L << 16) | ((0000L * 65536L) / 10000L), 0x00500F02},	/* 36.0000 */
149   {(37L << 16) | ((5000L * 65536L) / 10000L), 0x0050B108},	/* 37.5000 */
150   {(40L << 16) | ((0000L * 65536L) / 10000L), 0x0050D20D},	/* 40.0000 */
151   {(44L << 16) | ((9000L * 65536L) / 10000L), 0x0050DC0D},	/* 44.9000 */
152   {(49L << 16) | ((5000L * 65536L) / 10000L), 0x00501502},	/* 49.5000 */
153   {(50L << 16) | ((0000L * 65536L) / 10000L), 0x0050A404},	/* 50.0000 */
154   {(50L << 16) | ((3500L * 65536L) / 10000L), 0x0050E00C},	/* 50.3500 */
155   {(54L << 16) | ((0000L * 65536L) / 10000L), 0x00300300},	/* 54.0000 */
156   {(56L << 16) | ((3916L * 65536L) / 10000L), 0x0050F40D},	/* 56.3916 */
157   {(56L << 16) | ((6440L * 65536L) / 10000L), 0x0050EC0C},	/* 56.6440 */
158   {(59L << 16) | ((0000L * 65536L) / 10000L), 0x0030A207},	/* 59.0000 */
159   {(63L << 16) | ((0000L * 65536L) / 10000L), 0x00300D02},	/* 63.0000 */
160   {(65L << 16) | ((0000L * 65536L) / 10000L), 0x0030CC0F},	/* 65.0000 */
161   {(67L << 16) | ((5000L * 65536L) / 10000L), 0x00300400},	/* 67.5000 */
162   {(70L << 16) | ((8000L * 65536L) / 10000L), 0x00301403},	/* 70.8000 */
163   {(72L << 16) | ((0000L * 65536L) / 10000L), 0x00300F02},	/* 72.0000 */
164   {(75L << 16) | ((0000L * 65536L) / 10000L), 0x0030B108},	/* 75.0000 */
165   {(78L << 16) | ((7500L * 65536L) / 10000L), 0x0030A205},	/* 78.7500 */
166   {(80L << 16) | ((0000L * 65536L) / 10000L), 0x0030D20D},	/* 80.0000 */
167   {(87L << 16) | ((2728L * 65536L) / 10000L), 0x0030E00E},	/* 87.2728 */
168   {(89L << 16) | ((8000L * 65536L) / 10000L), 0x0030DC0D},	/* 89.8000 */
169   {(94L << 16) | ((5000L * 65536L) / 10000L), 0x00300600},	/* 99.0000 */
170   {(99L << 16) | ((0000L * 65536L) / 10000L), 0x00301502},	/* 99.0000 */
171   {(100L << 16) | ((0000L * 65536L) / 10000L), 0x0030A404},	/* 100.00 */
172   {(108L << 16) | ((0000L * 65536L) / 10000L), 0x00100300},	/* 108.00 */
173   {(112L << 16) | ((5000L * 65536L) / 10000L), 0x00301802},	/* 108.00 */
174   {(130L << 16) | ((0000L * 65536L) / 10000L), 0x0010CC0F},	/* 130.00 */
175   {(135L << 16) | ((0000L * 65536L) / 10000L), 0x00100400},	/* 135.00 */
176   {(157L << 16) | ((5000L * 65536L) / 10000L), 0x0010A205},	/* 157.50 */
177   {(162L << 16) | ((0000L * 65536L) / 10000L), 0x00100500},	/* 162.00 */
178   {(175L << 16) | ((0000L * 65536L) / 10000L), 0x0010E00E},	/* 175.50 */
179   {(189L << 16) | ((0000L * 65536L) / 10000L), 0x00100600},	/* 189.00 */
180   {(202L << 16) | ((0000L * 65536L) / 10000L), 0x0010EF0E},	/* 202.50 */
181   {(232L << 16) | ((0000L * 65536L) / 10000L), 0x0010AA04},	/* 232.50 */
182
183   /* Precomputed inidces in the hardware */
184   {0x0018EC4D, 0x000F0000},		/*  24.923052 */
185   {0x00192CCC, 0x00000000},		/*  25.1750 */
186   {0x001B0000, 0x00300100},		/*  27.0000 */
187   {0x001F8000, 0x00010000},		/*  31.5000 */
188   {0x00240000, 0x00020000},		/*  36.0000 */
189   {0x00280000, 0x00030000},		/*  40.0000 */
190   {0x00318000, 0x00050000},		/*  49.5000 */
191   {0x00320000, 0x00040000},		/*  50.0000 */
192   {0x00384000, 0x00060000},		/*  56.2500 */
193   {0x00410000, 0x00080000},		/*  65.0000 */
194   {0x004E8000, 0x000A0000},		/*  78.5000 */
195   {0x005E8000, 0x000B0000},		/*  94.5000 */
196   {0x006C0000, 0x000C0000},		/* 108.0000 */
197   {0x00870000, 0x000D0000},		/* 135.0000 */
198};
199
200#define NUM_SC1200_FREQUENCIES sizeof(gfx_sc1200_clock_table)/sizeof(SC1200PLL)
201
202int sc1200_set_video_enable(int enable);
203int sc1200_set_video_format(unsigned long format);
204int sc1200_set_video_size(unsigned short width, unsigned short height);
205int sc1200_set_video_yuv_pitch(unsigned long ypitch, unsigned long uvpitch);
206int sc1200_set_video_offset(unsigned long offset);
207int sc1200_set_video_yuv_offsets(unsigned long yoffset, unsigned long uoffset,
208				 unsigned long voffset);
209int sc1200_set_video_window(short x, short y, unsigned short w,
210			    unsigned short h);
211int sc1200_set_video_left_crop(unsigned short x);
212int sc1200_set_video_upscale(unsigned short srcw, unsigned short srch,
213			     unsigned short dstw, unsigned short dsth);
214int sc1200_set_video_scale(unsigned short srcw, unsigned short srch,
215			   unsigned short dstw, unsigned short dsth);
216int sc1200_set_video_vertical_downscale(unsigned short srch,
217					unsigned short dsth);
218void sc1200_set_video_vertical_downscale_enable(int enable);
219int sc1200_set_video_downscale_config(unsigned short type, unsigned short m);
220int sc1200_set_video_color_key(unsigned long key, unsigned long mask,
221			       int bluescreen);
222int sc1200_set_video_filter(int xfilter, int yfilter);
223int sc1200_set_video_palette(unsigned long *palette);
224int sc1200_set_video_palette_entry(unsigned long index, unsigned long color);
225int sc1200_set_video_downscale_coefficients(unsigned short coef1,
226					    unsigned short coef2,
227					    unsigned short coef3,
228					    unsigned short coef4);
229int sc1200_set_video_downscale_enable(int enable);
230int sc1200_set_video_source(VideoSourceType source);
231int sc1200_set_vbi_source(VbiSourceType source);
232int sc1200_set_vbi_lines(unsigned long even, unsigned long odd);
233int sc1200_set_vbi_total(unsigned long even, unsigned long odd);
234int sc1200_set_video_interlaced(int enable);
235int sc1200_set_color_space_YUV(int enable);
236int sc1200_set_vertical_scaler_offset(char offset);
237int sc1200_set_top_line_in_odd(int enable);
238int sc1200_set_genlock_delay(unsigned long delay);
239int sc1200_set_genlock_enable(int flags);
240int sc1200_set_video_cursor(unsigned long key, unsigned long mask,
241			    unsigned short select_color2,
242			    unsigned long color1, unsigned long color2);
243int sc1200_set_video_cursor_enable(int enable);
244int sc1200_set_video_request(short x, short y);
245
246int sc1200_select_alpha_region(int region);
247int sc1200_set_alpha_enable(int enable);
248int sc1200_set_alpha_window(short x, short y,
249			    unsigned short width, unsigned short height);
250int sc1200_set_alpha_value(unsigned char alpha, char delta);
251int sc1200_set_alpha_priority(int priority);
252int sc1200_set_alpha_color(unsigned long color);
253int sc1200_set_alpha_color_enable(int enable);
254int sc1200_set_no_ck_outside_alpha(int enable);
255int sc1200_disable_softvga(void);
256int sc1200_enable_softvga(void);
257int sc1200_set_macrovision_enable(int enable);
258void sc1200_reset_video(void);
259int sc1200_set_display_control(int sync_polarities);
260void sc1200_set_clock_frequency(unsigned long frequency);
261int sc1200_set_screen_enable(int enable);
262int sc1200_set_crt_enable(int enable);
263
264/* READ ROUTINES IN GFX_VID.C */
265
266int sc1200_get_video_enable(void);
267int sc1200_get_video_format(void);
268unsigned long sc1200_get_video_src_size(void);
269unsigned long sc1200_get_video_line_size(void);
270unsigned long sc1200_get_video_xclip(void);
271unsigned long sc1200_get_video_offset(void);
272void sc1200_get_video_yuv_offsets(unsigned long *yoffset,
273				  unsigned long *uoffset,
274				  unsigned long *voffset);
275void sc1200_get_video_yuv_pitch(unsigned long *ypitch,
276				unsigned long *uvpitch);
277unsigned long sc1200_get_video_upscale(void);
278unsigned long sc1200_get_video_scale(void);
279unsigned long sc1200_get_video_downscale_delta(void);
280int sc1200_get_video_vertical_downscale_enable(void);
281int sc1200_get_video_downscale_config(unsigned short *type,
282				      unsigned short *m);
283void sc1200_get_video_downscale_coefficients(unsigned short *coef1,
284					     unsigned short *coef2,
285					     unsigned short *coef3,
286					     unsigned short *coef4);
287void sc1200_get_video_downscale_enable(int *enable);
288unsigned long sc1200_get_video_dst_size(void);
289unsigned long sc1200_get_video_position(void);
290unsigned long sc1200_get_video_color_key(void);
291unsigned long sc1200_get_video_color_key_mask(void);
292int sc1200_get_video_palette_entry(unsigned long index,
293				   unsigned long *palette);
294int sc1200_get_video_color_key_src(void);
295int sc1200_get_video_filter(void);
296int sc1200_get_video_request(short *x, short *y);
297int sc1200_get_video_source(VideoSourceType * source);
298int sc1200_get_vbi_source(VbiSourceType * source);
299unsigned long sc1200_get_vbi_lines(int odd);
300unsigned long sc1200_get_vbi_total(int odd);
301int sc1200_get_video_interlaced(void);
302int sc1200_get_color_space_YUV(void);
303int sc1200_get_vertical_scaler_offset(char *offset);
304unsigned long sc1200_get_genlock_delay(void);
305int sc1200_get_genlock_enable(void);
306int sc1200_get_video_cursor(unsigned long *key, unsigned long *mask,
307			    unsigned short *select_color2,
308			    unsigned long *color1, unsigned short *color2);
309unsigned long sc1200_read_crc(void);
310unsigned long sc1200_read_crc32(void);
311unsigned long sc1200_read_window_crc(int source, unsigned short x,
312				     unsigned short y, unsigned short width,
313				     unsigned short height, int crc32);
314int sc1200_get_macrovision_enable(void);
315
316void sc1200_get_alpha_enable(int *enable);
317void sc1200_get_alpha_size(unsigned short *x, unsigned short *y,
318			   unsigned short *width, unsigned short *height);
319void sc1200_get_alpha_value(unsigned char *alpha, char *delta);
320void sc1200_get_alpha_priority(int *priority);
321void sc1200_get_alpha_color(unsigned long *color);
322unsigned long sc1200_get_clock_frequency(void);
323int sc1200_get_vsa2_softvga_enable(void);
324int sc1200_get_sync_polarities(void);
325
326/*---------------------------------------------------------------------------
327 * gfx_reset_video (PRIVATE ROUTINE: NOT PART OF DURANGO API)
328 *
329 * This routine is used to disable all components of video overlay before
330 * performing a mode switch.
331 *---------------------------------------------------------------------------
332 */
333#if GFX_VIDEO_DYNAMIC
334void
335sc1200_reset_video(void)
336#else
337void
338gfx_reset_video(void)
339#endif
340{
341   int i;
342
343   gfx_set_video_enable(0);
344
345   /* SET WINDOW 0 AFTER RESET */
346
347   for (i = 2; i >= 0; i--) {
348      gfx_select_alpha_region(i);
349      gfx_set_alpha_enable(0);
350      gfx_set_alpha_color_enable(0);
351   }
352}
353
354/*-----------------------------------------------------------------------------
355 * gfx_set_display_control (PRIVATE ROUTINE: NOT PART OF DURANGO API)
356 *
357 * This routine configures the display output.
358 *
359 * "sync_polarities" is used to set the polarities of the sync pulses according
360 * to the following mask:
361 *
362 *     Bit 0: If set to 1, negative horizontal polarity is programmed,
363 *            otherwise positive horizontal polarity is programmed.
364 *     Bit 1: If set to 1, negative vertical polarity is programmed,
365 *            otherwise positive vertical polarity is programmed.
366 *
367 *-----------------------------------------------------------------------------
368 */
369#if GFX_VIDEO_DYNAMIC
370int
371sc1200_set_display_control(int sync_polarities)
372#else
373int
374gfx_set_display_control(int sync_polarities)
375#endif
376{
377   unsigned long dcfg;
378
379   /* CONFIGURE DISPLAY OUTPUT FROM VIDEO PROCESSOR */
380
381   dcfg = READ_VID32(SC1200_DISPLAY_CONFIG);
382   dcfg &= ~(SC1200_DCFG_CRT_SYNC_SKW_MASK | SC1200_DCFG_PWR_SEQ_DLY_MASK |
383	     SC1200_DCFG_CRT_HSYNC_POL | SC1200_DCFG_CRT_VSYNC_POL |
384	     SC1200_DCFG_FP_PWR_EN | SC1200_DCFG_FP_DATA_EN);
385
386   dcfg |= (SC1200_DCFG_CRT_SYNC_SKW_INIT |
387	    SC1200_DCFG_PWR_SEQ_DLY_INIT | SC1200_DCFG_GV_PAL_BYP);
388
389   if (PanelEnable)
390      dcfg |= SC1200_DCFG_FP_PWR_EN;
391
392   /* SET APPROPRIATE SYNC POLARITIES */
393
394   if (sync_polarities & 0x1)
395      dcfg |= SC1200_DCFG_CRT_HSYNC_POL;
396   if (sync_polarities & 0x2)
397      dcfg |= SC1200_DCFG_CRT_VSYNC_POL;
398
399   WRITE_VID32(SC1200_DISPLAY_CONFIG, dcfg);
400
401   return (0);
402}
403
404/*---------------------------------------------------------------------------
405 * gfx_set_clock_frequency
406 *
407 * This routine sets the clock frequency, specified as a 16.16 fixed point
408 * value (0x00318000 = 49.5 MHz).  It will set the closest frequency found
409 * in the lookup table.
410 *---------------------------------------------------------------------------
411 */
412#if GFX_VIDEO_DYNAMIC
413void
414sc1200_set_clock_frequency(unsigned long frequency)
415#else
416void
417gfx_set_clock_frequency(unsigned long frequency)
418#endif
419{
420   unsigned int index;
421   unsigned long value, pll;
422   long min, diff;
423
424   /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */
425   /* Search the table for the closest frequency (16.16 format). */
426
427   value = gfx_sc1200_clock_table[0].clock_select;
428   min = (long)gfx_sc1200_clock_table[0].frequency - frequency;
429   if (min < 0L)
430      min = -min;
431   for (index = 1; index < NUM_SC1200_FREQUENCIES; index++) {
432      diff = (long)gfx_sc1200_clock_table[index].frequency - frequency;
433      if (diff < 0L)
434	 diff = -diff;
435      if (diff < min) {
436	 min = diff;
437	 value = gfx_sc1200_clock_table[index].clock_select;
438      }
439   }
440
441   /* SET THE DOT CLOCK REGISTER */
442
443   pll = READ_VID32(SC1200_VID_MISC);
444   WRITE_VID32(SC1200_VID_MISC, pll | SC1200_PLL_POWER_NORMAL);
445   WRITE_VID32(SC1200_VID_CLOCK_SELECT, value);
446   return;
447}
448
449/*---------------------------------------------------------------------------
450 * gfx_set_screen_enable (PRIVATE ROUTINE - NOT PART OF API)
451 *
452 * This routine enables or disables the graphics display logic of the video processor.
453 *---------------------------------------------------------------------------
454 */
455#if GFX_VIDEO_DYNAMIC
456int
457sc1200_set_screen_enable(int enable)
458#else
459int
460gfx_set_screen_enable(int enable)
461#endif
462{
463   unsigned long config;
464
465   config = READ_VID32(SC1200_DISPLAY_CONFIG);
466   if (enable)
467      WRITE_VID32(SC1200_DISPLAY_CONFIG, config | SC1200_DCFG_DIS_EN);
468   else
469      WRITE_VID32(SC1200_DISPLAY_CONFIG, config & ~SC1200_DCFG_DIS_EN);
470   return (GFX_STATUS_OK);
471}
472
473/*---------------------------------------------------------------------------
474 * gfx_set_crt_enable
475 *
476 * This routine enables or disables the CRT output from the video processor.
477 *---------------------------------------------------------------------------
478 */
479#if GFX_VIDEO_DYNAMIC
480int
481sc1200_set_crt_enable(int enable)
482#else
483int
484gfx_set_crt_enable(int enable)
485#endif
486{
487   unsigned long config, misc;
488
489   config = READ_VID32(SC1200_DISPLAY_CONFIG);
490   misc = READ_VID32(SC1200_VID_MISC);
491
492   /*
493    *  IMPORTANT: For all modes do NOT disable the graphics display logic
494    *  because it might be needed for TV
495    */
496
497   switch (enable) {
498   case CRT_DISABLE:			/* HSync:Off VSync:Off */
499      WRITE_VID32(SC1200_DISPLAY_CONFIG, config & ~(SC1200_DCFG_HSYNC_EN
500						    | SC1200_DCFG_VSYNC_EN
501						    | SC1200_DCFG_DAC_BL_EN));
502      WRITE_VID32(SC1200_VID_MISC, misc | SC1200_DAC_POWER_DOWN);
503      break;
504   case CRT_ENABLE:			/* Enable CRT display, including display logic */
505      WRITE_VID32(SC1200_DISPLAY_CONFIG, config | SC1200_DCFG_HSYNC_EN
506		  | SC1200_DCFG_VSYNC_EN | SC1200_DCFG_DAC_BL_EN);
507      WRITE_VID32(SC1200_VID_MISC, misc & ~SC1200_DAC_POWER_DOWN);
508
509      /* ENABLE GRAPHICS DISPLAY LOGIC */
510      gfx_set_screen_enable(1);
511      break;
512   case CRT_STANDBY:			/* HSync:Off VSync:On */
513      WRITE_VID32(SC1200_DISPLAY_CONFIG, (config & ~(SC1200_DCFG_HSYNC_EN
514						     | SC1200_DCFG_DAC_BL_EN))
515		  | SC1200_DCFG_VSYNC_EN);
516      WRITE_VID32(SC1200_VID_MISC, misc | SC1200_DAC_POWER_DOWN);
517      break;
518   case CRT_SUSPEND:			/* HSync:On VSync:Off */
519      WRITE_VID32(SC1200_DISPLAY_CONFIG, (config & ~(SC1200_DCFG_VSYNC_EN
520						     | SC1200_DCFG_DAC_BL_EN))
521		  | SC1200_DCFG_HSYNC_EN);
522      WRITE_VID32(SC1200_VID_MISC, misc | SC1200_DAC_POWER_DOWN);
523      break;
524   default:
525      return GFX_STATUS_BAD_PARAMETER;
526   }
527   return (GFX_STATUS_OK);
528}
529
530/*-----------------------------------------------------------------------------
531 * gfx_set_video_enable
532 *
533 * This routine enables or disables the video overlay functionality.
534 *-----------------------------------------------------------------------------
535 */
536#if GFX_VIDEO_DYNAMIC
537int
538sc1200_set_video_enable(int enable)
539#else
540int
541gfx_set_video_enable(int enable)
542#endif
543{
544   unsigned long vcfg;
545
546   /* WAIT FOR VERTICAL BLANK TO START */
547   /* Otherwise a glitch can be observed. */
548
549   if (gfx_test_timing_active()) {
550      if (!gfx_test_vertical_active()) {
551	 while (!gfx_test_vertical_active()) ;
552      }
553      while (gfx_test_vertical_active()) ;
554   }
555
556   vcfg = READ_VID32(SC1200_VIDEO_CONFIG);
557   if (enable) {
558      /* ENABLE VIDEO OVERLAY FROM DISPLAY CONTROLLER */
559      /* Use private routine to abstract the display controller. */
560
561      gfx_set_display_video_enable(1);
562
563      /* ENABLE SC1200 VIDEO OVERLAY */
564
565      vcfg |= SC1200_VCFG_VID_EN;
566      WRITE_VID32(SC1200_VIDEO_CONFIG, vcfg);
567   } else {
568      /* DISABLE SC1200 VIDEO OVERLAY */
569
570      vcfg &= ~SC1200_VCFG_VID_EN;
571      WRITE_VID32(SC1200_VIDEO_CONFIG, vcfg);
572
573      /* DISABLE VIDEO OVERLAY FROM DISPLAY CONTROLLER */
574      /* Use private routine to abstract the display controller. */
575
576      gfx_set_display_video_enable(0);
577   }
578   return (0);
579}
580
581/*-----------------------------------------------------------------------------
582 * gfx_set_video_format
583 *
584 * Sets input video format type, to one of the YUV formats or to RGB.
585 *-----------------------------------------------------------------------------
586 */
587#if GFX_VIDEO_DYNAMIC
588int
589sc1200_set_video_format(unsigned long format)
590#else
591int
592gfx_set_video_format(unsigned long format)
593#endif
594{
595   unsigned long ctrl, vcfg = 0;
596
597   /* SET THE SC1200 VIDEO INPUT FORMAT */
598
599   vcfg = READ_VID32(SC1200_VIDEO_CONFIG);
600   ctrl = READ_VID32(SC1200_VID_ALPHA_CONTROL);
601   ctrl &= ~(SC1200_VIDEO_INPUT_IS_RGB);
602   vcfg &= ~(SC1200_VCFG_VID_INP_FORMAT | SC1200_VCFG_4_2_0_MODE);
603   switch (format) {
604   case VIDEO_FORMAT_UYVY:
605      vcfg |= SC1200_VCFG_UYVY_FORMAT;
606      break;
607   case VIDEO_FORMAT_YUYV:
608      vcfg |= SC1200_VCFG_YUYV_FORMAT;
609      break;
610   case VIDEO_FORMAT_Y2YU:
611      vcfg |= SC1200_VCFG_Y2YU_FORMAT;
612      break;
613   case VIDEO_FORMAT_YVYU:
614      vcfg |= SC1200_VCFG_YVYU_FORMAT;
615      break;
616   case VIDEO_FORMAT_Y0Y1Y2Y3:
617      vcfg |= SC1200_VCFG_UYVY_FORMAT;
618      vcfg |= SC1200_VCFG_4_2_0_MODE;
619      break;
620   case VIDEO_FORMAT_Y3Y2Y1Y0:
621      vcfg |= SC1200_VCFG_Y2YU_FORMAT;
622      vcfg |= SC1200_VCFG_4_2_0_MODE;
623      break;
624   case VIDEO_FORMAT_Y1Y0Y3Y2:
625      vcfg |= SC1200_VCFG_YUYV_FORMAT;
626      vcfg |= SC1200_VCFG_4_2_0_MODE;
627      break;
628   case VIDEO_FORMAT_Y1Y2Y3Y0:
629      vcfg |= SC1200_VCFG_YVYU_FORMAT;
630      vcfg |= SC1200_VCFG_4_2_0_MODE;
631      break;
632   case VIDEO_FORMAT_RGB:
633      ctrl |= SC1200_VIDEO_INPUT_IS_RGB;
634      vcfg |= SC1200_VCFG_UYVY_FORMAT;
635      break;
636   case VIDEO_FORMAT_P2M_P2L_P1M_P1L:
637      ctrl |= SC1200_VIDEO_INPUT_IS_RGB;
638      vcfg |= SC1200_VCFG_Y2YU_FORMAT;
639      break;
640   case VIDEO_FORMAT_P1M_P1L_P2M_P2L:
641      ctrl |= SC1200_VIDEO_INPUT_IS_RGB;
642      vcfg |= SC1200_VCFG_YUYV_FORMAT;
643      break;
644   case VIDEO_FORMAT_P1M_P2L_P2M_P1L:
645      ctrl |= SC1200_VIDEO_INPUT_IS_RGB;
646      vcfg |= SC1200_VCFG_YVYU_FORMAT;
647      break;
648   default:
649      return GFX_STATUS_BAD_PARAMETER;
650   }
651
652   /* ALWAYS DISABLE GRAPHICS CSC */
653   /* This is enabled in the function gfx_set_color_space_YUV for */
654   /* YUV blending on TV.                                         */
655
656   ctrl &= ~SC1200_CSC_GFX_RGB_TO_YUV;
657
658   if (ctrl & SC1200_VIDEO_INPUT_IS_RGB)
659      ctrl &= ~SC1200_CSC_VIDEO_YUV_TO_RGB;
660   else
661      ctrl |= SC1200_CSC_VIDEO_YUV_TO_RGB;
662
663   WRITE_VID32(SC1200_VIDEO_CONFIG, vcfg);
664   WRITE_VID32(SC1200_VID_ALPHA_CONTROL, ctrl);
665
666   return (0);
667}
668
669/*-----------------------------------------------------------------------------
670 * gfx_set_video_size
671 *
672 * This routine specifies the size of the source data.  It is used only
673 * to determine how much data to transfer per frame, and is not used to
674 * calculate the scaling value (that is handled by a separate routine).
675 *-----------------------------------------------------------------------------
676 */
677#if GFX_VIDEO_DYNAMIC
678int
679sc1200_set_video_size(unsigned short width, unsigned short height)
680#else
681int
682gfx_set_video_size(unsigned short width, unsigned short height)
683#endif
684{
685   unsigned long size, vcfg;
686
687   /* SET THE SC1200 VIDEO LINE SIZE */
688
689   vcfg = READ_VID32(SC1200_VIDEO_CONFIG);
690   vcfg &= ~(SC1200_VCFG_LINE_SIZE_LOWER_MASK | SC1200_VCFG_LINE_SIZE_UPPER);
691   size = (width >> 1);
692   vcfg |= (size & 0x00FF) << 8;
693   if (size & 0x0100)
694      vcfg |= SC1200_VCFG_LINE_SIZE_UPPER;
695   WRITE_VID32(SC1200_VIDEO_CONFIG, vcfg);
696
697   /* SET TOTAL VIDEO BUFFER SIZE IN DISPLAY CONTROLLER */
698   /* Use private routine to abstract the display controller. */
699
700   /* Add 1 line to bypass issue #803 */
701   gfx_set_display_video_size(width, (unsigned short)(height + 2));
702   return (0);
703}
704
705/*-----------------------------------------------------------------------------
706 * gfx_set_video_offset
707 *
708 * This routine sets the starting offset for the video buffer when only
709 * one offset needs to be specified.
710 *-----------------------------------------------------------------------------
711 */
712#if GFX_VIDEO_DYNAMIC
713int
714sc1200_set_video_offset(unsigned long offset)
715#else
716int
717gfx_set_video_offset(unsigned long offset)
718#endif
719{
720   /* SAVE VALUE FOR FUTURE CLIPPING OF THE TOP OF THE VIDEO WINDOW */
721
722   gfx_vid_offset = offset;
723
724   /* SET VIDEO BUFFER OFFSET IN DISPLAY CONTROLLER */
725   /* Use private routine to abstract the display controller. */
726
727   gfx_set_display_video_offset(offset);
728   return (0);
729}
730
731/*---------------------------------------------------------------------------
732 * gfx_set_video_upscale
733 *
734 * This routine sets the scale factor for the video overlay window.  The
735 * size of the source and destination regions are specified in pixels.
736 *---------------------------------------------------------------------------
737 */
738#if GFX_VIDEO_DYNAMIC
739int
740sc1200_set_video_upscale(unsigned short srcw, unsigned short srch,
741			 unsigned short dstw, unsigned short dsth)
742#else
743int
744gfx_set_video_upscale(unsigned short srcw, unsigned short srch,
745		      unsigned short dstw, unsigned short dsth)
746#endif
747{
748   unsigned long xscale, yscale;
749
750   /* SAVE PARAMETERS (unless don't-care zero destination arguments are used) */
751   /* These are needed for clipping the video window later. */
752
753   if (dstw != 0) {
754      gfx_vid_srcw = srcw;
755      gfx_vid_dstw = dstw;
756   }
757   if (dsth != 0) {
758      gfx_vid_srch = srch;
759      gfx_vid_dsth = dsth;
760   }
761
762   /* CALCULATE SC1200 SCALE FACTORS */
763
764   if (dstw == 0)
765      xscale = READ_VID32(SC1200_VIDEO_UPSCALE) & 0xffff;	/* keep previous if don't-care argument */
766   else if (dstw <= srcw)
767      xscale = 0x2000l;			/* horizontal downscaling is currently done in a separate function */
768   else if ((srcw == 1) || (dstw == 1))
769      return GFX_STATUS_BAD_PARAMETER;
770   else
771      xscale = (0x2000l * (srcw - 1l)) / (dstw - 1l);
772
773   if (dsth == 0)
774      yscale = (READ_VID32(SC1200_VIDEO_UPSCALE) & 0xffff0000) >> 16;	/* keep previous if don't-care argument */
775   else if (dsth <= srch)
776      yscale = 0x2000l;			/* No vertical downscaling in SC1200 so force to 1x if attempted */
777   else if ((srch == 1) || (dsth == 1))
778      return GFX_STATUS_BAD_PARAMETER;
779   else
780      yscale = (0x2000l * (srch - 1l)) / (dsth - 1l);
781
782   WRITE_VID32(SC1200_VIDEO_UPSCALE, (yscale << 16) | xscale);
783
784   /* CALL ROUTINE TO UPDATE WINDOW POSITION */
785   /* This is required because the scale values effect the number of */
786   /* source data pixels that need to be clipped, as well as the */
787   /* amount of data that needs to be transferred. */
788
789   gfx_set_video_window(gfx_vid_xpos, gfx_vid_ypos, gfx_vid_width,
790			gfx_vid_height);
791   return (0);
792}
793
794/*---------------------------------------------------------------------------
795 * gfx_set_video_scale
796 *
797 * This routine sets the scale factor for the video overlay window.  The
798 * size of the source and destination regions are specified in pixels.
799 *---------------------------------------------------------------------------
800 */
801#if GFX_VIDEO_DYNAMIC
802int
803sc1200_set_video_scale(unsigned short srcw, unsigned short srch,
804		       unsigned short dstw, unsigned short dsth)
805#else
806int
807gfx_set_video_scale(unsigned short srcw, unsigned short srch,
808		    unsigned short dstw, unsigned short dsth)
809#endif
810{
811   return gfx_set_video_upscale(srcw, srch, dstw, dsth);
812}
813
814/*---------------------------------------------------------------------------
815 * gfx_set_video_downscale_config
816 *
817 * This routine sets the downscale type and factor for the video overlay window.
818 * Note: No downscaling support for RGB565 and YUV420 video formats.
819 *---------------------------------------------------------------------------
820 */
821#if GFX_VIDEO_DYNAMIC
822int
823sc1200_set_video_downscale_config(unsigned short type, unsigned short m)
824#else
825int
826gfx_set_video_downscale_config(unsigned short type, unsigned short m)
827#endif
828{
829   unsigned long downscale;
830
831   if ((m < 1) || (m > 16))
832      return GFX_STATUS_BAD_PARAMETER;
833
834   downscale = READ_VID32(SC1200_VIDEO_DOWNSCALER_CONTROL);
835   downscale &=
836	 ~(SC1200_VIDEO_DOWNSCALE_FACTOR_MASK |
837	   SC1200_VIDEO_DOWNSCALE_TYPE_MASK);
838   downscale |= ((m - 1l) << SC1200_VIDEO_DOWNSCALE_FACTOR_POS);
839   switch (type) {
840   case VIDEO_DOWNSCALE_KEEP_1_OF:
841      downscale |= SC1200_VIDEO_DOWNSCALE_TYPE_A;
842      break;
843   case VIDEO_DOWNSCALE_DROP_1_OF:
844      downscale |= SC1200_VIDEO_DOWNSCALE_TYPE_B;
845      break;
846   default:
847      return GFX_STATUS_BAD_PARAMETER;
848   }
849   WRITE_VID32(SC1200_VIDEO_DOWNSCALER_CONTROL, downscale);
850   return (0);
851}
852
853/*---------------------------------------------------------------------------
854 * gfx_set_video_downscale_coefficients
855 *
856 * This routine sets the downscale filter coefficients.
857 *---------------------------------------------------------------------------
858 */
859#if GFX_VIDEO_DYNAMIC
860int
861sc1200_set_video_downscale_coefficients(unsigned short coef1,
862					unsigned short coef2,
863					unsigned short coef3,
864					unsigned short coef4)
865#else
866int
867gfx_set_video_downscale_coefficients(unsigned short coef1,
868				     unsigned short coef2,
869				     unsigned short coef3,
870				     unsigned short coef4)
871#endif
872{
873   if ((coef1 + coef2 + coef3 + coef4) != 16)
874      return GFX_STATUS_BAD_PARAMETER;
875
876   WRITE_VID32(SC1200_VIDEO_DOWNSCALER_COEFFICIENTS,
877	       ((unsigned long)coef1 << SC1200_VIDEO_DOWNSCALER_COEF1_POS) |
878	       ((unsigned long)coef2 << SC1200_VIDEO_DOWNSCALER_COEF2_POS) |
879	       ((unsigned long)coef3 << SC1200_VIDEO_DOWNSCALER_COEF3_POS) |
880	       ((unsigned long)coef4 << SC1200_VIDEO_DOWNSCALER_COEF4_POS));
881   return (0);
882}
883
884/*---------------------------------------------------------------------------
885 * gfx_set_video_downscale_enable
886 *
887 * This routine enables or disables downscaling for the video overlay window.
888 *---------------------------------------------------------------------------
889 */
890#if GFX_VIDEO_DYNAMIC
891int
892sc1200_set_video_downscale_enable(int enable)
893#else
894int
895gfx_set_video_downscale_enable(int enable)
896#endif
897{
898   unsigned long downscale;
899
900   downscale = READ_VID32(SC1200_VIDEO_DOWNSCALER_CONTROL);
901   downscale &= ~SC1200_VIDEO_DOWNSCALE_ENABLE;
902   if (enable)
903      downscale |= SC1200_VIDEO_DOWNSCALE_ENABLE;
904   WRITE_VID32(SC1200_VIDEO_DOWNSCALER_CONTROL, downscale);
905   return (0);
906}
907
908/*---------------------------------------------------------------------------
909 * gfx_set_video_window
910 *
911 * This routine sets the position and size of the video overlay window.  The
912 * y position is specified in screen relative coordinates, and may be negative.
913 * The size of destination region is specified in pixels.  The line size
914 * indicates the number of bytes of source data per scanline.
915 * For the effect of negative x values, call the function
916 * gfx_set_video_left_crop().
917 *---------------------------------------------------------------------------
918 */
919#if GFX_VIDEO_DYNAMIC
920int
921sc1200_set_video_window(short x, short y, unsigned short w, unsigned short h)
922#else
923int
924gfx_set_video_window(short x, short y, unsigned short w, unsigned short h)
925#endif
926{
927   unsigned long control;
928   unsigned long hadjust, vadjust;
929   unsigned long xstart, ystart, xend, yend;
930
931   /* For left cropping call the function gfx_set_video_left_crop() */
932
933   if (x < 0)
934      return GFX_STATUS_BAD_PARAMETER;
935
936   /* SAVE PARAMETERS */
937   /* These are needed to call this routine if the scale value changes. */
938   /* In the case of SC1200 they are also needed for restoring when video is re-enabled */
939
940   gfx_vid_xpos = x;
941   gfx_vid_ypos = y;
942   gfx_vid_width = w;
943   gfx_vid_height = h;
944
945   /* GET ADJUSTMENT VALUES */
946   /* Use routines to abstract version of display controller. */
947
948   hadjust = gfx_get_htotal() - gfx_get_hsync_end() - 14l;
949   vadjust = gfx_get_vtotal() - gfx_get_vsync_end() + 1l;
950
951   /* HORIZONTAL START */
952
953   xstart = (unsigned long)x + hadjust;
954
955   /* HORIZONTAL END */
956   /* End positions in register are non-inclusive (one more than the actual end) */
957
958   if ((x + w) < gfx_get_hactive())
959      xend = (unsigned long)x + (unsigned long)w + hadjust;
960   else					/* right clipping needed */
961      xend = (unsigned long)gfx_get_hactive() + hadjust;
962
963   /* VERTICAL START */
964
965   ystart = (unsigned long)y + vadjust;
966
967   /* VERTICAL END */
968
969   if ((y + h) < gfx_get_vactive())
970      yend = (unsigned long)y + (unsigned long)h + vadjust;
971   else					/* bottom clipping needed */
972      yend = (unsigned long)gfx_get_vactive() + vadjust;
973
974   /* SET VIDEO LINE INVERT BIT */
975
976   control = READ_VID32(SC1200_VID_ALPHA_CONTROL);
977   if (y & 0x1)
978      WRITE_VID32(SC1200_VID_ALPHA_CONTROL,
979		  control | SC1200_VIDEO_LINE_OFFSET_ODD);
980   else
981      WRITE_VID32(SC1200_VID_ALPHA_CONTROL,
982		  control & ~SC1200_VIDEO_LINE_OFFSET_ODD);
983
984   /* SET VIDEO POSITION */
985
986   WRITE_VID32(SC1200_VIDEO_X_POS, (xend << 16) | xstart);
987   WRITE_VID32(SC1200_VIDEO_Y_POS, (yend << 16) | ystart);
988
989   return (0);
990}
991
992/*---------------------------------------------------------------------------
993 * gfx_set_video_left_crop
994 *
995 * This routine sets the number of pixels which will be cropped from the
996 * beginning of each video line. The video window will begin to display only
997 * from the pixel following the cropped pixels, and the cropped pixels
998 * will be ignored.
999 *---------------------------------------------------------------------------
1000 */
1001#if GFX_VIDEO_DYNAMIC
1002int
1003sc1200_set_video_left_crop(unsigned short x)
1004#else
1005int
1006gfx_set_video_left_crop(unsigned short x)
1007#endif
1008{
1009   unsigned long vcfg, initread;
1010
1011   /* CLIPPING ON LEFT */
1012   /* Adjust initial read for scale, checking for divide by zero */
1013
1014   if (gfx_vid_dstw)
1015      initread = (unsigned long)x *gfx_vid_srcw / gfx_vid_dstw;
1016
1017   else
1018      initread = 0l;
1019
1020   /* SET INITIAL READ ADDRESS */
1021
1022   vcfg = READ_VID32(SC1200_VIDEO_CONFIG);
1023   vcfg &= ~SC1200_VCFG_INIT_READ_MASK;
1024   vcfg |= (initread << 15) & SC1200_VCFG_INIT_READ_MASK;
1025   WRITE_VID32(SC1200_VIDEO_CONFIG, vcfg);
1026   return (0);
1027}
1028
1029/*---------------------------------------------------------------------------
1030 * gfx_set_video_color_key
1031 *
1032 * This routine specifies the color key value and mask for the video overlay
1033 * hardware. To disable color key, the color and mask should both be set to
1034 * zero. The hardware uses the color key in the following equation:
1035 *
1036 * ((source data) & (color key mask)) == ((color key) & (color key mask))
1037 *
1038 * If "graphics" is set to TRUE, the source data is graphics, and color key
1039 * is an RGB value. If "graphics" is set to FALSE, the source data is the video,
1040 * and color key is a YUV value.
1041 *---------------------------------------------------------------------------
1042 */
1043#if GFX_VIDEO_DYNAMIC
1044int
1045sc1200_set_video_color_key(unsigned long key, unsigned long mask,
1046			   int graphics)
1047#else
1048int
1049gfx_set_video_color_key(unsigned long key, unsigned long mask, int graphics)
1050#endif
1051{
1052   unsigned long dcfg = 0;
1053
1054   /* SET SC1200 COLOR KEY VALUE */
1055
1056   WRITE_VID32(SC1200_VIDEO_COLOR_KEY, key);
1057   WRITE_VID32(SC1200_VIDEO_COLOR_MASK, mask);
1058
1059   /* SELECT GRAPHICS OR VIDEO DATA TO COMPARE TO THE COLOR KEY */
1060
1061   dcfg = READ_VID32(SC1200_DISPLAY_CONFIG);
1062   if (graphics & 0x01)
1063      dcfg &= ~SC1200_DCFG_VG_CK;
1064   else
1065      dcfg |= SC1200_DCFG_VG_CK;
1066   WRITE_VID32(SC1200_DISPLAY_CONFIG, dcfg);
1067   return (0);
1068}
1069
1070/*---------------------------------------------------------------------------
1071 * gfx_set_video_filter
1072 *
1073 * This routine enables or disables the video overlay filters.
1074 *---------------------------------------------------------------------------
1075 */
1076#if GFX_VIDEO_DYNAMIC
1077int
1078sc1200_set_video_filter(int xfilter, int yfilter)
1079#else
1080int
1081gfx_set_video_filter(int xfilter, int yfilter)
1082#endif
1083{
1084   unsigned long vcfg = 0;
1085
1086   /* ENABLE OR DISABLE SC1200 VIDEO OVERLAY FILTERS */
1087
1088   vcfg = READ_VID32(SC1200_VIDEO_CONFIG);
1089   vcfg &= ~(SC1200_VCFG_X_FILTER_EN | SC1200_VCFG_Y_FILTER_EN);
1090   if (xfilter)
1091      vcfg |= SC1200_VCFG_X_FILTER_EN;
1092   if (yfilter)
1093      vcfg |= SC1200_VCFG_Y_FILTER_EN;
1094   WRITE_VID32(SC1200_VIDEO_CONFIG, vcfg);
1095   return (0);
1096}
1097
1098/*---------------------------------------------------------------------------
1099 * gfx_set_video_palette
1100 *
1101 * This routine loads the video hardware palette.  If a NULL pointer is
1102 * specified, the palette is bypassed (for SC1200, this means loading the
1103 * palette with identity values).
1104 *---------------------------------------------------------------------------
1105 */
1106#if GFX_VIDEO_DYNAMIC
1107int
1108sc1200_set_video_palette(unsigned long *palette)
1109#else
1110int
1111gfx_set_video_palette(unsigned long *palette)
1112#endif
1113{
1114   unsigned long i, entry;
1115
1116   /* WAIT FOR VERTICAL BLANK TO END */
1117   /* Otherwise palette will not be written properly. */
1118
1119   if (gfx_test_timing_active()) {
1120      if (gfx_test_vertical_active()) {
1121	 while (gfx_test_vertical_active()) ;
1122      }
1123      while (!gfx_test_vertical_active()) ;
1124   }
1125
1126   /* LOAD SC1200 VIDEO PALETTE */
1127
1128   WRITE_VID32(SC1200_PALETTE_ADDRESS, 0);
1129   for (i = 0; i < 256; i++) {
1130      if (palette)
1131	 entry = palette[i];
1132      else
1133	 entry = (i << 8) | (i << 16) | (i << 24);
1134      WRITE_VID32(SC1200_PALETTE_DATA, entry);
1135   }
1136   return (0);
1137}
1138
1139/*---------------------------------------------------------------------------
1140 * gfx_set_video_palette_entry
1141 *
1142 * This routine loads a single entry of the video hardware palette.
1143 *---------------------------------------------------------------------------
1144 */
1145#if GFX_VIDEO_DYNAMIC
1146int
1147sc1200_set_video_palette_entry(unsigned long index, unsigned long palette)
1148#else
1149int
1150gfx_set_video_palette_entry(unsigned long index, unsigned long palette)
1151#endif
1152{
1153   if (index > 0xFF)
1154      return GFX_STATUS_BAD_PARAMETER;
1155
1156   /* WAIT FOR VERTICAL BLANK TO END */
1157   /* Otherwise palette will not be written properly. */
1158
1159   if (gfx_test_timing_active()) {
1160      if (gfx_test_vertical_active()) {
1161	 while (gfx_test_vertical_active()) ;
1162      }
1163      while (!gfx_test_vertical_active()) ;
1164   }
1165
1166   /* SET A SINGLE ENTRY */
1167
1168   WRITE_VID32(SC1200_PALETTE_ADDRESS, index);
1169   WRITE_VID32(SC1200_PALETTE_DATA, palette);
1170
1171   return (0);
1172}
1173
1174/*---------------------------------------------------------------------------
1175 * gfx_set_video_request()
1176 *
1177 * This routine sets the horizontal (pixel) and vertical (line) video request
1178 * values.
1179 *---------------------------------------------------------------------------
1180 */
1181#if GFX_VIDEO_DYNAMIC
1182int
1183sc1200_set_video_request(short x, short y)
1184#else
1185int
1186gfx_set_video_request(short x, short y)
1187#endif
1188{
1189   /* SET SC1200 VIDEO REQUEST */
1190
1191   x += gfx_get_htotal() - gfx_get_hsync_end() - 2;
1192   y += gfx_get_vtotal() - gfx_get_vsync_end() + 1;
1193
1194   if ((x < 0) || (x > SC1200_VIDEO_REQUEST_MASK) ||
1195       (y < 0) || (y > SC1200_VIDEO_REQUEST_MASK))
1196      return GFX_STATUS_BAD_PARAMETER;
1197
1198   WRITE_VID32(SC1200_VIDEO_REQUEST,
1199	       ((unsigned long)x << SC1200_VIDEO_X_REQUEST_POS) |
1200	       ((unsigned long)y << SC1200_VIDEO_Y_REQUEST_POS));
1201   return (0);
1202}
1203
1204/*---------------------------------------------------------------------------
1205 * gfx_set_video_source()
1206 *
1207 * This routine sets the video source to either memory or Direct VIP.
1208 *---------------------------------------------------------------------------
1209 */
1210#if GFX_VIDEO_DYNAMIC
1211int
1212sc1200_set_video_source(VideoSourceType source)
1213#else
1214int
1215gfx_set_video_source(VideoSourceType source)
1216#endif
1217{
1218   unsigned long display_mode;
1219
1220   display_mode = READ_VID32(SC1200_VIDEO_DISPLAY_MODE);
1221
1222   /* SET SC1200 VIDEO SOURCE */
1223   switch (source) {
1224   case VIDEO_SOURCE_MEMORY:
1225      WRITE_VID32(SC1200_VIDEO_DISPLAY_MODE,
1226		  (display_mode & ~SC1200_VIDEO_SOURCE_MASK) |
1227		  SC1200_VIDEO_SOURCE_GX1);
1228      break;
1229   case VIDEO_SOURCE_DVIP:
1230      WRITE_VID32(SC1200_VIDEO_DISPLAY_MODE,
1231		  (display_mode & ~SC1200_VIDEO_SOURCE_MASK) |
1232		  SC1200_VIDEO_SOURCE_DVIP);
1233      break;
1234   default:
1235      return GFX_STATUS_BAD_PARAMETER;
1236   }
1237   return (0);
1238}
1239
1240/*---------------------------------------------------------------------------
1241 * gfx_set_vbi_source()
1242 *
1243 * This routine sets the vbi source to either memory or Direct VIP.
1244 *---------------------------------------------------------------------------
1245 */
1246#if GFX_VIDEO_DYNAMIC
1247int
1248sc1200_set_vbi_source(VbiSourceType source)
1249#else
1250int
1251gfx_set_vbi_source(VbiSourceType source)
1252#endif
1253{
1254   unsigned long display_mode;
1255
1256   display_mode = READ_VID32(SC1200_VIDEO_DISPLAY_MODE);
1257
1258   /* SET SC1200 VBI SOURCE */
1259   switch (source) {
1260   case VBI_SOURCE_MEMORY:
1261      WRITE_VID32(SC1200_VIDEO_DISPLAY_MODE,
1262		  (display_mode & ~SC1200_VBI_SOURCE_MASK) |
1263		  SC1200_VBI_SOURCE_GX1);
1264      break;
1265   case VBI_SOURCE_DVIP:
1266      WRITE_VID32(SC1200_VIDEO_DISPLAY_MODE,
1267		  (display_mode & ~SC1200_VBI_SOURCE_MASK) |
1268		  SC1200_VBI_SOURCE_DVIP);
1269      break;
1270   default:
1271      return GFX_STATUS_BAD_PARAMETER;
1272   }
1273   return (0);
1274}
1275
1276/*---------------------------------------------------------------------------
1277 * gfx_set_vbi_lines()
1278 *
1279 * This routine sets the VBI lines to pass to the TV encoder.
1280 *---------------------------------------------------------------------------
1281 */
1282#if GFX_VIDEO_DYNAMIC
1283int
1284sc1200_set_vbi_lines(unsigned long even, unsigned long odd)
1285#else
1286int
1287gfx_set_vbi_lines(unsigned long even, unsigned long odd)
1288#endif
1289{
1290   /* SET SC1200 VBI LINES */
1291   WRITE_VID32(SC1200_VIDEO_EVEN_VBI_LINE_ENABLE,
1292	       even & SC1200_VIDEO_VBI_LINE_ENABLE_MASK);
1293   WRITE_VID32(SC1200_VIDEO_ODD_VBI_LINE_ENABLE,
1294	       odd & SC1200_VIDEO_VBI_LINE_ENABLE_MASK);
1295   return (0);
1296}
1297
1298/*---------------------------------------------------------------------------
1299 * gfx_set_vbi_total()
1300 *
1301 * This routine sets the total number of VBI bytes for each field.
1302 * The total is needed when both VBI and active video are received from memory.
1303 *---------------------------------------------------------------------------
1304 */
1305#if GFX_VIDEO_DYNAMIC
1306int
1307sc1200_set_vbi_total(unsigned long even, unsigned long odd)
1308#else
1309int
1310gfx_set_vbi_total(unsigned long even, unsigned long odd)
1311#endif
1312{
1313   /* SET SC1200 VBI TOTAL */
1314   WRITE_VID32(SC1200_VIDEO_EVEN_VBI_TOTAL_COUNT,
1315	       even & SC1200_VIDEO_VBI_TOTAL_COUNT_MASK);
1316   WRITE_VID32(SC1200_VIDEO_ODD_VBI_TOTAL_COUNT,
1317	       odd & SC1200_VIDEO_VBI_TOTAL_COUNT_MASK);
1318   return (0);
1319}
1320
1321/*---------------------------------------------------------------------------
1322 * gfx_set_video_interlaced()
1323 *
1324 * This routine configures the video processor video overlay mode to be
1325 * interlaced YUV.
1326 *---------------------------------------------------------------------------
1327 */
1328#if GFX_VIDEO_DYNAMIC
1329int
1330sc1200_set_video_interlaced(int enable)
1331#else
1332int
1333gfx_set_video_interlaced(int enable)
1334#endif
1335{
1336   unsigned long control;
1337
1338   control = READ_VID32(SC1200_VID_ALPHA_CONTROL);
1339   /* SET INTERLACED VIDEO */
1340   if (enable)
1341      WRITE_VID32(SC1200_VID_ALPHA_CONTROL,
1342		  control | SC1200_VIDEO_IS_INTERLACED);
1343   else
1344      WRITE_VID32(SC1200_VID_ALPHA_CONTROL,
1345		  control & ~SC1200_VIDEO_IS_INTERLACED);
1346   return (0);
1347}
1348
1349/*---------------------------------------------------------------------------
1350 * gfx_set_color_space_YUV()
1351 *
1352 * This routine configures the video processor to process graphics and video
1353 * in either YUV or RGB color space. The mode should be set to tune image
1354 * quality.
1355 * Setting "enable" to TRUE improves image quality on TV,
1356 * but in this mode colors on CRT will not be correct.
1357 *---------------------------------------------------------------------------
1358 */
1359#if GFX_VIDEO_DYNAMIC
1360int
1361sc1200_set_color_space_YUV(int enable)
1362#else
1363int
1364gfx_set_color_space_YUV(int enable)
1365#endif
1366{
1367   unsigned long control;
1368
1369   control = READ_VID32(SC1200_VID_ALPHA_CONTROL);
1370
1371   /* SET SC1200 VIDEO COLOR SPACE TO YUV OR RGB */
1372
1373   if (enable) {
1374      /* ENABLE YUV BLENDING */
1375      /* YUV blending cannot be enabled in RGB video formats */
1376
1377      control |= SC1200_CSC_GFX_RGB_TO_YUV;	/* Convert graphics to YUV */
1378      control &= ~SC1200_CSC_VIDEO_YUV_TO_RGB;	/* Leave video in YUV      */
1379
1380      if (control & SC1200_VIDEO_INPUT_IS_RGB)
1381	 return (GFX_STATUS_UNSUPPORTED);	/* Can't convert video from RGB to YUV */
1382   } else {
1383      /* RGB BLENDING */
1384
1385      control &= ~SC1200_CSC_GFX_RGB_TO_YUV;	/* Leave graphics in RGB */
1386      if (control & SC1200_VIDEO_INPUT_IS_RGB)
1387	 control &= ~SC1200_CSC_VIDEO_YUV_TO_RGB;	/* Leave video in RGB */
1388      else
1389	 control |= SC1200_CSC_VIDEO_YUV_TO_RGB;	/* Convert video to RGB */
1390   }
1391   WRITE_VID32(SC1200_VID_ALPHA_CONTROL, control);
1392   return (0);
1393}
1394
1395/*---------------------------------------------------------------------------
1396 * gfx_set_vertical_scaler_offset()
1397 *
1398 * This routine sets the value by which the odd frame is shifted with respect
1399 * to the even frame. This is useful for de-interlacing in Bob method, by
1400 * setting the shift value to be one line.
1401 * If offset is 0, no shifting occurs.
1402 *---------------------------------------------------------------------------
1403 */
1404#if GFX_VIDEO_DYNAMIC
1405int
1406sc1200_set_vertical_scaler_offset(char offset)
1407#else
1408int
1409gfx_set_vertical_scaler_offset(char offset)
1410#endif
1411{
1412   unsigned long control;
1413
1414   control = READ_VID32(SC1200_VID_ALPHA_CONTROL);
1415   if (offset == 1) {
1416      control &= ~SC1200_VERTICAL_SCALER_SHIFT_MASK;	/* Clear shifting value */
1417      control |= SC1200_VERTICAL_SCALER_SHIFT_INIT;	/* Set shifting value */
1418      control |= SC1200_VERTICAL_SCALER_SHIFT_EN;	/* Enable odd frame shifting */
1419   } else if (offset == 0) {
1420      control &= ~SC1200_VERTICAL_SCALER_SHIFT_EN;	/* No shifting occurs */
1421      control &= ~SC1200_VERTICAL_SCALER_SHIFT_MASK;	/* Clear shifting value */
1422   } else
1423      return (GFX_STATUS_BAD_PARAMETER);	/* TODO: how to program other values ? */
1424   WRITE_VID32(SC1200_VID_ALPHA_CONTROL, control);
1425   return (0);
1426}
1427
1428/*---------------------------------------------------------------------------
1429 * gfx_set_top_line_in_odd()
1430 *
1431 * This routine sets the field in which the top line of input video resides.
1432 * If enable is "0", this is the even field (default). [not to be confused
1433 * with the odd field being the top field on TV].
1434 * If enable is "1", this is the odd field.
1435 * Use enable "1" for input devices whose field indication is reversed from
1436 * normal, i.e. an indication of "odd" field is given for even field data,
1437 * and vice versa.
1438 * This setting affects the video processor only when it is in either interlaced
1439 * or Bob (scaler offset active) modes.
1440  *---------------------------------------------------------------------------
1441 */
1442#if GFX_VIDEO_DYNAMIC
1443int
1444sc1200_set_top_line_in_odd(int enable)
1445#else
1446int
1447gfx_set_top_line_in_odd(int enable)
1448#endif
1449{
1450   unsigned long control;
1451
1452   control = READ_VID32(SC1200_VID_ALPHA_CONTROL);
1453   if (enable)
1454      control |= SC1200_TOP_LINE_IN_ODD;	/* Set shifting value */
1455   else
1456      control &= ~SC1200_TOP_LINE_IN_ODD;	/* No shifting occurs */
1457   WRITE_VID32(SC1200_VID_ALPHA_CONTROL, control);
1458   return (0);
1459}
1460
1461/*---------------------------------------------------------------------------
1462 * gfx_set_genlock_delay()
1463 *
1464 * This routine sets the delay between VIP VSYNC and display controller VSYNC.
1465 * The delay is in 27 MHz clocks.
1466 *---------------------------------------------------------------------------
1467 */
1468#if GFX_VIDEO_DYNAMIC
1469int
1470sc1200_set_genlock_delay(unsigned long delay)
1471#else
1472int
1473gfx_set_genlock_delay(unsigned long delay)
1474#endif
1475{
1476   /* SET SC1200 GENLOCK DELAY */
1477   WRITE_VID32(SC1200_GENLOCK_DELAY, delay & SC1200_GENLOCK_DELAY_MASK);
1478   return (0);
1479}
1480
1481/*---------------------------------------------------------------------------
1482 * gfx_set_genlock_enable()
1483 *
1484 * This routine sets and configures the genlock according to the flags parameter.
1485 * Flags value of 0 disables genlock and resets its configuration.
1486 *---------------------------------------------------------------------------
1487 */
1488#if GFX_VIDEO_DYNAMIC
1489int
1490sc1200_set_genlock_enable(int flags)
1491#else
1492int
1493gfx_set_genlock_enable(int flags)
1494#endif
1495{
1496   unsigned long genlock = 0;
1497
1498   if (flags) {
1499      /* SET SC1200 GENLOCK CONFIGURATION */
1500      if (flags & GENLOCK_SINGLE)
1501	 genlock |= SC1200_GENLOCK_SINGLE_ENABLE;
1502      if (flags & GENLOCK_FIELD_SYNC)
1503	 genlock |= SC1200_GENLOCK_FIELD_SYNC_ENABLE;
1504      if (flags & GENLOCK_CONTINUOUS)
1505	 genlock |= SC1200_GENLOCK_CONTINUOUS_ENABLE;
1506      if (flags & GENLOCK_SYNCED_EDGE_FALLING)
1507	 genlock |= SC1200_GENLOCK_GX_VSYNC_FALLING_EDGE;
1508      if (flags & GENLOCK_SYNCING_EDGE_FALLING)
1509	 genlock |= SC1200_GENLOCK_VIP_VSYNC_FALLING_EDGE;
1510      if (flags & GENLOCK_TIMEOUT)
1511	 genlock |= SC1200_GENLOCK_TIMEOUT_ENABLE;
1512      if (flags & GENLOCK_TVENC_RESET_EVEN_FIELD)
1513	 genlock |= SC1200_GENLOCK_TVENC_RESET_EVEN_FIELD;
1514      if (flags & GENLOCK_TVENC_RESET_BEFORE_DELAY)
1515	 genlock |= SC1200_GENLOCK_TVENC_RESET_BEFORE_DELAY;
1516      if (flags & GENLOCK_TVENC_RESET)
1517	 genlock |= SC1200_GENLOCK_TVENC_RESET_ENABLE;
1518      if (flags & GENLOCK_SYNC_TO_TVENC)
1519	 genlock |= SC1200_GENLOCK_SYNC_TO_TVENC;
1520   }
1521   WRITE_VID32(SC1200_GENLOCK, genlock);
1522   return (0);
1523}
1524
1525/*---------------------------------------------------------------------------
1526 * gfx_set_video_cursor()
1527 *
1528 * This routine configures the video hardware cursor.
1529 * If the "mask"ed bits in the graphics pixel match "key", then either "color1"
1530 * or "color2" will be used for this pixel, according to the value of bit
1531 * number "select_color2" of the graphics pixel.
1532 *
1533 * key - 24 bit RGB value
1534 * mask - 24 bit mask
1535 * color1, color2 - RGB or YUV, depending on the current color space conversion
1536 * select_color2 - value between 0 to 23
1537 *
1538 * To disable match, a "mask" and "key" value of 0xffffff should be set,
1539 * because the graphics pixels incoming to the video processor have maximum 16
1540 * bits set (0xF8FCF8).
1541 *
1542 * This feature is useful for disabling alpha blending of the cursor.
1543 * Otherwise cursor image would be blurred (or completely invisible if video
1544 * alpha is maximum value).
1545 * Note: the cursor pixel replacements take place both inside and outside the
1546 * video overlay window.
1547 *---------------------------------------------------------------------------
1548 */
1549#if GFX_VIDEO_DYNAMIC
1550int
1551sc1200_set_video_cursor(unsigned long key, unsigned long mask,
1552			unsigned short select_color2, unsigned long color1,
1553			unsigned long color2)
1554#else
1555int
1556gfx_set_video_cursor(unsigned long key, unsigned long mask,
1557		     unsigned short select_color2, unsigned long color1,
1558		     unsigned long color2)
1559#endif
1560{
1561   if (select_color2 > SC1200_CURSOR_COLOR_BITS)
1562      return GFX_STATUS_BAD_PARAMETER;
1563   key = (key & SC1200_COLOR_MASK) | ((unsigned long)select_color2 <<
1564				      SC1200_CURSOR_COLOR_KEY_OFFSET_POS);
1565   WRITE_VID32(SC1200_CURSOR_COLOR_KEY, key);
1566   WRITE_VID32(SC1200_CURSOR_COLOR_MASK, mask);
1567   WRITE_VID32(SC1200_CURSOR_COLOR_1, color1);
1568   WRITE_VID32(SC1200_CURSOR_COLOR_2, color2);
1569   return (0);
1570}
1571
1572/*---------------------------------------------------------------------------
1573 * gfx_set_alpha_enable
1574 *
1575 * This routine enables or disables the currently selected alpha region.
1576 *---------------------------------------------------------------------------
1577 */
1578#if GFX_VIDEO_DYNAMIC
1579int
1580sc1200_set_alpha_enable(int enable)
1581#else
1582int
1583gfx_set_alpha_enable(int enable)
1584#endif
1585{
1586   unsigned long address = 0, value = 0;
1587
1588   if (gfx_alpha_select > 2)
1589      return (GFX_STATUS_UNSUPPORTED);
1590   address = SC1200_ALPHA_CONTROL_1 + ((unsigned long)gfx_alpha_select << 4);
1591   value = READ_VID32(address);
1592   if (enable)
1593      value |= (SC1200_ACTRL_WIN_ENABLE | SC1200_ACTRL_LOAD_ALPHA);
1594   else
1595      value &= ~(SC1200_ACTRL_WIN_ENABLE);
1596   WRITE_VID32(address, value);
1597   return (GFX_STATUS_OK);
1598}
1599
1600/*---------------------------------------------------------------------------
1601 * gfx_set_alpha_window
1602 *
1603 * This routine sets the size of the currently selected alpha region.
1604 * Note: "x" and "y" are signed to enable using negative values needed for
1605 * implementing workarounds of hardware issues.
1606 *---------------------------------------------------------------------------
1607 */
1608#if GFX_VIDEO_DYNAMIC
1609int
1610sc1200_set_alpha_window(short x, short y,
1611			unsigned short width, unsigned short height)
1612#else
1613int
1614gfx_set_alpha_window(short x, short y,
1615		     unsigned short width, unsigned short height)
1616#endif
1617{
1618   unsigned long address = 0;
1619
1620   /* CHECK FOR CLIPPING */
1621
1622   if ((x + width) > gfx_get_hactive())
1623      width = gfx_get_hactive() - x;
1624   if ((y + height) > gfx_get_vactive())
1625      height = gfx_get_vactive() - y;
1626
1627   /* ADJUST POSITIONS */
1628
1629   x += gfx_get_htotal() - gfx_get_hsync_end() - 2;
1630   y += gfx_get_vtotal() - gfx_get_vsync_end() + 1;
1631
1632   if (gfx_alpha_select > 2)
1633      return (GFX_STATUS_UNSUPPORTED);
1634   address = SC1200_ALPHA_XPOS_1 + ((unsigned long)gfx_alpha_select << 4);
1635
1636   /* End positions in register are non-inclusive (one more than the actual end) */
1637
1638   WRITE_VID32(address, (unsigned long)x |
1639	       ((unsigned long)(x + width) << 16));
1640   WRITE_VID32(address + 4l, (unsigned long)y |
1641	       ((unsigned long)(y + height) << 16));
1642   return (GFX_STATUS_OK);
1643}
1644
1645/*---------------------------------------------------------------------------
1646 * gfx_set_alpha_value
1647 *
1648 * This routine sets the alpha value for the currently selected alpha
1649 * region.  It also specifies an increment/decrement value for fading.
1650 *---------------------------------------------------------------------------
1651 */
1652#if GFX_VIDEO_DYNAMIC
1653int
1654sc1200_set_alpha_value(unsigned char alpha, char delta)
1655#else
1656int
1657gfx_set_alpha_value(unsigned char alpha, char delta)
1658#endif
1659{
1660   unsigned long address = 0, value = 0;
1661   unsigned char new_value = 0;
1662   int loop = 1;
1663
1664   if (gfx_alpha_select > 2)
1665      return (GFX_STATUS_UNSUPPORTED);
1666   address = SC1200_ALPHA_CONTROL_1 + ((unsigned long)gfx_alpha_select << 4);
1667   value = READ_VID32(address);
1668   value &= SC1200_ACTRL_WIN_ENABLE;	/* keep only enable bit */
1669   value |= (unsigned long)alpha;
1670   value |= (((unsigned long)delta) & 0xff) << 8;
1671   value |= SC1200_ACTRL_LOAD_ALPHA;
1672   WRITE_VID32(address, value);
1673
1674   /* WORKAROUND FOR ISSUE #1187 */
1675   /* Need to verify that the alpha operation succeeded */
1676
1677   while (1) {
1678      /* WAIT FOR VERTICAL BLANK TO END */
1679      if (gfx_test_timing_active()) {
1680	 if (gfx_test_vertical_active())
1681	    while (gfx_test_vertical_active()) ;
1682	 while (!gfx_test_vertical_active()) ;
1683      }
1684      new_value =
1685	    (unsigned
1686	     char)((READ_VID32(SC1200_ALPHA_WATCH) >> (gfx_alpha_select << 3))
1687		   & 0xff);
1688      if (new_value == alpha)
1689	 return GFX_STATUS_OK;
1690      if (++loop > 10)
1691	 return GFX_STATUS_ERROR;
1692      WRITE_VID32(address, value);
1693   }
1694}
1695
1696/*---------------------------------------------------------------------------
1697 * gfx_set_alpha_priority
1698 *
1699 * This routine sets the priority of the currently selected alpha region.
1700 * A higher value indicates a higher priority.
1701 * Note: Priority of enabled alpha windows must be different.
1702 *---------------------------------------------------------------------------
1703 */
1704#if GFX_VIDEO_DYNAMIC
1705int
1706sc1200_set_alpha_priority(int priority)
1707#else
1708int
1709gfx_set_alpha_priority(int priority)
1710#endif
1711{
1712   unsigned long pos = 0, value = 0;
1713
1714   if (priority > 3)
1715      return (GFX_STATUS_BAD_PARAMETER);
1716   if (gfx_alpha_select > 2)
1717      return (GFX_STATUS_UNSUPPORTED);
1718   value = READ_VID32(SC1200_VID_ALPHA_CONTROL);
1719   pos = 16 + (gfx_alpha_select << 1);
1720   value &= ~(0x03l << pos);
1721   value |= (unsigned long)priority << pos;
1722   WRITE_VID32(SC1200_VID_ALPHA_CONTROL, value);
1723   return (GFX_STATUS_OK);
1724}
1725
1726/*---------------------------------------------------------------------------
1727 * gfx_set_alpha_color
1728 *
1729 * This routine sets the color to be displayed inside the currently selected
1730 * alpha window when there is a color key match (when the alpha color
1731 * mechanism is enabled).
1732 * "color" is a 24 bit RGB value (for RGB blending) or YUV value (for YUV blending).
1733 * In Interlaced YUV blending mode, Y/2 value should be used.
1734 *---------------------------------------------------------------------------
1735 */
1736#if GFX_VIDEO_DYNAMIC
1737int
1738sc1200_set_alpha_color(unsigned long color)
1739#else
1740int
1741gfx_set_alpha_color(unsigned long color)
1742#endif
1743{
1744   unsigned long address = 0;
1745
1746   if (gfx_alpha_select > 2)
1747      return (GFX_STATUS_UNSUPPORTED);
1748   address = SC1200_ALPHA_COLOR_1 + ((unsigned long)gfx_alpha_select << 4);
1749
1750   /* ONLY 24 VALID BITS */
1751   color &= 0xffffffl;
1752
1753   /* KEEP UPPER BYTE UNCHANGED */
1754   WRITE_VID32(address, (color | (READ_VID32(address) & ~0xffffffl)));
1755   return (GFX_STATUS_OK);
1756}
1757
1758/*---------------------------------------------------------------------------
1759 * gfx_set_alpha_color_enable
1760 *
1761 * Enable or disable the color mechanism in the alpha window.
1762 *---------------------------------------------------------------------------
1763 */
1764#if GFX_VIDEO_DYNAMIC
1765int
1766sc1200_set_alpha_color_enable(int enable)
1767#else
1768int
1769gfx_set_alpha_color_enable(int enable)
1770#endif
1771{
1772   unsigned long color;
1773   unsigned long address = 0;
1774
1775   if (gfx_alpha_select > 2)
1776      return (GFX_STATUS_UNSUPPORTED);
1777   address = SC1200_ALPHA_COLOR_1 + ((unsigned long)gfx_alpha_select << 4);
1778   color = READ_VID32(address);
1779   if (enable)
1780      color |= SC1200_ALPHA_COLOR_ENABLE;
1781   else
1782      color &= ~SC1200_ALPHA_COLOR_ENABLE;
1783   WRITE_VID32(address, color);
1784   return (GFX_STATUS_OK);
1785}
1786
1787/*---------------------------------------------------------------------------
1788 * gfx_set_no_ck_outside_alpha
1789 *
1790 * This function affects where inside the video window color key or chroma
1791 * key comparison is done:
1792 * If enable is TRUE, color/chroma key comparison is performed only inside
1793 * the enabled alpha windows. Outside the (enabled) alpha windows, only video
1794 * is displayed if color key is used, and only graphics is displayed if chroma
1795 * key is used.
1796 * If enable is FALSE, color/chroma key comparison is performed in all the
1797 * video window area.
1798 *---------------------------------------------------------------------------
1799 */
1800#if GFX_VIDEO_DYNAMIC
1801int
1802sc1200_set_no_ck_outside_alpha(int enable)
1803#else
1804int
1805gfx_set_no_ck_outside_alpha(int enable)
1806#endif
1807{
1808   unsigned long value;
1809
1810   value = READ_VID32(SC1200_VID_ALPHA_CONTROL);
1811   if (enable)
1812      WRITE_VID32(SC1200_VID_ALPHA_CONTROL,
1813		  value | SC1200_NO_CK_OUTSIDE_ALPHA);
1814   else
1815      WRITE_VID32(SC1200_VID_ALPHA_CONTROL,
1816		  value & ~SC1200_NO_CK_OUTSIDE_ALPHA);
1817   return (0);
1818}
1819
1820/*---------------------------------------------------------------------------
1821 * gfx_set_macrovision_enable
1822 *
1823 * This routine enables or disables macrovision on the tv encoder output.
1824 *---------------------------------------------------------------------------
1825 */
1826#if GFX_VIDEO_DYNAMIC
1827int
1828sc1200_set_macrovision_enable(int enable)
1829#else
1830int
1831gfx_set_macrovision_enable(int enable)
1832#endif
1833{
1834   if (enable)
1835      WRITE_VID32(SC1200_TVENC_MV_CONTROL, SC1200_TVENC_MV_ENABLE);
1836   else
1837      WRITE_VID32(SC1200_TVENC_MV_CONTROL, 0);
1838   return (GFX_STATUS_OK);
1839}
1840
1841#define SC1200_VIDEO_PCI_44 0x80009444
1842
1843/*---------------------------------------------------------------------------
1844 * gfx_disable_softvga
1845 *
1846 * Disables SoftVga. This function is only valid with VSA2, Returns 1 if
1847 * SoftVga can be disabled; 0 if not.
1848 *---------------------------------------------------------------------------
1849 */
1850#if GFX_VIDEO_DYNAMIC
1851int
1852sc1200_disable_softvga(void)
1853#else
1854int
1855gfx_disable_softvga(void)
1856#endif
1857{
1858   unsigned long reg_val;
1859
1860   /* get the current value */
1861   reg_val = gfx_pci_config_read(SC1200_VIDEO_PCI_44);
1862   /* setting video PCI register 44 bit 0 to 1 disables SoftVga */
1863   reg_val |= 0x1;
1864   gfx_pci_config_write(SC1200_VIDEO_PCI_44, reg_val);
1865
1866   /* see if we set the bit and return the appropriate value */
1867   reg_val = gfx_pci_config_read(SC1200_VIDEO_PCI_44);
1868   if ((reg_val & 0x1) == 0x1)
1869      return (1);
1870   else
1871      return (0);
1872}
1873
1874/*---------------------------------------------------------------------------
1875 * gfx_enable_softvga
1876 *
1877 * Enables SoftVga. This function is only valid with VSA2, Returns 1 if
1878 * SoftVga can be enbled; 0 if not.
1879 *---------------------------------------------------------------------------
1880 */
1881#if GFX_VIDEO_DYNAMIC
1882int
1883sc1200_enable_softvga(void)
1884#else
1885int
1886gfx_enable_softvga(void)
1887#endif
1888{
1889   unsigned long reg_val;
1890
1891   /* get the current value */
1892   reg_val = gfx_pci_config_read(SC1200_VIDEO_PCI_44);
1893   /* clearing video PCI register 44 bit 0 enables SoftVga */
1894   gfx_pci_config_write(SC1200_VIDEO_PCI_44, reg_val & 0xfffffffel);
1895
1896   /* see if we cleared the bit and return the appropriate value */
1897   reg_val = gfx_pci_config_read(SC1200_VIDEO_PCI_44);
1898   if ((reg_val & 0x1) == 0)
1899      return (1);
1900   else
1901      return (0);
1902}
1903
1904/*---------------------------------------------------------------------------
1905 * gfx_get_clock_frequency
1906 *
1907 * This routine returns the current clock frequency in 16.16 format.
1908 * It reads the current register value and finds the match in the table.
1909 * If no match is found, this routine returns 0.
1910 *---------------------------------------------------------------------------
1911 */
1912#if GFX_VIDEO_DYNAMIC
1913unsigned long
1914sc1200_get_clock_frequency(void)
1915#else
1916unsigned long
1917gfx_get_clock_frequency(void)
1918#endif
1919{
1920   unsigned int index;
1921   unsigned long value, mask;
1922
1923   mask = 0x007FFF0F;
1924   value = READ_VID32(SC1200_VID_CLOCK_SELECT) & mask;
1925   for (index = 0; index < NUM_SC1200_FREQUENCIES; index++) {
1926      if ((gfx_sc1200_clock_table[index].clock_select & mask) == value)
1927	 return (gfx_sc1200_clock_table[index].frequency);
1928   }
1929   return (0);
1930}
1931
1932/*************************************************************/
1933/*  READ ROUTINES  |  INCLUDED FOR DIAGNOSTIC PURPOSES ONLY  */
1934/*************************************************************/
1935
1936#if GFX_READ_ROUTINES
1937
1938/*---------------------------------------------------------------------------
1939 * gfx_get_vsa2_softvga_enable
1940 *
1941 * This function returns the enable status of SoftVGA.  It is valid
1942 * only if VSAII is present.
1943 *---------------------------------------------------------------------------
1944 */
1945#if GFX_VIDEO_DYNAMIC
1946int
1947sc1200_get_vsa2_softvga_enable(void)
1948#else
1949int
1950gfx_get_vsa2_softvga_enable(void)
1951#endif
1952{
1953   unsigned long reg_val;
1954
1955   reg_val = gfx_pci_config_read(SC1200_VIDEO_PCI_44);
1956   if ((reg_val & 0x1) == 0)
1957      return (1);
1958   else
1959      return (0);
1960
1961}
1962
1963/*---------------------------------------------------------------------------
1964 * gfx_get_sync_polarities
1965 *
1966 * This routine returns the polarities of the sync pulses:
1967 *     Bit 0: Set if negative horizontal polarity.
1968 *     Bit 1: Set if negative vertical polarity.
1969 *---------------------------------------------------------------------------
1970 */
1971#if GFX_VIDEO_DYNAMIC
1972int
1973sc1200_get_sync_polarities(void)
1974#else
1975int
1976gfx_get_sync_polarities(void)
1977#endif
1978{
1979   int polarities = 0;
1980
1981   if (READ_VID32(SC1200_DISPLAY_CONFIG) & SC1200_DCFG_CRT_HSYNC_POL)
1982      polarities |= 1;
1983   if (READ_VID32(SC1200_DISPLAY_CONFIG) & SC1200_DCFG_CRT_VSYNC_POL)
1984      polarities |= 2;
1985   return (polarities);
1986}
1987
1988/*---------------------------------------------------------------------------
1989 * gfx_get_video_palette_entry
1990 *
1991 * This routine returns a single palette entry.
1992 *---------------------------------------------------------------------------
1993 */
1994#if GFX_VIDEO_DYNAMIC
1995int
1996sc1200_get_video_palette_entry(unsigned long index, unsigned long *palette)
1997#else
1998int
1999gfx_get_video_palette_entry(unsigned long index, unsigned long *palette)
2000#endif
2001{
2002   if (index > 0xFF)
2003      return GFX_STATUS_BAD_PARAMETER;
2004
2005   /* READ A SINGLE ENTRY */
2006
2007   WRITE_VID32(SC1200_PALETTE_ADDRESS, index);
2008   *palette = READ_VID32(SC1200_PALETTE_DATA);
2009
2010   return (GFX_STATUS_OK);
2011}
2012
2013/*-----------------------------------------------------------------------------
2014 * gfx_get_video_enable
2015 *
2016 * This routine returns the value "one" if video overlay is currently enabled,
2017 * otherwise it returns the value "zero".
2018 *-----------------------------------------------------------------------------
2019 */
2020#if GFX_VIDEO_DYNAMIC
2021int
2022sc1200_get_video_enable(void)
2023#else
2024int
2025gfx_get_video_enable(void)
2026#endif
2027{
2028   if (READ_VID32(SC1200_VIDEO_CONFIG) & SC1200_VCFG_VID_EN)
2029      return (1);
2030   return (0);
2031}
2032
2033/*-----------------------------------------------------------------------------
2034 * gfx_get_video_format
2035 *
2036 * This routine returns the current video overlay format.
2037 *-----------------------------------------------------------------------------
2038 */
2039#if GFX_VIDEO_DYNAMIC
2040int
2041sc1200_get_video_format(void)
2042#else
2043int
2044gfx_get_video_format(void)
2045#endif
2046{
2047   unsigned long ctrl, vcfg;
2048
2049   ctrl = READ_VID32(SC1200_VID_ALPHA_CONTROL);
2050   vcfg = READ_VID32(SC1200_VIDEO_CONFIG);
2051
2052   if (ctrl & SC1200_VIDEO_INPUT_IS_RGB) {
2053      switch (vcfg & SC1200_VCFG_VID_INP_FORMAT) {
2054      case SC1200_VCFG_UYVY_FORMAT:
2055	 return VIDEO_FORMAT_RGB;
2056      case SC1200_VCFG_Y2YU_FORMAT:
2057	 return VIDEO_FORMAT_P2M_P2L_P1M_P1L;
2058      case SC1200_VCFG_YUYV_FORMAT:
2059	 return VIDEO_FORMAT_P1M_P1L_P2M_P2L;
2060      case SC1200_VCFG_YVYU_FORMAT:
2061	 return VIDEO_FORMAT_P1M_P2L_P2M_P1L;
2062      }
2063   }
2064
2065   if (vcfg & SC1200_VCFG_4_2_0_MODE) {
2066      switch (vcfg & SC1200_VCFG_VID_INP_FORMAT) {
2067      case SC1200_VCFG_UYVY_FORMAT:
2068	 return VIDEO_FORMAT_Y0Y1Y2Y3;
2069      case SC1200_VCFG_Y2YU_FORMAT:
2070	 return VIDEO_FORMAT_Y3Y2Y1Y0;
2071      case SC1200_VCFG_YUYV_FORMAT:
2072	 return VIDEO_FORMAT_Y1Y0Y3Y2;
2073      case SC1200_VCFG_YVYU_FORMAT:
2074	 return VIDEO_FORMAT_Y1Y2Y3Y0;
2075      }
2076   } else {
2077      switch (vcfg & SC1200_VCFG_VID_INP_FORMAT) {
2078      case SC1200_VCFG_UYVY_FORMAT:
2079	 return VIDEO_FORMAT_UYVY;
2080      case SC1200_VCFG_Y2YU_FORMAT:
2081	 return VIDEO_FORMAT_Y2YU;
2082      case SC1200_VCFG_YUYV_FORMAT:
2083	 return VIDEO_FORMAT_YUYV;
2084      case SC1200_VCFG_YVYU_FORMAT:
2085	 return VIDEO_FORMAT_YVYU;
2086      }
2087   }
2088   return (GFX_STATUS_ERROR);
2089}
2090
2091/*-----------------------------------------------------------------------------
2092 * gfx_get_video_src_size
2093 *
2094 * This routine returns the size of the source video overlay buffer.  The
2095 * return value is (height << 16) | width.
2096 *-----------------------------------------------------------------------------
2097 */
2098#if GFX_VIDEO_DYNAMIC
2099unsigned long
2100sc1200_get_video_src_size(void)
2101#else
2102unsigned long
2103gfx_get_video_src_size(void)
2104#endif
2105{
2106   unsigned long width = 0, height = 0;
2107
2108   /* DETERMINE SOURCE WIDTH FROM THE SC1200 VIDEO LINE SIZE */
2109
2110   width = (READ_VID32(SC1200_VIDEO_CONFIG) >> 7) & 0x000001FE;
2111   if (READ_VID32(SC1200_VIDEO_CONFIG) & SC1200_VCFG_LINE_SIZE_UPPER)
2112      width += 512l;
2113
2114   if (width) {
2115      /* DETERMINE HEIGHT BY DIVIDING TOTAL SIZE BY WIDTH */
2116      /* Get total size from display controller - abtracted. */
2117
2118      height = gfx_get_display_video_size() / (width << 1);
2119   }
2120   return ((height << 16) | width);
2121}
2122
2123/*-----------------------------------------------------------------------------
2124 * gfx_get_video_line_size
2125 *
2126 * This routine returns the line size of the source video overlay buffer, in
2127 * pixels.
2128 *-----------------------------------------------------------------------------
2129 */
2130#if GFX_VIDEO_DYNAMIC
2131unsigned long
2132sc1200_get_video_line_size(void)
2133#else
2134unsigned long
2135gfx_get_video_line_size(void)
2136#endif
2137{
2138   unsigned long width = 0;
2139
2140   /* DETERMINE SOURCE WIDTH FROM THE SC1200 VIDEO LINE SIZE */
2141
2142   width = (READ_VID32(SC1200_VIDEO_CONFIG) >> 7) & 0x000001FE;
2143   if (READ_VID32(SC1200_VIDEO_CONFIG) & SC1200_VCFG_LINE_SIZE_UPPER)
2144      width += 512l;
2145   return (width);
2146}
2147
2148/*-----------------------------------------------------------------------------
2149 * gfx_get_video_xclip
2150 *
2151 * This routine returns the number of bytes clipped on the left side of a
2152 * video overlay line (skipped at beginning).
2153 *-----------------------------------------------------------------------------
2154 */
2155#if GFX_VIDEO_DYNAMIC
2156unsigned long
2157sc1200_get_video_xclip(void)
2158#else
2159unsigned long
2160gfx_get_video_xclip(void)
2161#endif
2162{
2163   unsigned long clip = 0;
2164
2165   /* DETERMINE SOURCE WIDTH FROM THE SC1200 VIDEO LINE SIZE */
2166
2167   clip = (READ_VID32(SC1200_VIDEO_CONFIG) >> 14) & 0x000007FC;
2168   return (clip);
2169}
2170
2171/*-----------------------------------------------------------------------------
2172 * gfx_get_video_offset
2173 *
2174 * This routine returns the current offset for the video overlay buffer.
2175 *-----------------------------------------------------------------------------
2176 */
2177#if GFX_VIDEO_DYNAMIC
2178unsigned long
2179sc1200_get_video_offset(void)
2180#else
2181unsigned long
2182gfx_get_video_offset(void)
2183#endif
2184{
2185   return (gfx_get_display_video_offset());
2186}
2187
2188/*---------------------------------------------------------------------------
2189 * gfx_get_video_upscale
2190 *
2191 * This routine returns the scale factor for the video overlay window.
2192 *---------------------------------------------------------------------------
2193 */
2194#if GFX_VIDEO_DYNAMIC
2195unsigned long
2196sc1200_get_video_upscale(void)
2197#else
2198unsigned long
2199gfx_get_video_upscale(void)
2200#endif
2201{
2202   return (READ_VID32(SC1200_VIDEO_UPSCALE));
2203}
2204
2205/*---------------------------------------------------------------------------
2206 * gfx_get_video_scale
2207 *
2208 * This routine returns the scale factor for the video overlay window.
2209 *---------------------------------------------------------------------------
2210 */
2211#if GFX_VIDEO_DYNAMIC
2212unsigned long
2213sc1200_get_video_scale(void)
2214#else
2215unsigned long
2216gfx_get_video_scale(void)
2217#endif
2218{
2219   return gfx_get_video_upscale();
2220}
2221
2222/*---------------------------------------------------------------------------
2223 * gfx_get_video_downscale_config
2224 *
2225 * This routine returns the current type and value of video downscaling.
2226 *---------------------------------------------------------------------------
2227 */
2228#if GFX_VIDEO_DYNAMIC
2229int
2230sc1200_get_video_downscale_config(unsigned short *type, unsigned short *m)
2231#else
2232int
2233gfx_get_video_downscale_config(unsigned short *type, unsigned short *m)
2234#endif
2235{
2236   unsigned long downscale;
2237
2238   downscale = READ_VID32(SC1200_VIDEO_DOWNSCALER_CONTROL);
2239   *m = (unsigned short)((downscale & SC1200_VIDEO_DOWNSCALE_FACTOR_MASK) >>
2240			 SC1200_VIDEO_DOWNSCALE_FACTOR_POS) + 1;
2241
2242   switch (downscale & SC1200_VIDEO_DOWNSCALE_TYPE_MASK) {
2243   case SC1200_VIDEO_DOWNSCALE_TYPE_A:
2244      *type = VIDEO_DOWNSCALE_KEEP_1_OF;
2245      break;
2246   case SC1200_VIDEO_DOWNSCALE_TYPE_B:
2247      *type = VIDEO_DOWNSCALE_DROP_1_OF;
2248      break;
2249   default:
2250      return GFX_STATUS_ERROR;
2251      break;
2252   }
2253   return (0);
2254}
2255
2256/*---------------------------------------------------------------------------
2257 * gfx_get_video_downscale_coefficients
2258 *
2259 * This routine returns the current video downscaling coefficients.
2260 *---------------------------------------------------------------------------
2261 */
2262#if GFX_VIDEO_DYNAMIC
2263void
2264sc1200_get_video_downscale_coefficients(unsigned short *coef1,
2265					unsigned short *coef2,
2266					unsigned short *coef3,
2267					unsigned short *coef4)
2268#else
2269void
2270gfx_get_video_downscale_coefficients(unsigned short *coef1,
2271				     unsigned short *coef2,
2272				     unsigned short *coef3,
2273				     unsigned short *coef4)
2274#endif
2275{
2276   unsigned long coef;
2277
2278   coef = READ_VID32(SC1200_VIDEO_DOWNSCALER_COEFFICIENTS);
2279   *coef1 =
2280	 (unsigned short)((coef >> SC1200_VIDEO_DOWNSCALER_COEF1_POS) &
2281			  SC1200_VIDEO_DOWNSCALER_COEF_MASK);
2282   *coef2 =
2283	 (unsigned short)((coef >> SC1200_VIDEO_DOWNSCALER_COEF2_POS) &
2284			  SC1200_VIDEO_DOWNSCALER_COEF_MASK);
2285   *coef3 =
2286	 (unsigned short)((coef >> SC1200_VIDEO_DOWNSCALER_COEF3_POS) &
2287			  SC1200_VIDEO_DOWNSCALER_COEF_MASK);
2288   *coef4 =
2289	 (unsigned short)((coef >> SC1200_VIDEO_DOWNSCALER_COEF4_POS) &
2290			  SC1200_VIDEO_DOWNSCALER_COEF_MASK);
2291   return;
2292}
2293
2294/*---------------------------------------------------------------------------
2295 * gfx_get_video_downscale_enable
2296 *
2297 * This routine returns 1 if video downscaling is currently enabled,
2298 * or 0 if it is currently disabled.
2299 *---------------------------------------------------------------------------
2300 */
2301#if GFX_VIDEO_DYNAMIC
2302void
2303sc1200_get_video_downscale_enable(int *enable)
2304#else
2305void
2306gfx_get_video_downscale_enable(int *enable)
2307#endif
2308{
2309   if (READ_VID32(SC1200_VIDEO_DOWNSCALER_CONTROL) &
2310       SC1200_VIDEO_DOWNSCALE_ENABLE)
2311      *enable = 1;
2312   else
2313      *enable = 0;
2314   return;
2315}
2316
2317/*---------------------------------------------------------------------------
2318 * gfx_get_video_dst_size
2319 *
2320 * This routine returns the size of the displayed video overlay window.
2321 *---------------------------------------------------------------------------
2322 */
2323#if GFX_VIDEO_DYNAMIC
2324unsigned long
2325sc1200_get_video_dst_size(void)
2326#else
2327unsigned long
2328gfx_get_video_dst_size(void)
2329#endif
2330{
2331   unsigned long xsize, ysize;
2332
2333   xsize = READ_VID32(SC1200_VIDEO_X_POS);
2334   xsize = ((xsize >> 16) & 0x7FF) - (xsize & 0x7FF);
2335   ysize = READ_VID32(SC1200_VIDEO_Y_POS);
2336   ysize = ((ysize >> 16) & 0x7FF) - (ysize & 0x7FF);
2337   return ((ysize << 16) | xsize);
2338}
2339
2340/*---------------------------------------------------------------------------
2341 * gfx_get_video_position
2342 *
2343 * This routine returns the position of the video overlay window.  The
2344 * return value is (ypos << 16) | xpos.
2345 *---------------------------------------------------------------------------
2346 */
2347#if GFX_VIDEO_DYNAMIC
2348unsigned long
2349sc1200_get_video_position(void)
2350#else
2351unsigned long
2352gfx_get_video_position(void)
2353#endif
2354{
2355   unsigned long hadjust, vadjust;
2356   unsigned long xpos, ypos;
2357
2358   /* READ HARDWARE POSITION */
2359
2360   xpos = READ_VID32(SC1200_VIDEO_X_POS) & 0x000007FF;
2361   ypos = READ_VID32(SC1200_VIDEO_Y_POS) & 0x000007FF;
2362
2363   /* GET ADJUSTMENT VALUES */
2364   /* Use routines to abstract version of display controller. */
2365
2366   hadjust =
2367	 (unsigned long)gfx_get_htotal() -
2368	 (unsigned long)gfx_get_hsync_end() - 14l;
2369   vadjust =
2370	 (unsigned long)gfx_get_vtotal() -
2371	 (unsigned long)gfx_get_vsync_end() + 1l;
2372   xpos -= hadjust;
2373   ypos -= vadjust;
2374   return ((ypos << 16) | (xpos & 0x0000FFFF));
2375}
2376
2377/*---------------------------------------------------------------------------
2378 * gfx_get_video_color_key
2379 *
2380 * This routine returns the current video color key value.
2381 *---------------------------------------------------------------------------
2382 */
2383#if GFX_VIDEO_DYNAMIC
2384unsigned long
2385sc1200_get_video_color_key(void)
2386#else
2387unsigned long
2388gfx_get_video_color_key(void)
2389#endif
2390{
2391   return (READ_VID32(SC1200_VIDEO_COLOR_KEY));
2392}
2393
2394/*---------------------------------------------------------------------------
2395 * gfx_get_video_color_key_mask
2396 *
2397 * This routine returns the current video color mask value.
2398 *---------------------------------------------------------------------------
2399 */
2400#if GFX_VIDEO_DYNAMIC
2401unsigned long
2402sc1200_get_video_color_key_mask(void)
2403#else
2404unsigned long
2405gfx_get_video_color_key_mask(void)
2406#endif
2407{
2408   return (READ_VID32(SC1200_VIDEO_COLOR_MASK));
2409}
2410
2411/*---------------------------------------------------------------------------
2412 * gfx_get_video_color_key_src
2413 *
2414 * This routine returns 0 for video data compare, 1 for graphics data.
2415 *---------------------------------------------------------------------------
2416 */
2417#if GFX_VIDEO_DYNAMIC
2418int
2419sc1200_get_video_color_key_src(void)
2420#else
2421int
2422gfx_get_video_color_key_src(void)
2423#endif
2424{
2425   if (READ_VID32(SC1200_DISPLAY_CONFIG) & SC1200_DCFG_VG_CK)
2426      return (0);
2427   return (1);
2428}
2429
2430/*---------------------------------------------------------------------------
2431 * gfx_get_video_filter
2432 *
2433 * This routine returns if the filters are currently enabled.
2434 *---------------------------------------------------------------------------
2435 */
2436#if GFX_VIDEO_DYNAMIC
2437int
2438sc1200_get_video_filter(void)
2439#else
2440int
2441gfx_get_video_filter(void)
2442#endif
2443{
2444   int retval = 0;
2445
2446   if (READ_VID32(SC1200_VIDEO_CONFIG) & SC1200_VCFG_X_FILTER_EN)
2447      retval |= 1;
2448   if (READ_VID32(SC1200_VIDEO_CONFIG) & SC1200_VCFG_Y_FILTER_EN)
2449      retval |= 2;
2450   return (retval);
2451}
2452
2453/*---------------------------------------------------------------------------
2454 * gfx_get_video_request
2455 *
2456 * This routine returns the horizontal (pixel) and vertical (lines) video
2457 * request values.
2458 *---------------------------------------------------------------------------
2459 */
2460#if GFX_VIDEO_DYNAMIC
2461int
2462sc1200_get_video_request(short *x, short *y)
2463#else
2464int
2465gfx_get_video_request(short *x, short *y)
2466#endif
2467{
2468   int request = 0;
2469
2470   request = (int)(READ_VID32(SC1200_VIDEO_REQUEST));
2471   *x = (request >> SC1200_VIDEO_X_REQUEST_POS) & SC1200_VIDEO_REQUEST_MASK;
2472   *y = (request >> SC1200_VIDEO_Y_REQUEST_POS) & SC1200_VIDEO_REQUEST_MASK;
2473
2474   *x -= gfx_get_htotal() - gfx_get_hsync_end() - 2;
2475   *y -= gfx_get_vtotal() - gfx_get_vsync_end() + 1;
2476
2477   return (0);
2478}
2479
2480/*---------------------------------------------------------------------------
2481 * gfx_get_video_source
2482 *
2483 * This routine returns the current video source.
2484 *---------------------------------------------------------------------------
2485 */
2486#if GFX_VIDEO_DYNAMIC
2487int
2488sc1200_get_video_source(VideoSourceType * source)
2489#else
2490int
2491gfx_get_video_source(VideoSourceType * source)
2492#endif
2493{
2494   switch (READ_VID32(SC1200_VIDEO_DISPLAY_MODE) & SC1200_VIDEO_SOURCE_MASK) {
2495   case SC1200_VIDEO_SOURCE_GX1:
2496      *source = VIDEO_SOURCE_MEMORY;
2497      break;
2498   case SC1200_VIDEO_SOURCE_DVIP:
2499      *source = VIDEO_SOURCE_DVIP;
2500      break;
2501   default:
2502      return GFX_STATUS_ERROR;
2503   }
2504   return (0);
2505}
2506
2507/*---------------------------------------------------------------------------
2508 * gfx_get_vbi_source
2509 *
2510 * This routine returns the current vbi source.
2511 *---------------------------------------------------------------------------
2512 */
2513#if GFX_VIDEO_DYNAMIC
2514int
2515sc1200_get_vbi_source(VbiSourceType * source)
2516#else
2517int
2518gfx_get_vbi_source(VbiSourceType * source)
2519#endif
2520{
2521   switch (READ_VID32(SC1200_VIDEO_DISPLAY_MODE) & SC1200_VBI_SOURCE_MASK) {
2522   case SC1200_VBI_SOURCE_GX1:
2523      *source = VBI_SOURCE_MEMORY;
2524      break;
2525   case SC1200_VBI_SOURCE_DVIP:
2526      *source = VBI_SOURCE_DVIP;
2527      break;
2528   default:
2529      return GFX_STATUS_ERROR;
2530   }
2531   return (0);
2532}
2533
2534/*---------------------------------------------------------------------------
2535 * gfx_get_vbi_lines
2536 *
2537 * This routine returns the VBI lines which are sent to the TV encoder.
2538 *---------------------------------------------------------------------------
2539 */
2540#if GFX_VIDEO_DYNAMIC
2541unsigned long
2542sc1200_get_vbi_lines(int odd)
2543#else
2544unsigned long
2545gfx_get_vbi_lines(int odd)
2546#endif
2547{
2548   if (odd)
2549      return (READ_VID32(SC1200_VIDEO_ODD_VBI_LINE_ENABLE) &
2550	      SC1200_VIDEO_VBI_LINE_ENABLE_MASK);
2551   return (READ_VID32(SC1200_VIDEO_EVEN_VBI_LINE_ENABLE) &
2552	   SC1200_VIDEO_VBI_LINE_ENABLE_MASK);
2553}
2554
2555/*---------------------------------------------------------------------------
2556 * gfx_get_vbi_total
2557 *
2558 * This routine returns the total number of VBI bytes in the field.
2559 *---------------------------------------------------------------------------
2560 */
2561#if GFX_VIDEO_DYNAMIC
2562unsigned long
2563sc1200_get_vbi_total(int odd)
2564#else
2565unsigned long
2566gfx_get_vbi_total(int odd)
2567#endif
2568{
2569   if (odd)
2570      return (READ_VID32(SC1200_VIDEO_ODD_VBI_TOTAL_COUNT) &
2571	      SC1200_VIDEO_VBI_TOTAL_COUNT_MASK);
2572   return (READ_VID32(SC1200_VIDEO_EVEN_VBI_TOTAL_COUNT) &
2573	   SC1200_VIDEO_VBI_TOTAL_COUNT_MASK);
2574}
2575
2576/*---------------------------------------------------------------------------
2577 * gfx_get_video_interlaced()
2578 *
2579 * This routine returns "1" if input video is currently in interlaced mode.
2580 * "0" otherwise.
2581 *---------------------------------------------------------------------------
2582 */
2583#if GFX_VIDEO_DYNAMIC
2584int
2585sc1200_get_video_interlaced(void)
2586#else
2587int
2588gfx_get_video_interlaced(void)
2589#endif
2590{
2591   if (READ_VID32(SC1200_VID_ALPHA_CONTROL) & SC1200_VIDEO_IS_INTERLACED)
2592      return (1);
2593   else
2594      return (0);
2595}
2596
2597/*---------------------------------------------------------------------------
2598 * gfx_get_color_space_YUV()
2599 *
2600 * This routine returns "1" if video processor color space mode is currently
2601 * YUV. "0" otherwise.
2602 *---------------------------------------------------------------------------
2603 */
2604#if GFX_VIDEO_DYNAMIC
2605int
2606sc1200_get_color_space_YUV(void)
2607#else
2608int
2609gfx_get_color_space_YUV(void)
2610#endif
2611{
2612   unsigned long control;
2613
2614   control = READ_VID32(SC1200_VID_ALPHA_CONTROL);
2615
2616   /* IS SC1200 VIDEO COLOR SPACE RGB OR CONVERTED TO RGB */
2617   if ((control & SC1200_VIDEO_INPUT_IS_RGB)
2618       || (control & SC1200_CSC_VIDEO_YUV_TO_RGB))
2619      return (0);
2620   else
2621      return (1);
2622}
2623
2624/*---------------------------------------------------------------------------
2625 * gfx_get_vertical_scaler_offset()
2626 *
2627 * This routine sets "offset" to the value by which odd frames are shifted,
2628 * if insert is enabled, and to 0 if no shifting occurs.
2629 *---------------------------------------------------------------------------
2630 */
2631#if GFX_VIDEO_DYNAMIC
2632int
2633sc1200_get_vertical_scaler_offset(char *offset)
2634#else
2635int
2636gfx_get_vertical_scaler_offset(char *offset)
2637#endif
2638{
2639   unsigned long control;
2640
2641   control = READ_VID32(SC1200_VID_ALPHA_CONTROL);
2642   if (control & SC1200_VERTICAL_SCALER_SHIFT_EN) {
2643      if ((control & SC1200_VERTICAL_SCALER_SHIFT_MASK) ==
2644	  SC1200_VERTICAL_SCALER_SHIFT_INIT)
2645	 *offset = 1;
2646      else
2647	 return GFX_STATUS_ERROR;	/* TODO: find the interpretation of other values */
2648   } else
2649      *offset = 0;
2650   return (0);
2651}
2652
2653/*---------------------------------------------------------------------------
2654 * gfx_get_genlock_delay
2655 *
2656 * This routine returns the genlock delay in 27 MHz clocks.
2657 *---------------------------------------------------------------------------
2658 */
2659#if GFX_VIDEO_DYNAMIC
2660unsigned long
2661sc1200_get_genlock_delay(void)
2662#else
2663unsigned long
2664gfx_get_genlock_delay(void)
2665#endif
2666{
2667   return (READ_VID32(SC1200_GENLOCK_DELAY) & SC1200_GENLOCK_DELAY_MASK);
2668}
2669
2670/*---------------------------------------------------------------------------
2671 * gfx_get_genlock_enable
2672 *
2673 * This routine returns "1" if genlock is currently enabled, "0" otherwise.
2674 *---------------------------------------------------------------------------
2675 */
2676#if GFX_VIDEO_DYNAMIC
2677int
2678sc1200_get_genlock_enable(void)
2679#else
2680int
2681gfx_get_genlock_enable(void)
2682#endif
2683{
2684   if (READ_VID32(SC1200_GENLOCK) &
2685       (SC1200_GENLOCK_SINGLE_ENABLE | SC1200_GENLOCK_CONTINUOUS_ENABLE))
2686      return (1);
2687   else
2688      return (0);
2689}
2690
2691/*---------------------------------------------------------------------------
2692 * gfx_get_video_cursor()
2693 *
2694 * This routine configures the video hardware cursor.
2695 * If the "mask"ed bits in the graphics pixel match "key", then either "color1"
2696 * or "color2" will be used for this pixel, according to the value of the bit
2697 * in offset "select_color2".
2698 *---------------------------------------------------------------------------
2699 */
2700#if GFX_VIDEO_DYNAMIC
2701int
2702sc1200_get_video_cursor(unsigned long *key, unsigned long *mask,
2703			unsigned short *select_color2, unsigned long *color1,
2704			unsigned short *color2)
2705#else
2706int
2707gfx_get_video_cursor(unsigned long *key, unsigned long *mask,
2708		     unsigned short *select_color2, unsigned long *color1,
2709		     unsigned short *color2)
2710#endif
2711{
2712   *select_color2 =
2713	 (unsigned short)(READ_VID32(SC1200_CURSOR_COLOR_KEY) >>
2714			  SC1200_CURSOR_COLOR_KEY_OFFSET_POS);
2715   *key = READ_VID32(SC1200_CURSOR_COLOR_KEY) & SC1200_COLOR_MASK;
2716   *mask = READ_VID32(SC1200_CURSOR_COLOR_MASK) & SC1200_COLOR_MASK;
2717   *color1 = READ_VID32(SC1200_CURSOR_COLOR_1) & SC1200_COLOR_MASK;
2718   *color2 =
2719	 (unsigned short)(READ_VID32(SC1200_CURSOR_COLOR_2) &
2720			  SC1200_COLOR_MASK);
2721   return (0);
2722}
2723
2724/*---------------------------------------------------------------------------
2725 * gfx_read_crc
2726 *
2727 * This routine returns the hardware CRC value, which is used for automated
2728 * testing.  The value is like a checksum, but will change if pixels move
2729 * locations.
2730 *---------------------------------------------------------------------------
2731 */
2732#if GFX_VIDEO_DYNAMIC
2733unsigned long
2734sc1200_read_crc(void)
2735#else
2736unsigned long
2737gfx_read_crc(void)
2738#endif
2739{
2740   unsigned long crc = 0xFFFFFFFF;
2741
2742   if (gfx_test_timing_active()) {
2743      /* WAIT UNTIL ACTIVE DISPLAY */
2744
2745      while (!gfx_test_vertical_active()) ;
2746
2747      /* RESET CRC DURING ACTIVE DISPLAY */
2748
2749      WRITE_VID32(SC1200_VID_CRC, 0);
2750      WRITE_VID32(SC1200_VID_CRC, 1);
2751
2752      /* WAIT UNTIL NOT ACTIVE, THEN ACTIVE, NOT ACTIVE, THEN ACTIVE */
2753
2754      while (gfx_test_vertical_active()) ;
2755      while (!gfx_test_vertical_active()) ;
2756      while (gfx_test_vertical_active()) ;
2757      while (!gfx_test_vertical_active()) ;
2758      crc = READ_VID32(SC1200_VID_CRC) >> 8;
2759   }
2760   return (crc);
2761}
2762
2763/*-----------------------------------------------------------------------------
2764 * gfx_get_macrovision_enable
2765 *
2766 * This routine returns the value "one" if macrovision currently enabled in the
2767 * TV encoder, otherwise it returns the value "zero".
2768 *-----------------------------------------------------------------------------
2769 */
2770#if GFX_VIDEO_DYNAMIC
2771int
2772sc1200_get_macrovision_enable(void)
2773#else
2774int
2775gfx_get_macrovision_enable(void)
2776#endif
2777{
2778   if (READ_VID32(SC1200_TVENC_MV_CONTROL) == SC1200_TVENC_MV_ENABLE)
2779      return (1);
2780   return (0);
2781}
2782
2783/*---------------------------------------------------------------------------
2784 * gfx_get_alpha_enable
2785 *
2786 * This routine returns 1 if the selected alpha window is currently
2787 * enabled, or 0 if it is currently disabled.
2788 *---------------------------------------------------------------------------
2789 */
2790#if GFX_VIDEO_DYNAMIC
2791void
2792sc1200_get_alpha_enable(int *enable)
2793#else
2794void
2795gfx_get_alpha_enable(int *enable)
2796#endif
2797{
2798   unsigned long value = 0;
2799
2800   *enable = 0;
2801   if (gfx_alpha_select <= 2) {
2802      value =
2803	    READ_VID32(SC1200_ALPHA_CONTROL_1 +
2804		       ((unsigned long)gfx_alpha_select << 4));
2805      if (value & SC1200_ACTRL_WIN_ENABLE)
2806	 *enable = 1;
2807   }
2808   return;
2809}
2810
2811/*---------------------------------------------------------------------------
2812 * gfx_get_alpha_size
2813 *
2814 * This routine returns the size of the currently selected alpha region.
2815 *---------------------------------------------------------------------------
2816 */
2817#if GFX_VIDEO_DYNAMIC
2818void
2819sc1200_get_alpha_size(unsigned short *x, unsigned short *y,
2820		      unsigned short *width, unsigned short *height)
2821#else
2822void
2823gfx_get_alpha_size(unsigned short *x, unsigned short *y,
2824		   unsigned short *width, unsigned short *height)
2825#endif
2826{
2827   unsigned long value = 0;
2828
2829   *x = 0;
2830   *y = 0;
2831   *width = 0;
2832   *height = 0;
2833   if (gfx_alpha_select <= 2) {
2834      value =
2835	    READ_VID32(SC1200_ALPHA_XPOS_1 +
2836		       ((unsigned long)gfx_alpha_select << 4));
2837      *x = (unsigned short)(value & 0x000007FF);
2838      *width = (unsigned short)((value >> 16) & 0x000007FF) - *x;
2839      value =
2840	    READ_VID32(SC1200_ALPHA_YPOS_1 +
2841		       ((unsigned long)gfx_alpha_select << 4));
2842      *y = (unsigned short)(value & 0x000007FF);
2843      *height = (unsigned short)((value >> 16) & 0x000007FF) - *y;
2844   }
2845   *x -= gfx_get_htotal() - gfx_get_hsync_end() - 2;
2846   *y -= gfx_get_vtotal() - gfx_get_vsync_end() + 1;
2847   return;
2848}
2849
2850/*---------------------------------------------------------------------------
2851 * gfx_get_alpha_value
2852 *
2853 * This routine returns the alpha value and increment/decrement value of
2854 * the currently selected alpha region.
2855 *---------------------------------------------------------------------------
2856 */
2857#if GFX_VIDEO_DYNAMIC
2858void
2859sc1200_get_alpha_value(unsigned char *alpha, char *delta)
2860#else
2861void
2862gfx_get_alpha_value(unsigned char *alpha, char *delta)
2863#endif
2864{
2865   unsigned long value = 0;
2866
2867   *alpha = 0;
2868   *delta = 0;
2869   if (gfx_alpha_select <= 2) {
2870      value =
2871	    READ_VID32(SC1200_ALPHA_CONTROL_1 +
2872		       ((unsigned long)gfx_alpha_select << 4));
2873      *alpha = (unsigned char)(value & 0x00FF);
2874      *delta = (char)((value >> 8) & 0x00FF);
2875   }
2876   return;
2877}
2878
2879/*---------------------------------------------------------------------------
2880 * gfx_get_alpha_priority
2881 *
2882 * This routine returns the priority of the currently selected alpha region.
2883 *---------------------------------------------------------------------------
2884 */
2885#if GFX_VIDEO_DYNAMIC
2886void
2887sc1200_get_alpha_priority(int *priority)
2888#else
2889void
2890gfx_get_alpha_priority(int *priority)
2891#endif
2892{
2893   unsigned long pos = 0, value = 0;
2894
2895   *priority = 0;
2896   if (gfx_alpha_select <= 2) {
2897      value = READ_VID32(SC1200_VID_ALPHA_CONTROL);
2898      pos = 16 + (gfx_alpha_select << 1);
2899      *priority = (int)((value >> pos) & 3);
2900   }
2901   return;
2902}
2903
2904/*---------------------------------------------------------------------------
2905 * gfx_get_alpha_color
2906 *
2907 * This routine returns the color register value for the currently selected
2908 * alpha region.  Bit 24 is set if the color register is enabled.
2909 *---------------------------------------------------------------------------
2910 */
2911#if GFX_VIDEO_DYNAMIC
2912void
2913sc1200_get_alpha_color(unsigned long *color)
2914#else
2915void
2916gfx_get_alpha_color(unsigned long *color)
2917#endif
2918{
2919   *color = 0;
2920   if (gfx_alpha_select <= 2) {
2921      *color =
2922	    READ_VID32(SC1200_ALPHA_COLOR_1 +
2923		       ((unsigned long)gfx_alpha_select << 4));
2924   }
2925   return;
2926}
2927
2928#endif /* GFX_READ_ROUTINES */
2929
2930/* END OF FILE */
2931