171d7fec4Smrg/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/vid_rdcl.c,v 1.3 2003/02/21 16:51:10 alanh Exp $ */
271d7fec4Smrg/*
371d7fec4Smrg * $Workfile: vid_rdcl.c $
471d7fec4Smrg *
571d7fec4Smrg * This file contains routines to control the Redcloud display filter video overlay hardware.
671d7fec4Smrg *
771d7fec4Smrg * NSC_LIC_ALTERNATIVE_PREAMBLE
871d7fec4Smrg *
971d7fec4Smrg * Revision 1.0
1071d7fec4Smrg *
1171d7fec4Smrg * National Semiconductor Alternative GPL-BSD License
1271d7fec4Smrg *
1371d7fec4Smrg * National Semiconductor Corporation licenses this software
1471d7fec4Smrg * ("Software"):
1571d7fec4Smrg *
1671d7fec4Smrg *      Durango
1771d7fec4Smrg *
1871d7fec4Smrg * under one of the two following licenses, depending on how the
1971d7fec4Smrg * Software is received by the Licensee.
2071d7fec4Smrg *
2171d7fec4Smrg * If this Software is received as part of the Linux Framebuffer or
2271d7fec4Smrg * other GPL licensed software, then the GPL license designated
2371d7fec4Smrg * NSC_LIC_GPL applies to this Software; in all other circumstances
2471d7fec4Smrg * then the BSD-style license designated NSC_LIC_BSD shall apply.
2571d7fec4Smrg *
2671d7fec4Smrg * END_NSC_LIC_ALTERNATIVE_PREAMBLE */
2771d7fec4Smrg
2871d7fec4Smrg/* NSC_LIC_BSD
2971d7fec4Smrg *
3071d7fec4Smrg * National Semiconductor Corporation Open Source License for Durango
3171d7fec4Smrg *
3271d7fec4Smrg * (BSD License with Export Notice)
3371d7fec4Smrg *
3471d7fec4Smrg * Copyright (c) 1999-2001
3571d7fec4Smrg * National Semiconductor Corporation.
3671d7fec4Smrg * All rights reserved.
3771d7fec4Smrg *
3871d7fec4Smrg * Redistribution and use in source and binary forms, with or without
3971d7fec4Smrg * modification, are permitted provided that the following conditions
4071d7fec4Smrg * are met:
4171d7fec4Smrg *
4271d7fec4Smrg *   * Redistributions of source code must retain the above copyright
4371d7fec4Smrg *     notice, this list of conditions and the following disclaimer.
4471d7fec4Smrg *
4571d7fec4Smrg *   * Redistributions in binary form must reproduce the above
4671d7fec4Smrg *     copyright notice, this list of conditions and the following
4771d7fec4Smrg *     disclaimer in the documentation and/or other materials provided
4871d7fec4Smrg *     with the distribution.
4971d7fec4Smrg *
5071d7fec4Smrg *   * Neither the name of the National Semiconductor Corporation nor
5171d7fec4Smrg *     the names of its contributors may be used to endorse or promote
5271d7fec4Smrg *     products derived from this software without specific prior
5371d7fec4Smrg *     written permission.
5471d7fec4Smrg *
5571d7fec4Smrg * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
5671d7fec4Smrg * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5771d7fec4Smrg * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
5871d7fec4Smrg * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
5971d7fec4Smrg * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY
6071d7fec4Smrg * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
6171d7fec4Smrg * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
6271d7fec4Smrg * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
6371d7fec4Smrg * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
6471d7fec4Smrg * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE,
6571d7fec4Smrg * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY
6671d7fec4Smrg * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
6771d7fec4Smrg * OF SUCH DAMAGE.
6871d7fec4Smrg *
6971d7fec4Smrg * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF
7071d7fec4Smrg * YOUR JURISDICTION. It is licensee's responsibility to comply with
7171d7fec4Smrg * any export regulations applicable in licensee's jurisdiction. Under
7271d7fec4Smrg * CURRENT (2001) U.S. export regulations this software
7371d7fec4Smrg * is eligible for export from the U.S. and can be downloaded by or
7471d7fec4Smrg * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed
7571d7fec4Smrg * destinations which include Cuba, Iraq, Libya, North Korea, Iran,
7671d7fec4Smrg * Syria, Sudan, Afghanistan and any other country to which the U.S.
7771d7fec4Smrg * has embargoed goods and services.
7871d7fec4Smrg *
7971d7fec4Smrg * END_NSC_LIC_BSD */
8071d7fec4Smrg
8171d7fec4Smrg/* NSC_LIC_GPL
8271d7fec4Smrg *
8371d7fec4Smrg * National Semiconductor Corporation Gnu General Public License for Durango
8471d7fec4Smrg *
8571d7fec4Smrg * (GPL License with Export Notice)
8671d7fec4Smrg *
8771d7fec4Smrg * Copyright (c) 1999-2001
8871d7fec4Smrg * National Semiconductor Corporation.
8971d7fec4Smrg * All rights reserved.
9071d7fec4Smrg *
9171d7fec4Smrg * Redistribution and use in source and binary forms, with or without
9271d7fec4Smrg * modification, are permitted under the terms of the GNU General
9371d7fec4Smrg * Public License as published by the Free Software Foundation; either
9471d7fec4Smrg * version 2 of the License, or (at your option) any later version
9571d7fec4Smrg *
9671d7fec4Smrg * In addition to the terms of the GNU General Public License, neither
9771d7fec4Smrg * the name of the National Semiconductor Corporation nor the names of
9871d7fec4Smrg * its contributors may be used to endorse or promote products derived
9971d7fec4Smrg * from this software without specific prior written permission.
10071d7fec4Smrg *
10171d7fec4Smrg * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
10271d7fec4Smrg * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
10371d7fec4Smrg * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
10471d7fec4Smrg * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
10571d7fec4Smrg * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY
10671d7fec4Smrg * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
10771d7fec4Smrg * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
10871d7fec4Smrg * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
10971d7fec4Smrg * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
11071d7fec4Smrg * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE,
11171d7fec4Smrg * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY
11271d7fec4Smrg * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
11371d7fec4Smrg * OF SUCH DAMAGE. See the GNU General Public License for more details.
11471d7fec4Smrg *
11571d7fec4Smrg * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF
11671d7fec4Smrg * YOUR JURISDICTION. It is licensee's responsibility to comply with
11771d7fec4Smrg * any export regulations applicable in licensee's jurisdiction. Under
11871d7fec4Smrg * CURRENT (2001) U.S. export regulations this software
11971d7fec4Smrg * is eligible for export from the U.S. and can be downloaded by or
12071d7fec4Smrg * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed
12171d7fec4Smrg * destinations which include Cuba, Iraq, Libya, North Korea, Iran,
12271d7fec4Smrg * Syria, Sudan, Afghanistan and any other country to which the U.S.
12371d7fec4Smrg * has embargoed goods and services.
12471d7fec4Smrg *
12571d7fec4Smrg * You should have received a copy of the GNU General Public License
12671d7fec4Smrg * along with this file; if not, write to the Free Software Foundation,
12771d7fec4Smrg * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
12871d7fec4Smrg *
12971d7fec4Smrg * END_NSC_LIC_GPL */
13071d7fec4Smrg
13171d7fec4Smrg/* REDCLOUD PLL TABLE  */
13271d7fec4Smrg
13371d7fec4Smrgtypedef struct RCDFPLL
13471d7fec4Smrg{
13571d7fec4Smrg   long frequency;			/* 16.16 fixed point frequency            */
13671d7fec4Smrg   unsigned long post_div3;		/* MCP Frequency dividers and multipliers */
13771d7fec4Smrg   unsigned long pre_mul2;
13871d7fec4Smrg   unsigned long pre_div2;
13971d7fec4Smrg   unsigned long pll_value;		/* MCP DotPLL Register Upper 32(0x0015)   */
14071d7fec4Smrg}
14171d7fec4SmrgRCDFPLLENTRY;
14271d7fec4Smrg
14371d7fec4SmrgRCDFPLLENTRY RCDF_PLLtable48MHz[] = {
14471d7fec4Smrg   {0x00192CCC, 0, 0, 0, 0x00000037},	/*  25.1750 */
14571d7fec4Smrg   {0x001C526E, 1, 1, 0, 0x00000B1A},	/*  28.3220 */
14671d7fec4Smrg   {0x001F8000, 1, 0, 0, 0x000002D2},	/*  31.5000 */
14771d7fec4Smrg   {0x00240000, 1, 1, 0, 0x00000FE2},	/*  36.0000 */
14871d7fec4Smrg   {0x00258000, 1, 0, 0, 0x0000057A},	/*  37.5000 */
14971d7fec4Smrg   {0x00280000, 1, 0, 0, 0x0000030A},	/*  40.0000 */
15071d7fec4Smrg   {0x002CE666, 0, 0, 0, 0x00000063},	/*  44.9000 */
15171d7fec4Smrg   {0x00318000, 0, 0, 0, 0x0000054B},	/*  49.5000 */
15271d7fec4Smrg   {0x00320000, 0, 0, 0, 0x0000026E},	/*  50.0000 */
15371d7fec4Smrg   {0x00325999, 0, 1, 0, 0x00000037},	/*  50.3500 */
15471d7fec4Smrg   {0x00360000, 1, 1, 0, 0x00000B0D},	/*  54.0000 */
15571d7fec4Smrg   {0x00384000, 0, 0, 0, 0x00000577},	/*  56.2500 */
15671d7fec4Smrg   {0x0038643F, 0, 0, 0, 0x000007F7},	/*  56.3916 */
15771d7fec4Smrg   {0x0038A4DD, 0, 0, 0, 0x0000057B},	/*  56.6444 */
15871d7fec4Smrg   {0x003B0000, 0, 1, 0, 0x00000707},	/*  59.0000 */
15971d7fec4Smrg   {0x003F0000, 1, 1, 0, 0x00000B39},	/*  63.0000 */
16071d7fec4Smrg   {0x00410000, 1, 1, 0, 0x00000B45},	/*  65.0000 */
16171d7fec4Smrg   {0x00438000, 1, 1, 0, 0x00000FC1},	/*  67.5000 */
16271d7fec4Smrg   {0x0046CCCC, 1, 0, 0, 0x00000561},	/*  70.8000 */
16371d7fec4Smrg   {0x00480000, 1, 0, 0, 0x000007E1},	/*  72.0000 */
16471d7fec4Smrg   {0x004B0000, 0, 0, 0, 0x00000052},	/*  75.0000 */
16571d7fec4Smrg   {0x004EC000, 0, 0, 0, 0x00000056},	/*  78.7500 */
16671d7fec4Smrg   {0x00500000, 1, 1, 0, 0x00000709},	/*  80.0000 */
16771d7fec4Smrg   {0x0059CCCC, 0, 1, 0, 0x00000262},	/*  89.8000 */
16871d7fec4Smrg   {0x005E8000, 0, 0, 0, 0x000002D2},	/*  94.5000 */
16971d7fec4Smrg   {0x00630000, 0, 1, 0, 0x00000B4A},	/*  99.0000 */
17071d7fec4Smrg   {0x00640000, 0, 1, 0, 0x00000036},	/* 100.0000 */
17171d7fec4Smrg   {0x006C0000, 0, 0, 0, 0x000007E2},	/* 108.0000 */
17271d7fec4Smrg   {0x00708000, 0, 0, 0, 0x000007F6},	/* 112.5000 */
17371d7fec4Smrg   {0x00820000, 1, 1, 0, 0x00000FB0},	/* 130.0000 */
17471d7fec4Smrg   {0x00870000, 1, 1, 0, 0x00000B50},	/* 135.0000 */
17571d7fec4Smrg   {0x009D8000, 0, 0, 0, 0x00000055},	/* 157.5000 */
17671d7fec4Smrg   {0x00A20000, 0, 0, 0, 0x000009C1},	/* 162.0000 */
17771d7fec4Smrg   {0x00AF8000, 0, 0, 0, 0x000002C1},	/* 175.5000 */
17871d7fec4Smrg   {0x00BD0000, 0, 0, 0, 0x000002D1},	/* 189.0000 */
17971d7fec4Smrg   {0x00CA8000, 0, 0, 0, 0x00000551},	/* 202.5000 */
18071d7fec4Smrg   {0x00E58000, 0, 0, 0, 0x0000057D},	/* 229.5000 */
18171d7fec4Smrg};
18271d7fec4Smrg
18371d7fec4SmrgRCDFPLLENTRY RCDF_PLLtable14MHz[] = {
18471d7fec4Smrg   {0x00192CCC, 0, 0, 0, 0x00000037},	/*  25.1750 */
18571d7fec4Smrg   {0x001C526E, 0, 0, 0, 0x00000B7B},	/*  28.3220 */
18671d7fec4Smrg   {0x001F8000, 0, 0, 0, 0x000004D3},	/*  31.5000 */
18771d7fec4Smrg   {0x00240000, 0, 0, 0, 0x00000BE3},	/*  36.0000 */
18871d7fec4Smrg   {0x00258000, 0, 0, 0, 0x0000074F},	/*  37.5000 */
18971d7fec4Smrg   {0x00280000, 0, 0, 0, 0x0000050B},	/*  40.0000 */
19071d7fec4Smrg   {0x002CE666, 0, 0, 0, 0x00000063},	/*  44.9000 */
19171d7fec4Smrg   {0x00318000, 0, 0, 0, 0x0000054B},	/*  49.5000 */
19271d7fec4Smrg   {0x00320000, 0, 0, 0, 0x0000026E},	/*  50.0000 */
19371d7fec4Smrg   {0x00325999, 0, 0, 0, 0x000007C3},	/*  50.3500 */
19471d7fec4Smrg   {0x00360000, 0, 0, 0, 0x000007E3},	/*  54.0000 */
19571d7fec4Smrg   {0x00384000, 0, 0, 0, 0x00000577},	/*  56.2500 */
19671d7fec4Smrg   {0x0038643F, 0, 0, 0, 0x000002FB},	/*  56.3916 */
19771d7fec4Smrg   {0x0038A4DD, 0, 0, 0, 0x0000057B},	/*  56.6444 */
19871d7fec4Smrg   {0x003B0000, 0, 0, 0, 0x0000058B},	/*  59.0000 */
19971d7fec4Smrg   {0x003F0000, 0, 0, 0, 0x0000095E},	/*  63.0000 */
20071d7fec4Smrg   {0x00410000, 0, 0, 0, 0x0000096A},	/*  65.0000 */
20171d7fec4Smrg   {0x00438000, 0, 0, 0, 0x00000BC2},	/*  67.5000 */
20271d7fec4Smrg   {0x0046CCCC, 0, 0, 0, 0x0000098A},	/*  70.8000 */
20371d7fec4Smrg   {0x00480000, 0, 0, 0, 0x00000BE2},	/*  72.0000 */
20471d7fec4Smrg   {0x004B0000, 0, 0, 0, 0x00000052},	/*  75.0000 */
20571d7fec4Smrg   {0x004EC000, 0, 0, 0, 0x00000056},	/*  78.7500 */
20671d7fec4Smrg   {0x00500000, 0, 0, 0, 0x0000050A},	/*  80.0000 */
20771d7fec4Smrg   {0x0059CCCC, 0, 0, 0, 0x0000078E},	/*  89.8000 */
20871d7fec4Smrg   {0x005E8000, 0, 0, 0, 0x000002D2},	/*  94.5000 */
20971d7fec4Smrg   {0x00630000, 0, 0, 0, 0x000011F6},	/*  99.0000 */
21071d7fec4Smrg   {0x00640000, 0, 0, 0, 0x0000054E},	/* 100.0000 */
21171d7fec4Smrg   {0x006C0000, 0, 0, 0, 0x000007E2},	/* 108.0000 */
21271d7fec4Smrg   {0x00708000, 0, 0, 0, 0x000002FA},	/* 112.5000 */
21371d7fec4Smrg   {0x00820000, 0, 0, 0, 0x00000BB1},	/* 130.0000 */
21471d7fec4Smrg   {0x00870000, 0, 0, 0, 0x00000975},	/* 135.0000 */
21571d7fec4Smrg   {0x009D8000, 0, 0, 0, 0x00000055},	/* 157.5000 */
21671d7fec4Smrg   {0x00A20000, 0, 0, 0, 0x000009C1},	/* 162.0000 */
21771d7fec4Smrg   {0x00AF8000, 0, 0, 0, 0x000002C1},	/* 175.5000 */
21871d7fec4Smrg   {0x00BD0000, 0, 0, 0, 0x00000539},	/* 189.0000 */
21971d7fec4Smrg   {0x00CA8000, 0, 0, 0, 0x00000551},	/* 202.5000 */
22071d7fec4Smrg   {0x00E58000, 0, 0, 0, 0x0000057D},	/* 229.5000 */
22171d7fec4Smrg};
22271d7fec4Smrg
22371d7fec4Smrg#define NUM_RCDF_FREQUENCIES sizeof(RCDF_PLLtable14MHz)/sizeof(RCDFPLLENTRY)
22471d7fec4Smrg
22571d7fec4Smrgint redcloud_set_video_enable(int enable);
22671d7fec4Smrgint redcloud_set_video_format(unsigned long format);
22771d7fec4Smrgint redcloud_set_video_size(unsigned short width, unsigned short height);
22871d7fec4Smrgint redcloud_set_video_yuv_pitch(unsigned long ypitch, unsigned long uvpitch);
22971d7fec4Smrgint redcloud_set_video_offset(unsigned long offset);
23071d7fec4Smrgint redcloud_set_video_yuv_offsets(unsigned long yoffset,
23171d7fec4Smrg				   unsigned long uoffset,
23271d7fec4Smrg				   unsigned long voffset);
23371d7fec4Smrgint redcloud_set_video_window(short x, short y, unsigned short w,
23471d7fec4Smrg			      unsigned short h);
23571d7fec4Smrgint redcloud_set_video_left_crop(unsigned short x);
23671d7fec4Smrgint redcloud_set_video_upscale(unsigned short srcw, unsigned short srch,
23771d7fec4Smrg			       unsigned short dstw, unsigned short dsth);
23871d7fec4Smrgint redcloud_set_video_scale(unsigned short srcw, unsigned short srch,
23971d7fec4Smrg			     unsigned short dstw, unsigned short dsth);
24071d7fec4Smrgint redcloud_set_video_vertical_downscale(unsigned short srch,
24171d7fec4Smrg					  unsigned short dsth);
24271d7fec4Smrgvoid redcloud_set_video_vertical_downscale_enable(int enable);
24371d7fec4Smrgint redcloud_set_video_downscale_config(unsigned short type,
24471d7fec4Smrg					unsigned short m);
24571d7fec4Smrgint redcloud_set_video_color_key(unsigned long key, unsigned long mask,
24671d7fec4Smrg				 int bluescreen);
24771d7fec4Smrgint redcloud_set_video_filter(int xfilter, int yfilter);
24871d7fec4Smrgint redcloud_set_video_palette(unsigned long *palette);
24971d7fec4Smrgint redcloud_set_video_palette_entry(unsigned long index,
25071d7fec4Smrg				     unsigned long color);
25171d7fec4Smrgint redcloud_set_video_downscale_coefficients(unsigned short coef1,
25271d7fec4Smrg					      unsigned short coef2,
25371d7fec4Smrg					      unsigned short coef3,
25471d7fec4Smrg					      unsigned short coef4);
25571d7fec4Smrgint redcloud_set_video_downscale_enable(int enable);
25671d7fec4Smrgint redcloud_set_video_source(VideoSourceType source);
25771d7fec4Smrgint redcloud_set_vbi_source(VbiSourceType source);
25871d7fec4Smrgint redcloud_set_vbi_lines(unsigned long even, unsigned long odd);
25971d7fec4Smrgint redcloud_set_vbi_total(unsigned long even, unsigned long odd);
26071d7fec4Smrgint redcloud_set_video_interlaced(int enable);
26171d7fec4Smrgint redcloud_set_color_space_YUV(int enable);
26271d7fec4Smrgint redcloud_set_vertical_scaler_offset(char offset);
26371d7fec4Smrgint redcloud_set_top_line_in_odd(int enable);
26471d7fec4Smrgint redcloud_set_genlock_delay(unsigned long delay);
26571d7fec4Smrgint redcloud_set_genlock_enable(int flags);
26671d7fec4Smrgint redcloud_set_video_cursor(unsigned long key, unsigned long mask,
26771d7fec4Smrg			      unsigned short select_color2,
26871d7fec4Smrg			      unsigned long color1, unsigned long color2);
26971d7fec4Smrgint redcloud_set_video_cursor_enable(int enable);
27071d7fec4Smrgint redcloud_set_video_request(short x, short y);
27171d7fec4Smrg
27271d7fec4Smrgint redcloud_select_alpha_region(int region);
27371d7fec4Smrgint redcloud_set_alpha_enable(int enable);
27471d7fec4Smrgint redcloud_set_alpha_window(short x, short y,
27571d7fec4Smrg			      unsigned short width, unsigned short height);
27671d7fec4Smrgint redcloud_set_alpha_value(unsigned char alpha, char delta);
27771d7fec4Smrgint redcloud_set_alpha_priority(int priority);
27871d7fec4Smrgint redcloud_set_alpha_color(unsigned long color);
27971d7fec4Smrgint redcloud_set_alpha_color_enable(int enable);
28071d7fec4Smrgint redcloud_set_no_ck_outside_alpha(int enable);
28171d7fec4Smrgint redcloud_disable_softvga(void);
28271d7fec4Smrgint redcloud_enable_softvga(void);
28371d7fec4Smrgint redcloud_set_macrovision_enable(int enable);
28471d7fec4Smrgvoid redcloud_reset_video(void);
28571d7fec4Smrgint redcloud_set_display_control(int sync_polarities);
28671d7fec4Smrgvoid redcloud_set_clock_frequency(unsigned long frequency);
28771d7fec4Smrgint redcloud_set_crt_enable(int enable);
28871d7fec4Smrg
28971d7fec4Smrg/* READ ROUTINES IN GFX_VID.C */
29071d7fec4Smrg
29171d7fec4Smrgint redcloud_get_video_enable(void);
29271d7fec4Smrgint redcloud_get_video_format(void);
29371d7fec4Smrgunsigned long redcloud_get_video_src_size(void);
29471d7fec4Smrgunsigned long redcloud_get_video_line_size(void);
29571d7fec4Smrgunsigned long redcloud_get_video_xclip(void);
29671d7fec4Smrgunsigned long redcloud_get_video_offset(void);
29771d7fec4Smrgvoid redcloud_get_video_yuv_offsets(unsigned long *yoffset,
29871d7fec4Smrg				    unsigned long *uoffset,
29971d7fec4Smrg				    unsigned long *voffset);
30071d7fec4Smrgvoid redcloud_get_video_yuv_pitch(unsigned long *ypitch,
30171d7fec4Smrg				  unsigned long *uvpitch);
30271d7fec4Smrgunsigned long redcloud_get_video_upscale(void);
30371d7fec4Smrgunsigned long redcloud_get_video_scale(void);
30471d7fec4Smrgunsigned long redcloud_get_video_downscale_delta(void);
30571d7fec4Smrgint redcloud_get_video_vertical_downscale_enable(void);
30671d7fec4Smrgint redcloud_get_video_downscale_config(unsigned short *type,
30771d7fec4Smrg					unsigned short *m);
30871d7fec4Smrgvoid redcloud_get_video_downscale_coefficients(unsigned short *coef1,
30971d7fec4Smrg					       unsigned short *coef2,
31071d7fec4Smrg					       unsigned short *coef3,
31171d7fec4Smrg					       unsigned short *coef4);
31271d7fec4Smrgvoid redcloud_get_video_downscale_enable(int *enable);
31371d7fec4Smrgunsigned long redcloud_get_video_dst_size(void);
31471d7fec4Smrgunsigned long redcloud_get_video_position(void);
31571d7fec4Smrgunsigned long redcloud_get_video_color_key(void);
31671d7fec4Smrgunsigned long redcloud_get_video_color_key_mask(void);
31771d7fec4Smrgint redcloud_get_video_palette_entry(unsigned long index,
31871d7fec4Smrg				     unsigned long *palette);
31971d7fec4Smrgint redcloud_get_video_color_key_src(void);
32071d7fec4Smrgint redcloud_get_video_filter(void);
32171d7fec4Smrgint redcloud_get_video_request(short *x, short *y);
32271d7fec4Smrgint redcloud_get_video_source(VideoSourceType * source);
32371d7fec4Smrgint redcloud_get_vbi_source(VbiSourceType * source);
32471d7fec4Smrgunsigned long redcloud_get_vbi_lines(int odd);
32571d7fec4Smrgunsigned long redcloud_get_vbi_total(int odd);
32671d7fec4Smrgint redcloud_get_video_interlaced(void);
32771d7fec4Smrgint redcloud_get_color_space_YUV(void);
32871d7fec4Smrgint redcloud_get_vertical_scaler_offset(char *offset);
32971d7fec4Smrgunsigned long redcloud_get_genlock_delay(void);
33071d7fec4Smrgint redcloud_get_genlock_enable(void);
33171d7fec4Smrgint redcloud_get_video_cursor(unsigned long *key, unsigned long *mask,
33271d7fec4Smrg			      unsigned short *select_color2,
33371d7fec4Smrg			      unsigned long *color1, unsigned short *color2);
33471d7fec4Smrgunsigned long redcloud_read_crc(void);
33571d7fec4Smrgunsigned long redcloud_read_crc32(void);
33671d7fec4Smrgunsigned long redcloud_read_window_crc(int source, unsigned short x,
33771d7fec4Smrg				       unsigned short y, unsigned short width,
33871d7fec4Smrg				       unsigned short height, int crc32);
33971d7fec4Smrgint redcloud_get_macrovision_enable(void);
34071d7fec4Smrg
34171d7fec4Smrgvoid redcloud_get_alpha_enable(int *enable);
34271d7fec4Smrgvoid redcloud_get_alpha_size(unsigned short *x, unsigned short *y,
34371d7fec4Smrg			     unsigned short *width, unsigned short *height);
34471d7fec4Smrgvoid redcloud_get_alpha_value(unsigned char *alpha, char *delta);
34571d7fec4Smrgvoid redcloud_get_alpha_priority(int *priority);
34671d7fec4Smrgvoid redcloud_get_alpha_color(unsigned long *color);
34771d7fec4Smrgunsigned long redcloud_get_clock_frequency(void);
34871d7fec4Smrgint redcloud_get_sync_polarities(void);
34971d7fec4Smrg
35071d7fec4Smrg/*---------------------------------------------------------------------------
35171d7fec4Smrg * gfx_reset_video (PRIVATE ROUTINE: NOT PART OF DURANGO API)
35271d7fec4Smrg *
35371d7fec4Smrg * This routine is used to disable all components of video overlay before
35471d7fec4Smrg * performing a mode switch.
35571d7fec4Smrg *---------------------------------------------------------------------------
35671d7fec4Smrg */
35771d7fec4Smrg#if GFX_VIDEO_DYNAMIC
35871d7fec4Smrgvoid
35971d7fec4Smrgredcloud_reset_video(void)
36071d7fec4Smrg#else
36171d7fec4Smrgvoid
36271d7fec4Smrggfx_reset_video(void)
36371d7fec4Smrg#endif
36471d7fec4Smrg{
36571d7fec4Smrg   gfx_set_video_enable(0);
36671d7fec4Smrg   gfx_select_alpha_region(1);
36771d7fec4Smrg   gfx_set_alpha_enable(0);
36871d7fec4Smrg   gfx_select_alpha_region(2);
36971d7fec4Smrg   gfx_set_alpha_enable(0);
37071d7fec4Smrg
37171d7fec4Smrg   /* SET REGION 0 AFTER RESET */
37271d7fec4Smrg
37371d7fec4Smrg   gfx_select_alpha_region(0);
37471d7fec4Smrg   gfx_set_alpha_enable(0);
37571d7fec4Smrg}
37671d7fec4Smrg
37771d7fec4Smrg/*-----------------------------------------------------------------------------
37871d7fec4Smrg * gfx_set_display_control (PRIVATE ROUTINE: NOT PART OF DURANGO API)
37971d7fec4Smrg *
38071d7fec4Smrg * This routine configures the display output.
38171d7fec4Smrg *
38271d7fec4Smrg * "sync_polarities" is used to set the polarities of the sync pulses according
38371d7fec4Smrg * to the following mask:
38471d7fec4Smrg *
38571d7fec4Smrg *     Bit 0: If set to 1, negative horizontal polarity is programmed,
38671d7fec4Smrg *            otherwise positive horizontal polarity is programmed.
38771d7fec4Smrg *     Bit 1: If set to 1, negative vertical polarity is programmed,
38871d7fec4Smrg *            otherwise positive vertical polarity is programmed.
38971d7fec4Smrg *
39071d7fec4Smrg *-----------------------------------------------------------------------------
39171d7fec4Smrg */
39271d7fec4Smrg#if GFX_VIDEO_DYNAMIC
39371d7fec4Smrgint
39471d7fec4Smrgredcloud_set_display_control(int sync_polarities)
39571d7fec4Smrg#else
39671d7fec4Smrgint
39771d7fec4Smrggfx_set_display_control(int sync_polarities)
39871d7fec4Smrg#endif
39971d7fec4Smrg{
40071d7fec4Smrg   unsigned long power;
40171d7fec4Smrg   unsigned long dcfg;
40271d7fec4Smrg
40371d7fec4Smrg   /* CONFIGURE DISPLAY OUTPUT FROM VIDEO PROCESSOR */
40471d7fec4Smrg
40571d7fec4Smrg   dcfg = READ_VID32(RCDF_DISPLAY_CONFIG);
40671d7fec4Smrg   dcfg &= ~(RCDF_DCFG_CRT_SYNC_SKW_MASK | RCDF_DCFG_PWR_SEQ_DLY_MASK |
40771d7fec4Smrg	     RCDF_DCFG_CRT_HSYNC_POL | RCDF_DCFG_CRT_VSYNC_POL |
40871d7fec4Smrg	     RCDF_DCFG_FP_PWR_EN | RCDF_DCFG_FP_DATA_EN);
40971d7fec4Smrg
41071d7fec4Smrg   dcfg |= (RCDF_DCFG_CRT_SYNC_SKW_INIT |
41171d7fec4Smrg	    RCDF_DCFG_PWR_SEQ_DLY_INIT | RCDF_DCFG_GV_PAL_BYP);
41271d7fec4Smrg
41371d7fec4Smrg   if (PanelEnable) {
41471d7fec4Smrg      power = READ_VID32(RCDF_POWER_MANAGEMENT);
41571d7fec4Smrg      power |= RCDF_PM_PANEL_POWER_ON;
41671d7fec4Smrg      WRITE_VID32(RCDF_POWER_MANAGEMENT, power);
41771d7fec4Smrg   }
41871d7fec4Smrg
41971d7fec4Smrg   /* SET APPROPRIATE SYNC POLARITIES */
42071d7fec4Smrg
42171d7fec4Smrg   if (sync_polarities & 0x1)
42271d7fec4Smrg      dcfg |= RCDF_DCFG_CRT_HSYNC_POL;
42371d7fec4Smrg   if (sync_polarities & 0x2)
42471d7fec4Smrg      dcfg |= RCDF_DCFG_CRT_VSYNC_POL;
42571d7fec4Smrg
42671d7fec4Smrg   WRITE_VID32(RCDF_DISPLAY_CONFIG, dcfg);
42771d7fec4Smrg
42871d7fec4Smrg   return (0);
42971d7fec4Smrg}
43071d7fec4Smrg
43171d7fec4Smrg/*---------------------------------------------------------------------------
43271d7fec4Smrg * gfx_set_clock_frequency
43371d7fec4Smrg *
43471d7fec4Smrg * This routine sets the clock frequency, specified as a 16.16 fixed point
43571d7fec4Smrg * value (0x00318000 = 49.5 MHz).  It will set the closest frequency found
43671d7fec4Smrg * in the lookup table.
43771d7fec4Smrg *---------------------------------------------------------------------------
43871d7fec4Smrg */
43971d7fec4Smrg#if GFX_VIDEO_DYNAMIC
44071d7fec4Smrgvoid
44171d7fec4Smrgredcloud_set_clock_frequency(unsigned long frequency)
44271d7fec4Smrg#else
44371d7fec4Smrgvoid
44471d7fec4Smrggfx_set_clock_frequency(unsigned long frequency)
44571d7fec4Smrg#endif
44671d7fec4Smrg{
44771d7fec4Smrg   Q_WORD msr_value;
44871d7fec4Smrg   unsigned int i, index = 0;
44971d7fec4Smrg   unsigned long value;
45071d7fec4Smrg   long timeout = 1000;
45171d7fec4Smrg   long min, diff;
45271d7fec4Smrg   RCDFPLLENTRY *PllTable;
45371d7fec4Smrg
45471d7fec4Smrg   /* READ PLL REFERENCE FREQUENCY */
45571d7fec4Smrg   /* The reference frequency of GX2 1.x is different from 2.x and above. */
45671d7fec4Smrg
45771d7fec4Smrg   if ((gfx_cpu_version & 0xFF00) >= 0x0200)
45871d7fec4Smrg      PllTable = RCDF_PLLtable48MHz;
45971d7fec4Smrg   else
46071d7fec4Smrg      PllTable = RCDF_PLLtable14MHz;
46171d7fec4Smrg
46271d7fec4Smrg   /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */
46371d7fec4Smrg   /* Search the table for the closest frequency (16.16 format). */
46471d7fec4Smrg
46571d7fec4Smrg   value = PllTable[0].pll_value;
46671d7fec4Smrg   min = (long)PllTable[0].frequency - frequency;
46771d7fec4Smrg   if (min < 0L)
46871d7fec4Smrg      min = -min;
46971d7fec4Smrg   for (i = 1; i < NUM_RCDF_FREQUENCIES; i++) {
47071d7fec4Smrg      diff = (long)PllTable[i].frequency - frequency;
47171d7fec4Smrg      if (diff < 0L)
47271d7fec4Smrg	 diff = -diff;
47371d7fec4Smrg      if (diff < min) {
47471d7fec4Smrg	 min = diff;
47571d7fec4Smrg	 index = i;
47671d7fec4Smrg      }
47771d7fec4Smrg   }
47871d7fec4Smrg
47971d7fec4Smrg   /* PROGRAM THE SETTINGS WITH THE RESET BIT SET */
48071d7fec4Smrg   /* Clear the bypass bit to ensure that the programmed */
48171d7fec4Smrg   /* M, N and P values are being used.                  */
48271d7fec4Smrg
48371d7fec4Smrg   gfx_msr_read(RC_ID_MCP, MCP_DOTPLL, &msr_value);
48471d7fec4Smrg   msr_value.high = PllTable[index].pll_value;
48571d7fec4Smrg   msr_value.low |= 0x00000001;
48671d7fec4Smrg   msr_value.low &= ~MCP_DOTPLL_BYPASS;
48771d7fec4Smrg   gfx_msr_write(RC_ID_MCP, MCP_DOTPLL, &msr_value);
48871d7fec4Smrg
48971d7fec4Smrg   /* PROGRAM THE MCP DIVIDER VALUES */
49071d7fec4Smrg
49171d7fec4Smrg   gfx_msr_read(RC_ID_MCP, MCP_SYS_RSTPLL, &msr_value);
49271d7fec4Smrg   if (PllTable[index].post_div3)
49371d7fec4Smrg      msr_value.low |= MCP_DOTPOSTDIV3;
49471d7fec4Smrg   else
49571d7fec4Smrg      msr_value.low &= ~MCP_DOTPOSTDIV3;
49671d7fec4Smrg   if (PllTable[index].pre_div2)
49771d7fec4Smrg      msr_value.low |= MCP_DOTPREDIV2;
49871d7fec4Smrg   else
49971d7fec4Smrg      msr_value.low &= ~MCP_DOTPREDIV2;
50071d7fec4Smrg   if (PllTable[index].pre_mul2)
50171d7fec4Smrg      msr_value.low |= MCP_DOTPREMULT2;
50271d7fec4Smrg   else
50371d7fec4Smrg      msr_value.low &= ~MCP_DOTPREMULT2;
50471d7fec4Smrg   gfx_msr_write(RC_ID_MCP, MCP_SYS_RSTPLL, &msr_value);
50571d7fec4Smrg
50671d7fec4Smrg   /* CLEAR THE RESET BIT */
50771d7fec4Smrg
50871d7fec4Smrg   gfx_msr_read(RC_ID_MCP, MCP_DOTPLL, &msr_value);
50971d7fec4Smrg   msr_value.low &= 0xFFFFFFFE;
51071d7fec4Smrg   gfx_msr_write(RC_ID_MCP, MCP_DOTPLL, &msr_value);
51171d7fec4Smrg
51271d7fec4Smrg   /* WAIT FOR LOCK BIT */
51371d7fec4Smrg
51471d7fec4Smrg   do {
51571d7fec4Smrg      gfx_msr_read(RC_ID_MCP, MCP_DOTPLL, &msr_value);
51671d7fec4Smrg   } while (timeout-- && !(msr_value.low & MCP_DOTPLL_LOCK));
51771d7fec4Smrg}
51871d7fec4Smrg
51971d7fec4Smrg/*---------------------------------------------------------------------------
52071d7fec4Smrg * gfx_set_crt_enable
52171d7fec4Smrg *
52271d7fec4Smrg * This routine enables or disables the CRT output from the video processor.
52371d7fec4Smrg *---------------------------------------------------------------------------
52471d7fec4Smrg */
52571d7fec4Smrg#if GFX_VIDEO_DYNAMIC
52671d7fec4Smrgint
52771d7fec4Smrgredcloud_set_crt_enable(int enable)
52871d7fec4Smrg#else
52971d7fec4Smrgint
53071d7fec4Smrggfx_set_crt_enable(int enable)
53171d7fec4Smrg#endif
53271d7fec4Smrg{
53371d7fec4Smrg   unsigned long config, misc;
53471d7fec4Smrg
53571d7fec4Smrg   config = READ_VID32(RCDF_DISPLAY_CONFIG);
53671d7fec4Smrg   misc = READ_VID32(RCDF_VID_MISC);
53771d7fec4Smrg
53871d7fec4Smrg   switch (enable) {
53971d7fec4Smrg   case CRT_DISABLE:			/* DISABLE EVERYTHING */
54071d7fec4Smrg
54171d7fec4Smrg      WRITE_VID32(RCDF_DISPLAY_CONFIG,
54271d7fec4Smrg		  config & ~(RCDF_DCFG_DIS_EN | RCDF_DCFG_HSYNC_EN |
54371d7fec4Smrg			     RCDF_DCFG_VSYNC_EN | RCDF_DCFG_DAC_BL_EN));
54471d7fec4Smrg      WRITE_VID32(RCDF_VID_MISC, misc | RCDF_DAC_POWER_DOWN);
54571d7fec4Smrg      break;
54671d7fec4Smrg
54771d7fec4Smrg   case CRT_ENABLE:			/* ENABLE CRT DISPLAY, INCLUDING DISPLAY LOGIC */
54871d7fec4Smrg
54971d7fec4Smrg      WRITE_VID32(RCDF_DISPLAY_CONFIG,
55071d7fec4Smrg		  config | RCDF_DCFG_DIS_EN | RCDF_DCFG_HSYNC_EN |
55171d7fec4Smrg		  RCDF_DCFG_VSYNC_EN | RCDF_DCFG_DAC_BL_EN);
55271d7fec4Smrg      WRITE_VID32(RCDF_VID_MISC,
55371d7fec4Smrg		  misc & ~RCDF_DAC_POWER_DOWN & ~RCDF_ANALOG_POWER_DOWN);
55471d7fec4Smrg      break;
55571d7fec4Smrg
55671d7fec4Smrg   case CRT_STANDBY:			/* HSYNC:OFF VSYNC:ON */
55771d7fec4Smrg
55871d7fec4Smrg      WRITE_VID32(RCDF_DISPLAY_CONFIG,
55971d7fec4Smrg		  (config &
56071d7fec4Smrg		   ~(RCDF_DCFG_DIS_EN | RCDF_DCFG_HSYNC_EN |
56171d7fec4Smrg		     RCDF_DCFG_DAC_BL_EN)) | RCDF_DCFG_VSYNC_EN);
56271d7fec4Smrg      WRITE_VID32(RCDF_VID_MISC, misc | RCDF_DAC_POWER_DOWN);
56371d7fec4Smrg      break;
56471d7fec4Smrg
56571d7fec4Smrg   case CRT_SUSPEND:			/* HSYNC:ON VSYNC:OFF */
56671d7fec4Smrg
56771d7fec4Smrg      WRITE_VID32(RCDF_DISPLAY_CONFIG,
56871d7fec4Smrg		  (config &
56971d7fec4Smrg		   ~(RCDF_DCFG_DIS_EN | RCDF_DCFG_VSYNC_EN |
57071d7fec4Smrg		     RCDF_DCFG_DAC_BL_EN)) | RCDF_DCFG_HSYNC_EN);
57171d7fec4Smrg      WRITE_VID32(RCDF_VID_MISC, misc | RCDF_DAC_POWER_DOWN);
57271d7fec4Smrg      break;
57371d7fec4Smrg
57471d7fec4Smrg   default:
57571d7fec4Smrg      return (GFX_STATUS_BAD_PARAMETER);
57671d7fec4Smrg   }
57771d7fec4Smrg   return (GFX_STATUS_OK);
57871d7fec4Smrg}
57971d7fec4Smrg
58071d7fec4Smrg/*-----------------------------------------------------------------------------
58171d7fec4Smrg * gfx_set_video_enable
58271d7fec4Smrg *
58371d7fec4Smrg * This routine enables or disables the video overlay functionality.
58471d7fec4Smrg *-----------------------------------------------------------------------------
58571d7fec4Smrg */
58671d7fec4Smrg#if GFX_VIDEO_DYNAMIC
58771d7fec4Smrgint
58871d7fec4Smrgredcloud_set_video_enable(int enable)
58971d7fec4Smrg#else
59071d7fec4Smrgint
59171d7fec4Smrggfx_set_video_enable(int enable)
59271d7fec4Smrg#endif
59371d7fec4Smrg{
59471d7fec4Smrg   unsigned long vcfg;
59571d7fec4Smrg
59671d7fec4Smrg   /* WAIT FOR VERTICAL BLANK TO START */
59771d7fec4Smrg   /* Otherwise a glitch can be observed. */
59871d7fec4Smrg
59971d7fec4Smrg   if (gfx_test_timing_active()) {
60071d7fec4Smrg      if (!gfx_test_vertical_active()) {
60171d7fec4Smrg	 while (!gfx_test_vertical_active()) ;
60271d7fec4Smrg      }
60371d7fec4Smrg      while (gfx_test_vertical_active()) ;
60471d7fec4Smrg   }
60571d7fec4Smrg
60671d7fec4Smrg   vcfg = READ_VID32(RCDF_VIDEO_CONFIG);
60771d7fec4Smrg   if (enable) {
60871d7fec4Smrg      /* ENABLE VIDEO OVERLAY FROM DISPLAY CONTROLLER */
60971d7fec4Smrg      /* Use private routine to abstract the display controller. */
61071d7fec4Smrg
61171d7fec4Smrg      gfx_set_display_video_enable(1);
61271d7fec4Smrg
61371d7fec4Smrg      /* ENABLE DISPLAY FILTER VIDEO OVERLAY */
61471d7fec4Smrg
61571d7fec4Smrg      vcfg |= RCDF_VCFG_VID_EN;
61671d7fec4Smrg      WRITE_VID32(RCDF_VIDEO_CONFIG, vcfg);
61771d7fec4Smrg   } else {
61871d7fec4Smrg      /* DISABLE DISPLAY FILTER VIDEO OVERLAY */
61971d7fec4Smrg
62071d7fec4Smrg      vcfg &= ~RCDF_VCFG_VID_EN;
62171d7fec4Smrg      WRITE_VID32(RCDF_VIDEO_CONFIG, vcfg);
62271d7fec4Smrg
62371d7fec4Smrg      /* DISABLE VIDEO OVERLAY FROM DISPLAY CONTROLLER */
62471d7fec4Smrg      /* Use private routine to abstract the display controller. */
62571d7fec4Smrg
62671d7fec4Smrg      gfx_set_display_video_enable(0);
62771d7fec4Smrg   }
62871d7fec4Smrg   return (0);
62971d7fec4Smrg}
63071d7fec4Smrg
63171d7fec4Smrg/*-----------------------------------------------------------------------------
63271d7fec4Smrg * gfx_set_video_format
63371d7fec4Smrg *
63471d7fec4Smrg * Sets input video format type, to one of the YUV formats or to RGB.
63571d7fec4Smrg *-----------------------------------------------------------------------------
63671d7fec4Smrg */
63771d7fec4Smrg#if GFX_VIDEO_DYNAMIC
63871d7fec4Smrgint
63971d7fec4Smrgredcloud_set_video_format(unsigned long format)
64071d7fec4Smrg#else
64171d7fec4Smrgint
64271d7fec4Smrggfx_set_video_format(unsigned long format)
64371d7fec4Smrg#endif
64471d7fec4Smrg{
64571d7fec4Smrg   unsigned long ctrl, vcfg = 0;
64671d7fec4Smrg
64771d7fec4Smrg   /* SET THE DISPLAY FILTER VIDEO INPUT FORMAT */
64871d7fec4Smrg
64971d7fec4Smrg   vcfg = READ_VID32(RCDF_VIDEO_CONFIG);
65071d7fec4Smrg   ctrl = READ_VID32(RCDF_VID_ALPHA_CONTROL);
65171d7fec4Smrg   ctrl &= ~(RCDF_VIDEO_INPUT_IS_RGB | RCDF_CSC_VIDEO_YUV_TO_RGB);
65271d7fec4Smrg   vcfg &= ~(RCDF_VCFG_VID_INP_FORMAT | RCDF_VCFG_4_2_0_MODE);
65371d7fec4Smrg   switch (format) {
65471d7fec4Smrg   case VIDEO_FORMAT_UYVY:
65571d7fec4Smrg      vcfg |= RCDF_VCFG_UYVY_FORMAT;
65671d7fec4Smrg      ctrl |= RCDF_CSC_VIDEO_YUV_TO_RGB;
65771d7fec4Smrg      break;
65871d7fec4Smrg   case VIDEO_FORMAT_YUYV:
65971d7fec4Smrg      vcfg |= RCDF_VCFG_YUYV_FORMAT;
66071d7fec4Smrg      ctrl |= RCDF_CSC_VIDEO_YUV_TO_RGB;
66171d7fec4Smrg      break;
66271d7fec4Smrg   case VIDEO_FORMAT_Y2YU:
66371d7fec4Smrg      vcfg |= RCDF_VCFG_Y2YU_FORMAT;
66471d7fec4Smrg      ctrl |= RCDF_CSC_VIDEO_YUV_TO_RGB;
66571d7fec4Smrg      break;
66671d7fec4Smrg   case VIDEO_FORMAT_YVYU:
66771d7fec4Smrg      vcfg |= RCDF_VCFG_YVYU_FORMAT;
66871d7fec4Smrg      ctrl |= RCDF_CSC_VIDEO_YUV_TO_RGB;
66971d7fec4Smrg      break;
67071d7fec4Smrg   case VIDEO_FORMAT_Y0Y1Y2Y3:
67171d7fec4Smrg      vcfg |= RCDF_VCFG_UYVY_FORMAT;
67271d7fec4Smrg      ctrl |= RCDF_CSC_VIDEO_YUV_TO_RGB;
67371d7fec4Smrg      vcfg |= RCDF_VCFG_4_2_0_MODE;
67471d7fec4Smrg      break;
67571d7fec4Smrg   case VIDEO_FORMAT_Y3Y2Y1Y0:
67671d7fec4Smrg      vcfg |= RCDF_VCFG_Y2YU_FORMAT;
67771d7fec4Smrg      ctrl |= RCDF_CSC_VIDEO_YUV_TO_RGB;
67871d7fec4Smrg      vcfg |= RCDF_VCFG_4_2_0_MODE;
67971d7fec4Smrg      break;
68071d7fec4Smrg   case VIDEO_FORMAT_Y1Y0Y3Y2:
68171d7fec4Smrg      vcfg |= RCDF_VCFG_YUYV_FORMAT;
68271d7fec4Smrg      ctrl |= RCDF_CSC_VIDEO_YUV_TO_RGB;
68371d7fec4Smrg      vcfg |= RCDF_VCFG_4_2_0_MODE;
68471d7fec4Smrg      break;
68571d7fec4Smrg   case VIDEO_FORMAT_Y1Y2Y3Y0:
68671d7fec4Smrg      vcfg |= RCDF_VCFG_YVYU_FORMAT;
68771d7fec4Smrg      ctrl |= RCDF_CSC_VIDEO_YUV_TO_RGB;
68871d7fec4Smrg      vcfg |= RCDF_VCFG_4_2_0_MODE;
68971d7fec4Smrg      break;
69071d7fec4Smrg   case VIDEO_FORMAT_RGB:
69171d7fec4Smrg      ctrl |= RCDF_VIDEO_INPUT_IS_RGB;
69271d7fec4Smrg      vcfg |= RCDF_VCFG_UYVY_FORMAT;
69371d7fec4Smrg      break;
69471d7fec4Smrg   case VIDEO_FORMAT_P2M_P2L_P1M_P1L:
69571d7fec4Smrg      ctrl |= RCDF_VIDEO_INPUT_IS_RGB;
69671d7fec4Smrg      vcfg |= RCDF_VCFG_Y2YU_FORMAT;
69771d7fec4Smrg      break;
69871d7fec4Smrg   case VIDEO_FORMAT_P1M_P1L_P2M_P2L:
69971d7fec4Smrg      ctrl |= RCDF_VIDEO_INPUT_IS_RGB;
70071d7fec4Smrg      vcfg |= RCDF_VCFG_YUYV_FORMAT;
70171d7fec4Smrg      break;
70271d7fec4Smrg   case VIDEO_FORMAT_P1M_P2L_P2M_P1L:
70371d7fec4Smrg      ctrl |= RCDF_VIDEO_INPUT_IS_RGB;
70471d7fec4Smrg      vcfg |= RCDF_VCFG_YVYU_FORMAT;
70571d7fec4Smrg      break;
70671d7fec4Smrg   default:
70771d7fec4Smrg      return GFX_STATUS_BAD_PARAMETER;
70871d7fec4Smrg   }
70971d7fec4Smrg   WRITE_VID32(RCDF_VIDEO_CONFIG, vcfg);
71071d7fec4Smrg   WRITE_VID32(RCDF_VID_ALPHA_CONTROL, ctrl);
71171d7fec4Smrg
71271d7fec4Smrg   /* SET THE VIDEO FORMAT IN THE DISPLAY CONTROLLER      */
71371d7fec4Smrg   /* Use private routine to abstract display controller. */
71471d7fec4Smrg
71571d7fec4Smrg   gfx_set_display_video_format(format);
71671d7fec4Smrg   return (0);
71771d7fec4Smrg}
71871d7fec4Smrg
71971d7fec4Smrg/*-----------------------------------------------------------------------------
72071d7fec4Smrg * gfx_set_video_size
72171d7fec4Smrg *
72271d7fec4Smrg * This routine specifies the size of the source data.  It is used only
72371d7fec4Smrg * to determine how much data to transfer per frame, and is not used to
72471d7fec4Smrg * calculate the scaling value (that is handled by a separate routine).
72571d7fec4Smrg *-----------------------------------------------------------------------------
72671d7fec4Smrg */
72771d7fec4Smrg#if GFX_VIDEO_DYNAMIC
72871d7fec4Smrgint
72971d7fec4Smrgredcloud_set_video_size(unsigned short width, unsigned short height)
73071d7fec4Smrg#else
73171d7fec4Smrgint
73271d7fec4Smrggfx_set_video_size(unsigned short width, unsigned short height)
73371d7fec4Smrg#endif
73471d7fec4Smrg{
73571d7fec4Smrg   unsigned long size, vcfg, vid_420, pitch;
73671d7fec4Smrg
73771d7fec4Smrg   /* SET THE DISPLAY FILTER VIDEO LINE SIZE                            */
73871d7fec4Smrg   /* Match the DC hardware alignment requirement.  The line size must  */
73971d7fec4Smrg   /* always be 32-byte aligned.  However, we can manage smaller        */
74071d7fec4Smrg   /* alignments by decreasing the pitch and clipping the video window. */
74171d7fec4Smrg   /* The VG will fetch extra data for each line, but the decreased     */
74271d7fec4Smrg   /* pitch will ensure that it always begins fetching at the start of  */
74371d7fec4Smrg   /* the video line.                                                   */
74471d7fec4Smrg
74571d7fec4Smrg   vcfg = READ_VID32(RCDF_VIDEO_CONFIG);
74671d7fec4Smrg
74771d7fec4Smrg   vid_420 = vcfg & RCDF_VCFG_4_2_0_MODE;
74871d7fec4Smrg
74971d7fec4Smrg   vcfg &= ~(RCDF_VCFG_LINE_SIZE_LOWER_MASK | RCDF_VCFG_LINE_SIZE_UPPER);
75071d7fec4Smrg
75171d7fec4Smrg   size = ((width >> 1) + 7) & 0xFFF8;
75271d7fec4Smrg   pitch = ((width << 1) + 7) & 0xFFF8;
75371d7fec4Smrg
75471d7fec4Smrg   vcfg |= (size & 0x00FF) << 8;
75571d7fec4Smrg   if (size & 0x0100)
75671d7fec4Smrg      vcfg |= RCDF_VCFG_LINE_SIZE_UPPER;
75771d7fec4Smrg   WRITE_VID32(RCDF_VIDEO_CONFIG, vcfg);
75871d7fec4Smrg
75971d7fec4Smrg   /* SET VIDEO BUFFER LINE SIZE IN DISPLAY CONTROLLER */
76071d7fec4Smrg   /* Use private routine to abstract the display controller. */
76171d7fec4Smrg
76271d7fec4Smrg   gfx_set_display_video_size(width, height);
76371d7fec4Smrg
76471d7fec4Smrg   /* SET VIDEO PITCH */
76571d7fec4Smrg   /* We are only maintaining legacy for 4:2:2 video formats. */
76671d7fec4Smrg   /* 4:2:0 video in previous chips was inadequate for most   */
76771d7fec4Smrg   /* common video formats.                                   */
76871d7fec4Smrg
76971d7fec4Smrg   if (!vid_420)
77071d7fec4Smrg      gfx_set_video_yuv_pitch(pitch, pitch << 1);
77171d7fec4Smrg
77271d7fec4Smrg   return (0);
77371d7fec4Smrg}
77471d7fec4Smrg
77571d7fec4Smrg/*-----------------------------------------------------------------------------
77671d7fec4Smrg * gfx_set_video_offset
77771d7fec4Smrg *
77871d7fec4Smrg * This routine sets the starting offset for the video buffer when only
77971d7fec4Smrg * one offset needs to be specified.
78071d7fec4Smrg *-----------------------------------------------------------------------------
78171d7fec4Smrg */
78271d7fec4Smrg#if GFX_VIDEO_DYNAMIC
78371d7fec4Smrgint
78471d7fec4Smrgredcloud_set_video_offset(unsigned long offset)
78571d7fec4Smrg#else
78671d7fec4Smrgint
78771d7fec4Smrggfx_set_video_offset(unsigned long offset)
78871d7fec4Smrg#endif
78971d7fec4Smrg{
79071d7fec4Smrg   /* SAVE VALUE FOR FUTURE CLIPPING OF THE TOP OF THE VIDEO WINDOW */
79171d7fec4Smrg
79271d7fec4Smrg   gfx_vid_offset = offset;
79371d7fec4Smrg
79471d7fec4Smrg   /* SET VIDEO BUFFER OFFSET IN DISPLAY CONTROLLER */
79571d7fec4Smrg   /* Use private routine to abstract the display controller. */
79671d7fec4Smrg
79771d7fec4Smrg   gfx_set_display_video_offset(offset);
79871d7fec4Smrg   return (0);
79971d7fec4Smrg}
80071d7fec4Smrg
80171d7fec4Smrg/*-----------------------------------------------------------------------------
80271d7fec4Smrg * gfx_set_video_yuv_offsets
80371d7fec4Smrg *
80471d7fec4Smrg * This routine sets the starting offset for the video buffer when displaying
80571d7fec4Smrg * 4:2:0 video.
80671d7fec4Smrg *-----------------------------------------------------------------------------
80771d7fec4Smrg */
80871d7fec4Smrg#if GFX_VIDEO_DYNAMIC
80971d7fec4Smrgint
81071d7fec4Smrgredcloud_set_video_yuv_offsets(unsigned long yoffset, unsigned long uoffset,
81171d7fec4Smrg			       unsigned long voffset)
81271d7fec4Smrg#else
81371d7fec4Smrgint
81471d7fec4Smrggfx_set_video_yuv_offsets(unsigned long yoffset, unsigned long uoffset,
81571d7fec4Smrg			  unsigned long voffset)
81671d7fec4Smrg#endif
81771d7fec4Smrg{
81871d7fec4Smrg   /* SAVE VALUE FOR FUTURE CLIPPING OF THE TOP OF THE VIDEO WINDOW */
81971d7fec4Smrg
82071d7fec4Smrg   gfx_vid_offset = yoffset;
82171d7fec4Smrg   gfx_vid_uoffset = uoffset;
82271d7fec4Smrg   gfx_vid_voffset = voffset;
82371d7fec4Smrg
82471d7fec4Smrg   /* SET VIDEO BUFFER OFFSET IN DISPLAY CONTROLLER */
82571d7fec4Smrg   /* Use private routine to abstract the display controller. */
82671d7fec4Smrg
82771d7fec4Smrg   gfx_set_display_video_yuv_offsets(yoffset, uoffset, voffset);
82871d7fec4Smrg
82971d7fec4Smrg   return (0);
83071d7fec4Smrg}
83171d7fec4Smrg
83271d7fec4Smrg/*-----------------------------------------------------------------------------
83371d7fec4Smrg * gfx_set_video_yuv_pitch
83471d7fec4Smrg *
83571d7fec4Smrg * This routine sets the byte offset between consecutive scanlines of YUV video data
83671d7fec4Smrg *-----------------------------------------------------------------------------
83771d7fec4Smrg */
83871d7fec4Smrg#if GFX_VIDEO_DYNAMIC
83971d7fec4Smrgint
84071d7fec4Smrgredcloud_set_video_yuv_pitch(unsigned long ypitch, unsigned long uvpitch)
84171d7fec4Smrg#else
84271d7fec4Smrgint
84371d7fec4Smrggfx_set_video_yuv_pitch(unsigned long ypitch, unsigned long uvpitch)
84471d7fec4Smrg#endif
84571d7fec4Smrg{
84671d7fec4Smrg   /* SET VIDEO PITCH IN DISPLAY CONTROLLER */
84771d7fec4Smrg   /* Use private routine to abstract the display controller. */
84871d7fec4Smrg
84971d7fec4Smrg   gfx_set_display_video_yuv_pitch(ypitch, uvpitch);
85071d7fec4Smrg
85171d7fec4Smrg   return (0);
85271d7fec4Smrg}
85371d7fec4Smrg
85471d7fec4Smrg/*---------------------------------------------------------------------------
85571d7fec4Smrg * gfx_set_video_scale
85671d7fec4Smrg *
85771d7fec4Smrg * This routine sets the scale factor for the video overlay window.  The
85871d7fec4Smrg * size of the source and destination regions are specified in pixels.
85971d7fec4Smrg *---------------------------------------------------------------------------
86071d7fec4Smrg */
86171d7fec4Smrg#if GFX_VIDEO_DYNAMIC
86271d7fec4Smrgint
86371d7fec4Smrgredcloud_set_video_scale(unsigned short srcw, unsigned short srch,
86471d7fec4Smrg			 unsigned short dstw, unsigned short dsth)
86571d7fec4Smrg#else
86671d7fec4Smrgint
86771d7fec4Smrggfx_set_video_scale(unsigned short srcw, unsigned short srch,
86871d7fec4Smrg		    unsigned short dstw, unsigned short dsth)
86971d7fec4Smrg#endif
87071d7fec4Smrg{
87171d7fec4Smrg   unsigned long xscale, yscale;
87271d7fec4Smrg
87371d7fec4Smrg   /* SAVE PARAMETERS (unless don't-care zero destination arguments are used) */
87471d7fec4Smrg   /* These are needed for clipping the video window later. */
87571d7fec4Smrg
87671d7fec4Smrg   if (dstw != 0) {
87771d7fec4Smrg      gfx_vid_srcw = srcw;
87871d7fec4Smrg      gfx_vid_dstw = dstw;
87971d7fec4Smrg   }
88071d7fec4Smrg   if (dsth != 0) {
88171d7fec4Smrg      gfx_vid_srch = srch;
88271d7fec4Smrg      gfx_vid_dsth = dsth;
88371d7fec4Smrg   }
88471d7fec4Smrg
88571d7fec4Smrg   /* CALCULATE DISPLAY FILTER SCALE FACTORS */
88671d7fec4Smrg   /* Zero width and height indicate don't care conditions */
88771d7fec4Smrg   /* Downscaling is performed in a separate function.     */
88871d7fec4Smrg
88971d7fec4Smrg   if (dstw == 0)
89071d7fec4Smrg      xscale = READ_VID32(RCDF_VIDEO_SCALE) & 0xffff;	/* keep previous if don't-care argument */
89171d7fec4Smrg   else if (dstw <= srcw)
89271d7fec4Smrg      xscale = 0x2000;			/* horizontal downscaling is currently done in a separate function */
89371d7fec4Smrg   else if ((srcw == 1) || (dstw == 1))
89471d7fec4Smrg      return GFX_STATUS_BAD_PARAMETER;
89571d7fec4Smrg   else
89671d7fec4Smrg      xscale = (0x2000l * (srcw - 1l)) / (dstw - 1l);
89771d7fec4Smrg
89871d7fec4Smrg   if (dsth == 0)
89971d7fec4Smrg      yscale = (READ_VID32(RCDF_VIDEO_SCALE) & 0xffff0000) >> 16;	/* keep previous if don't-care argument */
90071d7fec4Smrg   else if (dsth <= srch)
90171d7fec4Smrg      yscale = 0x2000;			/* vertical downscaling is handled in a separate function */
90271d7fec4Smrg   else if ((srch == 1) || (dsth == 1))
90371d7fec4Smrg      return GFX_STATUS_BAD_PARAMETER;
90471d7fec4Smrg   else
90571d7fec4Smrg      yscale = (0x2000l * (srch - 1l)) / (dsth - 1l);
90671d7fec4Smrg
90771d7fec4Smrg   WRITE_VID32(RCDF_VIDEO_SCALE, (yscale << 16) | xscale);
90871d7fec4Smrg
90971d7fec4Smrg   /* CALL ROUTINE TO UPDATE WINDOW POSITION */
91071d7fec4Smrg   /* This is required because the scale values affect the number of */
91171d7fec4Smrg   /* source data pixels that need to be clipped, as well as the     */
91271d7fec4Smrg   /* amount of data that needs to be transferred.                   */
91371d7fec4Smrg
91471d7fec4Smrg   gfx_set_video_window(gfx_vid_xpos, gfx_vid_ypos, gfx_vid_width,
91571d7fec4Smrg			gfx_vid_height);
91671d7fec4Smrg   return (0);
91771d7fec4Smrg}
91871d7fec4Smrg
91971d7fec4Smrg/*---------------------------------------------------------------------------
92071d7fec4Smrg * gfx_set_video_vertical_downscale
92171d7fec4Smrg *
92271d7fec4Smrg * This routine sets the vertical downscale factor for the video overlay window.
92371d7fec4Smrg * The height of the source and destination regions are specified in pixels.
92471d7fec4Smrg *---------------------------------------------------------------------------
92571d7fec4Smrg */
92671d7fec4Smrg#if GFX_VIDEO_DYNAMIC
92771d7fec4Smrgint
92871d7fec4Smrgredcloud_set_video_vertical_downscale(unsigned short srch,
92971d7fec4Smrg				      unsigned short dsth)
93071d7fec4Smrg#else
93171d7fec4Smrgint
93271d7fec4Smrggfx_set_video_vertical_downscale(unsigned short srch, unsigned short dsth)
93371d7fec4Smrg#endif
93471d7fec4Smrg{
93571d7fec4Smrg   /* SET VIDEO SCALE IN DISPLAY CONTROLLER    */
93671d7fec4Smrg   /* Use private routine to abstract hardware */
93771d7fec4Smrg
93871d7fec4Smrg   gfx_set_display_video_downscale(srch, dsth);
93971d7fec4Smrg   return 0;
94071d7fec4Smrg}
94171d7fec4Smrg
94271d7fec4Smrg/*---------------------------------------------------------------------------
94371d7fec4Smrg * gfx_set_video_vertical_downscale_enable
94471d7fec4Smrg *
94571d7fec4Smrg * This routine sets the vertical downscale enable for the video overlay window.
94671d7fec4Smrg *---------------------------------------------------------------------------
94771d7fec4Smrg */
94871d7fec4Smrg#if GFX_VIDEO_DYNAMIC
94971d7fec4Smrgvoid
95071d7fec4Smrgredcloud_set_video_vertical_downscale_enable(int enable)
95171d7fec4Smrg#else
95271d7fec4Smrgvoid
95371d7fec4Smrggfx_set_video_vertical_downscale_enable(int enable)
95471d7fec4Smrg#endif
95571d7fec4Smrg{
95671d7fec4Smrg   /* SET VIDEO SCALE IN DISPLAY CONTROLLER    */
95771d7fec4Smrg   /* Use private routine to abstract hardware */
95871d7fec4Smrg
95971d7fec4Smrg   gfx_set_display_video_vertical_downscale_enable(enable);
96071d7fec4Smrg}
96171d7fec4Smrg
96271d7fec4Smrg/*---------------------------------------------------------------------------
96371d7fec4Smrg * gfx_set_video_downscale_config
96471d7fec4Smrg *
96571d7fec4Smrg * This routine sets the downscale type and factor for the video overlay window.
96671d7fec4Smrg * Note: No downscaling support for RGB565 and YUV420 video formats.
96771d7fec4Smrg *---------------------------------------------------------------------------
96871d7fec4Smrg */
96971d7fec4Smrg#if GFX_VIDEO_DYNAMIC
97071d7fec4Smrgint
97171d7fec4Smrgredcloud_set_video_downscale_config(unsigned short type, unsigned short m)
97271d7fec4Smrg#else
97371d7fec4Smrgint
97471d7fec4Smrggfx_set_video_downscale_config(unsigned short type, unsigned short m)
97571d7fec4Smrg#endif
97671d7fec4Smrg{
97771d7fec4Smrg   unsigned long downscale;
97871d7fec4Smrg
97971d7fec4Smrg   if ((m < 1) || (m > 16))
98071d7fec4Smrg      return GFX_STATUS_BAD_PARAMETER;
98171d7fec4Smrg
98271d7fec4Smrg   downscale = READ_VID32(RCDF_VIDEO_DOWNSCALER_CONTROL);
98371d7fec4Smrg   downscale &=
98471d7fec4Smrg	 ~(RCDF_VIDEO_DOWNSCALE_FACTOR_MASK | RCDF_VIDEO_DOWNSCALE_TYPE_MASK);
98571d7fec4Smrg   downscale |= ((unsigned long)(m - 1) << RCDF_VIDEO_DOWNSCALE_FACTOR_POS);
98671d7fec4Smrg   switch (type) {
98771d7fec4Smrg   case VIDEO_DOWNSCALE_KEEP_1_OF:
98871d7fec4Smrg      downscale |= RCDF_VIDEO_DOWNSCALE_TYPE_A;
98971d7fec4Smrg      break;
99071d7fec4Smrg   case VIDEO_DOWNSCALE_DROP_1_OF:
99171d7fec4Smrg      downscale |= RCDF_VIDEO_DOWNSCALE_TYPE_B;
99271d7fec4Smrg      break;
99371d7fec4Smrg   default:
99471d7fec4Smrg      return GFX_STATUS_BAD_PARAMETER;
99571d7fec4Smrg   }
99671d7fec4Smrg   WRITE_VID32(RCDF_VIDEO_DOWNSCALER_CONTROL, downscale);
99771d7fec4Smrg   return (0);
99871d7fec4Smrg}
99971d7fec4Smrg
100071d7fec4Smrg/*---------------------------------------------------------------------------
100171d7fec4Smrg * gfx_set_video_downscale_coefficients
100271d7fec4Smrg *
100371d7fec4Smrg * This routine sets the downscale filter coefficients.
100471d7fec4Smrg *---------------------------------------------------------------------------
100571d7fec4Smrg */
100671d7fec4Smrg#if GFX_VIDEO_DYNAMIC
100771d7fec4Smrgint
100871d7fec4Smrgredcloud_set_video_downscale_coefficients(unsigned short coef1,
100971d7fec4Smrg					  unsigned short coef2,
101071d7fec4Smrg					  unsigned short coef3,
101171d7fec4Smrg					  unsigned short coef4)
101271d7fec4Smrg#else
101371d7fec4Smrgint
101471d7fec4Smrggfx_set_video_downscale_coefficients(unsigned short coef1,
101571d7fec4Smrg				     unsigned short coef2,
101671d7fec4Smrg				     unsigned short coef3,
101771d7fec4Smrg				     unsigned short coef4)
101871d7fec4Smrg#endif
101971d7fec4Smrg{
102071d7fec4Smrg   if ((coef1 + coef2 + coef3 + coef4) != 16)
102171d7fec4Smrg      return GFX_STATUS_BAD_PARAMETER;
102271d7fec4Smrg
102371d7fec4Smrg   WRITE_VID32(RCDF_VIDEO_DOWNSCALER_COEFFICIENTS,
102471d7fec4Smrg	       ((unsigned long)coef1 << RCDF_VIDEO_DOWNSCALER_COEF1_POS) |
102571d7fec4Smrg	       ((unsigned long)coef2 << RCDF_VIDEO_DOWNSCALER_COEF2_POS) |
102671d7fec4Smrg	       ((unsigned long)coef3 << RCDF_VIDEO_DOWNSCALER_COEF3_POS) |
102771d7fec4Smrg	       ((unsigned long)coef4 << RCDF_VIDEO_DOWNSCALER_COEF4_POS));
102871d7fec4Smrg   return (0);
102971d7fec4Smrg}
103071d7fec4Smrg
103171d7fec4Smrg/*---------------------------------------------------------------------------
103271d7fec4Smrg * gfx_set_video_downscale_enable
103371d7fec4Smrg *
103471d7fec4Smrg * This routine enables or disables downscaling for the video overlay window.
103571d7fec4Smrg *---------------------------------------------------------------------------
103671d7fec4Smrg */
103771d7fec4Smrg#if GFX_VIDEO_DYNAMIC
103871d7fec4Smrgint
103971d7fec4Smrgredcloud_set_video_downscale_enable(int enable)
104071d7fec4Smrg#else
104171d7fec4Smrgint
104271d7fec4Smrggfx_set_video_downscale_enable(int enable)
104371d7fec4Smrg#endif
104471d7fec4Smrg{
104571d7fec4Smrg   unsigned long downscale;
104671d7fec4Smrg
104771d7fec4Smrg   downscale = READ_VID32(RCDF_VIDEO_DOWNSCALER_CONTROL);
104871d7fec4Smrg   if (enable)
104971d7fec4Smrg      downscale |= RCDF_VIDEO_DOWNSCALE_ENABLE;
105071d7fec4Smrg   else
105171d7fec4Smrg      downscale &= ~RCDF_VIDEO_DOWNSCALE_ENABLE;
105271d7fec4Smrg   WRITE_VID32(RCDF_VIDEO_DOWNSCALER_CONTROL, downscale);
105371d7fec4Smrg   return (0);
105471d7fec4Smrg}
105571d7fec4Smrg
105671d7fec4Smrg/*---------------------------------------------------------------------------
105771d7fec4Smrg * gfx_set_video_window
105871d7fec4Smrg *
105971d7fec4Smrg * This routine sets the position and size of the video overlay window.  The
106071d7fec4Smrg * x and y positions are specified in screen relative coordinates, and may be negative.
106171d7fec4Smrg * The size of destination region is specified in pixels.  The line size
106271d7fec4Smrg * indicates the number of bytes of source data per scanline.
106371d7fec4Smrg *---------------------------------------------------------------------------
106471d7fec4Smrg */
106571d7fec4Smrg#if GFX_VIDEO_DYNAMIC
106671d7fec4Smrgint
106771d7fec4Smrgredcloud_set_video_window(short x, short y, unsigned short w,
106871d7fec4Smrg			  unsigned short h)
106971d7fec4Smrg#else
107071d7fec4Smrgint
107171d7fec4Smrggfx_set_video_window(short x, short y, unsigned short w, unsigned short h)
107271d7fec4Smrg#endif
107371d7fec4Smrg{
107471d7fec4Smrg   unsigned long hadjust, vadjust;
107571d7fec4Smrg   unsigned long xstart, ystart, xend, yend;
107671d7fec4Smrg
107771d7fec4Smrg   /* SAVE PARAMETERS */
107871d7fec4Smrg   /* These are needed to call this routine if the scale value changes. */
107971d7fec4Smrg
108071d7fec4Smrg   gfx_vid_xpos = x;
108171d7fec4Smrg   gfx_vid_ypos = y;
108271d7fec4Smrg   gfx_vid_width = w;
108371d7fec4Smrg   gfx_vid_height = h;
108471d7fec4Smrg
108571d7fec4Smrg   /* GET ADJUSTMENT VALUES */
108671d7fec4Smrg   /* Use routines to abstract version of display controller. */
108771d7fec4Smrg
108871d7fec4Smrg   hadjust = gfx_get_htotal() - gfx_get_hsync_end() - 14l;
108971d7fec4Smrg   vadjust = gfx_get_vtotal() - gfx_get_vsync_end() + 1l;
109071d7fec4Smrg
109171d7fec4Smrg   /* HORIZONTAL START */
109271d7fec4Smrg   xstart = (unsigned long)x + hadjust;
109371d7fec4Smrg
109471d7fec4Smrg   /* HORIZONTAL END */
109571d7fec4Smrg   /* End positions in register are non-inclusive (one more than the actual end) */
109671d7fec4Smrg
109771d7fec4Smrg   if ((x + w) < gfx_get_hactive())
109871d7fec4Smrg      xend = (unsigned long)x + (unsigned long)w + hadjust;
109971d7fec4Smrg
110071d7fec4Smrg   /* RIGHT-CLIPPING */
110171d7fec4Smrg   else
110271d7fec4Smrg      xend = (unsigned long)gfx_get_hactive() + hadjust;
110371d7fec4Smrg
110471d7fec4Smrg   /* VERTICAL START */
110571d7fec4Smrg
110671d7fec4Smrg   ystart = (unsigned long)y + vadjust;
110771d7fec4Smrg
110871d7fec4Smrg   /* VERTICAL END */
110971d7fec4Smrg
111071d7fec4Smrg   if ((y + h) < gfx_get_vactive())
111171d7fec4Smrg      yend = (unsigned long)y + (unsigned long)h + vadjust;
111271d7fec4Smrg
111371d7fec4Smrg   /* BOTTOM-CLIPPING */
111471d7fec4Smrg   else
111571d7fec4Smrg      yend = (unsigned long)gfx_get_vactive() + vadjust;
111671d7fec4Smrg
111771d7fec4Smrg   /* SET VIDEO POSITION */
111871d7fec4Smrg
111971d7fec4Smrg   WRITE_VID32(RCDF_VIDEO_X_POS, (xend << 16) | xstart);
112071d7fec4Smrg   WRITE_VID32(RCDF_VIDEO_Y_POS, (yend << 16) | ystart);
112171d7fec4Smrg
112271d7fec4Smrg   return (0);
112371d7fec4Smrg}
112471d7fec4Smrg
112571d7fec4Smrg/*---------------------------------------------------------------------------
112671d7fec4Smrg * gfx_set_video_left_crop
112771d7fec4Smrg *
112871d7fec4Smrg * This routine sets the number of pixels which will be cropped from the
112971d7fec4Smrg * beginning of each video line. The video window will begin to display only
113071d7fec4Smrg * from the pixel following the cropped pixels, and the cropped pixels
113171d7fec4Smrg * will be ignored.
113271d7fec4Smrg *---------------------------------------------------------------------------
113371d7fec4Smrg */
113471d7fec4Smrg#if GFX_VIDEO_DYNAMIC
113571d7fec4Smrgint
113671d7fec4Smrgredcloud_set_video_left_crop(unsigned short x)
113771d7fec4Smrg#else
113871d7fec4Smrgint
113971d7fec4Smrggfx_set_video_left_crop(unsigned short x)
114071d7fec4Smrg#endif
114171d7fec4Smrg{
114271d7fec4Smrg   unsigned long vcfg, initread;
114371d7fec4Smrg
114471d7fec4Smrg   vcfg = READ_VID32(RCDF_VIDEO_CONFIG);
114571d7fec4Smrg
114671d7fec4Smrg   /* CLIPPING ON LEFT */
114771d7fec4Smrg   /* Adjust initial read for scale, checking for divide by zero. Mask the     */
114871d7fec4Smrg   /* lower three bits when clipping 4:2:0 video.  By masking the bits instead */
114971d7fec4Smrg   /* of rounding up we ensure that we always clip less than or equal to the   */
115071d7fec4Smrg   /* desired number of pixels.  This prevents visual artifacts from           */
115171d7fec4Smrg   /* over-clipping.  We mask three bits to meet the HW requirement that 4:2:0 */
115271d7fec4Smrg   /* clipping be 16-byte or 8-pixel aligned.                                  */
115371d7fec4Smrg
115471d7fec4Smrg   if (gfx_vid_dstw) {
115571d7fec4Smrg      initread = (unsigned long)x *gfx_vid_srcw / gfx_vid_dstw;
115671d7fec4Smrg
115771d7fec4Smrg      if (vcfg & RCDF_VCFG_4_2_0_MODE)
115871d7fec4Smrg	 initread &= 0xFFF8;
115971d7fec4Smrg   } else
116071d7fec4Smrg      initread = 0;
116171d7fec4Smrg
116271d7fec4Smrg   /* SET INITIAL READ ADDRESS */
116371d7fec4Smrg
116471d7fec4Smrg   vcfg &= ~RCDF_VCFG_INIT_READ_MASK;
116571d7fec4Smrg   vcfg |= (initread << 15) & RCDF_VCFG_INIT_READ_MASK;
116671d7fec4Smrg   WRITE_VID32(RCDF_VIDEO_CONFIG, vcfg);
116771d7fec4Smrg   return (0);
116871d7fec4Smrg}
116971d7fec4Smrg
117071d7fec4Smrg/*---------------------------------------------------------------------------
117171d7fec4Smrg * gfx_set_video_color_key
117271d7fec4Smrg *
117371d7fec4Smrg * This routine specifies the color key value and mask for the video overlay
117471d7fec4Smrg * hardware. To disable color key, the color and mask should both be set to
117571d7fec4Smrg * zero. The hardware uses the color key in the following equation:
117671d7fec4Smrg *
117771d7fec4Smrg * ((source data) & (color key mask)) == ((color key) & (color key mask))
117871d7fec4Smrg *
117971d7fec4Smrg * If "graphics" is set to TRUE, the source data is graphics, and color key
118071d7fec4Smrg * is an RGB value. If "graphics" is set to FALSE, the source data is the video,
118171d7fec4Smrg * and color key is a YUV value.
118271d7fec4Smrg *---------------------------------------------------------------------------
118371d7fec4Smrg */
118471d7fec4Smrg#if GFX_VIDEO_DYNAMIC
118571d7fec4Smrgint
118671d7fec4Smrgredcloud_set_video_color_key(unsigned long key, unsigned long mask,
118771d7fec4Smrg			     int graphics)
118871d7fec4Smrg#else
118971d7fec4Smrgint
119071d7fec4Smrggfx_set_video_color_key(unsigned long key, unsigned long mask, int graphics)
119171d7fec4Smrg#endif
119271d7fec4Smrg{
119371d7fec4Smrg   unsigned long dcfg = 0;
119471d7fec4Smrg
119571d7fec4Smrg   /* SET RCDF COLOR KEY VALUE */
119671d7fec4Smrg
119771d7fec4Smrg   WRITE_VID32(RCDF_VIDEO_COLOR_KEY, key);
119871d7fec4Smrg   WRITE_VID32(RCDF_VIDEO_COLOR_MASK, mask);
119971d7fec4Smrg
120071d7fec4Smrg   /* SELECT GRAPHICS OR VIDEO DATA TO COMPARE TO THE COLOR KEY */
120171d7fec4Smrg
120271d7fec4Smrg   dcfg = READ_VID32(RCDF_DISPLAY_CONFIG);
120371d7fec4Smrg   if (graphics & 0x01)
120471d7fec4Smrg      dcfg &= ~RCDF_DCFG_VG_CK;
120571d7fec4Smrg   else
120671d7fec4Smrg      dcfg |= RCDF_DCFG_VG_CK;
120771d7fec4Smrg   WRITE_VID32(RCDF_DISPLAY_CONFIG, dcfg);
120871d7fec4Smrg   return (0);
120971d7fec4Smrg}
121071d7fec4Smrg
121171d7fec4Smrg/*---------------------------------------------------------------------------
121271d7fec4Smrg * gfx_set_video_filter
121371d7fec4Smrg *
121471d7fec4Smrg * This routine enables or disables the video overlay filters.
121571d7fec4Smrg *---------------------------------------------------------------------------
121671d7fec4Smrg */
121771d7fec4Smrg#if GFX_VIDEO_DYNAMIC
121871d7fec4Smrgint
121971d7fec4Smrgredcloud_set_video_filter(int xfilter, int yfilter)
122071d7fec4Smrg#else
122171d7fec4Smrgint
122271d7fec4Smrggfx_set_video_filter(int xfilter, int yfilter)
122371d7fec4Smrg#endif
122471d7fec4Smrg{
122571d7fec4Smrg   unsigned long vcfg = 0;
122671d7fec4Smrg
122771d7fec4Smrg   /* ENABLE OR DISABLE DISPLAY FILTER VIDEO OVERLAY FILTERS */
122871d7fec4Smrg
122971d7fec4Smrg   vcfg = READ_VID32(RCDF_VIDEO_CONFIG);
123071d7fec4Smrg   vcfg &= ~(RCDF_VCFG_X_FILTER_EN | RCDF_VCFG_Y_FILTER_EN);
123171d7fec4Smrg   if (xfilter)
123271d7fec4Smrg      vcfg |= RCDF_VCFG_X_FILTER_EN;
123371d7fec4Smrg   if (yfilter)
123471d7fec4Smrg      vcfg |= RCDF_VCFG_Y_FILTER_EN;
123571d7fec4Smrg   WRITE_VID32(RCDF_VIDEO_CONFIG, vcfg);
123671d7fec4Smrg   return (0);
123771d7fec4Smrg}
123871d7fec4Smrg
123971d7fec4Smrg/*---------------------------------------------------------------------------
124071d7fec4Smrg * gfx_set_video_palette
124171d7fec4Smrg *
124271d7fec4Smrg * This routine loads the video hardware palette.  If a NULL pointer is
124371d7fec4Smrg * specified, the palette is bypassed (for Redcloud, this means loading the
124471d7fec4Smrg * palette with identity values).
124571d7fec4Smrg *---------------------------------------------------------------------------
124671d7fec4Smrg */
124771d7fec4Smrg#if GFX_VIDEO_DYNAMIC
124871d7fec4Smrgint
124971d7fec4Smrgredcloud_set_video_palette(unsigned long *palette)
125071d7fec4Smrg#else
125171d7fec4Smrgint
125271d7fec4Smrggfx_set_video_palette(unsigned long *palette)
125371d7fec4Smrg#endif
125471d7fec4Smrg{
125571d7fec4Smrg   unsigned long i, entry;
125671d7fec4Smrg
125771d7fec4Smrg   /* LOAD REDCLOUD VIDEO PALETTE */
125871d7fec4Smrg
125971d7fec4Smrg   WRITE_VID32(RCDF_PALETTE_ADDRESS, 0);
126071d7fec4Smrg   for (i = 0; i < 256; i++) {
126171d7fec4Smrg      if (palette)
126271d7fec4Smrg	 entry = palette[i];
126371d7fec4Smrg      else
126471d7fec4Smrg	 entry = i | (i << 8) | (i << 16);
126571d7fec4Smrg      WRITE_VID32(RCDF_PALETTE_DATA, entry);
126671d7fec4Smrg   }
126771d7fec4Smrg   return (0);
126871d7fec4Smrg}
126971d7fec4Smrg
127071d7fec4Smrg/*---------------------------------------------------------------------------
127171d7fec4Smrg * gfx_set_video_palette_entry
127271d7fec4Smrg *
127371d7fec4Smrg * This routine loads a single entry of the video hardware palette.
127471d7fec4Smrg *---------------------------------------------------------------------------
127571d7fec4Smrg */
127671d7fec4Smrg#if GFX_VIDEO_DYNAMIC
127771d7fec4Smrgint
127871d7fec4Smrgredcloud_set_video_palette_entry(unsigned long index, unsigned long palette)
127971d7fec4Smrg#else
128071d7fec4Smrgint
128171d7fec4Smrggfx_set_video_palette_entry(unsigned long index, unsigned long palette)
128271d7fec4Smrg#endif
128371d7fec4Smrg{
128471d7fec4Smrg   if (index > 0xFF)
128571d7fec4Smrg      return GFX_STATUS_BAD_PARAMETER;
128671d7fec4Smrg
128771d7fec4Smrg   /* SET A SINGLE ENTRY */
128871d7fec4Smrg
128971d7fec4Smrg   WRITE_VID32(RCDF_PALETTE_ADDRESS, index);
129071d7fec4Smrg   WRITE_VID32(RCDF_PALETTE_DATA, palette);
129171d7fec4Smrg
129271d7fec4Smrg   return (0);
129371d7fec4Smrg}
129471d7fec4Smrg
129571d7fec4Smrg/*---------------------------------------------------------------------------
129671d7fec4Smrg * gfx_set_video_request()
129771d7fec4Smrg *
129871d7fec4Smrg * This routine sets the horizontal (pixel) and vertical (line) video request
129971d7fec4Smrg * values.
130071d7fec4Smrg *---------------------------------------------------------------------------
130171d7fec4Smrg */
130271d7fec4Smrg#if GFX_VIDEO_DYNAMIC
130371d7fec4Smrgint
130471d7fec4Smrgredcloud_set_video_request(short x, short y)
130571d7fec4Smrg#else
130671d7fec4Smrgint
130771d7fec4Smrggfx_set_video_request(short x, short y)
130871d7fec4Smrg#endif
130971d7fec4Smrg{
131071d7fec4Smrg   /* SET DISPLAY FILTER VIDEO REQUEST */
131171d7fec4Smrg
131271d7fec4Smrg   x += gfx_get_htotal() - gfx_get_hsync_end() - 2;
131371d7fec4Smrg   y += gfx_get_vtotal() - gfx_get_vsync_end() + 1;
131471d7fec4Smrg
131571d7fec4Smrg   if ((x < 0) || (x > RCDF_VIDEO_REQUEST_MASK) ||
131671d7fec4Smrg       (y < 0) || (y > RCDF_VIDEO_REQUEST_MASK))
131771d7fec4Smrg      return GFX_STATUS_BAD_PARAMETER;
131871d7fec4Smrg
131971d7fec4Smrg   WRITE_VID32(RCDF_VIDEO_REQUEST,
132071d7fec4Smrg	       ((unsigned long)x << RCDF_VIDEO_X_REQUEST_POS) |
132171d7fec4Smrg	       ((unsigned long)y << RCDF_VIDEO_Y_REQUEST_POS));
132271d7fec4Smrg   return (0);
132371d7fec4Smrg}
132471d7fec4Smrg
132571d7fec4Smrg/*---------------------------------------------------------------------------
132671d7fec4Smrg * gfx_set_video_cursor()
132771d7fec4Smrg *
132871d7fec4Smrg * This routine configures the video hardware cursor.
132971d7fec4Smrg * If the "mask"ed bits in the graphics pixel match "key", then either "color1"
133071d7fec4Smrg * or "color2" will be used for this pixel, according to the value of bit
133171d7fec4Smrg * number "select_color2" of the graphics pixel.
133271d7fec4Smrg *
133371d7fec4Smrg * key - 24 bit RGB value
133471d7fec4Smrg * mask - 24 bit mask
133571d7fec4Smrg * color1, color2 - RGB or YUV, depending on the current color space conversion
133671d7fec4Smrg * select_color2 - value between 0 to 23
133771d7fec4Smrg *
133871d7fec4Smrg * To disable match, a "mask" and "key" value of 0xffffff should be set,
133971d7fec4Smrg * because the graphics pixels incoming to the video processor have maximum 16
134071d7fec4Smrg * bits set (0xF8FCF8).
134171d7fec4Smrg *
134271d7fec4Smrg * This feature is useful for disabling alpha blending of the cursor.
134371d7fec4Smrg * Otherwise cursor image would be blurred (or completely invisible if video
134471d7fec4Smrg * alpha is maximum value).
134571d7fec4Smrg * Note: the cursor pixel replacements take place both inside and outside the
134671d7fec4Smrg * video overlay window.
134771d7fec4Smrg *---------------------------------------------------------------------------
134871d7fec4Smrg */
134971d7fec4Smrg#if GFX_VIDEO_DYNAMIC
135071d7fec4Smrgint
135171d7fec4Smrgredcloud_set_video_cursor(unsigned long key, unsigned long mask,
135271d7fec4Smrg			  unsigned short select_color2, unsigned long color1,
135371d7fec4Smrg			  unsigned long color2)
135471d7fec4Smrg#else
135571d7fec4Smrgint
135671d7fec4Smrggfx_set_video_cursor(unsigned long key, unsigned long mask,
135771d7fec4Smrg		     unsigned short select_color2, unsigned long color1,
135871d7fec4Smrg		     unsigned long color2)
135971d7fec4Smrg#endif
136071d7fec4Smrg{
136171d7fec4Smrg   if (select_color2 > RCDF_CURSOR_COLOR_BITS)
136271d7fec4Smrg      return GFX_STATUS_BAD_PARAMETER;
136371d7fec4Smrg   key = (key & RCDF_COLOR_MASK) | ((unsigned long)select_color2 <<
136471d7fec4Smrg				    RCDF_CURSOR_COLOR_KEY_OFFSET_POS);
136571d7fec4Smrg   WRITE_VID32(RCDF_CURSOR_COLOR_KEY, key);
136671d7fec4Smrg   WRITE_VID32(RCDF_CURSOR_COLOR_MASK, mask);
136771d7fec4Smrg   WRITE_VID32(RCDF_CURSOR_COLOR_1, color1);
136871d7fec4Smrg   WRITE_VID32(RCDF_CURSOR_COLOR_2, color2);
136971d7fec4Smrg   return (0);
137071d7fec4Smrg}
137171d7fec4Smrg
137271d7fec4Smrg/*---------------------------------------------------------------------------
137371d7fec4Smrg * gfx_set_video_cursor()
137471d7fec4Smrg *
137571d7fec4Smrg * This routine configures the video hardware cursor.
137671d7fec4Smrg * If the "mask"ed bits in the graphics pixel match "key", then either "color1"
137771d7fec4Smrg * or "color2" will be used for this pixel, according to the value of bit
137871d7fec4Smrg * number "select_color2" of the graphics pixel.
137971d7fec4Smrg *
138071d7fec4Smrg * key - 24 bit RGB value
138171d7fec4Smrg * mask - 24 bit mask
138271d7fec4Smrg * color1, color2 - RGB or YUV, depending on the current color space conversion
138371d7fec4Smrg * select_color2 - value between 0 to 23
138471d7fec4Smrg *
138571d7fec4Smrg * To disable match, a "mask" and "key" value of 0xffffff should be set,
138671d7fec4Smrg * because the graphics pixels incoming to the video processor have maximum 16
138771d7fec4Smrg * bits set (0xF8FCF8).
138871d7fec4Smrg *
138971d7fec4Smrg * This feature is useful for disabling alpha blending of the cursor.
139071d7fec4Smrg * Otherwise cursor image would be blurred (or completely invisible if video
139171d7fec4Smrg * alpha is maximum value).
139271d7fec4Smrg * Note: the cursor pixel replacements take place both inside and outside the
139371d7fec4Smrg * video overlay window.
139471d7fec4Smrg *---------------------------------------------------------------------------
139571d7fec4Smrg */
139671d7fec4Smrg#if GFX_VIDEO_DYNAMIC
139771d7fec4Smrgint
139871d7fec4Smrgredcloud_set_video_cursor_enable(int enable)
139971d7fec4Smrg#else
140071d7fec4Smrgint
140171d7fec4Smrggfx_set_video_cursor_enable(int enable)
140271d7fec4Smrg#endif
140371d7fec4Smrg{
140471d7fec4Smrg   unsigned long temp = READ_VID32(RCDF_CURSOR_COLOR_KEY);
140571d7fec4Smrg
140671d7fec4Smrg   if (enable)
140771d7fec4Smrg      temp |= RCDF_CURSOR_COLOR_KEY_ENABLE;
140871d7fec4Smrg   else
140971d7fec4Smrg      temp &= ~RCDF_CURSOR_COLOR_KEY_ENABLE;
141071d7fec4Smrg
141171d7fec4Smrg   WRITE_VID32(RCDF_CURSOR_COLOR_KEY, temp);
141271d7fec4Smrg   return (0);
141371d7fec4Smrg}
141471d7fec4Smrg
141571d7fec4Smrg/*---------------------------------------------------------------------------
141671d7fec4Smrg * gfx_set_alpha_enable
141771d7fec4Smrg *
141871d7fec4Smrg * This routine enables or disables the currently selected alpha region.
141971d7fec4Smrg *---------------------------------------------------------------------------
142071d7fec4Smrg */
142171d7fec4Smrg#if GFX_VIDEO_DYNAMIC
142271d7fec4Smrgint
142371d7fec4Smrgredcloud_set_alpha_enable(int enable)
142471d7fec4Smrg#else
142571d7fec4Smrgint
142671d7fec4Smrggfx_set_alpha_enable(int enable)
142771d7fec4Smrg#endif
142871d7fec4Smrg{
142971d7fec4Smrg   unsigned long address = 0, value = 0;
143071d7fec4Smrg
143171d7fec4Smrg   if (gfx_alpha_select > 2)
143271d7fec4Smrg      return (GFX_STATUS_UNSUPPORTED);
143371d7fec4Smrg   address = RCDF_ALPHA_CONTROL_1 + ((unsigned long)gfx_alpha_select << 5);
143471d7fec4Smrg   value = READ_VID32(address);
143571d7fec4Smrg   if (enable)
143671d7fec4Smrg      value |= RCDF_ACTRL_WIN_ENABLE;
143771d7fec4Smrg   else
143871d7fec4Smrg      value &= ~(RCDF_ACTRL_WIN_ENABLE);
143971d7fec4Smrg   WRITE_VID32(address, value);
144071d7fec4Smrg   return (GFX_STATUS_OK);
144171d7fec4Smrg}
144271d7fec4Smrg
144371d7fec4Smrg/*---------------------------------------------------------------------------
144471d7fec4Smrg * gfx_set_alpha_window
144571d7fec4Smrg *
144671d7fec4Smrg * This routine sets the size of the currently selected alpha region.
144771d7fec4Smrg * Note: "x" and "y" are signed to enable using negative values needed for
144871d7fec4Smrg * implementing workarounds of hardware issues.
144971d7fec4Smrg *---------------------------------------------------------------------------
145071d7fec4Smrg */
145171d7fec4Smrg#if GFX_VIDEO_DYNAMIC
145271d7fec4Smrgint
145371d7fec4Smrgredcloud_set_alpha_window(short x, short y,
145471d7fec4Smrg			  unsigned short width, unsigned short height)
145571d7fec4Smrg#else
145671d7fec4Smrgint
145771d7fec4Smrggfx_set_alpha_window(short x, short y,
145871d7fec4Smrg		     unsigned short width, unsigned short height)
145971d7fec4Smrg#endif
146071d7fec4Smrg{
146171d7fec4Smrg   unsigned long address = 0;
146271d7fec4Smrg
146371d7fec4Smrg   /* CHECK FOR CLIPPING */
146471d7fec4Smrg
146571d7fec4Smrg   if ((x + width) > gfx_get_hactive())
146671d7fec4Smrg      width = gfx_get_hactive() - x;
146771d7fec4Smrg   if ((y + height) > gfx_get_vactive())
146871d7fec4Smrg      height = gfx_get_vactive() - y;
146971d7fec4Smrg
147071d7fec4Smrg   /* ADJUST POSITIONS */
147171d7fec4Smrg
147271d7fec4Smrg   x += gfx_get_htotal() - gfx_get_hsync_end() - 2;
147371d7fec4Smrg   y += gfx_get_vtotal() - gfx_get_vsync_end() + 1;
147471d7fec4Smrg
147571d7fec4Smrg   if (gfx_alpha_select > 2)
147671d7fec4Smrg      return (GFX_STATUS_UNSUPPORTED);
147771d7fec4Smrg   address = RCDF_ALPHA_XPOS_1 + ((unsigned long)gfx_alpha_select << 5);
147871d7fec4Smrg
147971d7fec4Smrg   /* END POSITIONS IN REGISTERS ARE NON-INCLUSIVE (ONE MORE THAN ACTUAL END) */
148071d7fec4Smrg
148171d7fec4Smrg   WRITE_VID32(address, (unsigned long)x |
148271d7fec4Smrg	       ((unsigned long)(x + width) << 16));
148371d7fec4Smrg   WRITE_VID32(address + 8, (unsigned long)y |
148471d7fec4Smrg	       ((unsigned long)(y + height) << 16));
148571d7fec4Smrg   return (GFX_STATUS_OK);
148671d7fec4Smrg}
148771d7fec4Smrg
148871d7fec4Smrg/*---------------------------------------------------------------------------
148971d7fec4Smrg * gfx_set_alpha_value
149071d7fec4Smrg *
149171d7fec4Smrg * This routine sets the alpha value for the currently selected alpha
149271d7fec4Smrg * region.  It also specifies an increment/decrement value for fading.
149371d7fec4Smrg *---------------------------------------------------------------------------
149471d7fec4Smrg */
149571d7fec4Smrg#if GFX_VIDEO_DYNAMIC
149671d7fec4Smrgint
149771d7fec4Smrgredcloud_set_alpha_value(unsigned char alpha, char delta)
149871d7fec4Smrg#else
149971d7fec4Smrgint
150071d7fec4Smrggfx_set_alpha_value(unsigned char alpha, char delta)
150171d7fec4Smrg#endif
150271d7fec4Smrg{
150371d7fec4Smrg   unsigned long address = 0, value = 0;
150471d7fec4Smrg
150571d7fec4Smrg   if (gfx_alpha_select > 2)
150671d7fec4Smrg      return (GFX_STATUS_UNSUPPORTED);
150771d7fec4Smrg   address = RCDF_ALPHA_CONTROL_1 + ((unsigned long)gfx_alpha_select << 5);
150871d7fec4Smrg   value = READ_VID32(address);
150971d7fec4Smrg   value &= RCDF_ACTRL_WIN_ENABLE;	/* keep only enable bit */
151071d7fec4Smrg   value |= (unsigned long)alpha;
151171d7fec4Smrg   value |= (((unsigned long)delta) & 0xff) << 8;
151271d7fec4Smrg   value |= RCDF_ACTRL_LOAD_ALPHA;
151371d7fec4Smrg   WRITE_VID32(address, value);
151471d7fec4Smrg   return (GFX_STATUS_OK);
151571d7fec4Smrg}
151671d7fec4Smrg
151771d7fec4Smrg/*---------------------------------------------------------------------------
151871d7fec4Smrg * gfx_set_alpha_priority
151971d7fec4Smrg *
152071d7fec4Smrg * This routine sets the priority of the currently selected alpha region.
152171d7fec4Smrg * A higher value indicates a higher priority.
152271d7fec4Smrg * Note: Priority of enabled alpha windows must be different.
152371d7fec4Smrg *---------------------------------------------------------------------------
152471d7fec4Smrg */
152571d7fec4Smrg#if GFX_VIDEO_DYNAMIC
152671d7fec4Smrgint
152771d7fec4Smrgredcloud_set_alpha_priority(int priority)
152871d7fec4Smrg#else
152971d7fec4Smrgint
153071d7fec4Smrggfx_set_alpha_priority(int priority)
153171d7fec4Smrg#endif
153271d7fec4Smrg{
153371d7fec4Smrg   unsigned long pos = 0, value = 0;
153471d7fec4Smrg
153571d7fec4Smrg   if (priority > 3)
153671d7fec4Smrg      return (GFX_STATUS_BAD_PARAMETER);
153771d7fec4Smrg   if (gfx_alpha_select > 2)
153871d7fec4Smrg      return (GFX_STATUS_UNSUPPORTED);
153971d7fec4Smrg   value = READ_VID32(RCDF_VID_ALPHA_CONTROL);
154071d7fec4Smrg   pos = 16 + (gfx_alpha_select << 1);
154171d7fec4Smrg   value &= ~(0x03l << pos);
154271d7fec4Smrg   value |= (unsigned long)priority << pos;
154371d7fec4Smrg   WRITE_VID32(RCDF_VID_ALPHA_CONTROL, value);
154471d7fec4Smrg   return (GFX_STATUS_OK);
154571d7fec4Smrg}
154671d7fec4Smrg
154771d7fec4Smrg/*---------------------------------------------------------------------------
154871d7fec4Smrg * gfx_set_alpha_color
154971d7fec4Smrg *
155071d7fec4Smrg * This routine sets the color to be displayed inside the currently selected
155171d7fec4Smrg * alpha window when there is a color key match (when the alpha color
155271d7fec4Smrg * mechanism is enabled).
155371d7fec4Smrg * "color" is an RGB value (for RGB blending) or a YUV value (for YUV blending).
155471d7fec4Smrg * In Interlaced YUV blending mode, Y/2 value should be used.
155571d7fec4Smrg *---------------------------------------------------------------------------
155671d7fec4Smrg */
155771d7fec4Smrg#if GFX_VIDEO_DYNAMIC
155871d7fec4Smrgint
155971d7fec4Smrgredcloud_set_alpha_color(unsigned long color)
156071d7fec4Smrg#else
156171d7fec4Smrgint
156271d7fec4Smrggfx_set_alpha_color(unsigned long color)
156371d7fec4Smrg#endif
156471d7fec4Smrg{
156571d7fec4Smrg   unsigned long address = 0;
156671d7fec4Smrg
156771d7fec4Smrg   if (gfx_alpha_select > 2)
156871d7fec4Smrg      return (GFX_STATUS_UNSUPPORTED);
156971d7fec4Smrg   address = RCDF_ALPHA_COLOR_1 + ((unsigned long)gfx_alpha_select << 5);
157071d7fec4Smrg   WRITE_VID32(address, color);
157171d7fec4Smrg   return (GFX_STATUS_OK);
157271d7fec4Smrg}
157371d7fec4Smrg
157471d7fec4Smrg/*---------------------------------------------------------------------------
157571d7fec4Smrg * gfx_set_alpha_color_enable
157671d7fec4Smrg *
157771d7fec4Smrg * Enable or disable the color mechanism in the alpha window.
157871d7fec4Smrg *---------------------------------------------------------------------------
157971d7fec4Smrg */
158071d7fec4Smrg#if GFX_VIDEO_DYNAMIC
158171d7fec4Smrgint
158271d7fec4Smrgredcloud_set_alpha_color_enable(int enable)
158371d7fec4Smrg#else
158471d7fec4Smrgint
158571d7fec4Smrggfx_set_alpha_color_enable(int enable)
158671d7fec4Smrg#endif
158771d7fec4Smrg{
158871d7fec4Smrg   unsigned long color;
158971d7fec4Smrg   unsigned long address = 0;
159071d7fec4Smrg
159171d7fec4Smrg   if (gfx_alpha_select > 2)
159271d7fec4Smrg      return (GFX_STATUS_UNSUPPORTED);
159371d7fec4Smrg   address = RCDF_ALPHA_COLOR_1 + ((unsigned long)gfx_alpha_select << 5);
159471d7fec4Smrg   color = READ_VID32(address);
159571d7fec4Smrg   if (enable)
159671d7fec4Smrg      color |= RCDF_ALPHA_COLOR_ENABLE;
159771d7fec4Smrg   else
159871d7fec4Smrg      color &= ~RCDF_ALPHA_COLOR_ENABLE;
159971d7fec4Smrg   WRITE_VID32(address, color);
160071d7fec4Smrg   return (GFX_STATUS_OK);
160171d7fec4Smrg}
160271d7fec4Smrg
160371d7fec4Smrg/*---------------------------------------------------------------------------
160471d7fec4Smrg * gfx_set_no_ck_outside_alpha
160571d7fec4Smrg *
160671d7fec4Smrg * This function affects where inside the video window color key or chroma
160771d7fec4Smrg * key comparison is done:
160871d7fec4Smrg * If enable is TRUE, color/chroma key comparison is performed only inside
160971d7fec4Smrg * the enabled alpha windows. Outside the (enabled) alpha windows, only video
161071d7fec4Smrg * is displayed if color key is used, and only graphics is displayed if chroma
161171d7fec4Smrg * key is used.
161271d7fec4Smrg * If enable is FALSE, color/chroma key comparison is performed in all the
161371d7fec4Smrg * video window area.
161471d7fec4Smrg *---------------------------------------------------------------------------
161571d7fec4Smrg */
161671d7fec4Smrg#if GFX_VIDEO_DYNAMIC
161771d7fec4Smrgint
161871d7fec4Smrgredcloud_set_no_ck_outside_alpha(int enable)
161971d7fec4Smrg#else
162071d7fec4Smrgint
162171d7fec4Smrggfx_set_no_ck_outside_alpha(int enable)
162271d7fec4Smrg#endif
162371d7fec4Smrg{
162471d7fec4Smrg   unsigned long value;
162571d7fec4Smrg
162671d7fec4Smrg   value = READ_VID32(RCDF_VID_ALPHA_CONTROL);
162771d7fec4Smrg   if (enable)
162871d7fec4Smrg      WRITE_VID32(RCDF_VID_ALPHA_CONTROL, value | RCDF_NO_CK_OUTSIDE_ALPHA);
162971d7fec4Smrg   else
163071d7fec4Smrg      WRITE_VID32(RCDF_VID_ALPHA_CONTROL, value & ~RCDF_NO_CK_OUTSIDE_ALPHA);
163171d7fec4Smrg   return (0);
163271d7fec4Smrg}
163371d7fec4Smrg
163471d7fec4Smrg/*---------------------------------------------------------------------------
163571d7fec4Smrg * gfx_get_clock_frequency
163671d7fec4Smrg *
163771d7fec4Smrg * This routine returns the current clock frequency in 16.16 format.
163871d7fec4Smrg * It reads the current register value and finds the match in the table.
163971d7fec4Smrg * If no match is found, this routine returns 0.
164071d7fec4Smrg *---------------------------------------------------------------------------
164171d7fec4Smrg */
164271d7fec4Smrg#if GFX_VIDEO_DYNAMIC
164371d7fec4Smrgunsigned long
164471d7fec4Smrgredcloud_get_clock_frequency(void)
164571d7fec4Smrg#else
164671d7fec4Smrgunsigned long
164771d7fec4Smrggfx_get_clock_frequency(void)
164871d7fec4Smrg#endif
164971d7fec4Smrg{
165071d7fec4Smrg   Q_WORD msr_value;
165171d7fec4Smrg   RCDFPLLENTRY *PLLTable;
165271d7fec4Smrg   unsigned int index;
165371d7fec4Smrg   unsigned long value, mask = 0x00001FFF;
165471d7fec4Smrg   unsigned long post_div3 = 0, pre_mult2 = 0;
165571d7fec4Smrg
165671d7fec4Smrg   /* READ PLL SETTING */
165771d7fec4Smrg
165871d7fec4Smrg   gfx_msr_read(RC_ID_MCP, MCP_DOTPLL, &msr_value);
165971d7fec4Smrg   value = msr_value.high & mask;
166071d7fec4Smrg
166171d7fec4Smrg   /* READ DIVISOR SETTINGS */
166271d7fec4Smrg
166371d7fec4Smrg   if ((gfx_cpu_version & 0xFF00) == 0x200) {
166471d7fec4Smrg      PLLTable = RCDF_PLLtable48MHz;
166571d7fec4Smrg
166671d7fec4Smrg      gfx_msr_read(RC_ID_MCP, MCP_SYS_RSTPLL, &msr_value);
166771d7fec4Smrg      post_div3 = (msr_value.low & MCP_DOTPOSTDIV3) ? 1 : 0;
166871d7fec4Smrg      pre_mult2 = (msr_value.low & MCP_DOTPREMULT2) ? 1 : 0;
166971d7fec4Smrg   } else
167071d7fec4Smrg      PLLTable = RCDF_PLLtable14MHz;
167171d7fec4Smrg
167271d7fec4Smrg   /* SEARCH FOR A MATCH */
167371d7fec4Smrg
167471d7fec4Smrg   for (index = 0; index < NUM_RCDF_FREQUENCIES; index++) {
167571d7fec4Smrg      if ((PLLTable[index].pll_value & mask) == value &&
167671d7fec4Smrg	  post_div3 == PLLTable[index].post_div3 &&
167771d7fec4Smrg	  pre_mult2 == PLLTable[index].pre_mul2)
167871d7fec4Smrg	 return (PLLTable[index].frequency);
167971d7fec4Smrg   }
168071d7fec4Smrg   return (0);
168171d7fec4Smrg}
168271d7fec4Smrg
168371d7fec4Smrg/*************************************************************/
168471d7fec4Smrg/*  READ ROUTINES  |  INCLUDED FOR DIAGNOSTIC PURPOSES ONLY  */
168571d7fec4Smrg/*************************************************************/
168671d7fec4Smrg
168771d7fec4Smrg#if GFX_READ_ROUTINES
168871d7fec4Smrg
168971d7fec4Smrg/*---------------------------------------------------------------------------
169071d7fec4Smrg * gfx_get_sync_polarities
169171d7fec4Smrg *
169271d7fec4Smrg * This routine returns the polarities of the sync pulses:
169371d7fec4Smrg *     Bit 0: Set if negative horizontal polarity.
169471d7fec4Smrg *     Bit 1: Set if negative vertical polarity.
169571d7fec4Smrg *---------------------------------------------------------------------------
169671d7fec4Smrg */
169771d7fec4Smrg#if GFX_VIDEO_DYNAMIC
169871d7fec4Smrgint
169971d7fec4Smrgredcloud_get_sync_polarities(void)
170071d7fec4Smrg#else
170171d7fec4Smrgint
170271d7fec4Smrggfx_get_sync_polarities(void)
170371d7fec4Smrg#endif
170471d7fec4Smrg{
170571d7fec4Smrg   int polarities = 0;
170671d7fec4Smrg
170771d7fec4Smrg   if (READ_VID32(RCDF_DISPLAY_CONFIG) & RCDF_DCFG_CRT_HSYNC_POL)
170871d7fec4Smrg      polarities |= 1;
170971d7fec4Smrg   if (READ_VID32(RCDF_DISPLAY_CONFIG) & RCDF_DCFG_CRT_VSYNC_POL)
171071d7fec4Smrg      polarities |= 2;
171171d7fec4Smrg   return (polarities);
171271d7fec4Smrg}
171371d7fec4Smrg
171471d7fec4Smrg/*---------------------------------------------------------------------------
171571d7fec4Smrg * gfx_get_video_palette_entry
171671d7fec4Smrg *
171771d7fec4Smrg * This routine returns a single palette entry.
171871d7fec4Smrg *---------------------------------------------------------------------------
171971d7fec4Smrg */
172071d7fec4Smrg#if GFX_VIDEO_DYNAMIC
172171d7fec4Smrgint
172271d7fec4Smrgredcloud_get_video_palette_entry(unsigned long index, unsigned long *palette)
172371d7fec4Smrg#else
172471d7fec4Smrgint
172571d7fec4Smrggfx_get_video_palette_entry(unsigned long index, unsigned long *palette)
172671d7fec4Smrg#endif
172771d7fec4Smrg{
172871d7fec4Smrg   if (index > 0xFF)
172971d7fec4Smrg      return GFX_STATUS_BAD_PARAMETER;
173071d7fec4Smrg
173171d7fec4Smrg   /* READ A SINGLE ENTRY */
173271d7fec4Smrg
173371d7fec4Smrg   WRITE_VID32(RCDF_PALETTE_ADDRESS, index);
173471d7fec4Smrg   *palette = READ_VID32(RCDF_PALETTE_DATA);
173571d7fec4Smrg
173671d7fec4Smrg   return (GFX_STATUS_OK);
173771d7fec4Smrg}
173871d7fec4Smrg
173971d7fec4Smrg/*-----------------------------------------------------------------------------
174071d7fec4Smrg * gfx_get_video_enable
174171d7fec4Smrg *
174271d7fec4Smrg * This routine returns the value "one" if video overlay is currently enabled,
174371d7fec4Smrg * otherwise it returns the value "zero".
174471d7fec4Smrg *-----------------------------------------------------------------------------
174571d7fec4Smrg */
174671d7fec4Smrg#if GFX_VIDEO_DYNAMIC
174771d7fec4Smrgint
174871d7fec4Smrgredcloud_get_video_enable(void)
174971d7fec4Smrg#else
175071d7fec4Smrgint
175171d7fec4Smrggfx_get_video_enable(void)
175271d7fec4Smrg#endif
175371d7fec4Smrg{
175471d7fec4Smrg   if (READ_VID32(RCDF_VIDEO_CONFIG) & RCDF_VCFG_VID_EN)
175571d7fec4Smrg      return (1);
175671d7fec4Smrg   return (0);
175771d7fec4Smrg}
175871d7fec4Smrg
175971d7fec4Smrg/*-----------------------------------------------------------------------------
176071d7fec4Smrg * gfx_get_video_format
176171d7fec4Smrg *
176271d7fec4Smrg * This routine returns the current video overlay format.
176371d7fec4Smrg *-----------------------------------------------------------------------------
176471d7fec4Smrg */
176571d7fec4Smrg#if GFX_VIDEO_DYNAMIC
176671d7fec4Smrgint
176771d7fec4Smrgredcloud_get_video_format(void)
176871d7fec4Smrg#else
176971d7fec4Smrgint
177071d7fec4Smrggfx_get_video_format(void)
177171d7fec4Smrg#endif
177271d7fec4Smrg{
177371d7fec4Smrg   unsigned long ctrl, vcfg;
177471d7fec4Smrg
177571d7fec4Smrg   ctrl = READ_VID32(RCDF_VID_ALPHA_CONTROL);
177671d7fec4Smrg   vcfg = READ_VID32(RCDF_VIDEO_CONFIG);
177771d7fec4Smrg
177871d7fec4Smrg   if (ctrl & RCDF_VIDEO_INPUT_IS_RGB) {
177971d7fec4Smrg      switch (vcfg & RCDF_VCFG_VID_INP_FORMAT) {
178071d7fec4Smrg      case RCDF_VCFG_UYVY_FORMAT:
178171d7fec4Smrg	 return VIDEO_FORMAT_RGB;
178271d7fec4Smrg      case RCDF_VCFG_Y2YU_FORMAT:
178371d7fec4Smrg	 return VIDEO_FORMAT_P2M_P2L_P1M_P1L;
178471d7fec4Smrg      case RCDF_VCFG_YUYV_FORMAT:
178571d7fec4Smrg	 return VIDEO_FORMAT_P1M_P1L_P2M_P2L;
178671d7fec4Smrg      case RCDF_VCFG_YVYU_FORMAT:
178771d7fec4Smrg	 return VIDEO_FORMAT_P1M_P2L_P2M_P1L;
178871d7fec4Smrg      }
178971d7fec4Smrg   }
179071d7fec4Smrg
179171d7fec4Smrg   if (vcfg & RCDF_VCFG_4_2_0_MODE) {
179271d7fec4Smrg      switch (vcfg & RCDF_VCFG_VID_INP_FORMAT) {
179371d7fec4Smrg      case RCDF_VCFG_UYVY_FORMAT:
179471d7fec4Smrg	 return VIDEO_FORMAT_Y0Y1Y2Y3;
179571d7fec4Smrg      case RCDF_VCFG_Y2YU_FORMAT:
179671d7fec4Smrg	 return VIDEO_FORMAT_Y3Y2Y1Y0;
179771d7fec4Smrg      case RCDF_VCFG_YUYV_FORMAT:
179871d7fec4Smrg	 return VIDEO_FORMAT_Y1Y0Y3Y2;
179971d7fec4Smrg      case RCDF_VCFG_YVYU_FORMAT:
180071d7fec4Smrg	 return VIDEO_FORMAT_Y1Y2Y3Y0;
180171d7fec4Smrg      }
180271d7fec4Smrg   } else {
180371d7fec4Smrg      switch (vcfg & RCDF_VCFG_VID_INP_FORMAT) {
180471d7fec4Smrg      case RCDF_VCFG_UYVY_FORMAT:
180571d7fec4Smrg	 return VIDEO_FORMAT_UYVY;
180671d7fec4Smrg      case RCDF_VCFG_Y2YU_FORMAT:
180771d7fec4Smrg	 return VIDEO_FORMAT_Y2YU;
180871d7fec4Smrg      case RCDF_VCFG_YUYV_FORMAT:
180971d7fec4Smrg	 return VIDEO_FORMAT_YUYV;
181071d7fec4Smrg      case RCDF_VCFG_YVYU_FORMAT:
181171d7fec4Smrg	 return VIDEO_FORMAT_YVYU;
181271d7fec4Smrg      }
181371d7fec4Smrg   }
181471d7fec4Smrg   return (GFX_STATUS_ERROR);
181571d7fec4Smrg}
181671d7fec4Smrg
181771d7fec4Smrg/*-----------------------------------------------------------------------------
181871d7fec4Smrg * gfx_get_video_src_size
181971d7fec4Smrg *
182071d7fec4Smrg * This routine returns the size of the source video overlay buffer.  The
182171d7fec4Smrg * return value is (height << 16) | width.
182271d7fec4Smrg *-----------------------------------------------------------------------------
182371d7fec4Smrg */
182471d7fec4Smrg#if GFX_VIDEO_DYNAMIC
182571d7fec4Smrgunsigned long
182671d7fec4Smrgredcloud_get_video_src_size(void)
182771d7fec4Smrg#else
182871d7fec4Smrgunsigned long
182971d7fec4Smrggfx_get_video_src_size(void)
183071d7fec4Smrg#endif
183171d7fec4Smrg{
183271d7fec4Smrg   unsigned long width, height, scale, delta;
183371d7fec4Smrg   int down_enable;
183471d7fec4Smrg
183571d7fec4Smrg   /* DETERMINE SOURCE WIDTH FROM THE DISPLAY FILTER VIDEO LINE SIZE */
183671d7fec4Smrg
183771d7fec4Smrg   width = (READ_VID32(RCDF_VIDEO_CONFIG) >> 7) & 0x000001FE;
183871d7fec4Smrg   if (READ_VID32(RCDF_VIDEO_CONFIG) & RCDF_VCFG_LINE_SIZE_UPPER)
183971d7fec4Smrg      width += 512l;
184071d7fec4Smrg
184171d7fec4Smrg   /* DETERMINE SOURCE HEIGHT FROM THE DISPLAY FILTER HEIGHT AND SCALE VALUES     */
184271d7fec4Smrg   /* There is no true "source buffer size" in Redcloud.  Instead, the VG module  */
184371d7fec4Smrg   /* provides video data as needed on a per-line basis.  The source buffer size  */
184471d7fec4Smrg   /* is always assumed to equal the amount of required video data.  The returned */
184571d7fec4Smrg   /* height is equal to the height of the required video buffer data (before all */
184671d7fec4Smrg   /* scaling.)                                                                   */
184771d7fec4Smrg
184871d7fec4Smrg   scale = (READ_VID32(RCDF_VIDEO_SCALE) >> 16) & 0x3FFF;
184971d7fec4Smrg   height = ((READ_VID32(RCDF_VIDEO_Y_POS) >> 16) & 0x7FF) -
185071d7fec4Smrg	 (READ_VID32(RCDF_VIDEO_Y_POS) & 0x7FF);
185171d7fec4Smrg   delta = gfx_get_video_downscale_delta();
185271d7fec4Smrg   down_enable = gfx_get_video_vertical_downscale_enable();
185371d7fec4Smrg
185471d7fec4Smrg   /* REVERSE UPSCALING */
185571d7fec4Smrg
185671d7fec4Smrg   if (height)
185771d7fec4Smrg      height = ((scale * (height - 1l)) / 0x2000l) + 2l;
185871d7fec4Smrg
185971d7fec4Smrg   /* REVERSE DOWNSCALING */
186071d7fec4Smrg   /* Original lines = height * (0x3FFF + delta) / 0x3FFF */
186171d7fec4Smrg   /* As this may cause rounding errors, we add 1 to the  */
186271d7fec4Smrg   /* returned source size.  The return value of this     */
186371d7fec4Smrg   /* function could thus be off by 1.                    */
186471d7fec4Smrg
186571d7fec4Smrg   if (down_enable && height)
186671d7fec4Smrg      height = ((height * (0x3FFFl + delta)) / 0x3FFFl) + 1;
186771d7fec4Smrg
186871d7fec4Smrg   return ((height << 16) | width);
186971d7fec4Smrg}
187071d7fec4Smrg
187171d7fec4Smrg/*-----------------------------------------------------------------------------
187271d7fec4Smrg * gfx_get_video_line_size
187371d7fec4Smrg *
187471d7fec4Smrg * This routine returns the line size of the source video overlay buffer, in
187571d7fec4Smrg * pixels.
187671d7fec4Smrg *-----------------------------------------------------------------------------
187771d7fec4Smrg */
187871d7fec4Smrg#if GFX_VIDEO_DYNAMIC
187971d7fec4Smrgunsigned long
188071d7fec4Smrgredcloud_get_video_line_size(void)
188171d7fec4Smrg#else
188271d7fec4Smrgunsigned long
188371d7fec4Smrggfx_get_video_line_size(void)
188471d7fec4Smrg#endif
188571d7fec4Smrg{
188671d7fec4Smrg   unsigned long width = 0;
188771d7fec4Smrg
188871d7fec4Smrg   /* DETERMINE SOURCE WIDTH FROM THE RCDF VIDEO LINE SIZE */
188971d7fec4Smrg
189071d7fec4Smrg   width = (READ_VID32(RCDF_VIDEO_CONFIG) >> 7) & 0x000001FE;
189171d7fec4Smrg   if (READ_VID32(RCDF_VIDEO_CONFIG) & RCDF_VCFG_LINE_SIZE_UPPER)
189271d7fec4Smrg      width += 512l;
189371d7fec4Smrg   return (width);
189471d7fec4Smrg}
189571d7fec4Smrg
189671d7fec4Smrg/*-----------------------------------------------------------------------------
189771d7fec4Smrg * gfx_get_video_xclip
189871d7fec4Smrg *
189971d7fec4Smrg * This routine returns the number of bytes clipped on the left side of a
190071d7fec4Smrg * video overlay line (skipped at beginning).
190171d7fec4Smrg *-----------------------------------------------------------------------------
190271d7fec4Smrg */
190371d7fec4Smrg#if GFX_VIDEO_DYNAMIC
190471d7fec4Smrgunsigned long
190571d7fec4Smrgredcloud_get_video_xclip(void)
190671d7fec4Smrg#else
190771d7fec4Smrgunsigned long
190871d7fec4Smrggfx_get_video_xclip(void)
190971d7fec4Smrg#endif
191071d7fec4Smrg{
191171d7fec4Smrg   unsigned long clip = 0;
191271d7fec4Smrg
191371d7fec4Smrg   /* DETERMINE SOURCE WIDTH FROM THE RCDF VIDEO LINE SIZE */
191471d7fec4Smrg
191571d7fec4Smrg   clip = (READ_VID32(RCDF_VIDEO_CONFIG) >> 14) & 0x000007FC;
191671d7fec4Smrg   return (clip);
191771d7fec4Smrg}
191871d7fec4Smrg
191971d7fec4Smrg/*-----------------------------------------------------------------------------
192071d7fec4Smrg * gfx_get_video_offset
192171d7fec4Smrg *
192271d7fec4Smrg * This routine returns the current offset for the video overlay buffer.
192371d7fec4Smrg *-----------------------------------------------------------------------------
192471d7fec4Smrg */
192571d7fec4Smrg#if GFX_VIDEO_DYNAMIC
192671d7fec4Smrgunsigned long
192771d7fec4Smrgredcloud_get_video_offset(void)
192871d7fec4Smrg#else
192971d7fec4Smrgunsigned long
193071d7fec4Smrggfx_get_video_offset(void)
193171d7fec4Smrg#endif
193271d7fec4Smrg{
193371d7fec4Smrg   return (gfx_get_display_video_offset());
193471d7fec4Smrg}
193571d7fec4Smrg
193671d7fec4Smrg/*-----------------------------------------------------------------------------
193771d7fec4Smrg * gfx_get_video_yuv_offsets
193871d7fec4Smrg *
193971d7fec4Smrg * This routine returns the current offsets for the video overlay buffer when in 4:2:0.
194071d7fec4Smrg *-----------------------------------------------------------------------------
194171d7fec4Smrg */
194271d7fec4Smrg#if GFX_VIDEO_DYNAMIC
194371d7fec4Smrgvoid
194471d7fec4Smrgredcloud_get_video_yuv_offsets(unsigned long *yoffset, unsigned long *uoffset,
194571d7fec4Smrg			       unsigned long *voffset)
194671d7fec4Smrg#else
194771d7fec4Smrgvoid
194871d7fec4Smrggfx_get_video_yuv_offsets(unsigned long *yoffset, unsigned long *uoffset,
194971d7fec4Smrg			  unsigned long *voffset)
195071d7fec4Smrg#endif
195171d7fec4Smrg{
195271d7fec4Smrg   gfx_get_display_video_yuv_offsets(yoffset, uoffset, voffset);
195371d7fec4Smrg}
195471d7fec4Smrg
195571d7fec4Smrg/*-----------------------------------------------------------------------------
195671d7fec4Smrg * gfx_get_video_yuv_pitch
195771d7fec4Smrg *
195871d7fec4Smrg * This routine returns the current pitch values for the video overlay buffer.
195971d7fec4Smrg *-----------------------------------------------------------------------------
196071d7fec4Smrg */
196171d7fec4Smrg#if GFX_VIDEO_DYNAMIC
196271d7fec4Smrgvoid
196371d7fec4Smrgredcloud_get_video_yuv_pitch(unsigned long *ypitch, unsigned long *uvpitch)
196471d7fec4Smrg#else
196571d7fec4Smrgvoid
196671d7fec4Smrggfx_get_video_yuv_pitch(unsigned long *ypitch, unsigned long *uvpitch)
196771d7fec4Smrg#endif
196871d7fec4Smrg{
196971d7fec4Smrg   gfx_get_display_video_yuv_pitch(ypitch, uvpitch);
197071d7fec4Smrg}
197171d7fec4Smrg
197271d7fec4Smrg/*---------------------------------------------------------------------------
197371d7fec4Smrg * gfx_get_video_scale
197471d7fec4Smrg *
197571d7fec4Smrg * This routine returns the scale factor for the video overlay window.
197671d7fec4Smrg *---------------------------------------------------------------------------
197771d7fec4Smrg */
197871d7fec4Smrg#if GFX_VIDEO_DYNAMIC
197971d7fec4Smrgunsigned long
198071d7fec4Smrgredcloud_get_video_scale(void)
198171d7fec4Smrg#else
198271d7fec4Smrgunsigned long
198371d7fec4Smrggfx_get_video_scale(void)
198471d7fec4Smrg#endif
198571d7fec4Smrg{
198671d7fec4Smrg   return (READ_VID32(RCDF_VIDEO_SCALE));
198771d7fec4Smrg}
198871d7fec4Smrg
198971d7fec4Smrg/*---------------------------------------------------------------------------
199071d7fec4Smrg * gfx_get_video_downscale_delta
199171d7fec4Smrg *
199271d7fec4Smrg * This routine returns the vertical downscale factor for the video overlay window.
199371d7fec4Smrg *---------------------------------------------------------------------------
199471d7fec4Smrg */
199571d7fec4Smrg#if GFX_VIDEO_DYNAMIC
199671d7fec4Smrgunsigned long
199771d7fec4Smrgredcloud_get_video_downscale_delta(void)
199871d7fec4Smrg#else
199971d7fec4Smrgunsigned long
200071d7fec4Smrggfx_get_video_downscale_delta(void)
200171d7fec4Smrg#endif
200271d7fec4Smrg{
200371d7fec4Smrg   /* USE PRIVATE ROUTINE TO ABSTRACT THE DIPSLAY CONTROLLER */
200471d7fec4Smrg
200571d7fec4Smrg   return (gfx_get_display_video_downscale_delta());
200671d7fec4Smrg}
200771d7fec4Smrg
200871d7fec4Smrg/*---------------------------------------------------------------------------
200971d7fec4Smrg * gfx_get_video_vertical_downscale_enable
201071d7fec4Smrg *
201171d7fec4Smrg * This routine returns the vertical downscale enable for the video overlay window.
201271d7fec4Smrg *---------------------------------------------------------------------------
201371d7fec4Smrg */
201471d7fec4Smrg#if GFX_VIDEO_DYNAMIC
201571d7fec4Smrgint
201671d7fec4Smrgredcloud_get_video_vertical_downscale_enable(void)
201771d7fec4Smrg#else
201871d7fec4Smrgint
201971d7fec4Smrggfx_get_video_vertical_downscale_enable(void)
202071d7fec4Smrg#endif
202171d7fec4Smrg{
202271d7fec4Smrg   /* USE PRIVATE ROUTINE TO ABSTRACT THE DIPSLAY CONTROLLER */
202371d7fec4Smrg
202471d7fec4Smrg   return (gfx_get_display_video_downscale_enable());
202571d7fec4Smrg}
202671d7fec4Smrg
202771d7fec4Smrg/*---------------------------------------------------------------------------
202871d7fec4Smrg * gfx_get_video_downscale_config
202971d7fec4Smrg *
203071d7fec4Smrg * This routine returns the current type and value of video downscaling.
203171d7fec4Smrg *---------------------------------------------------------------------------
203271d7fec4Smrg */
203371d7fec4Smrg#if GFX_VIDEO_DYNAMIC
203471d7fec4Smrgint
203571d7fec4Smrgredcloud_get_video_downscale_config(unsigned short *type, unsigned short *m)
203671d7fec4Smrg#else
203771d7fec4Smrgint
203871d7fec4Smrggfx_get_video_downscale_config(unsigned short *type, unsigned short *m)
203971d7fec4Smrg#endif
204071d7fec4Smrg{
204171d7fec4Smrg   unsigned long downscale;
204271d7fec4Smrg
204371d7fec4Smrg   downscale = READ_VID32(RCDF_VIDEO_DOWNSCALER_CONTROL);
204471d7fec4Smrg   *m = (unsigned short)((downscale & RCDF_VIDEO_DOWNSCALE_FACTOR_MASK) >>
204571d7fec4Smrg			 RCDF_VIDEO_DOWNSCALE_FACTOR_POS) + 1;
204671d7fec4Smrg
204771d7fec4Smrg   switch (downscale & RCDF_VIDEO_DOWNSCALE_TYPE_MASK) {
204871d7fec4Smrg   case RCDF_VIDEO_DOWNSCALE_TYPE_A:
204971d7fec4Smrg      *type = VIDEO_DOWNSCALE_KEEP_1_OF;
205071d7fec4Smrg      break;
205171d7fec4Smrg   case RCDF_VIDEO_DOWNSCALE_TYPE_B:
205271d7fec4Smrg      *type = VIDEO_DOWNSCALE_DROP_1_OF;
205371d7fec4Smrg      break;
205471d7fec4Smrg   default:
205571d7fec4Smrg      return GFX_STATUS_ERROR;
205671d7fec4Smrg      break;
205771d7fec4Smrg   }
205871d7fec4Smrg   return (0);
205971d7fec4Smrg}
206071d7fec4Smrg
206171d7fec4Smrg/*---------------------------------------------------------------------------
206271d7fec4Smrg * gfx_get_video_downscale_coefficients
206371d7fec4Smrg *
206471d7fec4Smrg * This routine returns the current video downscaling coefficients.
206571d7fec4Smrg *---------------------------------------------------------------------------
206671d7fec4Smrg */
206771d7fec4Smrg#if GFX_VIDEO_DYNAMIC
206871d7fec4Smrgvoid
206971d7fec4Smrgredcloud_get_video_downscale_coefficients(unsigned short *coef1,
207071d7fec4Smrg					  unsigned short *coef2,
207171d7fec4Smrg					  unsigned short *coef3,
207271d7fec4Smrg					  unsigned short *coef4)
207371d7fec4Smrg#else
207471d7fec4Smrgvoid
207571d7fec4Smrggfx_get_video_downscale_coefficients(unsigned short *coef1,
207671d7fec4Smrg				     unsigned short *coef2,
207771d7fec4Smrg				     unsigned short *coef3,
207871d7fec4Smrg				     unsigned short *coef4)
207971d7fec4Smrg#endif
208071d7fec4Smrg{
208171d7fec4Smrg   unsigned long coef;
208271d7fec4Smrg
208371d7fec4Smrg   coef = READ_VID32(RCDF_VIDEO_DOWNSCALER_COEFFICIENTS);
208471d7fec4Smrg   *coef1 =
208571d7fec4Smrg	 (unsigned short)((coef >> RCDF_VIDEO_DOWNSCALER_COEF1_POS) &
208671d7fec4Smrg			  RCDF_VIDEO_DOWNSCALER_COEF_MASK);
208771d7fec4Smrg   *coef2 =
208871d7fec4Smrg	 (unsigned short)((coef >> RCDF_VIDEO_DOWNSCALER_COEF2_POS) &
208971d7fec4Smrg			  RCDF_VIDEO_DOWNSCALER_COEF_MASK);
209071d7fec4Smrg   *coef3 =
209171d7fec4Smrg	 (unsigned short)((coef >> RCDF_VIDEO_DOWNSCALER_COEF3_POS) &
209271d7fec4Smrg			  RCDF_VIDEO_DOWNSCALER_COEF_MASK);
209371d7fec4Smrg   *coef4 =
209471d7fec4Smrg	 (unsigned short)((coef >> RCDF_VIDEO_DOWNSCALER_COEF4_POS) &
209571d7fec4Smrg			  RCDF_VIDEO_DOWNSCALER_COEF_MASK);
209671d7fec4Smrg   return;
209771d7fec4Smrg}
209871d7fec4Smrg
209971d7fec4Smrg/*---------------------------------------------------------------------------
210071d7fec4Smrg * gfx_get_video_downscale_enable
210171d7fec4Smrg *
210271d7fec4Smrg * This routine returns 1 if video downscaling is currently enabled,
210371d7fec4Smrg * or 0 if it is currently disabled.
210471d7fec4Smrg *---------------------------------------------------------------------------
210571d7fec4Smrg */
210671d7fec4Smrg#if GFX_VIDEO_DYNAMIC
210771d7fec4Smrgvoid
210871d7fec4Smrgredcloud_get_video_downscale_enable(int *enable)
210971d7fec4Smrg#else
211071d7fec4Smrgvoid
211171d7fec4Smrggfx_get_video_downscale_enable(int *enable)
211271d7fec4Smrg#endif
211371d7fec4Smrg{
211471d7fec4Smrg   if (READ_VID32(RCDF_VIDEO_DOWNSCALER_CONTROL) &
211571d7fec4Smrg       RCDF_VIDEO_DOWNSCALE_ENABLE)
211671d7fec4Smrg      *enable = 1;
211771d7fec4Smrg   else
211871d7fec4Smrg      *enable = 0;
211971d7fec4Smrg   return;
212071d7fec4Smrg}
212171d7fec4Smrg
212271d7fec4Smrg/*---------------------------------------------------------------------------
212371d7fec4Smrg * gfx_get_video_dst_size
212471d7fec4Smrg *
212571d7fec4Smrg * This routine returns the size of the displayed video overlay window.
212671d7fec4Smrg *---------------------------------------------------------------------------
212771d7fec4Smrg */
212871d7fec4Smrg#if GFX_VIDEO_DYNAMIC
212971d7fec4Smrgunsigned long
213071d7fec4Smrgredcloud_get_video_dst_size(void)
213171d7fec4Smrg#else
213271d7fec4Smrgunsigned long
213371d7fec4Smrggfx_get_video_dst_size(void)
213471d7fec4Smrg#endif
213571d7fec4Smrg{
213671d7fec4Smrg   unsigned long xsize, ysize;
213771d7fec4Smrg
213871d7fec4Smrg   xsize = READ_VID32(RCDF_VIDEO_X_POS);
213971d7fec4Smrg   xsize = ((xsize >> 16) & 0x7FF) - (xsize & 0x7FF);
214071d7fec4Smrg   ysize = READ_VID32(RCDF_VIDEO_Y_POS);
214171d7fec4Smrg   ysize = ((ysize >> 16) & 0x7FF) - (ysize & 0x7FF);
214271d7fec4Smrg   return ((ysize << 16) | xsize);
214371d7fec4Smrg}
214471d7fec4Smrg
214571d7fec4Smrg/*---------------------------------------------------------------------------
214671d7fec4Smrg * gfx_get_video_position
214771d7fec4Smrg *
214871d7fec4Smrg * This routine returns the position of the video overlay window.  The
214971d7fec4Smrg * return value is (ypos << 16) | xpos.
215071d7fec4Smrg *---------------------------------------------------------------------------
215171d7fec4Smrg */
215271d7fec4Smrg#if GFX_VIDEO_DYNAMIC
215371d7fec4Smrgunsigned long
215471d7fec4Smrgredcloud_get_video_position(void)
215571d7fec4Smrg#else
215671d7fec4Smrgunsigned long
215771d7fec4Smrggfx_get_video_position(void)
215871d7fec4Smrg#endif
215971d7fec4Smrg{
216071d7fec4Smrg   unsigned long hadjust, vadjust;
216171d7fec4Smrg   unsigned long xpos, ypos;
216271d7fec4Smrg
216371d7fec4Smrg   /* READ HARDWARE POSITION */
216471d7fec4Smrg
216571d7fec4Smrg   xpos = READ_VID32(RCDF_VIDEO_X_POS) & 0x000007FF;
216671d7fec4Smrg   ypos = READ_VID32(RCDF_VIDEO_Y_POS) & 0x000007FF;
216771d7fec4Smrg
216871d7fec4Smrg   /* GET ADJUSTMENT VALUES */
216971d7fec4Smrg   /* Use routines to abstract version of display controller. */
217071d7fec4Smrg
217171d7fec4Smrg   hadjust =
217271d7fec4Smrg	 (unsigned long)gfx_get_htotal() -
217371d7fec4Smrg	 (unsigned long)gfx_get_hsync_end() - 14l;
217471d7fec4Smrg   vadjust =
217571d7fec4Smrg	 (unsigned long)gfx_get_vtotal() -
217671d7fec4Smrg	 (unsigned long)gfx_get_vsync_end() + 1l;
217771d7fec4Smrg   xpos -= hadjust;
217871d7fec4Smrg   ypos -= vadjust;
217971d7fec4Smrg   return ((ypos << 16) | (xpos & 0x0000FFFF));
218071d7fec4Smrg}
218171d7fec4Smrg
218271d7fec4Smrg/*---------------------------------------------------------------------------
218371d7fec4Smrg * gfx_get_video_color_key
218471d7fec4Smrg *
218571d7fec4Smrg * This routine returns the current video color key value.
218671d7fec4Smrg *---------------------------------------------------------------------------
218771d7fec4Smrg */
218871d7fec4Smrg#if GFX_VIDEO_DYNAMIC
218971d7fec4Smrgunsigned long
219071d7fec4Smrgredcloud_get_video_color_key(void)
219171d7fec4Smrg#else
219271d7fec4Smrgunsigned long
219371d7fec4Smrggfx_get_video_color_key(void)
219471d7fec4Smrg#endif
219571d7fec4Smrg{
219671d7fec4Smrg   return (READ_VID32(RCDF_VIDEO_COLOR_KEY));
219771d7fec4Smrg}
219871d7fec4Smrg
219971d7fec4Smrg/*---------------------------------------------------------------------------
220071d7fec4Smrg * gfx_get_video_color_key_mask
220171d7fec4Smrg *
220271d7fec4Smrg * This routine returns the current video color mask value.
220371d7fec4Smrg *---------------------------------------------------------------------------
220471d7fec4Smrg */
220571d7fec4Smrg#if GFX_VIDEO_DYNAMIC
220671d7fec4Smrgunsigned long
220771d7fec4Smrgredcloud_get_video_color_key_mask(void)
220871d7fec4Smrg#else
220971d7fec4Smrgunsigned long
221071d7fec4Smrggfx_get_video_color_key_mask(void)
221171d7fec4Smrg#endif
221271d7fec4Smrg{
221371d7fec4Smrg   return (READ_VID32(RCDF_VIDEO_COLOR_MASK));
221471d7fec4Smrg}
221571d7fec4Smrg
221671d7fec4Smrg/*---------------------------------------------------------------------------
221771d7fec4Smrg * gfx_get_video_color_key_src
221871d7fec4Smrg *
221971d7fec4Smrg * This routine returns 0 for video data compare, 1 for graphics data.
222071d7fec4Smrg *---------------------------------------------------------------------------
222171d7fec4Smrg */
222271d7fec4Smrg#if GFX_VIDEO_DYNAMIC
222371d7fec4Smrgint
222471d7fec4Smrgredcloud_get_video_color_key_src(void)
222571d7fec4Smrg#else
222671d7fec4Smrgint
222771d7fec4Smrggfx_get_video_color_key_src(void)
222871d7fec4Smrg#endif
222971d7fec4Smrg{
223071d7fec4Smrg   if (READ_VID32(RCDF_DISPLAY_CONFIG) & RCDF_DCFG_VG_CK)
223171d7fec4Smrg      return (0);
223271d7fec4Smrg   return (1);
223371d7fec4Smrg}
223471d7fec4Smrg
223571d7fec4Smrg/*---------------------------------------------------------------------------
223671d7fec4Smrg * gfx_get_video_filter
223771d7fec4Smrg *
223871d7fec4Smrg * This routine returns if the filters are currently enabled.
223971d7fec4Smrg *---------------------------------------------------------------------------
224071d7fec4Smrg */
224171d7fec4Smrg#if GFX_VIDEO_DYNAMIC
224271d7fec4Smrgint
224371d7fec4Smrgredcloud_get_video_filter(void)
224471d7fec4Smrg#else
224571d7fec4Smrgint
224671d7fec4Smrggfx_get_video_filter(void)
224771d7fec4Smrg#endif
224871d7fec4Smrg{
224971d7fec4Smrg   int retval = 0;
225071d7fec4Smrg
225171d7fec4Smrg   if (READ_VID32(RCDF_VIDEO_CONFIG) & RCDF_VCFG_X_FILTER_EN)
225271d7fec4Smrg      retval |= 1;
225371d7fec4Smrg   if (READ_VID32(RCDF_VIDEO_CONFIG) & RCDF_VCFG_Y_FILTER_EN)
225471d7fec4Smrg      retval |= 2;
225571d7fec4Smrg   return (retval);
225671d7fec4Smrg}
225771d7fec4Smrg
225871d7fec4Smrg/*---------------------------------------------------------------------------
225971d7fec4Smrg * gfx_get_video_request
226071d7fec4Smrg *
226171d7fec4Smrg * This routine returns the horizontal (pixel) and vertical (lines) video
226271d7fec4Smrg * request values.
226371d7fec4Smrg *---------------------------------------------------------------------------
226471d7fec4Smrg */
226571d7fec4Smrg#if GFX_VIDEO_DYNAMIC
226671d7fec4Smrgint
226771d7fec4Smrgredcloud_get_video_request(short *x, short *y)
226871d7fec4Smrg#else
226971d7fec4Smrgint
227071d7fec4Smrggfx_get_video_request(short *x, short *y)
227171d7fec4Smrg#endif
227271d7fec4Smrg{
227371d7fec4Smrg   unsigned long request = 0;
227471d7fec4Smrg
227571d7fec4Smrg   request = (READ_VID32(RCDF_VIDEO_REQUEST));
227671d7fec4Smrg   *x = (short)((request >> RCDF_VIDEO_X_REQUEST_POS) &
227771d7fec4Smrg		RCDF_VIDEO_REQUEST_MASK);
227871d7fec4Smrg   *y = (short)((request >> RCDF_VIDEO_Y_REQUEST_POS) &
227971d7fec4Smrg		RCDF_VIDEO_REQUEST_MASK);
228071d7fec4Smrg
228171d7fec4Smrg   *x -= gfx_get_htotal() - gfx_get_hsync_end() - 2;
228271d7fec4Smrg   *y -= gfx_get_vtotal() - gfx_get_vsync_end() + 1;
228371d7fec4Smrg
228471d7fec4Smrg   return (0);
228571d7fec4Smrg}
228671d7fec4Smrg
228771d7fec4Smrg/*---------------------------------------------------------------------------
228871d7fec4Smrg * gfx_get_video_cursor()
228971d7fec4Smrg *
229071d7fec4Smrg * This routine configures the video hardware cursor.
229171d7fec4Smrg * If the "mask"ed bits in the graphics pixel match "key", then either "color1"
229271d7fec4Smrg * or "color2" will be used for this pixel, according to the value of the bit
229371d7fec4Smrg * in offset "select_color2".
229471d7fec4Smrg *---------------------------------------------------------------------------
229571d7fec4Smrg */
229671d7fec4Smrg#if GFX_VIDEO_DYNAMIC
229771d7fec4Smrgint
229871d7fec4Smrgredcloud_get_video_cursor(unsigned long *key, unsigned long *mask,
229971d7fec4Smrg			  unsigned short *select_color2,
230071d7fec4Smrg			  unsigned long *color1, unsigned short *color2)
230171d7fec4Smrg#else
230271d7fec4Smrgint
230371d7fec4Smrggfx_get_video_cursor(unsigned long *key, unsigned long *mask,
230471d7fec4Smrg		     unsigned short *select_color2, unsigned long *color1,
230571d7fec4Smrg		     unsigned short *color2)
230671d7fec4Smrg#endif
230771d7fec4Smrg{
230871d7fec4Smrg   *select_color2 =
230971d7fec4Smrg	 (unsigned short)(READ_VID32(RCDF_CURSOR_COLOR_KEY) >>
231071d7fec4Smrg			  RCDF_CURSOR_COLOR_KEY_OFFSET_POS);
231171d7fec4Smrg   *key = READ_VID32(RCDF_CURSOR_COLOR_KEY) & RCDF_COLOR_MASK;
231271d7fec4Smrg   *mask = READ_VID32(RCDF_CURSOR_COLOR_MASK) & RCDF_COLOR_MASK;
231371d7fec4Smrg   *color1 = READ_VID32(RCDF_CURSOR_COLOR_1) & RCDF_COLOR_MASK;
231471d7fec4Smrg   *color2 =
231571d7fec4Smrg	 (unsigned short)(READ_VID32(RCDF_CURSOR_COLOR_2) & RCDF_COLOR_MASK);
231671d7fec4Smrg   return (0);
231771d7fec4Smrg}
231871d7fec4Smrg
231971d7fec4Smrg/*---------------------------------------------------------------------------
232071d7fec4Smrg * gfx_read_crc
232171d7fec4Smrg *
232271d7fec4Smrg * This routine returns the hardware CRC value, which is used for automated
232371d7fec4Smrg * testing.  The value is like a checksum, but will change if pixels move
232471d7fec4Smrg * locations.
232571d7fec4Smrg *---------------------------------------------------------------------------
232671d7fec4Smrg */
232771d7fec4Smrg#if GFX_VIDEO_DYNAMIC
232871d7fec4Smrgunsigned long
232971d7fec4Smrgredcloud_read_crc(void)
233071d7fec4Smrg#else
233171d7fec4Smrgunsigned long
233271d7fec4Smrggfx_read_crc(void)
233371d7fec4Smrg#endif
233471d7fec4Smrg{
233571d7fec4Smrg   Q_WORD msr_value;
233671d7fec4Smrg   unsigned long crc = 0xFFFFFFFF;
233771d7fec4Smrg
233871d7fec4Smrg   /* DISABLE 32-BIT CRCS */
233971d7fec4Smrg   /* For GX1.x, this is a reserved bit, and is assumed to be a benign access */
234071d7fec4Smrg
234171d7fec4Smrg   gfx_msr_read(RC_ID_DF, RCDF_MBD_MSR_DIAG_DF, &msr_value);
234271d7fec4Smrg   msr_value.low &= ~RCDF_DIAG_32BIT_CRC;
234371d7fec4Smrg   gfx_msr_write(RC_ID_DF, RCDF_MBD_MSR_DIAG_DF, &msr_value);
234471d7fec4Smrg
234571d7fec4Smrg   if (gfx_test_timing_active()) {
234671d7fec4Smrg      /* WAIT UNTIL ACTIVE DISPLAY */
234771d7fec4Smrg
234871d7fec4Smrg      while (!gfx_test_vertical_active()) ;
234971d7fec4Smrg
235071d7fec4Smrg      /* RESET CRC DURING ACTIVE DISPLAY */
235171d7fec4Smrg
235271d7fec4Smrg      WRITE_VID32(RCDF_VID_CRC, 0);
235371d7fec4Smrg      WRITE_VID32(RCDF_VID_CRC, 1);
235471d7fec4Smrg
235571d7fec4Smrg      /* WAIT UNTIL NOT ACTIVE, THEN ACTIVE, NOT ACTIVE, THEN ACTIVE */
235671d7fec4Smrg
235771d7fec4Smrg      while (!gfx_test_vertical_active()) ;
235871d7fec4Smrg      while (gfx_test_vertical_active()) ;
235971d7fec4Smrg      while (!gfx_test_vertical_active()) ;
236071d7fec4Smrg      while (gfx_test_vertical_active()) ;
236171d7fec4Smrg      while (!gfx_test_vertical_active()) ;
236271d7fec4Smrg      crc = READ_VID32(RCDF_VID_CRC) >> 8;
236371d7fec4Smrg   }
236471d7fec4Smrg   return (crc);
236571d7fec4Smrg}
236671d7fec4Smrg
236771d7fec4Smrg/*---------------------------------------------------------------------------
236871d7fec4Smrg * gfx_read_crc32
236971d7fec4Smrg *
237071d7fec4Smrg * This routine returns the 32-bit hardware CRC value, which is used for automated
237171d7fec4Smrg * testing.  The value is like a checksum, but will change if pixels move
237271d7fec4Smrg * locations.
237371d7fec4Smrg *---------------------------------------------------------------------------
237471d7fec4Smrg */
237571d7fec4Smrg#if GFX_VIDEO_DYNAMIC
237671d7fec4Smrgunsigned long
237771d7fec4Smrgredcloud_read_crc32(void)
237871d7fec4Smrg#else
237971d7fec4Smrgunsigned long
238071d7fec4Smrggfx_read_crc32(void)
238171d7fec4Smrg#endif
238271d7fec4Smrg{
238371d7fec4Smrg   Q_WORD msr_value;
238471d7fec4Smrg   unsigned long crc = 0xFFFFFFFF;
238571d7fec4Smrg
238671d7fec4Smrg   /* ENABLE 32-BIT CRCS */
238771d7fec4Smrg   /* For GX1.x, this is a reserved bit, and is assumed to be a benign access */
238871d7fec4Smrg
238971d7fec4Smrg   gfx_msr_read(RC_ID_DF, RCDF_MBD_MSR_DIAG_DF, &msr_value);
239071d7fec4Smrg   msr_value.low |= RCDF_DIAG_32BIT_CRC;
239171d7fec4Smrg   gfx_msr_write(RC_ID_DF, RCDF_MBD_MSR_DIAG_DF, &msr_value);
239271d7fec4Smrg
239371d7fec4Smrg   if (gfx_test_timing_active()) {
239471d7fec4Smrg      /* WAIT UNTIL ACTIVE DISPLAY */
239571d7fec4Smrg
239671d7fec4Smrg      while (!gfx_test_vertical_active()) ;
239771d7fec4Smrg
239871d7fec4Smrg      /* RESET CRC DURING ACTIVE DISPLAY */
239971d7fec4Smrg
240071d7fec4Smrg      WRITE_VID32(RCDF_VID_CRC, 0);
240171d7fec4Smrg      WRITE_VID32(RCDF_VID_CRC, 1);
240271d7fec4Smrg
240371d7fec4Smrg      /* WAIT UNTIL NOT ACTIVE, THEN ACTIVE, NOT ACTIVE, THEN ACTIVE */
240471d7fec4Smrg
240571d7fec4Smrg      while (!gfx_test_vertical_active()) ;
240671d7fec4Smrg      while (gfx_test_vertical_active()) ;
240771d7fec4Smrg      while (!gfx_test_vertical_active()) ;
240871d7fec4Smrg      while (gfx_test_vertical_active()) ;
240971d7fec4Smrg      while (!gfx_test_vertical_active()) ;
241071d7fec4Smrg      crc = READ_VID32(RCDF_VID_CRC32);
241171d7fec4Smrg   }
241271d7fec4Smrg   return (crc);
241371d7fec4Smrg}
241471d7fec4Smrg
241571d7fec4Smrg/*---------------------------------------------------------------------------
241671d7fec4Smrg * gfx_read_window_crc
241771d7fec4Smrg *
241871d7fec4Smrg * This routine returns the hardware CRC value for a subsection of the display.
241971d7fec4Smrg * This value is used to debug whole-screen CRC failures.
242071d7fec4Smrg *---------------------------------------------------------------------------
242171d7fec4Smrg */
242271d7fec4Smrg#if GFX_VIDEO_DYNAMIC
242371d7fec4Smrgunsigned long
242471d7fec4Smrgredcloud_read_window_crc(int source, unsigned short x, unsigned short y,
242571d7fec4Smrg			 unsigned short width, unsigned short height,
242671d7fec4Smrg			 int crc32)
242771d7fec4Smrg#else
242871d7fec4Smrgunsigned long
242971d7fec4Smrggfx_read_window_crc(int source, unsigned short x, unsigned short y,
243071d7fec4Smrg		    unsigned short width, unsigned short height, int crc32)
243171d7fec4Smrg#endif
243271d7fec4Smrg{
243371d7fec4Smrg   Q_WORD msr_value;
243471d7fec4Smrg   unsigned long xpos, ypos, crc = 0;
243571d7fec4Smrg   unsigned long old_fmt = 0;
243671d7fec4Smrg   unsigned int vsync_active_base, vsync_inactive_base, hsync_active_base;
243771d7fec4Smrg   unsigned int vsync_active_shift, vsync_inactive_shift, hsync_active_shift;
243871d7fec4Smrg   unsigned int vsync_bit, hsync_bit, sync_polarities = 0;
243971d7fec4Smrg
244071d7fec4Smrg   /* CONFIGURE DISPLAY FILTER TO LOAD DATA ONTO LOWER 32-BITS */
244171d7fec4Smrg
244271d7fec4Smrg   msr_value.high = 0;
244371d7fec4Smrg   msr_value.low =
244471d7fec4Smrg	 (source == CRC_SOURCE_GFX_DATA) ? (RCDF_MBD_DIAG_EN0 | 0x0000000F)
244571d7fec4Smrg	 : (RCDF_MBD_DIAG_EN0 | 0x0000000B);
244671d7fec4Smrg   gfx_msr_write(RC_ID_DF, MBD_MSR_DIAG, &msr_value);
244771d7fec4Smrg
244871d7fec4Smrg   /* CONFIGURE DISPLAY FILTER FOR APPROPRIATE OUTPUT */
244971d7fec4Smrg
245071d7fec4Smrg   if (source != CRC_SOURCE_GFX_DATA) {
245171d7fec4Smrg      gfx_msr_read(RC_ID_DF, MBD_MSR_CONFIG, &msr_value);
245271d7fec4Smrg      old_fmt = msr_value.low;
245371d7fec4Smrg      msr_value.low &= ~(RCDF_CONFIG_FMT_MASK);
245471d7fec4Smrg      msr_value.low |= ((source == CRC_SOURCE_FP_DATA) ? RCDF_CONFIG_FMT_FP :
245571d7fec4Smrg			RCDF_CONFIG_FMT_CRT);
245671d7fec4Smrg      gfx_msr_write(RC_ID_DF, MBD_MSR_CONFIG, &msr_value);
245771d7fec4Smrg   }
245871d7fec4Smrg
245971d7fec4Smrg   /* CONFIGURE MCP TO LOAD REGB DATA ONTO UPPER 32-BITS */
246071d7fec4Smrg
246171d7fec4Smrg   msr_value.low = MCP_MBD_DIAG_EN1 | 0x00050000;
246271d7fec4Smrg   gfx_msr_write(RC_ID_MCP, MBD_MSR_DIAG, &msr_value);
246371d7fec4Smrg
246471d7fec4Smrg   /* ENABLE HW CLOCK GATING AND SET MCP CLOCK TO DOT CLOCK */
246571d7fec4Smrg
246671d7fec4Smrg   msr_value.low = 1l;
246771d7fec4Smrg   gfx_msr_write(RC_ID_MCP, MBD_MSR_PM, &msr_value);
246871d7fec4Smrg   msr_value.low = 0;
246971d7fec4Smrg   gfx_msr_write(RC_ID_MCP, MCP_DBGCLKCTL, &msr_value);
247071d7fec4Smrg   msr_value.low = 3;
247171d7fec4Smrg   gfx_msr_write(RC_ID_MCP, MCP_DBGCLKCTL, &msr_value);
247271d7fec4Smrg
247371d7fec4Smrg   /* DISABLE MCP ACTIONS */
247471d7fec4Smrg
247571d7fec4Smrg   msr_value.high = 0x00000000;
247671d7fec4Smrg   msr_value.low = 0x00000000;
247771d7fec4Smrg   gfx_msr_write(RC_ID_MCP, MCP_DIAGCTL, &msr_value);
247871d7fec4Smrg
247971d7fec4Smrg   /* SET APPROPRIATE BASE ADDRESS */
248071d7fec4Smrg   /* M-Sets use normal diag bits, while N-Sets use inverted diag bits */
248171d7fec4Smrg   /* We thus use the M-sets when polling for a high signal and the N  */
248271d7fec4Smrg   /* sets when polling for a low signal.                              */
248371d7fec4Smrg
248471d7fec4Smrg   if (source != CRC_SOURCE_GFX_DATA) {
248571d7fec4Smrg      sync_polarities = gfx_get_sync_polarities();
248671d7fec4Smrg      vsync_bit = 29;
248771d7fec4Smrg      hsync_bit = 30;
248871d7fec4Smrg   } else {
248971d7fec4Smrg      vsync_bit = 25;
249071d7fec4Smrg      hsync_bit = 26;
249171d7fec4Smrg   }
249271d7fec4Smrg
249371d7fec4Smrg   if (sync_polarities & 1) {
249471d7fec4Smrg      hsync_active_base = MCP_SETM0CTL;
249571d7fec4Smrg      hsync_active_shift = 2;
249671d7fec4Smrg   } else {
249771d7fec4Smrg      hsync_active_base = MCP_SETN0CTL;
249871d7fec4Smrg      hsync_active_shift = 1;
249971d7fec4Smrg   }
250071d7fec4Smrg   if (sync_polarities & 2) {
250171d7fec4Smrg      vsync_active_base = MCP_SETM0CTL;
250271d7fec4Smrg      vsync_inactive_base = MCP_SETN0CTL;
250371d7fec4Smrg      vsync_active_shift = 2;
250471d7fec4Smrg      vsync_inactive_shift = 1;
250571d7fec4Smrg   } else {
250671d7fec4Smrg      vsync_active_base = MCP_SETN0CTL;
250771d7fec4Smrg      vsync_inactive_base = MCP_SETM0CTL;
250871d7fec4Smrg      vsync_active_shift = 1;
250971d7fec4Smrg      vsync_inactive_shift = 2;
251071d7fec4Smrg   }
251171d7fec4Smrg
251271d7fec4Smrg   /* SET STATE TRANSITIONS          */
251371d7fec4Smrg
251471d7fec4Smrg   /* STATE 0-1 TRANSITION (SET 0)      */
251571d7fec4Smrg   /* XState = 00 and VSync Inactive    */
251671d7fec4Smrg   /* Note: DF VSync = Diag Bus Bit 29  */
251771d7fec4Smrg   /*       VG VSync = Diag Bus Bit 25  */
251871d7fec4Smrg
251971d7fec4Smrg   msr_value.low = 0x000000A0;
252071d7fec4Smrg   msr_value.high = 0x00008000 | ((unsigned long)vsync_bit << 16) |
252171d7fec4Smrg	 ((unsigned long)vsync_bit << 21) | ((unsigned long)vsync_bit << 26);
252271d7fec4Smrg   gfx_msr_write(RC_ID_MCP, vsync_inactive_base, &msr_value);
252371d7fec4Smrg
252471d7fec4Smrg   /* STATE 1-2 TRANSITION (SET 4)   */
252571d7fec4Smrg   /* XState = 01 and VSync Active   */
252671d7fec4Smrg
252771d7fec4Smrg   msr_value.low = 0x000000C0;
252871d7fec4Smrg   gfx_msr_write(RC_ID_MCP, vsync_active_base + 4, &msr_value);
252971d7fec4Smrg
253071d7fec4Smrg   /* STATE 2-3 TRANSITION (SET 1)   */
253171d7fec4Smrg   /* XState = 10 and VSync Inactive */
253271d7fec4Smrg
253371d7fec4Smrg   msr_value.low = 0x00000120;
253471d7fec4Smrg   gfx_msr_write(RC_ID_MCP, vsync_inactive_base + 1, &msr_value);
253571d7fec4Smrg
253671d7fec4Smrg   /* HORIZONTAL COUNTER (SET 5)         */
253771d7fec4Smrg   /* XState = 10 and HSync Active       */
253871d7fec4Smrg   /* Notes: DF HSync = Diag Bus Bit 30  */
253971d7fec4Smrg   /*        VG HSync = Diag Bus Bit 26  */
254071d7fec4Smrg
254171d7fec4Smrg   msr_value.high = 0x00008000 | ((unsigned long)hsync_bit << 16) |
254271d7fec4Smrg	 ((unsigned long)hsync_bit << 21) | ((unsigned long)hsync_bit << 26);
254371d7fec4Smrg   msr_value.low = 0x00000120;
254471d7fec4Smrg   gfx_msr_write(RC_ID_MCP, hsync_active_base + 5, &msr_value);
254571d7fec4Smrg
254671d7fec4Smrg   /* HORIZONTAL COUNTER RESET (SET 4)     */
254771d7fec4Smrg   /* XState = 10 and H. Counter = limit   */
254871d7fec4Smrg   /* Note: H. Counter is lower 16-bits of */
254971d7fec4Smrg   /*       RegB.                          */
255071d7fec4Smrg
255171d7fec4Smrg   msr_value.high = 0x00000000;
255271d7fec4Smrg   msr_value.low = 0x00000128;
255371d7fec4Smrg   gfx_msr_write(RC_ID_MCP, vsync_inactive_base + 4, &msr_value);
255471d7fec4Smrg
255571d7fec4Smrg   /* CRC TRIGGER (SET 0)   */
255671d7fec4Smrg   /* Cmp0 <= xpos <  Cmp1  */
255771d7fec4Smrg   /* Cmp2 <= ypos <  Cmp2  */
255871d7fec4Smrg
255971d7fec4Smrg   msr_value.high = 0x00000000;
256071d7fec4Smrg   msr_value.low = 0x10C20120;
256171d7fec4Smrg   gfx_msr_write(RC_ID_MCP, vsync_active_base, &msr_value);
256271d7fec4Smrg
256371d7fec4Smrg   /* SET COMPARATOR VALUES */
256471d7fec4Smrg   /* Note: The VG data outputs from the DF are delayed by one pixel clock. */
256571d7fec4Smrg   /*       In this mode, we thus add one to horizontal comparator limits.  */
256671d7fec4Smrg
256771d7fec4Smrg   /* COMPARATOR 0                                        */
256871d7fec4Smrg   /* Lower limit = xpos + (h_blank_pixels - 1) - 3       */
256971d7fec4Smrg   /* Notes:                                              */
257071d7fec4Smrg   /*   1. 3 is the pipeline delay for MCP register       */
257171d7fec4Smrg   /*      data to access the diag bus                    */
257271d7fec4Smrg   /*   2. h_blank_pixels = HTOTAL - HSYNC_END            */
257371d7fec4Smrg
257471d7fec4Smrg   xpos = (unsigned long)x + ((unsigned long)gfx_get_htotal() -
257571d7fec4Smrg			      (unsigned long)gfx_get_hsync_end() - 1l) - 3l;
257671d7fec4Smrg   if (source == CRC_SOURCE_GFX_DATA)
257771d7fec4Smrg      xpos++;
257871d7fec4Smrg   msr_value.high = 0x00000000;
257971d7fec4Smrg   msr_value.low = xpos;
258071d7fec4Smrg   gfx_msr_write(RC_ID_MCP, MCP_CMPVAL0, &msr_value);
258171d7fec4Smrg
258271d7fec4Smrg   /* COMPARATOR 1                                          */
258371d7fec4Smrg   /* Upper limit = xpos + width + (h_blank_pixels - 1) - 3 */
258471d7fec4Smrg
258571d7fec4Smrg   msr_value.low = xpos + (unsigned long)width;
258671d7fec4Smrg   gfx_msr_write(RC_ID_MCP, MCP_CMPVAL0 + 2, &msr_value);
258771d7fec4Smrg
258871d7fec4Smrg   /* COMPARATOR 2                                  */
258971d7fec4Smrg   /* Lower limit = ypos + v_blank_pixels           */
259071d7fec4Smrg   /* Notes:                                        */
259171d7fec4Smrg   /*   1. v_blank_pixels = VTOTAL - VSYNC_END      */
259271d7fec4Smrg
259371d7fec4Smrg   ypos = (unsigned long)y + (unsigned long)gfx_get_vtotal() -
259471d7fec4Smrg	 (unsigned long)gfx_get_vsync_end();
259571d7fec4Smrg   msr_value.low = ypos << 16;
259671d7fec4Smrg   gfx_msr_write(RC_ID_MCP, MCP_CMPVAL0 + 4, &msr_value);
259771d7fec4Smrg
259871d7fec4Smrg   /* COMPARATOR 3                                  */
259971d7fec4Smrg   /* Upper limit = ypos + height + v_blank_pixels  */
260071d7fec4Smrg
260171d7fec4Smrg   msr_value.low = (ypos + (unsigned long)height) << 16;
260271d7fec4Smrg   gfx_msr_write(RC_ID_MCP, MCP_CMPVAL0 + 6, &msr_value);
260371d7fec4Smrg
260471d7fec4Smrg   /* SET COMPARATOR MASKS */
260571d7fec4Smrg
260671d7fec4Smrg   /* COMPARATORS 0 AND 1 REFER TO LOWER 16 BITS OF REGB */
260771d7fec4Smrg
260871d7fec4Smrg   msr_value.high = 0x00000000;
260971d7fec4Smrg   msr_value.low = 0x0000FFFF;
261071d7fec4Smrg   gfx_msr_write(RC_ID_MCP, MCP_CMPMASK0, &msr_value);
261171d7fec4Smrg   gfx_msr_write(RC_ID_MCP, MCP_CMPMASK0 + 2, &msr_value);
261271d7fec4Smrg
261371d7fec4Smrg   /* COMPARATORS 2 AND 3 REFER TO UPPER 16 BITS OF REGB */
261471d7fec4Smrg
261571d7fec4Smrg   msr_value.low = 0xFFFF0000;
261671d7fec4Smrg   gfx_msr_write(RC_ID_MCP, MCP_CMPMASK0 + 4, &msr_value);
261771d7fec4Smrg   gfx_msr_write(RC_ID_MCP, MCP_CMPMASK0 + 6, &msr_value);
261871d7fec4Smrg
261971d7fec4Smrg   /* SET REGA MASK TO CRC ONLY 24 BITS OF DATA */
262071d7fec4Smrg
262171d7fec4Smrg   msr_value.high = 0x00000000;
262271d7fec4Smrg   msr_value.low = 0x00FFFFFF;
262371d7fec4Smrg   gfx_msr_write(RC_ID_MCP, MCP_REGAMASK, &msr_value);
262471d7fec4Smrg
262571d7fec4Smrg   /* SET REGB VALUE */
262671d7fec4Smrg   /* Lower 16 bits use HTOTAL - SYNC TIME - 1 to set the counter rollover limit. */
262771d7fec4Smrg   /* Upper 16 bits use 0xFFFF to remove auto-clear behavior.     */
262871d7fec4Smrg
262971d7fec4Smrg   msr_value.high = 0x00000000;
263071d7fec4Smrg   msr_value.low = 0xFFFF0000 |
263171d7fec4Smrg	 ((gfx_get_htotal() - (gfx_get_hsync_end() - gfx_get_hsync_start()) -
263271d7fec4Smrg	   1) & 0xFFFF);
263371d7fec4Smrg   gfx_msr_write(RC_ID_MCP, MCP_REGBVAL, &msr_value);
263471d7fec4Smrg
263571d7fec4Smrg   /* PROGRAM ACTIONS */
263671d7fec4Smrg
263771d7fec4Smrg   /* GOTO STATE 01 */
263871d7fec4Smrg
263971d7fec4Smrg   msr_value.high = 0x00000000;
264071d7fec4Smrg   msr_value.low = 0x00000008 | (1l << vsync_inactive_shift);
264171d7fec4Smrg   gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 14, &msr_value);
264271d7fec4Smrg
264371d7fec4Smrg   /* GOTO STATE 10 */
264471d7fec4Smrg
264571d7fec4Smrg   msr_value.low = 0x00080000 | (1l << (vsync_active_shift + 16));
264671d7fec4Smrg   gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 15, &msr_value);
264771d7fec4Smrg
264871d7fec4Smrg   /* GOTO STATE 11 */
264971d7fec4Smrg
265071d7fec4Smrg   msr_value.low = 0x00000080 | (1l << (vsync_inactive_shift + 4));
265171d7fec4Smrg   gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 16, &msr_value);
265271d7fec4Smrg
265371d7fec4Smrg   /* CLEAR REGB (COUNTERS)  */
265471d7fec4Smrg   /* RegB is cleared upon transitioning to state 10              */
265571d7fec4Smrg   /* RegA is not cleared as the initial value must be 0x00000001 */
265671d7fec4Smrg
265771d7fec4Smrg   msr_value.low = 0x00080000 | (1l << (vsync_active_shift + 16));
265871d7fec4Smrg   gfx_msr_write(RC_ID_MCP, MCP_ACTION0, &msr_value);
265971d7fec4Smrg
266071d7fec4Smrg   /* CRC INTO REGA        */
266171d7fec4Smrg   /* INCREMENT H. COUNTER */
266271d7fec4Smrg   /* cmp0 <= xpos < cmp1  */
266371d7fec4Smrg   /* cmp2 <= ypos < cmp3  */
266471d7fec4Smrg   /* XState = 10          */
266571d7fec4Smrg
266671d7fec4Smrg   msr_value.low = 0x00000008 | (1l << vsync_active_shift) |
266771d7fec4Smrg	 0x00800000 | (1l << (hsync_active_shift + 20));
266871d7fec4Smrg   gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 1, &msr_value);
266971d7fec4Smrg
267071d7fec4Smrg   /* INCREMENT V. COUNTER */
267171d7fec4Smrg   /* V. Counter is incremented when the H. Counter */
267271d7fec4Smrg   /* rolls over.                                   */
267371d7fec4Smrg
267471d7fec4Smrg   msr_value.low = 0x00080000 | (1l << (vsync_inactive_shift + 16));
267571d7fec4Smrg   gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 2, &msr_value);
267671d7fec4Smrg
267771d7fec4Smrg   /* CLEAR ALL OTHER ACTIONS */
267871d7fec4Smrg   /* This prevents side-effects from previous accesses to the MCP */
267971d7fec4Smrg   /* debug logic.                                                 */
268071d7fec4Smrg   msr_value.low = 0x00000000;
268171d7fec4Smrg   msr_value.high = 0x00000000;
268271d7fec4Smrg   gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 3, &msr_value);
268371d7fec4Smrg   gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 4, &msr_value);
268471d7fec4Smrg   gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 5, &msr_value);
268571d7fec4Smrg   gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 6, &msr_value);
268671d7fec4Smrg   gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 7, &msr_value);
268771d7fec4Smrg   gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 8, &msr_value);
268871d7fec4Smrg   gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 9, &msr_value);
268971d7fec4Smrg   gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 10, &msr_value);
269071d7fec4Smrg   gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 11, &msr_value);
269171d7fec4Smrg   gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 12, &msr_value);
269271d7fec4Smrg   gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 13, &msr_value);
269371d7fec4Smrg   gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 17, &msr_value);
269471d7fec4Smrg   gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 18, &msr_value);
269571d7fec4Smrg   gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 19, &msr_value);
269671d7fec4Smrg   gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 20, &msr_value);
269771d7fec4Smrg
269871d7fec4Smrg   /* SET REGA CRC VALUE TO 1 OR 0 */
269971d7fec4Smrg
270071d7fec4Smrg   if (!crc32)
270171d7fec4Smrg      msr_value.low = 0x00000001;
270271d7fec4Smrg   gfx_msr_write(RC_ID_MCP, MCP_REGA, &msr_value);
270371d7fec4Smrg
270471d7fec4Smrg   /* SET XSTATE TO 0 */
270571d7fec4Smrg
270671d7fec4Smrg   msr_value.low = 0;
270771d7fec4Smrg   msr_value.high = 0;
270871d7fec4Smrg   gfx_msr_write(RC_ID_MCP, MCP_XSTATE, &msr_value);
270971d7fec4Smrg
271071d7fec4Smrg   /* CONFIGURE DIAG CONTROL */
271171d7fec4Smrg   /* Set all four comparators to watch the upper diag bus.           */
271271d7fec4Smrg   /* Set REGA action1 to legacy CRC or 32-bit CRC.                   */
271371d7fec4Smrg   /* Set REGB action1 to increment lower 16 bits and clear at limit. */
271471d7fec4Smrg   /* Set REGB action2 to increment upper 16 bits.                    */
271571d7fec4Smrg   /* Enable all actions.                                             */
271671d7fec4Smrg
271771d7fec4Smrg   if (crc32)
271871d7fec4Smrg      msr_value.low = 0x9A820055;
271971d7fec4Smrg   else
272071d7fec4Smrg      msr_value.low = 0x9A840055;
272171d7fec4Smrg   msr_value.high = 0x00000000;
272271d7fec4Smrg   gfx_msr_write(RC_ID_MCP, MCP_DIAGCTL, &msr_value);
272371d7fec4Smrg
272471d7fec4Smrg   /* DELAY TWO FRAMES */
272571d7fec4Smrg
272671d7fec4Smrg   while (!gfx_test_vertical_active()) ;
272771d7fec4Smrg   while (gfx_test_vertical_active()) ;
272871d7fec4Smrg   while (!gfx_test_vertical_active()) ;
272971d7fec4Smrg   while (gfx_test_vertical_active()) ;
273071d7fec4Smrg   while (!gfx_test_vertical_active()) ;
273171d7fec4Smrg
273271d7fec4Smrg   /* VERIFY THAT XSTATE = 11 */
273371d7fec4Smrg
273471d7fec4Smrg   gfx_msr_read(RC_ID_MCP, MCP_XSTATE, &msr_value);
273571d7fec4Smrg   if ((msr_value.low & 3) == 3) {
273671d7fec4Smrg      gfx_msr_read(RC_ID_MCP, MCP_REGA, &msr_value);
273771d7fec4Smrg
273871d7fec4Smrg      crc = msr_value.low;
273971d7fec4Smrg      if (!crc32)
274071d7fec4Smrg	 crc &= 0xFFFFFF;
274171d7fec4Smrg   }
274271d7fec4Smrg
274371d7fec4Smrg   /* DISABLE MCP AND DF DIAG BUS OUTPUTS */
274471d7fec4Smrg
274571d7fec4Smrg   msr_value.low = 0x00000000;
274671d7fec4Smrg   msr_value.high = 0x00000000;
274771d7fec4Smrg   gfx_msr_write(RC_ID_DF, MBD_MSR_DIAG, &msr_value);
274871d7fec4Smrg   gfx_msr_write(RC_ID_MCP, MBD_MSR_DIAG, &msr_value);
274971d7fec4Smrg
275071d7fec4Smrg   /* DISABLE MCP ACTIONS */
275171d7fec4Smrg
275271d7fec4Smrg   msr_value.high = 0x00000000;
275371d7fec4Smrg   msr_value.low = 0x00000000;
275471d7fec4Smrg   gfx_msr_write(RC_ID_MCP, MCP_DIAGCTL, &msr_value);
275571d7fec4Smrg
275671d7fec4Smrg   /* RESTORE PREVIOUS OUTPUT FORMAT */
275771d7fec4Smrg
275871d7fec4Smrg   if (source != CRC_SOURCE_GFX_DATA) {
275971d7fec4Smrg      gfx_msr_read(RC_ID_DF, MBD_MSR_CONFIG, &msr_value);
276071d7fec4Smrg      msr_value.low = old_fmt;
276171d7fec4Smrg      gfx_msr_write(RC_ID_DF, MBD_MSR_CONFIG, &msr_value);
276271d7fec4Smrg   }
276371d7fec4Smrg   return crc;
276471d7fec4Smrg}
276571d7fec4Smrg
276671d7fec4Smrg/*---------------------------------------------------------------------------
276771d7fec4Smrg * gfx_get_alpha_enable
276871d7fec4Smrg *
276971d7fec4Smrg * This routine returns 1 if the selected alpha window is currently
277071d7fec4Smrg * enabled, or 0 if it is currently disabled.
277171d7fec4Smrg *---------------------------------------------------------------------------
277271d7fec4Smrg */
277371d7fec4Smrg#if GFX_VIDEO_DYNAMIC
277471d7fec4Smrgvoid
277571d7fec4Smrgredcloud_get_alpha_enable(int *enable)
277671d7fec4Smrg#else
277771d7fec4Smrgvoid
277871d7fec4Smrggfx_get_alpha_enable(int *enable)
277971d7fec4Smrg#endif
278071d7fec4Smrg{
278171d7fec4Smrg   unsigned long value = 0;
278271d7fec4Smrg
278371d7fec4Smrg   *enable = 0;
278471d7fec4Smrg   if (gfx_alpha_select <= 2) {
278571d7fec4Smrg      value =
278671d7fec4Smrg	    READ_VID32(RCDF_ALPHA_CONTROL_1 +
278771d7fec4Smrg		       ((unsigned long)gfx_alpha_select << 5));
278871d7fec4Smrg      if (value & RCDF_ACTRL_WIN_ENABLE)
278971d7fec4Smrg	 *enable = 1;
279071d7fec4Smrg   }
279171d7fec4Smrg   return;
279271d7fec4Smrg}
279371d7fec4Smrg
279471d7fec4Smrg/*---------------------------------------------------------------------------
279571d7fec4Smrg * gfx_get_alpha_size
279671d7fec4Smrg *
279771d7fec4Smrg * This routine returns the size of the currently selected alpha region.
279871d7fec4Smrg *---------------------------------------------------------------------------
279971d7fec4Smrg */
280071d7fec4Smrg#if GFX_VIDEO_DYNAMIC
280171d7fec4Smrgvoid
280271d7fec4Smrgredcloud_get_alpha_size(unsigned short *x, unsigned short *y,
280371d7fec4Smrg			unsigned short *width, unsigned short *height)
280471d7fec4Smrg#else
280571d7fec4Smrgvoid
280671d7fec4Smrggfx_get_alpha_size(unsigned short *x, unsigned short *y,
280771d7fec4Smrg		   unsigned short *width, unsigned short *height)
280871d7fec4Smrg#endif
280971d7fec4Smrg{
281071d7fec4Smrg   unsigned long value = 0;
281171d7fec4Smrg
281271d7fec4Smrg   *x = 0;
281371d7fec4Smrg   *y = 0;
281471d7fec4Smrg   *width = 0;
281571d7fec4Smrg   *height = 0;
281671d7fec4Smrg   if (gfx_alpha_select <= 2) {
281771d7fec4Smrg      value =
281871d7fec4Smrg	    READ_VID32(RCDF_ALPHA_XPOS_1 +
281971d7fec4Smrg		       ((unsigned long)gfx_alpha_select << 5));
282071d7fec4Smrg      *x = (unsigned short)(value & 0x000007FF);
282171d7fec4Smrg      *width = (unsigned short)((value >> 16) & 0x000007FF) - *x;
282271d7fec4Smrg      value =
282371d7fec4Smrg	    READ_VID32(RCDF_ALPHA_YPOS_1 +
282471d7fec4Smrg		       ((unsigned long)gfx_alpha_select << 5));
282571d7fec4Smrg      *y = (unsigned short)(value & 0x000007FF);
282671d7fec4Smrg      *height = (unsigned short)((value >> 16) & 0x000007FF) - *y;
282771d7fec4Smrg   }
282871d7fec4Smrg   *x -= gfx_get_htotal() - gfx_get_hsync_end() - 2;
282971d7fec4Smrg   *y -= gfx_get_vtotal() - gfx_get_vsync_end() + 1;
283071d7fec4Smrg   return;
283171d7fec4Smrg}
283271d7fec4Smrg
283371d7fec4Smrg/*---------------------------------------------------------------------------
283471d7fec4Smrg * gfx_get_alpha_value
283571d7fec4Smrg *
283671d7fec4Smrg * This routine returns the alpha value and increment/decrement value of
283771d7fec4Smrg * the currently selected alpha region.
283871d7fec4Smrg *---------------------------------------------------------------------------
283971d7fec4Smrg */
284071d7fec4Smrg#if GFX_VIDEO_DYNAMIC
284171d7fec4Smrgvoid
284271d7fec4Smrgredcloud_get_alpha_value(unsigned char *alpha, char *delta)
284371d7fec4Smrg#else
284471d7fec4Smrgvoid
284571d7fec4Smrggfx_get_alpha_value(unsigned char *alpha, char *delta)
284671d7fec4Smrg#endif
284771d7fec4Smrg{
284871d7fec4Smrg   unsigned long value = 0;
284971d7fec4Smrg
285071d7fec4Smrg   *alpha = 0;
285171d7fec4Smrg   *delta = 0;
285271d7fec4Smrg   if (gfx_alpha_select <= 2) {
285371d7fec4Smrg      value =
285471d7fec4Smrg	    READ_VID32(RCDF_ALPHA_CONTROL_1 +
285571d7fec4Smrg		       ((unsigned long)gfx_alpha_select << 5));
285671d7fec4Smrg      *alpha = (unsigned char)(value & 0x00FF);
285771d7fec4Smrg      *delta = (char)((value >> 8) & 0x00FF);
285871d7fec4Smrg   }
285971d7fec4Smrg   return;
286071d7fec4Smrg}
286171d7fec4Smrg
286271d7fec4Smrg/*---------------------------------------------------------------------------
286371d7fec4Smrg * gfx_get_alpha_priority
286471d7fec4Smrg *
286571d7fec4Smrg * This routine returns the priority of the currently selected alpha region.
286671d7fec4Smrg *---------------------------------------------------------------------------
286771d7fec4Smrg */
286871d7fec4Smrg#if GFX_VIDEO_DYNAMIC
286971d7fec4Smrgvoid
287071d7fec4Smrgredcloud_get_alpha_priority(int *priority)
287171d7fec4Smrg#else
287271d7fec4Smrgvoid
287371d7fec4Smrggfx_get_alpha_priority(int *priority)
287471d7fec4Smrg#endif
287571d7fec4Smrg{
287671d7fec4Smrg   unsigned long pos = 0, value = 0;
287771d7fec4Smrg
287871d7fec4Smrg   *priority = 0;
287971d7fec4Smrg   if (gfx_alpha_select <= 2) {
288071d7fec4Smrg      value = READ_VID32(RCDF_VID_ALPHA_CONTROL);
288171d7fec4Smrg      pos = 16 + (gfx_alpha_select << 1);
288271d7fec4Smrg      *priority = (int)((value >> pos) & 3);
288371d7fec4Smrg   }
288471d7fec4Smrg   return;
288571d7fec4Smrg}
288671d7fec4Smrg
288771d7fec4Smrg/*---------------------------------------------------------------------------
288871d7fec4Smrg * gfx_get_alpha_color
288971d7fec4Smrg *
289071d7fec4Smrg * This routine returns the color register value for the currently selected
289171d7fec4Smrg * alpha region.  Bit 24 is set if the color register is enabled.
289271d7fec4Smrg *---------------------------------------------------------------------------
289371d7fec4Smrg */
289471d7fec4Smrg#if GFX_VIDEO_DYNAMIC
289571d7fec4Smrgvoid
289671d7fec4Smrgredcloud_get_alpha_color(unsigned long *color)
289771d7fec4Smrg#else
289871d7fec4Smrgvoid
289971d7fec4Smrggfx_get_alpha_color(unsigned long *color)
290071d7fec4Smrg#endif
290171d7fec4Smrg{
290271d7fec4Smrg   *color = 0;
290371d7fec4Smrg   if (gfx_alpha_select <= 2) {
290471d7fec4Smrg      *color =
290571d7fec4Smrg	    READ_VID32(RCDF_ALPHA_COLOR_1 +
290671d7fec4Smrg		       ((unsigned long)gfx_alpha_select << 5));
290771d7fec4Smrg   }
290871d7fec4Smrg   return;
290971d7fec4Smrg}
291071d7fec4Smrg
291171d7fec4Smrg#endif /* GFX_READ_ROUTINES */
291271d7fec4Smrg
291371d7fec4Smrg/* END OF FILE */
2914