diff options
Diffstat (limited to 'src/gfx/vid_1200.c')
-rw-r--r-- | src/gfx/vid_1200.c | 2930 |
1 files changed, 2930 insertions, 0 deletions
diff --git a/src/gfx/vid_1200.c b/src/gfx/vid_1200.c new file mode 100644 index 0000000..f52d02b --- /dev/null +++ b/src/gfx/vid_1200.c @@ -0,0 +1,2930 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/vid_1200.c,v 1.2 2003/01/14 09:34:34 alanh Exp $ */ +/* + * $Workfile: vid_1200.c $ + * + * This file contains routines to control the SC1200 video overlay hardware. + * + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Durango + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for Durango + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for Durango + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +/*---------------------------------------------------------------------------- + * SC1200 PLL TABLE + *---------------------------------------------------------------------------- + */ + +typedef struct tagSC1200PLL +{ + long frequency; /* 16.16 fixed point frequency */ + unsigned long clock_select; /* clock select register (0x2C) */ +} +SC1200PLL; + +SC1200PLL gfx_sc1200_clock_table[] = { + {(25L << 16) | ((1750L * 65536L) / 10000L), 0x0070E00C}, /* 25.1750 (sc=24.9231) */ + {(27L << 16) | ((0000L * 65536L) / 10000L), 0x00300100}, /* 27.0000 */ + {(28L << 16) | ((3220L * 65536L) / 10000L), 0x0070EC0C}, /* 28.3220 (SC=27.000) */ + {(31L << 16) | ((5000L * 65536L) / 10000L), 0x00500D02}, /* 31.5000 */ + {(36L << 16) | ((0000L * 65536L) / 10000L), 0x00500F02}, /* 36.0000 */ + {(37L << 16) | ((5000L * 65536L) / 10000L), 0x0050B108}, /* 37.5000 */ + {(40L << 16) | ((0000L * 65536L) / 10000L), 0x0050D20D}, /* 40.0000 */ + {(44L << 16) | ((9000L * 65536L) / 10000L), 0x0050DC0D}, /* 44.9000 */ + {(49L << 16) | ((5000L * 65536L) / 10000L), 0x00501502}, /* 49.5000 */ + {(50L << 16) | ((0000L * 65536L) / 10000L), 0x0050A404}, /* 50.0000 */ + {(50L << 16) | ((3500L * 65536L) / 10000L), 0x0050E00C}, /* 50.3500 */ + {(54L << 16) | ((0000L * 65536L) / 10000L), 0x00300300}, /* 54.0000 */ + {(56L << 16) | ((3916L * 65536L) / 10000L), 0x0050F40D}, /* 56.3916 */ + {(56L << 16) | ((6440L * 65536L) / 10000L), 0x0050EC0C}, /* 56.6440 */ + {(59L << 16) | ((0000L * 65536L) / 10000L), 0x0030A207}, /* 59.0000 */ + {(63L << 16) | ((0000L * 65536L) / 10000L), 0x00300D02}, /* 63.0000 */ + {(65L << 16) | ((0000L * 65536L) / 10000L), 0x0030CC0F}, /* 65.0000 */ + {(67L << 16) | ((5000L * 65536L) / 10000L), 0x00300400}, /* 67.5000 */ + {(70L << 16) | ((8000L * 65536L) / 10000L), 0x00301403}, /* 70.8000 */ + {(72L << 16) | ((0000L * 65536L) / 10000L), 0x00300F02}, /* 72.0000 */ + {(75L << 16) | ((0000L * 65536L) / 10000L), 0x0030B108}, /* 75.0000 */ + {(78L << 16) | ((7500L * 65536L) / 10000L), 0x0030A205}, /* 78.7500 */ + {(80L << 16) | ((0000L * 65536L) / 10000L), 0x0030D20D}, /* 80.0000 */ + {(87L << 16) | ((2728L * 65536L) / 10000L), 0x0030E00E}, /* 87.2728 */ + {(89L << 16) | ((8000L * 65536L) / 10000L), 0x0030DC0D}, /* 89.8000 */ + {(94L << 16) | ((5000L * 65536L) / 10000L), 0x00300600}, /* 99.0000 */ + {(99L << 16) | ((0000L * 65536L) / 10000L), 0x00301502}, /* 99.0000 */ + {(100L << 16) | ((0000L * 65536L) / 10000L), 0x0030A404}, /* 100.00 */ + {(108L << 16) | ((0000L * 65536L) / 10000L), 0x00100300}, /* 108.00 */ + {(112L << 16) | ((5000L * 65536L) / 10000L), 0x00301802}, /* 108.00 */ + {(130L << 16) | ((0000L * 65536L) / 10000L), 0x0010CC0F}, /* 130.00 */ + {(135L << 16) | ((0000L * 65536L) / 10000L), 0x00100400}, /* 135.00 */ + {(157L << 16) | ((5000L * 65536L) / 10000L), 0x0010A205}, /* 157.50 */ + {(162L << 16) | ((0000L * 65536L) / 10000L), 0x00100500}, /* 162.00 */ + {(175L << 16) | ((0000L * 65536L) / 10000L), 0x0010E00E}, /* 175.50 */ + {(189L << 16) | ((0000L * 65536L) / 10000L), 0x00100600}, /* 189.00 */ + {(202L << 16) | ((0000L * 65536L) / 10000L), 0x0010EF0E}, /* 202.50 */ + {(232L << 16) | ((0000L * 65536L) / 10000L), 0x0010AA04}, /* 232.50 */ + + /* Precomputed inidces in the hardware */ + {0x0018EC4D, 0x000F0000}, /* 24.923052 */ + {0x00192CCC, 0x00000000}, /* 25.1750 */ + {0x001B0000, 0x00300100}, /* 27.0000 */ + {0x001F8000, 0x00010000}, /* 31.5000 */ + {0x00240000, 0x00020000}, /* 36.0000 */ + {0x00280000, 0x00030000}, /* 40.0000 */ + {0x00318000, 0x00050000}, /* 49.5000 */ + {0x00320000, 0x00040000}, /* 50.0000 */ + {0x00384000, 0x00060000}, /* 56.2500 */ + {0x00410000, 0x00080000}, /* 65.0000 */ + {0x004E8000, 0x000A0000}, /* 78.5000 */ + {0x005E8000, 0x000B0000}, /* 94.5000 */ + {0x006C0000, 0x000C0000}, /* 108.0000 */ + {0x00870000, 0x000D0000}, /* 135.0000 */ +}; + +#define NUM_SC1200_FREQUENCIES sizeof(gfx_sc1200_clock_table)/sizeof(SC1200PLL) + +int sc1200_set_video_enable(int enable); +int sc1200_set_video_format(unsigned long format); +int sc1200_set_video_size(unsigned short width, unsigned short height); +int sc1200_set_video_yuv_pitch(unsigned long ypitch, unsigned long uvpitch); +int sc1200_set_video_offset(unsigned long offset); +int sc1200_set_video_yuv_offsets(unsigned long yoffset, unsigned long uoffset, + unsigned long voffset); +int sc1200_set_video_window(short x, short y, unsigned short w, + unsigned short h); +int sc1200_set_video_left_crop(unsigned short x); +int sc1200_set_video_upscale(unsigned short srcw, unsigned short srch, + unsigned short dstw, unsigned short dsth); +int sc1200_set_video_scale(unsigned short srcw, unsigned short srch, + unsigned short dstw, unsigned short dsth); +int sc1200_set_video_vertical_downscale(unsigned short srch, + unsigned short dsth); +void sc1200_set_video_vertical_downscale_enable(int enable); +int sc1200_set_video_downscale_config(unsigned short type, unsigned short m); +int sc1200_set_video_color_key(unsigned long key, unsigned long mask, + int bluescreen); +int sc1200_set_video_filter(int xfilter, int yfilter); +int sc1200_set_video_palette(unsigned long *palette); +int sc1200_set_video_palette_entry(unsigned long index, unsigned long color); +int sc1200_set_video_downscale_coefficients(unsigned short coef1, + unsigned short coef2, + unsigned short coef3, + unsigned short coef4); +int sc1200_set_video_downscale_enable(int enable); +int sc1200_set_video_source(VideoSourceType source); +int sc1200_set_vbi_source(VbiSourceType source); +int sc1200_set_vbi_lines(unsigned long even, unsigned long odd); +int sc1200_set_vbi_total(unsigned long even, unsigned long odd); +int sc1200_set_video_interlaced(int enable); +int sc1200_set_color_space_YUV(int enable); +int sc1200_set_vertical_scaler_offset(char offset); +int sc1200_set_top_line_in_odd(int enable); +int sc1200_set_genlock_delay(unsigned long delay); +int sc1200_set_genlock_enable(int flags); +int sc1200_set_video_cursor(unsigned long key, unsigned long mask, + unsigned short select_color2, + unsigned long color1, unsigned long color2); +int sc1200_set_video_cursor_enable(int enable); +int sc1200_set_video_request(short x, short y); + +int sc1200_select_alpha_region(int region); +int sc1200_set_alpha_enable(int enable); +int sc1200_set_alpha_window(short x, short y, + unsigned short width, unsigned short height); +int sc1200_set_alpha_value(unsigned char alpha, char delta); +int sc1200_set_alpha_priority(int priority); +int sc1200_set_alpha_color(unsigned long color); +int sc1200_set_alpha_color_enable(int enable); +int sc1200_set_no_ck_outside_alpha(int enable); +int sc1200_disable_softvga(void); +int sc1200_enable_softvga(void); +int sc1200_set_macrovision_enable(int enable); +void sc1200_reset_video(void); +int sc1200_set_display_control(int sync_polarities); +void sc1200_set_clock_frequency(unsigned long frequency); +int sc1200_set_screen_enable(int enable); +int sc1200_set_crt_enable(int enable); + +/* READ ROUTINES IN GFX_VID.C */ + +int sc1200_get_video_enable(void); +int sc1200_get_video_format(void); +unsigned long sc1200_get_video_src_size(void); +unsigned long sc1200_get_video_line_size(void); +unsigned long sc1200_get_video_xclip(void); +unsigned long sc1200_get_video_offset(void); +void sc1200_get_video_yuv_offsets(unsigned long *yoffset, + unsigned long *uoffset, + unsigned long *voffset); +void sc1200_get_video_yuv_pitch(unsigned long *ypitch, + unsigned long *uvpitch); +unsigned long sc1200_get_video_upscale(void); +unsigned long sc1200_get_video_scale(void); +unsigned long sc1200_get_video_downscale_delta(void); +int sc1200_get_video_vertical_downscale_enable(void); +int sc1200_get_video_downscale_config(unsigned short *type, + unsigned short *m); +void sc1200_get_video_downscale_coefficients(unsigned short *coef1, + unsigned short *coef2, + unsigned short *coef3, + unsigned short *coef4); +void sc1200_get_video_downscale_enable(int *enable); +unsigned long sc1200_get_video_dst_size(void); +unsigned long sc1200_get_video_position(void); +unsigned long sc1200_get_video_color_key(void); +unsigned long sc1200_get_video_color_key_mask(void); +int sc1200_get_video_palette_entry(unsigned long index, + unsigned long *palette); +int sc1200_get_video_color_key_src(void); +int sc1200_get_video_filter(void); +int sc1200_get_video_request(short *x, short *y); +int sc1200_get_video_source(VideoSourceType * source); +int sc1200_get_vbi_source(VbiSourceType * source); +unsigned long sc1200_get_vbi_lines(int odd); +unsigned long sc1200_get_vbi_total(int odd); +int sc1200_get_video_interlaced(void); +int sc1200_get_color_space_YUV(void); +int sc1200_get_vertical_scaler_offset(char *offset); +unsigned long sc1200_get_genlock_delay(void); +int sc1200_get_genlock_enable(void); +int sc1200_get_video_cursor(unsigned long *key, unsigned long *mask, + unsigned short *select_color2, + unsigned long *color1, unsigned short *color2); +unsigned long sc1200_read_crc(void); +unsigned long sc1200_read_crc32(void); +unsigned long sc1200_read_window_crc(int source, unsigned short x, + unsigned short y, unsigned short width, + unsigned short height, int crc32); +int sc1200_get_macrovision_enable(void); + +void sc1200_get_alpha_enable(int *enable); +void sc1200_get_alpha_size(unsigned short *x, unsigned short *y, + unsigned short *width, unsigned short *height); +void sc1200_get_alpha_value(unsigned char *alpha, char *delta); +void sc1200_get_alpha_priority(int *priority); +void sc1200_get_alpha_color(unsigned long *color); +unsigned long sc1200_get_clock_frequency(void); +int sc1200_get_vsa2_softvga_enable(void); +int sc1200_get_sync_polarities(void); + +/*--------------------------------------------------------------------------- + * gfx_reset_video (PRIVATE ROUTINE: NOT PART OF DURANGO API) + * + * This routine is used to disable all components of video overlay before + * performing a mode switch. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +void +sc1200_reset_video(void) +#else +void +gfx_reset_video(void) +#endif +{ + int i; + + gfx_set_video_enable(0); + + /* SET WINDOW 0 AFTER RESET */ + + for (i = 2; i >= 0; i--) { + gfx_select_alpha_region(i); + gfx_set_alpha_enable(0); + gfx_set_alpha_color_enable(0); + } +} + +/*----------------------------------------------------------------------------- + * gfx_set_display_control (PRIVATE ROUTINE: NOT PART OF DURANGO API) + * + * This routine configures the display output. + * + * "sync_polarities" is used to set the polarities of the sync pulses according + * to the following mask: + * + * Bit 0: If set to 1, negative horizontal polarity is programmed, + * otherwise positive horizontal polarity is programmed. + * Bit 1: If set to 1, negative vertical polarity is programmed, + * otherwise positive vertical polarity is programmed. + * + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_display_control(int sync_polarities) +#else +int +gfx_set_display_control(int sync_polarities) +#endif +{ + unsigned long dcfg; + + /* CONFIGURE DISPLAY OUTPUT FROM VIDEO PROCESSOR */ + + dcfg = READ_VID32(SC1200_DISPLAY_CONFIG); + dcfg &= ~(SC1200_DCFG_CRT_SYNC_SKW_MASK | SC1200_DCFG_PWR_SEQ_DLY_MASK | + SC1200_DCFG_CRT_HSYNC_POL | SC1200_DCFG_CRT_VSYNC_POL | + SC1200_DCFG_FP_PWR_EN | SC1200_DCFG_FP_DATA_EN); + + dcfg |= (SC1200_DCFG_CRT_SYNC_SKW_INIT | + SC1200_DCFG_PWR_SEQ_DLY_INIT | SC1200_DCFG_GV_PAL_BYP); + + if (PanelEnable) + dcfg |= SC1200_DCFG_FP_PWR_EN; + + /* SET APPROPRIATE SYNC POLARITIES */ + + if (sync_polarities & 0x1) + dcfg |= SC1200_DCFG_CRT_HSYNC_POL; + if (sync_polarities & 0x2) + dcfg |= SC1200_DCFG_CRT_VSYNC_POL; + + WRITE_VID32(SC1200_DISPLAY_CONFIG, dcfg); + + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_clock_frequency + * + * This routine sets the clock frequency, specified as a 16.16 fixed point + * value (0x00318000 = 49.5 MHz). It will set the closest frequency found + * in the lookup table. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +void +sc1200_set_clock_frequency(unsigned long frequency) +#else +void +gfx_set_clock_frequency(unsigned long frequency) +#endif +{ + unsigned int index; + unsigned long value, pll; + long min, diff; + + /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */ + /* Search the table for the closest frequency (16.16 format). */ + + value = gfx_sc1200_clock_table[0].clock_select; + min = (long)gfx_sc1200_clock_table[0].frequency - frequency; + if (min < 0L) + min = -min; + for (index = 1; index < NUM_SC1200_FREQUENCIES; index++) { + diff = (long)gfx_sc1200_clock_table[index].frequency - frequency; + if (diff < 0L) + diff = -diff; + if (diff < min) { + min = diff; + value = gfx_sc1200_clock_table[index].clock_select; + } + } + + /* SET THE DOT CLOCK REGISTER */ + + pll = READ_VID32(SC1200_VID_MISC); + WRITE_VID32(SC1200_VID_MISC, pll | SC1200_PLL_POWER_NORMAL); + WRITE_VID32(SC1200_VID_CLOCK_SELECT, value); + return; +} + +/*--------------------------------------------------------------------------- + * gfx_set_screen_enable (PRIVATE ROUTINE - NOT PART OF API) + * + * This routine enables or disables the graphics display logic of the video processor. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_screen_enable(int enable) +#else +int +gfx_set_screen_enable(int enable) +#endif +{ + unsigned long config; + + config = READ_VID32(SC1200_DISPLAY_CONFIG); + if (enable) + WRITE_VID32(SC1200_DISPLAY_CONFIG, config | SC1200_DCFG_DIS_EN); + else + WRITE_VID32(SC1200_DISPLAY_CONFIG, config & ~SC1200_DCFG_DIS_EN); + return (GFX_STATUS_OK); +} + +/*--------------------------------------------------------------------------- + * gfx_set_crt_enable + * + * This routine enables or disables the CRT output from the video processor. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_crt_enable(int enable) +#else +int +gfx_set_crt_enable(int enable) +#endif +{ + unsigned long config, misc; + + config = READ_VID32(SC1200_DISPLAY_CONFIG); + misc = READ_VID32(SC1200_VID_MISC); + + /* + * IMPORTANT: For all modes do NOT disable the graphics display logic + * because it might be needed for TV + */ + + switch (enable) { + case CRT_DISABLE: /* HSync:Off VSync:Off */ + WRITE_VID32(SC1200_DISPLAY_CONFIG, config & ~(SC1200_DCFG_HSYNC_EN + | SC1200_DCFG_VSYNC_EN + | SC1200_DCFG_DAC_BL_EN)); + WRITE_VID32(SC1200_VID_MISC, misc | SC1200_DAC_POWER_DOWN); + break; + case CRT_ENABLE: /* Enable CRT display, including display logic */ + WRITE_VID32(SC1200_DISPLAY_CONFIG, config | SC1200_DCFG_HSYNC_EN + | SC1200_DCFG_VSYNC_EN | SC1200_DCFG_DAC_BL_EN); + WRITE_VID32(SC1200_VID_MISC, misc & ~SC1200_DAC_POWER_DOWN); + + /* ENABLE GRAPHICS DISPLAY LOGIC */ + gfx_set_screen_enable(1); + break; + case CRT_STANDBY: /* HSync:Off VSync:On */ + WRITE_VID32(SC1200_DISPLAY_CONFIG, (config & ~(SC1200_DCFG_HSYNC_EN + | SC1200_DCFG_DAC_BL_EN)) + | SC1200_DCFG_VSYNC_EN); + WRITE_VID32(SC1200_VID_MISC, misc | SC1200_DAC_POWER_DOWN); + break; + case CRT_SUSPEND: /* HSync:On VSync:Off */ + WRITE_VID32(SC1200_DISPLAY_CONFIG, (config & ~(SC1200_DCFG_VSYNC_EN + | SC1200_DCFG_DAC_BL_EN)) + | SC1200_DCFG_HSYNC_EN); + WRITE_VID32(SC1200_VID_MISC, misc | SC1200_DAC_POWER_DOWN); + break; + default: + return GFX_STATUS_BAD_PARAMETER; + } + return (GFX_STATUS_OK); +} + +/*----------------------------------------------------------------------------- + * gfx_set_video_enable + * + * This routine enables or disables the video overlay functionality. + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_video_enable(int enable) +#else +int +gfx_set_video_enable(int enable) +#endif +{ + unsigned long vcfg; + + /* WAIT FOR VERTICAL BLANK TO START */ + /* Otherwise a glitch can be observed. */ + + if (gfx_test_timing_active()) { + if (!gfx_test_vertical_active()) { + while (!gfx_test_vertical_active()) ; + } + while (gfx_test_vertical_active()) ; + } + + vcfg = READ_VID32(SC1200_VIDEO_CONFIG); + if (enable) { + /* ENABLE VIDEO OVERLAY FROM DISPLAY CONTROLLER */ + /* Use private routine to abstract the display controller. */ + + gfx_set_display_video_enable(1); + + /* ENABLE SC1200 VIDEO OVERLAY */ + + vcfg |= SC1200_VCFG_VID_EN; + WRITE_VID32(SC1200_VIDEO_CONFIG, vcfg); + } else { + /* DISABLE SC1200 VIDEO OVERLAY */ + + vcfg &= ~SC1200_VCFG_VID_EN; + WRITE_VID32(SC1200_VIDEO_CONFIG, vcfg); + + /* DISABLE VIDEO OVERLAY FROM DISPLAY CONTROLLER */ + /* Use private routine to abstract the display controller. */ + + gfx_set_display_video_enable(0); + } + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_video_format + * + * Sets input video format type, to one of the YUV formats or to RGB. + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_video_format(unsigned long format) +#else +int +gfx_set_video_format(unsigned long format) +#endif +{ + unsigned long ctrl, vcfg = 0; + + /* SET THE SC1200 VIDEO INPUT FORMAT */ + + vcfg = READ_VID32(SC1200_VIDEO_CONFIG); + ctrl = READ_VID32(SC1200_VID_ALPHA_CONTROL); + ctrl &= ~(SC1200_VIDEO_INPUT_IS_RGB); + vcfg &= ~(SC1200_VCFG_VID_INP_FORMAT | SC1200_VCFG_4_2_0_MODE); + switch (format) { + case VIDEO_FORMAT_UYVY: + vcfg |= SC1200_VCFG_UYVY_FORMAT; + break; + case VIDEO_FORMAT_YUYV: + vcfg |= SC1200_VCFG_YUYV_FORMAT; + break; + case VIDEO_FORMAT_Y2YU: + vcfg |= SC1200_VCFG_Y2YU_FORMAT; + break; + case VIDEO_FORMAT_YVYU: + vcfg |= SC1200_VCFG_YVYU_FORMAT; + break; + case VIDEO_FORMAT_Y0Y1Y2Y3: + vcfg |= SC1200_VCFG_UYVY_FORMAT; + vcfg |= SC1200_VCFG_4_2_0_MODE; + break; + case VIDEO_FORMAT_Y3Y2Y1Y0: + vcfg |= SC1200_VCFG_Y2YU_FORMAT; + vcfg |= SC1200_VCFG_4_2_0_MODE; + break; + case VIDEO_FORMAT_Y1Y0Y3Y2: + vcfg |= SC1200_VCFG_YUYV_FORMAT; + vcfg |= SC1200_VCFG_4_2_0_MODE; + break; + case VIDEO_FORMAT_Y1Y2Y3Y0: + vcfg |= SC1200_VCFG_YVYU_FORMAT; + vcfg |= SC1200_VCFG_4_2_0_MODE; + break; + case VIDEO_FORMAT_RGB: + ctrl |= SC1200_VIDEO_INPUT_IS_RGB; + vcfg |= SC1200_VCFG_UYVY_FORMAT; + break; + case VIDEO_FORMAT_P2M_P2L_P1M_P1L: + ctrl |= SC1200_VIDEO_INPUT_IS_RGB; + vcfg |= SC1200_VCFG_Y2YU_FORMAT; + break; + case VIDEO_FORMAT_P1M_P1L_P2M_P2L: + ctrl |= SC1200_VIDEO_INPUT_IS_RGB; + vcfg |= SC1200_VCFG_YUYV_FORMAT; + break; + case VIDEO_FORMAT_P1M_P2L_P2M_P1L: + ctrl |= SC1200_VIDEO_INPUT_IS_RGB; + vcfg |= SC1200_VCFG_YVYU_FORMAT; + break; + default: + return GFX_STATUS_BAD_PARAMETER; + } + + /* ALWAYS DISABLE GRAPHICS CSC */ + /* This is enabled in the function gfx_set_color_space_YUV for */ + /* YUV blending on TV. */ + + ctrl &= ~SC1200_CSC_GFX_RGB_TO_YUV; + + if (ctrl & SC1200_VIDEO_INPUT_IS_RGB) + ctrl &= ~SC1200_CSC_VIDEO_YUV_TO_RGB; + else + ctrl |= SC1200_CSC_VIDEO_YUV_TO_RGB; + + WRITE_VID32(SC1200_VIDEO_CONFIG, vcfg); + WRITE_VID32(SC1200_VID_ALPHA_CONTROL, ctrl); + + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_video_size + * + * This routine specifies the size of the source data. It is used only + * to determine how much data to transfer per frame, and is not used to + * calculate the scaling value (that is handled by a separate routine). + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_video_size(unsigned short width, unsigned short height) +#else +int +gfx_set_video_size(unsigned short width, unsigned short height) +#endif +{ + unsigned long size, vcfg; + + /* SET THE SC1200 VIDEO LINE SIZE */ + + vcfg = READ_VID32(SC1200_VIDEO_CONFIG); + vcfg &= ~(SC1200_VCFG_LINE_SIZE_LOWER_MASK | SC1200_VCFG_LINE_SIZE_UPPER); + size = (width >> 1); + vcfg |= (size & 0x00FF) << 8; + if (size & 0x0100) + vcfg |= SC1200_VCFG_LINE_SIZE_UPPER; + WRITE_VID32(SC1200_VIDEO_CONFIG, vcfg); + + /* SET TOTAL VIDEO BUFFER SIZE IN DISPLAY CONTROLLER */ + /* Use private routine to abstract the display controller. */ + + /* Add 1 line to bypass issue #803 */ + gfx_set_display_video_size(width, (unsigned short)(height + 2)); + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_video_offset + * + * This routine sets the starting offset for the video buffer when only + * one offset needs to be specified. + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_video_offset(unsigned long offset) +#else +int +gfx_set_video_offset(unsigned long offset) +#endif +{ + /* SAVE VALUE FOR FUTURE CLIPPING OF THE TOP OF THE VIDEO WINDOW */ + + gfx_vid_offset = offset; + + /* SET VIDEO BUFFER OFFSET IN DISPLAY CONTROLLER */ + /* Use private routine to abstract the display controller. */ + + gfx_set_display_video_offset(offset); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_upscale + * + * This routine sets the scale factor for the video overlay window. The + * size of the source and destination regions are specified in pixels. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_video_upscale(unsigned short srcw, unsigned short srch, + unsigned short dstw, unsigned short dsth) +#else +int +gfx_set_video_upscale(unsigned short srcw, unsigned short srch, + unsigned short dstw, unsigned short dsth) +#endif +{ + unsigned long xscale, yscale; + + /* SAVE PARAMETERS (unless don't-care zero destination arguments are used) */ + /* These are needed for clipping the video window later. */ + + if (dstw != 0) { + gfx_vid_srcw = srcw; + gfx_vid_dstw = dstw; + } + if (dsth != 0) { + gfx_vid_srch = srch; + gfx_vid_dsth = dsth; + } + + /* CALCULATE SC1200 SCALE FACTORS */ + + if (dstw == 0) + xscale = READ_VID32(SC1200_VIDEO_UPSCALE) & 0xffff; /* keep previous if don't-care argument */ + else if (dstw <= srcw) + xscale = 0x2000l; /* horizontal downscaling is currently done in a separate function */ + else if ((srcw == 1) || (dstw == 1)) + return GFX_STATUS_BAD_PARAMETER; + else + xscale = (0x2000l * (srcw - 1l)) / (dstw - 1l); + + if (dsth == 0) + yscale = (READ_VID32(SC1200_VIDEO_UPSCALE) & 0xffff0000) >> 16; /* keep previous if don't-care argument */ + else if (dsth <= srch) + yscale = 0x2000l; /* No vertical downscaling in SC1200 so force to 1x if attempted */ + else if ((srch == 1) || (dsth == 1)) + return GFX_STATUS_BAD_PARAMETER; + else + yscale = (0x2000l * (srch - 1l)) / (dsth - 1l); + + WRITE_VID32(SC1200_VIDEO_UPSCALE, (yscale << 16) | xscale); + + /* CALL ROUTINE TO UPDATE WINDOW POSITION */ + /* This is required because the scale values effect the number of */ + /* source data pixels that need to be clipped, as well as the */ + /* amount of data that needs to be transferred. */ + + gfx_set_video_window(gfx_vid_xpos, gfx_vid_ypos, gfx_vid_width, + gfx_vid_height); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_scale + * + * This routine sets the scale factor for the video overlay window. The + * size of the source and destination regions are specified in pixels. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_video_scale(unsigned short srcw, unsigned short srch, + unsigned short dstw, unsigned short dsth) +#else +int +gfx_set_video_scale(unsigned short srcw, unsigned short srch, + unsigned short dstw, unsigned short dsth) +#endif +{ + return gfx_set_video_upscale(srcw, srch, dstw, dsth); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_downscale_config + * + * This routine sets the downscale type and factor for the video overlay window. + * Note: No downscaling support for RGB565 and YUV420 video formats. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_video_downscale_config(unsigned short type, unsigned short m) +#else +int +gfx_set_video_downscale_config(unsigned short type, unsigned short m) +#endif +{ + unsigned long downscale; + + if ((m < 1) || (m > 16)) + return GFX_STATUS_BAD_PARAMETER; + + downscale = READ_VID32(SC1200_VIDEO_DOWNSCALER_CONTROL); + downscale &= + ~(SC1200_VIDEO_DOWNSCALE_FACTOR_MASK | + SC1200_VIDEO_DOWNSCALE_TYPE_MASK); + downscale |= ((m - 1l) << SC1200_VIDEO_DOWNSCALE_FACTOR_POS); + switch (type) { + case VIDEO_DOWNSCALE_KEEP_1_OF: + downscale |= SC1200_VIDEO_DOWNSCALE_TYPE_A; + break; + case VIDEO_DOWNSCALE_DROP_1_OF: + downscale |= SC1200_VIDEO_DOWNSCALE_TYPE_B; + break; + default: + return GFX_STATUS_BAD_PARAMETER; + } + WRITE_VID32(SC1200_VIDEO_DOWNSCALER_CONTROL, downscale); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_downscale_coefficients + * + * This routine sets the downscale filter coefficients. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_video_downscale_coefficients(unsigned short coef1, + unsigned short coef2, + unsigned short coef3, + unsigned short coef4) +#else +int +gfx_set_video_downscale_coefficients(unsigned short coef1, + unsigned short coef2, + unsigned short coef3, + unsigned short coef4) +#endif +{ + if ((coef1 + coef2 + coef3 + coef4) != 16) + return GFX_STATUS_BAD_PARAMETER; + + WRITE_VID32(SC1200_VIDEO_DOWNSCALER_COEFFICIENTS, + ((unsigned long)coef1 << SC1200_VIDEO_DOWNSCALER_COEF1_POS) | + ((unsigned long)coef2 << SC1200_VIDEO_DOWNSCALER_COEF2_POS) | + ((unsigned long)coef3 << SC1200_VIDEO_DOWNSCALER_COEF3_POS) | + ((unsigned long)coef4 << SC1200_VIDEO_DOWNSCALER_COEF4_POS)); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_downscale_enable + * + * This routine enables or disables downscaling for the video overlay window. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_video_downscale_enable(int enable) +#else +int +gfx_set_video_downscale_enable(int enable) +#endif +{ + unsigned long downscale; + + downscale = READ_VID32(SC1200_VIDEO_DOWNSCALER_CONTROL); + downscale &= ~SC1200_VIDEO_DOWNSCALE_ENABLE; + if (enable) + downscale |= SC1200_VIDEO_DOWNSCALE_ENABLE; + WRITE_VID32(SC1200_VIDEO_DOWNSCALER_CONTROL, downscale); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_window + * + * This routine sets the position and size of the video overlay window. The + * y position is specified in screen relative coordinates, and may be negative. + * The size of destination region is specified in pixels. The line size + * indicates the number of bytes of source data per scanline. + * For the effect of negative x values, call the function + * gfx_set_video_left_crop(). + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_video_window(short x, short y, unsigned short w, unsigned short h) +#else +int +gfx_set_video_window(short x, short y, unsigned short w, unsigned short h) +#endif +{ + unsigned long control; + unsigned long hadjust, vadjust; + unsigned long xstart, ystart, xend, yend; + + /* For left cropping call the function gfx_set_video_left_crop() */ + + if (x < 0) + return GFX_STATUS_BAD_PARAMETER; + + /* SAVE PARAMETERS */ + /* These are needed to call this routine if the scale value changes. */ + /* In the case of SC1200 they are also needed for restoring when video is re-enabled */ + + gfx_vid_xpos = x; + gfx_vid_ypos = y; + gfx_vid_width = w; + gfx_vid_height = h; + + /* GET ADJUSTMENT VALUES */ + /* Use routines to abstract version of display controller. */ + + hadjust = gfx_get_htotal() - gfx_get_hsync_end() - 14l; + vadjust = gfx_get_vtotal() - gfx_get_vsync_end() + 1l; + + /* HORIZONTAL START */ + + xstart = (unsigned long)x + hadjust; + + /* HORIZONTAL END */ + /* End positions in register are non-inclusive (one more than the actual end) */ + + if ((x + w) < gfx_get_hactive()) + xend = (unsigned long)x + (unsigned long)w + hadjust; + else /* right clipping needed */ + xend = (unsigned long)gfx_get_hactive() + hadjust; + + /* VERTICAL START */ + + ystart = (unsigned long)y + vadjust; + + /* VERTICAL END */ + + if ((y + h) < gfx_get_vactive()) + yend = (unsigned long)y + (unsigned long)h + vadjust; + else /* bottom clipping needed */ + yend = (unsigned long)gfx_get_vactive() + vadjust; + + /* SET VIDEO LINE INVERT BIT */ + + control = READ_VID32(SC1200_VID_ALPHA_CONTROL); + if (y & 0x1) + WRITE_VID32(SC1200_VID_ALPHA_CONTROL, + control | SC1200_VIDEO_LINE_OFFSET_ODD); + else + WRITE_VID32(SC1200_VID_ALPHA_CONTROL, + control & ~SC1200_VIDEO_LINE_OFFSET_ODD); + + /* SET VIDEO POSITION */ + + WRITE_VID32(SC1200_VIDEO_X_POS, (xend << 16) | xstart); + WRITE_VID32(SC1200_VIDEO_Y_POS, (yend << 16) | ystart); + + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_left_crop + * + * This routine sets the number of pixels which will be cropped from the + * beginning of each video line. The video window will begin to display only + * from the pixel following the cropped pixels, and the cropped pixels + * will be ignored. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_video_left_crop(unsigned short x) +#else +int +gfx_set_video_left_crop(unsigned short x) +#endif +{ + unsigned long vcfg, initread; + + /* CLIPPING ON LEFT */ + /* Adjust initial read for scale, checking for divide by zero */ + + if (gfx_vid_dstw) + initread = (unsigned long)x *gfx_vid_srcw / gfx_vid_dstw; + + else + initread = 0l; + + /* SET INITIAL READ ADDRESS */ + + vcfg = READ_VID32(SC1200_VIDEO_CONFIG); + vcfg &= ~SC1200_VCFG_INIT_READ_MASK; + vcfg |= (initread << 15) & SC1200_VCFG_INIT_READ_MASK; + WRITE_VID32(SC1200_VIDEO_CONFIG, vcfg); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_color_key + * + * This routine specifies the color key value and mask for the video overlay + * hardware. To disable color key, the color and mask should both be set to + * zero. The hardware uses the color key in the following equation: + * + * ((source data) & (color key mask)) == ((color key) & (color key mask)) + * + * If "graphics" is set to TRUE, the source data is graphics, and color key + * is an RGB value. If "graphics" is set to FALSE, the source data is the video, + * and color key is a YUV value. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_video_color_key(unsigned long key, unsigned long mask, + int graphics) +#else +int +gfx_set_video_color_key(unsigned long key, unsigned long mask, int graphics) +#endif +{ + unsigned long dcfg = 0; + + /* SET SC1200 COLOR KEY VALUE */ + + WRITE_VID32(SC1200_VIDEO_COLOR_KEY, key); + WRITE_VID32(SC1200_VIDEO_COLOR_MASK, mask); + + /* SELECT GRAPHICS OR VIDEO DATA TO COMPARE TO THE COLOR KEY */ + + dcfg = READ_VID32(SC1200_DISPLAY_CONFIG); + if (graphics & 0x01) + dcfg &= ~SC1200_DCFG_VG_CK; + else + dcfg |= SC1200_DCFG_VG_CK; + WRITE_VID32(SC1200_DISPLAY_CONFIG, dcfg); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_filter + * + * This routine enables or disables the video overlay filters. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_video_filter(int xfilter, int yfilter) +#else +int +gfx_set_video_filter(int xfilter, int yfilter) +#endif +{ + unsigned long vcfg = 0; + + /* ENABLE OR DISABLE SC1200 VIDEO OVERLAY FILTERS */ + + vcfg = READ_VID32(SC1200_VIDEO_CONFIG); + vcfg &= ~(SC1200_VCFG_X_FILTER_EN | SC1200_VCFG_Y_FILTER_EN); + if (xfilter) + vcfg |= SC1200_VCFG_X_FILTER_EN; + if (yfilter) + vcfg |= SC1200_VCFG_Y_FILTER_EN; + WRITE_VID32(SC1200_VIDEO_CONFIG, vcfg); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_palette + * + * This routine loads the video hardware palette. If a NULL pointer is + * specified, the palette is bypassed (for SC1200, this means loading the + * palette with identity values). + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_video_palette(unsigned long *palette) +#else +int +gfx_set_video_palette(unsigned long *palette) +#endif +{ + unsigned long i, entry; + + /* WAIT FOR VERTICAL BLANK TO END */ + /* Otherwise palette will not be written properly. */ + + if (gfx_test_timing_active()) { + if (gfx_test_vertical_active()) { + while (gfx_test_vertical_active()) ; + } + while (!gfx_test_vertical_active()) ; + } + + /* LOAD SC1200 VIDEO PALETTE */ + + WRITE_VID32(SC1200_PALETTE_ADDRESS, 0); + for (i = 0; i < 256; i++) { + if (palette) + entry = palette[i]; + else + entry = (i << 8) | (i << 16) | (i << 24); + WRITE_VID32(SC1200_PALETTE_DATA, entry); + } + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_palette_entry + * + * This routine loads a single entry of the video hardware palette. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_video_palette_entry(unsigned long index, unsigned long palette) +#else +int +gfx_set_video_palette_entry(unsigned long index, unsigned long palette) +#endif +{ + if (index > 0xFF) + return GFX_STATUS_BAD_PARAMETER; + + /* WAIT FOR VERTICAL BLANK TO END */ + /* Otherwise palette will not be written properly. */ + + if (gfx_test_timing_active()) { + if (gfx_test_vertical_active()) { + while (gfx_test_vertical_active()) ; + } + while (!gfx_test_vertical_active()) ; + } + + /* SET A SINGLE ENTRY */ + + WRITE_VID32(SC1200_PALETTE_ADDRESS, index); + WRITE_VID32(SC1200_PALETTE_DATA, palette); + + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_request() + * + * This routine sets the horizontal (pixel) and vertical (line) video request + * values. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_video_request(short x, short y) +#else +int +gfx_set_video_request(short x, short y) +#endif +{ + /* SET SC1200 VIDEO REQUEST */ + + x += gfx_get_htotal() - gfx_get_hsync_end() - 2; + y += gfx_get_vtotal() - gfx_get_vsync_end() + 1; + + if ((x < 0) || (x > SC1200_VIDEO_REQUEST_MASK) || + (y < 0) || (y > SC1200_VIDEO_REQUEST_MASK)) + return GFX_STATUS_BAD_PARAMETER; + + WRITE_VID32(SC1200_VIDEO_REQUEST, + ((unsigned long)x << SC1200_VIDEO_X_REQUEST_POS) | + ((unsigned long)y << SC1200_VIDEO_Y_REQUEST_POS)); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_source() + * + * This routine sets the video source to either memory or Direct VIP. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_video_source(VideoSourceType source) +#else +int +gfx_set_video_source(VideoSourceType source) +#endif +{ + unsigned long display_mode; + + display_mode = READ_VID32(SC1200_VIDEO_DISPLAY_MODE); + + /* SET SC1200 VIDEO SOURCE */ + switch (source) { + case VIDEO_SOURCE_MEMORY: + WRITE_VID32(SC1200_VIDEO_DISPLAY_MODE, + (display_mode & ~SC1200_VIDEO_SOURCE_MASK) | + SC1200_VIDEO_SOURCE_GX1); + break; + case VIDEO_SOURCE_DVIP: + WRITE_VID32(SC1200_VIDEO_DISPLAY_MODE, + (display_mode & ~SC1200_VIDEO_SOURCE_MASK) | + SC1200_VIDEO_SOURCE_DVIP); + break; + default: + return GFX_STATUS_BAD_PARAMETER; + } + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_vbi_source() + * + * This routine sets the vbi source to either memory or Direct VIP. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_vbi_source(VbiSourceType source) +#else +int +gfx_set_vbi_source(VbiSourceType source) +#endif +{ + unsigned long display_mode; + + display_mode = READ_VID32(SC1200_VIDEO_DISPLAY_MODE); + + /* SET SC1200 VBI SOURCE */ + switch (source) { + case VBI_SOURCE_MEMORY: + WRITE_VID32(SC1200_VIDEO_DISPLAY_MODE, + (display_mode & ~SC1200_VBI_SOURCE_MASK) | + SC1200_VBI_SOURCE_GX1); + break; + case VBI_SOURCE_DVIP: + WRITE_VID32(SC1200_VIDEO_DISPLAY_MODE, + (display_mode & ~SC1200_VBI_SOURCE_MASK) | + SC1200_VBI_SOURCE_DVIP); + break; + default: + return GFX_STATUS_BAD_PARAMETER; + } + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_vbi_lines() + * + * This routine sets the VBI lines to pass to the TV encoder. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_vbi_lines(unsigned long even, unsigned long odd) +#else +int +gfx_set_vbi_lines(unsigned long even, unsigned long odd) +#endif +{ + /* SET SC1200 VBI LINES */ + WRITE_VID32(SC1200_VIDEO_EVEN_VBI_LINE_ENABLE, + even & SC1200_VIDEO_VBI_LINE_ENABLE_MASK); + WRITE_VID32(SC1200_VIDEO_ODD_VBI_LINE_ENABLE, + odd & SC1200_VIDEO_VBI_LINE_ENABLE_MASK); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_vbi_total() + * + * This routine sets the total number of VBI bytes for each field. + * The total is needed when both VBI and active video are received from memory. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_vbi_total(unsigned long even, unsigned long odd) +#else +int +gfx_set_vbi_total(unsigned long even, unsigned long odd) +#endif +{ + /* SET SC1200 VBI TOTAL */ + WRITE_VID32(SC1200_VIDEO_EVEN_VBI_TOTAL_COUNT, + even & SC1200_VIDEO_VBI_TOTAL_COUNT_MASK); + WRITE_VID32(SC1200_VIDEO_ODD_VBI_TOTAL_COUNT, + odd & SC1200_VIDEO_VBI_TOTAL_COUNT_MASK); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_interlaced() + * + * This routine configures the video processor video overlay mode to be + * interlaced YUV. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_video_interlaced(int enable) +#else +int +gfx_set_video_interlaced(int enable) +#endif +{ + unsigned long control; + + control = READ_VID32(SC1200_VID_ALPHA_CONTROL); + /* SET INTERLACED VIDEO */ + if (enable) + WRITE_VID32(SC1200_VID_ALPHA_CONTROL, + control | SC1200_VIDEO_IS_INTERLACED); + else + WRITE_VID32(SC1200_VID_ALPHA_CONTROL, + control & ~SC1200_VIDEO_IS_INTERLACED); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_color_space_YUV() + * + * This routine configures the video processor to process graphics and video + * in either YUV or RGB color space. The mode should be set to tune image + * quality. + * Setting "enable" to TRUE improves image quality on TV, + * but in this mode colors on CRT will not be correct. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_color_space_YUV(int enable) +#else +int +gfx_set_color_space_YUV(int enable) +#endif +{ + unsigned long control; + + control = READ_VID32(SC1200_VID_ALPHA_CONTROL); + + /* SET SC1200 VIDEO COLOR SPACE TO YUV OR RGB */ + + if (enable) { + /* ENABLE YUV BLENDING */ + /* YUV blending cannot be enabled in RGB video formats */ + + control |= SC1200_CSC_GFX_RGB_TO_YUV; /* Convert graphics to YUV */ + control &= ~SC1200_CSC_VIDEO_YUV_TO_RGB; /* Leave video in YUV */ + + if (control & SC1200_VIDEO_INPUT_IS_RGB) + return (GFX_STATUS_UNSUPPORTED); /* Can't convert video from RGB to YUV */ + } else { + /* RGB BLENDING */ + + control &= ~SC1200_CSC_GFX_RGB_TO_YUV; /* Leave graphics in RGB */ + if (control & SC1200_VIDEO_INPUT_IS_RGB) + control &= ~SC1200_CSC_VIDEO_YUV_TO_RGB; /* Leave video in RGB */ + else + control |= SC1200_CSC_VIDEO_YUV_TO_RGB; /* Convert video to RGB */ + } + WRITE_VID32(SC1200_VID_ALPHA_CONTROL, control); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_vertical_scaler_offset() + * + * This routine sets the value by which the odd frame is shifted with respect + * to the even frame. This is useful for de-interlacing in Bob method, by + * setting the shift value to be one line. + * If offset is 0, no shifting occurs. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_vertical_scaler_offset(char offset) +#else +int +gfx_set_vertical_scaler_offset(char offset) +#endif +{ + unsigned long control; + + control = READ_VID32(SC1200_VID_ALPHA_CONTROL); + if (offset == 1) { + control &= ~SC1200_VERTICAL_SCALER_SHIFT_MASK; /* Clear shifting value */ + control |= SC1200_VERTICAL_SCALER_SHIFT_INIT; /* Set shifting value */ + control |= SC1200_VERTICAL_SCALER_SHIFT_EN; /* Enable odd frame shifting */ + } else if (offset == 0) { + control &= ~SC1200_VERTICAL_SCALER_SHIFT_EN; /* No shifting occurs */ + control &= ~SC1200_VERTICAL_SCALER_SHIFT_MASK; /* Clear shifting value */ + } else + return (GFX_STATUS_BAD_PARAMETER); /* TODO: how to program other values ? */ + WRITE_VID32(SC1200_VID_ALPHA_CONTROL, control); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_top_line_in_odd() + * + * This routine sets the field in which the top line of input video resides. + * If enable is "0", this is the even field (default). [not to be confused + * with the odd field being the top field on TV]. + * If enable is "1", this is the odd field. + * Use enable "1" for input devices whose field indication is reversed from + * normal, i.e. an indication of "odd" field is given for even field data, + * and vice versa. + * This setting affects the video processor only when it is in either interlaced + * or Bob (scaler offset active) modes. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_top_line_in_odd(int enable) +#else +int +gfx_set_top_line_in_odd(int enable) +#endif +{ + unsigned long control; + + control = READ_VID32(SC1200_VID_ALPHA_CONTROL); + if (enable) + control |= SC1200_TOP_LINE_IN_ODD; /* Set shifting value */ + else + control &= ~SC1200_TOP_LINE_IN_ODD; /* No shifting occurs */ + WRITE_VID32(SC1200_VID_ALPHA_CONTROL, control); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_genlock_delay() + * + * This routine sets the delay between VIP VSYNC and display controller VSYNC. + * The delay is in 27 MHz clocks. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_genlock_delay(unsigned long delay) +#else +int +gfx_set_genlock_delay(unsigned long delay) +#endif +{ + /* SET SC1200 GENLOCK DELAY */ + WRITE_VID32(SC1200_GENLOCK_DELAY, delay & SC1200_GENLOCK_DELAY_MASK); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_genlock_enable() + * + * This routine sets and configures the genlock according to the flags parameter. + * Flags value of 0 disables genlock and resets its configuration. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_genlock_enable(int flags) +#else +int +gfx_set_genlock_enable(int flags) +#endif +{ + unsigned long genlock = 0; + + if (flags) { + /* SET SC1200 GENLOCK CONFIGURATION */ + if (flags & GENLOCK_SINGLE) + genlock |= SC1200_GENLOCK_SINGLE_ENABLE; + if (flags & GENLOCK_FIELD_SYNC) + genlock |= SC1200_GENLOCK_FIELD_SYNC_ENABLE; + if (flags & GENLOCK_CONTINUOUS) + genlock |= SC1200_GENLOCK_CONTINUOUS_ENABLE; + if (flags & GENLOCK_SYNCED_EDGE_FALLING) + genlock |= SC1200_GENLOCK_GX_VSYNC_FALLING_EDGE; + if (flags & GENLOCK_SYNCING_EDGE_FALLING) + genlock |= SC1200_GENLOCK_VIP_VSYNC_FALLING_EDGE; + if (flags & GENLOCK_TIMEOUT) + genlock |= SC1200_GENLOCK_TIMEOUT_ENABLE; + if (flags & GENLOCK_TVENC_RESET_EVEN_FIELD) + genlock |= SC1200_GENLOCK_TVENC_RESET_EVEN_FIELD; + if (flags & GENLOCK_TVENC_RESET_BEFORE_DELAY) + genlock |= SC1200_GENLOCK_TVENC_RESET_BEFORE_DELAY; + if (flags & GENLOCK_TVENC_RESET) + genlock |= SC1200_GENLOCK_TVENC_RESET_ENABLE; + if (flags & GENLOCK_SYNC_TO_TVENC) + genlock |= SC1200_GENLOCK_SYNC_TO_TVENC; + } + WRITE_VID32(SC1200_GENLOCK, genlock); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_cursor() + * + * This routine configures the video hardware cursor. + * If the "mask"ed bits in the graphics pixel match "key", then either "color1" + * or "color2" will be used for this pixel, according to the value of bit + * number "select_color2" of the graphics pixel. + * + * key - 24 bit RGB value + * mask - 24 bit mask + * color1, color2 - RGB or YUV, depending on the current color space conversion + * select_color2 - value between 0 to 23 + * + * To disable match, a "mask" and "key" value of 0xffffff should be set, + * because the graphics pixels incoming to the video processor have maximum 16 + * bits set (0xF8FCF8). + * + * This feature is useful for disabling alpha blending of the cursor. + * Otherwise cursor image would be blurred (or completely invisible if video + * alpha is maximum value). + * Note: the cursor pixel replacements take place both inside and outside the + * video overlay window. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_video_cursor(unsigned long key, unsigned long mask, + unsigned short select_color2, unsigned long color1, + unsigned long color2) +#else +int +gfx_set_video_cursor(unsigned long key, unsigned long mask, + unsigned short select_color2, unsigned long color1, + unsigned long color2) +#endif +{ + if (select_color2 > SC1200_CURSOR_COLOR_BITS) + return GFX_STATUS_BAD_PARAMETER; + key = (key & SC1200_COLOR_MASK) | ((unsigned long)select_color2 << + SC1200_CURSOR_COLOR_KEY_OFFSET_POS); + WRITE_VID32(SC1200_CURSOR_COLOR_KEY, key); + WRITE_VID32(SC1200_CURSOR_COLOR_MASK, mask); + WRITE_VID32(SC1200_CURSOR_COLOR_1, color1); + WRITE_VID32(SC1200_CURSOR_COLOR_2, color2); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_alpha_enable + * + * This routine enables or disables the currently selected alpha region. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_alpha_enable(int enable) +#else +int +gfx_set_alpha_enable(int enable) +#endif +{ + unsigned long address = 0, value = 0; + + if (gfx_alpha_select > 2) + return (GFX_STATUS_UNSUPPORTED); + address = SC1200_ALPHA_CONTROL_1 + ((unsigned long)gfx_alpha_select << 4); + value = READ_VID32(address); + if (enable) + value |= (SC1200_ACTRL_WIN_ENABLE | SC1200_ACTRL_LOAD_ALPHA); + else + value &= ~(SC1200_ACTRL_WIN_ENABLE); + WRITE_VID32(address, value); + return (GFX_STATUS_OK); +} + +/*--------------------------------------------------------------------------- + * gfx_set_alpha_window + * + * This routine sets the size of the currently selected alpha region. + * Note: "x" and "y" are signed to enable using negative values needed for + * implementing workarounds of hardware issues. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_alpha_window(short x, short y, + unsigned short width, unsigned short height) +#else +int +gfx_set_alpha_window(short x, short y, + unsigned short width, unsigned short height) +#endif +{ + unsigned long address = 0; + + /* CHECK FOR CLIPPING */ + + if ((x + width) > gfx_get_hactive()) + width = gfx_get_hactive() - x; + if ((y + height) > gfx_get_vactive()) + height = gfx_get_vactive() - y; + + /* ADJUST POSITIONS */ + + x += gfx_get_htotal() - gfx_get_hsync_end() - 2; + y += gfx_get_vtotal() - gfx_get_vsync_end() + 1; + + if (gfx_alpha_select > 2) + return (GFX_STATUS_UNSUPPORTED); + address = SC1200_ALPHA_XPOS_1 + ((unsigned long)gfx_alpha_select << 4); + + /* End positions in register are non-inclusive (one more than the actual end) */ + + WRITE_VID32(address, (unsigned long)x | + ((unsigned long)(x + width) << 16)); + WRITE_VID32(address + 4l, (unsigned long)y | + ((unsigned long)(y + height) << 16)); + return (GFX_STATUS_OK); +} + +/*--------------------------------------------------------------------------- + * gfx_set_alpha_value + * + * This routine sets the alpha value for the currently selected alpha + * region. It also specifies an increment/decrement value for fading. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_alpha_value(unsigned char alpha, char delta) +#else +int +gfx_set_alpha_value(unsigned char alpha, char delta) +#endif +{ + unsigned long address = 0, value = 0; + unsigned char new_value = 0; + int loop = 1; + + if (gfx_alpha_select > 2) + return (GFX_STATUS_UNSUPPORTED); + address = SC1200_ALPHA_CONTROL_1 + ((unsigned long)gfx_alpha_select << 4); + value = READ_VID32(address); + value &= SC1200_ACTRL_WIN_ENABLE; /* keep only enable bit */ + value |= (unsigned long)alpha; + value |= (((unsigned long)delta) & 0xff) << 8; + value |= SC1200_ACTRL_LOAD_ALPHA; + WRITE_VID32(address, value); + + /* WORKAROUND FOR ISSUE #1187 */ + /* Need to verify that the alpha operation succeeded */ + + while (1) { + /* WAIT FOR VERTICAL BLANK TO END */ + if (gfx_test_timing_active()) { + if (gfx_test_vertical_active()) + while (gfx_test_vertical_active()) ; + while (!gfx_test_vertical_active()) ; + } + new_value = + (unsigned + char)((READ_VID32(SC1200_ALPHA_WATCH) >> (gfx_alpha_select << 3)) + & 0xff); + if (new_value == alpha) + return GFX_STATUS_OK; + if (++loop > 10) + return GFX_STATUS_ERROR; + WRITE_VID32(address, value); + } +} + +/*--------------------------------------------------------------------------- + * gfx_set_alpha_priority + * + * This routine sets the priority of the currently selected alpha region. + * A higher value indicates a higher priority. + * Note: Priority of enabled alpha windows must be different. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_alpha_priority(int priority) +#else +int +gfx_set_alpha_priority(int priority) +#endif +{ + unsigned long pos = 0, value = 0; + + if (priority > 3) + return (GFX_STATUS_BAD_PARAMETER); + if (gfx_alpha_select > 2) + return (GFX_STATUS_UNSUPPORTED); + value = READ_VID32(SC1200_VID_ALPHA_CONTROL); + pos = 16 + (gfx_alpha_select << 1); + value &= ~(0x03l << pos); + value |= (unsigned long)priority << pos; + WRITE_VID32(SC1200_VID_ALPHA_CONTROL, value); + return (GFX_STATUS_OK); +} + +/*--------------------------------------------------------------------------- + * gfx_set_alpha_color + * + * This routine sets the color to be displayed inside the currently selected + * alpha window when there is a color key match (when the alpha color + * mechanism is enabled). + * "color" is a 24 bit RGB value (for RGB blending) or YUV value (for YUV blending). + * In Interlaced YUV blending mode, Y/2 value should be used. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_alpha_color(unsigned long color) +#else +int +gfx_set_alpha_color(unsigned long color) +#endif +{ + unsigned long address = 0; + + if (gfx_alpha_select > 2) + return (GFX_STATUS_UNSUPPORTED); + address = SC1200_ALPHA_COLOR_1 + ((unsigned long)gfx_alpha_select << 4); + + /* ONLY 24 VALID BITS */ + color &= 0xffffffl; + + /* KEEP UPPER BYTE UNCHANGED */ + WRITE_VID32(address, (color | (READ_VID32(address) & ~0xffffffl))); + return (GFX_STATUS_OK); +} + +/*--------------------------------------------------------------------------- + * gfx_set_alpha_color_enable + * + * Enable or disable the color mechanism in the alpha window. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_alpha_color_enable(int enable) +#else +int +gfx_set_alpha_color_enable(int enable) +#endif +{ + unsigned long color; + unsigned long address = 0; + + if (gfx_alpha_select > 2) + return (GFX_STATUS_UNSUPPORTED); + address = SC1200_ALPHA_COLOR_1 + ((unsigned long)gfx_alpha_select << 4); + color = READ_VID32(address); + if (enable) + color |= SC1200_ALPHA_COLOR_ENABLE; + else + color &= ~SC1200_ALPHA_COLOR_ENABLE; + WRITE_VID32(address, color); + return (GFX_STATUS_OK); +} + +/*--------------------------------------------------------------------------- + * gfx_set_no_ck_outside_alpha + * + * This function affects where inside the video window color key or chroma + * key comparison is done: + * If enable is TRUE, color/chroma key comparison is performed only inside + * the enabled alpha windows. Outside the (enabled) alpha windows, only video + * is displayed if color key is used, and only graphics is displayed if chroma + * key is used. + * If enable is FALSE, color/chroma key comparison is performed in all the + * video window area. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_no_ck_outside_alpha(int enable) +#else +int +gfx_set_no_ck_outside_alpha(int enable) +#endif +{ + unsigned long value; + + value = READ_VID32(SC1200_VID_ALPHA_CONTROL); + if (enable) + WRITE_VID32(SC1200_VID_ALPHA_CONTROL, + value | SC1200_NO_CK_OUTSIDE_ALPHA); + else + WRITE_VID32(SC1200_VID_ALPHA_CONTROL, + value & ~SC1200_NO_CK_OUTSIDE_ALPHA); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_macrovision_enable + * + * This routine enables or disables macrovision on the tv encoder output. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_macrovision_enable(int enable) +#else +int +gfx_set_macrovision_enable(int enable) +#endif +{ + if (enable) + WRITE_VID32(SC1200_TVENC_MV_CONTROL, SC1200_TVENC_MV_ENABLE); + else + WRITE_VID32(SC1200_TVENC_MV_CONTROL, 0); + return (GFX_STATUS_OK); +} + +#define SC1200_VIDEO_PCI_44 0x80009444 + +/*--------------------------------------------------------------------------- + * gfx_disable_softvga + * + * Disables SoftVga. This function is only valid with VSA2, Returns 1 if + * SoftVga can be disabled; 0 if not. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_disable_softvga(void) +#else +int +gfx_disable_softvga(void) +#endif +{ + unsigned long reg_val; + + /* get the current value */ + reg_val = gfx_pci_config_read(SC1200_VIDEO_PCI_44); + /* setting video PCI register 44 bit 0 to 1 disables SoftVga */ + reg_val |= 0x1; + gfx_pci_config_write(SC1200_VIDEO_PCI_44, reg_val); + + /* see if we set the bit and return the appropriate value */ + reg_val = gfx_pci_config_read(SC1200_VIDEO_PCI_44); + if ((reg_val & 0x1) == 0x1) + return (1); + else + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_enable_softvga + * + * Enables SoftVga. This function is only valid with VSA2, Returns 1 if + * SoftVga can be enbled; 0 if not. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_enable_softvga(void) +#else +int +gfx_enable_softvga(void) +#endif +{ + unsigned long reg_val; + + /* get the current value */ + reg_val = gfx_pci_config_read(SC1200_VIDEO_PCI_44); + /* clearing video PCI register 44 bit 0 enables SoftVga */ + gfx_pci_config_write(SC1200_VIDEO_PCI_44, reg_val & 0xfffffffel); + + /* see if we cleared the bit and return the appropriate value */ + reg_val = gfx_pci_config_read(SC1200_VIDEO_PCI_44); + if ((reg_val & 0x1) == 0) + return (1); + else + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_get_clock_frequency + * + * This routine returns the current clock frequency in 16.16 format. + * It reads the current register value and finds the match in the table. + * If no match is found, this routine returns 0. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +sc1200_get_clock_frequency(void) +#else +unsigned long +gfx_get_clock_frequency(void) +#endif +{ + unsigned int index; + unsigned long value, mask; + + mask = 0x007FFF0F; + value = READ_VID32(SC1200_VID_CLOCK_SELECT) & mask; + for (index = 0; index < NUM_SC1200_FREQUENCIES; index++) { + if ((gfx_sc1200_clock_table[index].clock_select & mask) == value) + return (gfx_sc1200_clock_table[index].frequency); + } + return (0); +} + +/*************************************************************/ +/* READ ROUTINES | INCLUDED FOR DIAGNOSTIC PURPOSES ONLY */ +/*************************************************************/ + +#if GFX_READ_ROUTINES + +/*--------------------------------------------------------------------------- + * gfx_get_vsa2_softvga_enable + * + * This function returns the enable status of SoftVGA. It is valid + * only if VSAII is present. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_get_vsa2_softvga_enable(void) +#else +int +gfx_get_vsa2_softvga_enable(void) +#endif +{ + unsigned long reg_val; + + reg_val = gfx_pci_config_read(SC1200_VIDEO_PCI_44); + if ((reg_val & 0x1) == 0) + return (1); + else + return (0); + +} + +/*--------------------------------------------------------------------------- + * gfx_get_sync_polarities + * + * This routine returns the polarities of the sync pulses: + * Bit 0: Set if negative horizontal polarity. + * Bit 1: Set if negative vertical polarity. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_get_sync_polarities(void) +#else +int +gfx_get_sync_polarities(void) +#endif +{ + int polarities = 0; + + if (READ_VID32(SC1200_DISPLAY_CONFIG) & SC1200_DCFG_CRT_HSYNC_POL) + polarities |= 1; + if (READ_VID32(SC1200_DISPLAY_CONFIG) & SC1200_DCFG_CRT_VSYNC_POL) + polarities |= 2; + return (polarities); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_palette_entry + * + * This routine returns a single palette entry. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_get_video_palette_entry(unsigned long index, unsigned long *palette) +#else +int +gfx_get_video_palette_entry(unsigned long index, unsigned long *palette) +#endif +{ + if (index > 0xFF) + return GFX_STATUS_BAD_PARAMETER; + + /* READ A SINGLE ENTRY */ + + WRITE_VID32(SC1200_PALETTE_ADDRESS, index); + *palette = READ_VID32(SC1200_PALETTE_DATA); + + return (GFX_STATUS_OK); +} + +/*----------------------------------------------------------------------------- + * gfx_get_video_enable + * + * This routine returns the value "one" if video overlay is currently enabled, + * otherwise it returns the value "zero". + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_get_video_enable(void) +#else +int +gfx_get_video_enable(void) +#endif +{ + if (READ_VID32(SC1200_VIDEO_CONFIG) & SC1200_VCFG_VID_EN) + return (1); + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_get_video_format + * + * This routine returns the current video overlay format. + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_get_video_format(void) +#else +int +gfx_get_video_format(void) +#endif +{ + unsigned long ctrl, vcfg; + + ctrl = READ_VID32(SC1200_VID_ALPHA_CONTROL); + vcfg = READ_VID32(SC1200_VIDEO_CONFIG); + + if (ctrl & SC1200_VIDEO_INPUT_IS_RGB) { + switch (vcfg & SC1200_VCFG_VID_INP_FORMAT) { + case SC1200_VCFG_UYVY_FORMAT: + return VIDEO_FORMAT_RGB; + case SC1200_VCFG_Y2YU_FORMAT: + return VIDEO_FORMAT_P2M_P2L_P1M_P1L; + case SC1200_VCFG_YUYV_FORMAT: + return VIDEO_FORMAT_P1M_P1L_P2M_P2L; + case SC1200_VCFG_YVYU_FORMAT: + return VIDEO_FORMAT_P1M_P2L_P2M_P1L; + } + } + + if (vcfg & SC1200_VCFG_4_2_0_MODE) { + switch (vcfg & SC1200_VCFG_VID_INP_FORMAT) { + case SC1200_VCFG_UYVY_FORMAT: + return VIDEO_FORMAT_Y0Y1Y2Y3; + case SC1200_VCFG_Y2YU_FORMAT: + return VIDEO_FORMAT_Y3Y2Y1Y0; + case SC1200_VCFG_YUYV_FORMAT: + return VIDEO_FORMAT_Y1Y0Y3Y2; + case SC1200_VCFG_YVYU_FORMAT: + return VIDEO_FORMAT_Y1Y2Y3Y0; + } + } else { + switch (vcfg & SC1200_VCFG_VID_INP_FORMAT) { + case SC1200_VCFG_UYVY_FORMAT: + return VIDEO_FORMAT_UYVY; + case SC1200_VCFG_Y2YU_FORMAT: + return VIDEO_FORMAT_Y2YU; + case SC1200_VCFG_YUYV_FORMAT: + return VIDEO_FORMAT_YUYV; + case SC1200_VCFG_YVYU_FORMAT: + return VIDEO_FORMAT_YVYU; + } + } + return (GFX_STATUS_ERROR); +} + +/*----------------------------------------------------------------------------- + * gfx_get_video_src_size + * + * This routine returns the size of the source video overlay buffer. The + * return value is (height << 16) | width. + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +sc1200_get_video_src_size(void) +#else +unsigned long +gfx_get_video_src_size(void) +#endif +{ + unsigned long width = 0, height = 0; + + /* DETERMINE SOURCE WIDTH FROM THE SC1200 VIDEO LINE SIZE */ + + width = (READ_VID32(SC1200_VIDEO_CONFIG) >> 7) & 0x000001FE; + if (READ_VID32(SC1200_VIDEO_CONFIG) & SC1200_VCFG_LINE_SIZE_UPPER) + width += 512l; + + if (width) { + /* DETERMINE HEIGHT BY DIVIDING TOTAL SIZE BY WIDTH */ + /* Get total size from display controller - abtracted. */ + + height = gfx_get_display_video_size() / (width << 1); + } + return ((height << 16) | width); +} + +/*----------------------------------------------------------------------------- + * gfx_get_video_line_size + * + * This routine returns the line size of the source video overlay buffer, in + * pixels. + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +sc1200_get_video_line_size(void) +#else +unsigned long +gfx_get_video_line_size(void) +#endif +{ + unsigned long width = 0; + + /* DETERMINE SOURCE WIDTH FROM THE SC1200 VIDEO LINE SIZE */ + + width = (READ_VID32(SC1200_VIDEO_CONFIG) >> 7) & 0x000001FE; + if (READ_VID32(SC1200_VIDEO_CONFIG) & SC1200_VCFG_LINE_SIZE_UPPER) + width += 512l; + return (width); +} + +/*----------------------------------------------------------------------------- + * gfx_get_video_xclip + * + * This routine returns the number of bytes clipped on the left side of a + * video overlay line (skipped at beginning). + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +sc1200_get_video_xclip(void) +#else +unsigned long +gfx_get_video_xclip(void) +#endif +{ + unsigned long clip = 0; + + /* DETERMINE SOURCE WIDTH FROM THE SC1200 VIDEO LINE SIZE */ + + clip = (READ_VID32(SC1200_VIDEO_CONFIG) >> 14) & 0x000007FC; + return (clip); +} + +/*----------------------------------------------------------------------------- + * gfx_get_video_offset + * + * This routine returns the current offset for the video overlay buffer. + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +sc1200_get_video_offset(void) +#else +unsigned long +gfx_get_video_offset(void) +#endif +{ + return (gfx_get_display_video_offset()); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_upscale + * + * This routine returns the scale factor for the video overlay window. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +sc1200_get_video_upscale(void) +#else +unsigned long +gfx_get_video_upscale(void) +#endif +{ + return (READ_VID32(SC1200_VIDEO_UPSCALE)); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_scale + * + * This routine returns the scale factor for the video overlay window. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +sc1200_get_video_scale(void) +#else +unsigned long +gfx_get_video_scale(void) +#endif +{ + return gfx_get_video_upscale(); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_downscale_config + * + * This routine returns the current type and value of video downscaling. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_get_video_downscale_config(unsigned short *type, unsigned short *m) +#else +int +gfx_get_video_downscale_config(unsigned short *type, unsigned short *m) +#endif +{ + unsigned long downscale; + + downscale = READ_VID32(SC1200_VIDEO_DOWNSCALER_CONTROL); + *m = (unsigned short)((downscale & SC1200_VIDEO_DOWNSCALE_FACTOR_MASK) >> + SC1200_VIDEO_DOWNSCALE_FACTOR_POS) + 1; + + switch (downscale & SC1200_VIDEO_DOWNSCALE_TYPE_MASK) { + case SC1200_VIDEO_DOWNSCALE_TYPE_A: + *type = VIDEO_DOWNSCALE_KEEP_1_OF; + break; + case SC1200_VIDEO_DOWNSCALE_TYPE_B: + *type = VIDEO_DOWNSCALE_DROP_1_OF; + break; + default: + return GFX_STATUS_ERROR; + break; + } + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_downscale_coefficients + * + * This routine returns the current video downscaling coefficients. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +void +sc1200_get_video_downscale_coefficients(unsigned short *coef1, + unsigned short *coef2, + unsigned short *coef3, + unsigned short *coef4) +#else +void +gfx_get_video_downscale_coefficients(unsigned short *coef1, + unsigned short *coef2, + unsigned short *coef3, + unsigned short *coef4) +#endif +{ + unsigned long coef; + + coef = READ_VID32(SC1200_VIDEO_DOWNSCALER_COEFFICIENTS); + *coef1 = + (unsigned short)((coef >> SC1200_VIDEO_DOWNSCALER_COEF1_POS) & + SC1200_VIDEO_DOWNSCALER_COEF_MASK); + *coef2 = + (unsigned short)((coef >> SC1200_VIDEO_DOWNSCALER_COEF2_POS) & + SC1200_VIDEO_DOWNSCALER_COEF_MASK); + *coef3 = + (unsigned short)((coef >> SC1200_VIDEO_DOWNSCALER_COEF3_POS) & + SC1200_VIDEO_DOWNSCALER_COEF_MASK); + *coef4 = + (unsigned short)((coef >> SC1200_VIDEO_DOWNSCALER_COEF4_POS) & + SC1200_VIDEO_DOWNSCALER_COEF_MASK); + return; +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_downscale_enable + * + * This routine returns 1 if video downscaling is currently enabled, + * or 0 if it is currently disabled. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +void +sc1200_get_video_downscale_enable(int *enable) +#else +void +gfx_get_video_downscale_enable(int *enable) +#endif +{ + if (READ_VID32(SC1200_VIDEO_DOWNSCALER_CONTROL) & + SC1200_VIDEO_DOWNSCALE_ENABLE) + *enable = 1; + else + *enable = 0; + return; +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_dst_size + * + * This routine returns the size of the displayed video overlay window. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +sc1200_get_video_dst_size(void) +#else +unsigned long +gfx_get_video_dst_size(void) +#endif +{ + unsigned long xsize, ysize; + + xsize = READ_VID32(SC1200_VIDEO_X_POS); + xsize = ((xsize >> 16) & 0x7FF) - (xsize & 0x7FF); + ysize = READ_VID32(SC1200_VIDEO_Y_POS); + ysize = ((ysize >> 16) & 0x7FF) - (ysize & 0x7FF); + return ((ysize << 16) | xsize); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_position + * + * This routine returns the position of the video overlay window. The + * return value is (ypos << 16) | xpos. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +sc1200_get_video_position(void) +#else +unsigned long +gfx_get_video_position(void) +#endif +{ + unsigned long hadjust, vadjust; + unsigned long xpos, ypos; + + /* READ HARDWARE POSITION */ + + xpos = READ_VID32(SC1200_VIDEO_X_POS) & 0x000007FF; + ypos = READ_VID32(SC1200_VIDEO_Y_POS) & 0x000007FF; + + /* GET ADJUSTMENT VALUES */ + /* Use routines to abstract version of display controller. */ + + hadjust = + (unsigned long)gfx_get_htotal() - + (unsigned long)gfx_get_hsync_end() - 14l; + vadjust = + (unsigned long)gfx_get_vtotal() - + (unsigned long)gfx_get_vsync_end() + 1l; + xpos -= hadjust; + ypos -= vadjust; + return ((ypos << 16) | (xpos & 0x0000FFFF)); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_color_key + * + * This routine returns the current video color key value. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +sc1200_get_video_color_key(void) +#else +unsigned long +gfx_get_video_color_key(void) +#endif +{ + return (READ_VID32(SC1200_VIDEO_COLOR_KEY)); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_color_key_mask + * + * This routine returns the current video color mask value. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +sc1200_get_video_color_key_mask(void) +#else +unsigned long +gfx_get_video_color_key_mask(void) +#endif +{ + return (READ_VID32(SC1200_VIDEO_COLOR_MASK)); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_color_key_src + * + * This routine returns 0 for video data compare, 1 for graphics data. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_get_video_color_key_src(void) +#else +int +gfx_get_video_color_key_src(void) +#endif +{ + if (READ_VID32(SC1200_DISPLAY_CONFIG) & SC1200_DCFG_VG_CK) + return (0); + return (1); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_filter + * + * This routine returns if the filters are currently enabled. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_get_video_filter(void) +#else +int +gfx_get_video_filter(void) +#endif +{ + int retval = 0; + + if (READ_VID32(SC1200_VIDEO_CONFIG) & SC1200_VCFG_X_FILTER_EN) + retval |= 1; + if (READ_VID32(SC1200_VIDEO_CONFIG) & SC1200_VCFG_Y_FILTER_EN) + retval |= 2; + return (retval); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_request + * + * This routine returns the horizontal (pixel) and vertical (lines) video + * request values. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_get_video_request(short *x, short *y) +#else +int +gfx_get_video_request(short *x, short *y) +#endif +{ + int request = 0; + + request = (int)(READ_VID32(SC1200_VIDEO_REQUEST)); + *x = (request >> SC1200_VIDEO_X_REQUEST_POS) & SC1200_VIDEO_REQUEST_MASK; + *y = (request >> SC1200_VIDEO_Y_REQUEST_POS) & SC1200_VIDEO_REQUEST_MASK; + + *x -= gfx_get_htotal() - gfx_get_hsync_end() - 2; + *y -= gfx_get_vtotal() - gfx_get_vsync_end() + 1; + + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_source + * + * This routine returns the current video source. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_get_video_source(VideoSourceType * source) +#else +int +gfx_get_video_source(VideoSourceType * source) +#endif +{ + switch (READ_VID32(SC1200_VIDEO_DISPLAY_MODE) & SC1200_VIDEO_SOURCE_MASK) { + case SC1200_VIDEO_SOURCE_GX1: + *source = VIDEO_SOURCE_MEMORY; + break; + case SC1200_VIDEO_SOURCE_DVIP: + *source = VIDEO_SOURCE_DVIP; + break; + default: + return GFX_STATUS_ERROR; + } + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_get_vbi_source + * + * This routine returns the current vbi source. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_get_vbi_source(VbiSourceType * source) +#else +int +gfx_get_vbi_source(VbiSourceType * source) +#endif +{ + switch (READ_VID32(SC1200_VIDEO_DISPLAY_MODE) & SC1200_VBI_SOURCE_MASK) { + case SC1200_VBI_SOURCE_GX1: + *source = VBI_SOURCE_MEMORY; + break; + case SC1200_VBI_SOURCE_DVIP: + *source = VBI_SOURCE_DVIP; + break; + default: + return GFX_STATUS_ERROR; + } + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_get_vbi_lines + * + * This routine returns the VBI lines which are sent to the TV encoder. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +sc1200_get_vbi_lines(int odd) +#else +unsigned long +gfx_get_vbi_lines(int odd) +#endif +{ + if (odd) + return (READ_VID32(SC1200_VIDEO_ODD_VBI_LINE_ENABLE) & + SC1200_VIDEO_VBI_LINE_ENABLE_MASK); + return (READ_VID32(SC1200_VIDEO_EVEN_VBI_LINE_ENABLE) & + SC1200_VIDEO_VBI_LINE_ENABLE_MASK); +} + +/*--------------------------------------------------------------------------- + * gfx_get_vbi_total + * + * This routine returns the total number of VBI bytes in the field. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +sc1200_get_vbi_total(int odd) +#else +unsigned long +gfx_get_vbi_total(int odd) +#endif +{ + if (odd) + return (READ_VID32(SC1200_VIDEO_ODD_VBI_TOTAL_COUNT) & + SC1200_VIDEO_VBI_TOTAL_COUNT_MASK); + return (READ_VID32(SC1200_VIDEO_EVEN_VBI_TOTAL_COUNT) & + SC1200_VIDEO_VBI_TOTAL_COUNT_MASK); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_interlaced() + * + * This routine returns "1" if input video is currently in interlaced mode. + * "0" otherwise. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_get_video_interlaced(void) +#else +int +gfx_get_video_interlaced(void) +#endif +{ + if (READ_VID32(SC1200_VID_ALPHA_CONTROL) & SC1200_VIDEO_IS_INTERLACED) + return (1); + else + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_get_color_space_YUV() + * + * This routine returns "1" if video processor color space mode is currently + * YUV. "0" otherwise. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_get_color_space_YUV(void) +#else +int +gfx_get_color_space_YUV(void) +#endif +{ + unsigned long control; + + control = READ_VID32(SC1200_VID_ALPHA_CONTROL); + + /* IS SC1200 VIDEO COLOR SPACE RGB OR CONVERTED TO RGB */ + if ((control & SC1200_VIDEO_INPUT_IS_RGB) + || (control & SC1200_CSC_VIDEO_YUV_TO_RGB)) + return (0); + else + return (1); +} + +/*--------------------------------------------------------------------------- + * gfx_get_vertical_scaler_offset() + * + * This routine sets "offset" to the value by which odd frames are shifted, + * if insert is enabled, and to 0 if no shifting occurs. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_get_vertical_scaler_offset(char *offset) +#else +int +gfx_get_vertical_scaler_offset(char *offset) +#endif +{ + unsigned long control; + + control = READ_VID32(SC1200_VID_ALPHA_CONTROL); + if (control & SC1200_VERTICAL_SCALER_SHIFT_EN) { + if ((control & SC1200_VERTICAL_SCALER_SHIFT_MASK) == + SC1200_VERTICAL_SCALER_SHIFT_INIT) + *offset = 1; + else + return GFX_STATUS_ERROR; /* TODO: find the interpretation of other values */ + } else + *offset = 0; + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_get_genlock_delay + * + * This routine returns the genlock delay in 27 MHz clocks. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +sc1200_get_genlock_delay(void) +#else +unsigned long +gfx_get_genlock_delay(void) +#endif +{ + return (READ_VID32(SC1200_GENLOCK_DELAY) & SC1200_GENLOCK_DELAY_MASK); +} + +/*--------------------------------------------------------------------------- + * gfx_get_genlock_enable + * + * This routine returns "1" if genlock is currently enabled, "0" otherwise. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_get_genlock_enable(void) +#else +int +gfx_get_genlock_enable(void) +#endif +{ + if (READ_VID32(SC1200_GENLOCK) & + (SC1200_GENLOCK_SINGLE_ENABLE | SC1200_GENLOCK_CONTINUOUS_ENABLE)) + return (1); + else + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_cursor() + * + * This routine configures the video hardware cursor. + * If the "mask"ed bits in the graphics pixel match "key", then either "color1" + * or "color2" will be used for this pixel, according to the value of the bit + * in offset "select_color2". + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_get_video_cursor(unsigned long *key, unsigned long *mask, + unsigned short *select_color2, unsigned long *color1, + unsigned short *color2) +#else +int +gfx_get_video_cursor(unsigned long *key, unsigned long *mask, + unsigned short *select_color2, unsigned long *color1, + unsigned short *color2) +#endif +{ + *select_color2 = + (unsigned short)(READ_VID32(SC1200_CURSOR_COLOR_KEY) >> + SC1200_CURSOR_COLOR_KEY_OFFSET_POS); + *key = READ_VID32(SC1200_CURSOR_COLOR_KEY) & SC1200_COLOR_MASK; + *mask = READ_VID32(SC1200_CURSOR_COLOR_MASK) & SC1200_COLOR_MASK; + *color1 = READ_VID32(SC1200_CURSOR_COLOR_1) & SC1200_COLOR_MASK; + *color2 = + (unsigned short)(READ_VID32(SC1200_CURSOR_COLOR_2) & + SC1200_COLOR_MASK); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_read_crc + * + * This routine returns the hardware CRC value, which is used for automated + * testing. The value is like a checksum, but will change if pixels move + * locations. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +sc1200_read_crc(void) +#else +unsigned long +gfx_read_crc(void) +#endif +{ + unsigned long crc = 0xFFFFFFFF; + + if (gfx_test_timing_active()) { + /* WAIT UNTIL ACTIVE DISPLAY */ + + while (!gfx_test_vertical_active()) ; + + /* RESET CRC DURING ACTIVE DISPLAY */ + + WRITE_VID32(SC1200_VID_CRC, 0); + WRITE_VID32(SC1200_VID_CRC, 1); + + /* WAIT UNTIL NOT ACTIVE, THEN ACTIVE, NOT ACTIVE, THEN ACTIVE */ + + while (gfx_test_vertical_active()) ; + while (!gfx_test_vertical_active()) ; + while (gfx_test_vertical_active()) ; + while (!gfx_test_vertical_active()) ; + crc = READ_VID32(SC1200_VID_CRC) >> 8; + } + return (crc); +} + +/*----------------------------------------------------------------------------- + * gfx_get_macrovision_enable + * + * This routine returns the value "one" if macrovision currently enabled in the + * TV encoder, otherwise it returns the value "zero". + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_get_macrovision_enable(void) +#else +int +gfx_get_macrovision_enable(void) +#endif +{ + if (READ_VID32(SC1200_TVENC_MV_CONTROL) == SC1200_TVENC_MV_ENABLE) + return (1); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_get_alpha_enable + * + * This routine returns 1 if the selected alpha window is currently + * enabled, or 0 if it is currently disabled. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +void +sc1200_get_alpha_enable(int *enable) +#else +void +gfx_get_alpha_enable(int *enable) +#endif +{ + unsigned long value = 0; + + *enable = 0; + if (gfx_alpha_select <= 2) { + value = + READ_VID32(SC1200_ALPHA_CONTROL_1 + + ((unsigned long)gfx_alpha_select << 4)); + if (value & SC1200_ACTRL_WIN_ENABLE) + *enable = 1; + } + return; +} + +/*--------------------------------------------------------------------------- + * gfx_get_alpha_size + * + * This routine returns the size of the currently selected alpha region. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +void +sc1200_get_alpha_size(unsigned short *x, unsigned short *y, + unsigned short *width, unsigned short *height) +#else +void +gfx_get_alpha_size(unsigned short *x, unsigned short *y, + unsigned short *width, unsigned short *height) +#endif +{ + unsigned long value = 0; + + *x = 0; + *y = 0; + *width = 0; + *height = 0; + if (gfx_alpha_select <= 2) { + value = + READ_VID32(SC1200_ALPHA_XPOS_1 + + ((unsigned long)gfx_alpha_select << 4)); + *x = (unsigned short)(value & 0x000007FF); + *width = (unsigned short)((value >> 16) & 0x000007FF) - *x; + value = + READ_VID32(SC1200_ALPHA_YPOS_1 + + ((unsigned long)gfx_alpha_select << 4)); + *y = (unsigned short)(value & 0x000007FF); + *height = (unsigned short)((value >> 16) & 0x000007FF) - *y; + } + *x -= gfx_get_htotal() - gfx_get_hsync_end() - 2; + *y -= gfx_get_vtotal() - gfx_get_vsync_end() + 1; + return; +} + +/*--------------------------------------------------------------------------- + * gfx_get_alpha_value + * + * This routine returns the alpha value and increment/decrement value of + * the currently selected alpha region. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +void +sc1200_get_alpha_value(unsigned char *alpha, char *delta) +#else +void +gfx_get_alpha_value(unsigned char *alpha, char *delta) +#endif +{ + unsigned long value = 0; + + *alpha = 0; + *delta = 0; + if (gfx_alpha_select <= 2) { + value = + READ_VID32(SC1200_ALPHA_CONTROL_1 + + ((unsigned long)gfx_alpha_select << 4)); + *alpha = (unsigned char)(value & 0x00FF); + *delta = (char)((value >> 8) & 0x00FF); + } + return; +} + +/*--------------------------------------------------------------------------- + * gfx_get_alpha_priority + * + * This routine returns the priority of the currently selected alpha region. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +void +sc1200_get_alpha_priority(int *priority) +#else +void +gfx_get_alpha_priority(int *priority) +#endif +{ + unsigned long pos = 0, value = 0; + + *priority = 0; + if (gfx_alpha_select <= 2) { + value = READ_VID32(SC1200_VID_ALPHA_CONTROL); + pos = 16 + (gfx_alpha_select << 1); + *priority = (int)((value >> pos) & 3); + } + return; +} + +/*--------------------------------------------------------------------------- + * gfx_get_alpha_color + * + * This routine returns the color register value for the currently selected + * alpha region. Bit 24 is set if the color register is enabled. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +void +sc1200_get_alpha_color(unsigned long *color) +#else +void +gfx_get_alpha_color(unsigned long *color) +#endif +{ + *color = 0; + if (gfx_alpha_select <= 2) { + *color = + READ_VID32(SC1200_ALPHA_COLOR_1 + + ((unsigned long)gfx_alpha_select << 4)); + } + return; +} + +#endif /* GFX_READ_ROUTINES */ + +/* END OF FILE */ |