1f29dbc25Smrg/* Copyright (c) 2005 Advanced Micro Devices, Inc.
2f29dbc25Smrg *
3f29dbc25Smrg * Permission is hereby granted, free of charge, to any person obtaining a copy
4f29dbc25Smrg * of this software and associated documentation files (the "Software"), to
5f29dbc25Smrg * deal in the Software without restriction, including without limitation the
6f29dbc25Smrg * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7f29dbc25Smrg * sell copies of the Software, and to permit persons to whom the Software is
8f29dbc25Smrg * furnished to do so, subject to the following conditions:
9f29dbc25Smrg *
10f29dbc25Smrg * The above copyright notice and this permission notice shall be included in
11f29dbc25Smrg * all copies or substantial portions of the Software.
12f29dbc25Smrg *
13f29dbc25Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14f29dbc25Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15f29dbc25Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16f29dbc25Smrg * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17f29dbc25Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18f29dbc25Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19f29dbc25Smrg * IN THE SOFTWARE.
20f29dbc25Smrg *
21f29dbc25Smrg * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
22f29dbc25Smrg * contributors may be used to endorse or promote products derived from this
23f29dbc25Smrg * software without specific prior written permission.
24f29dbc25Smrg * */
25f29dbc25Smrg
26f29dbc25Smrg/*
27f29dbc25Smrg * This file contains routines to control the Redcloud display filter video
28f29dbc25Smrg * overlay hardware.
29f29dbc25Smrg * */
30f29dbc25Smrg
31f29dbc25Smrgunsigned long gfx_gamma_ram_redcloud[] = {
32f29dbc25Smrg    0x00000000, 0x00040003, 0x00050104, 0x00060205, 0x00070306, 0x00080407,
33f29dbc25Smrg    0x00090508, 0x000A0609, 0x000B070A, 0x000C080B, 0x000D090C, 0x000E0A0D,
34f29dbc25Smrg    0x000F0B0E, 0x00100C0F, 0x00110D10, 0x00110E11, 0x00120F12, 0x00141013,
35f29dbc25Smrg    0x00151114, 0x00161215, 0x00171316, 0x00181417, 0x00191518, 0x001A1619,
36f29dbc25Smrg    0x001B171A, 0x001C181B, 0x001D191C, 0x001D1A1D, 0x001E1B1E, 0x00201C1F,
37f29dbc25Smrg    0x00201D20, 0x00221E21, 0x00231F22, 0x00242023, 0x00252124, 0x00262225,
38f29dbc25Smrg    0x00262326, 0x00282427, 0x00292528, 0x00292629, 0x002B272A, 0x002C282B,
39f29dbc25Smrg    0x002D292C, 0x002E2A2D, 0x002F2B2E, 0x00302C2F, 0x00312D30, 0x00322E31,
40f29dbc25Smrg    0x00332F32, 0x00343033, 0x00353134, 0x00363235, 0x00373336, 0x00383437,
41f29dbc25Smrg    0x00393538, 0x003A3639, 0x003B373A, 0x003C383B, 0x003D393C, 0x003E3A3D,
42f29dbc25Smrg    0x003F3B3E, 0x00403C3F, 0x00413D40, 0x00423E41, 0x00433F42, 0x00444043,
43f29dbc25Smrg    0x00444144, 0x00454245, 0x00474346, 0x00484447, 0x00494548, 0x004A4649,
44f29dbc25Smrg    0x004B474A, 0x004C484B, 0x004D494C, 0x004E4A4D, 0x004F4B4E, 0x00504C4F,
45f29dbc25Smrg    0x00514D50, 0x00524E51, 0x00534F52, 0x00545053, 0x00555154, 0x00565255,
46f29dbc25Smrg    0x00575356, 0x00585457, 0x00595558, 0x005A5659, 0x005B575A, 0x005C585B,
47f29dbc25Smrg    0x005D595C, 0x005E5A5D, 0x005F5B5E, 0x00605C5F, 0x00615D60, 0x00625E61,
48f29dbc25Smrg    0x00635F62, 0x00646063, 0x00656164, 0x00666265, 0x00676366, 0x00686467,
49f29dbc25Smrg    0x00696568, 0x006A6669, 0x006B676A, 0x006C686B, 0x006D696C, 0x006E6A6D,
50f29dbc25Smrg    0x006F6B6E, 0x00706C6F, 0x00716D70, 0x00726E71, 0x00736F72, 0x00747073,
51f29dbc25Smrg    0x00757174, 0x00767275, 0x00777376, 0x00787477, 0x00797578, 0x007A7679,
52f29dbc25Smrg    0x007B777A, 0x007C787B, 0x007D797C, 0x007E7A7D, 0x007F7B7E, 0x00807C7F,
53f29dbc25Smrg    0x00817D80, 0x00827E81, 0x00837F82, 0x00848083, 0x00858184, 0x00868285,
54f29dbc25Smrg    0x00878386, 0x00888487, 0x00898588, 0x008A8689, 0x008B878A, 0x008C888B,
55f29dbc25Smrg    0x008D898C, 0x008E8A8D, 0x008F8B8E, 0x00908C8F, 0x00918D90, 0x00928E91,
56f29dbc25Smrg    0x00938F92, 0x00949093, 0x00959194, 0x00969295, 0x00979396, 0x00989497,
57f29dbc25Smrg    0x00999598, 0x009A9699, 0x009B979A, 0x009C989B, 0x009D999C, 0x009E9A9D,
58f29dbc25Smrg    0x009F9B9E, 0x00A09C9F, 0x00A19DA0, 0x00A29EA1, 0x00A39FA2, 0x00A4A0A3,
59f29dbc25Smrg    0x00A5A1A4, 0x00A6A2A5, 0x00A7A3A6, 0x00A8A4A7, 0x00A9A5A8, 0x00AAA6A9,
60f29dbc25Smrg    0x00ABA7AA, 0x00ACA8AB, 0x00ADA9AC, 0x00AEAAAD, 0x00AFABAE, 0x00B0ACAF,
61f29dbc25Smrg    0x00B1ADB0, 0x00B2AEB1, 0x00B3AFB2, 0x00B4B0B3, 0x00B5B1B4, 0x00B6B2B5,
62f29dbc25Smrg    0x00B7B3B6, 0x00B8B4B7, 0x00B9B5B8, 0x00BAB6B9, 0x00BBB7BA, 0x00BCB8BB,
63f29dbc25Smrg    0x00BDB9BC, 0x00BEBABD, 0x00BFBBBE, 0x00C0BCBF, 0x00C1BDC0, 0x00C2BEC1,
64f29dbc25Smrg    0x00C3BFC2, 0x00C4C0C3, 0x00C5C1C4, 0x00C6C2C5, 0x00C7C3C6, 0x00C8C4C7,
65f29dbc25Smrg    0x00C9C5C8, 0x00CAC6C9, 0x00CBC7CA, 0x00CCC8CB, 0x00CDC9CC, 0x00CECACD,
66f29dbc25Smrg    0x00CFCBCE, 0x00D0CCCF, 0x00D1CDD0, 0x00D2CED1, 0x00D3CFD2, 0x00D4D0D3,
67f29dbc25Smrg    0x00D5D1D4, 0x00D6D2D5, 0x00D7D3D6, 0x00D8D4D7, 0x00D9D5D8, 0x00DAD6D9,
68f29dbc25Smrg    0x00DBD7DA, 0x00DCD8DB, 0x00DDD9DC, 0x00DEDADD, 0x00DFDBDE, 0x00E0DCDF,
69f29dbc25Smrg    0x00E1DDE0, 0x00E2DEE1, 0x00E3DFE2, 0x00E4E0E3, 0x00E5E1E4, 0x00E6E2E5,
70f29dbc25Smrg    0x00E7E3E6, 0x00E8E4E7, 0x00E9E5E8, 0x00EAE6E9, 0x00EBE7EA, 0x00ECE8EB,
71f29dbc25Smrg    0x00EDE9EC, 0x00EEEAED, 0x00EFEBEE, 0x00F0ECEF, 0x00F1EDF0, 0x00F2EEF1,
72f29dbc25Smrg    0x00F3EFF2, 0x00F4F0F3, 0x00F5F1F4, 0x00F6F2F5, 0x00F7F3F6, 0x00F8F4F7,
73f29dbc25Smrg    0x00F9F5F8, 0x00FAF6F9, 0x00FBF7FA, 0x00FCF8FB, 0x00FDF9FC, 0x00FEFAFD,
74f29dbc25Smrg    0x00FFFBFE, 0x00FFFCFE, 0x00FFFDFE, 0x00FFFFFF
75f29dbc25Smrg};
76f29dbc25Smrg
77f29dbc25Smrg/* REDCLOUD PLL TABLE  */
78f29dbc25Smrg
7904007ebaSmrgtypedef struct RCDFPLL {
8004007ebaSmrg    long frequency;             /* 16.16 fixed point frequency                  */
8104007ebaSmrg    unsigned long post_div3;    /* MCP Frequency dividers and multipliers       */
82f29dbc25Smrg    unsigned long pre_mul2;
83f29dbc25Smrg    unsigned long pre_div2;
8404007ebaSmrg    unsigned long pll_value;    /* MCP DotPLL Register Upper 32(0x0015)         */
85f29dbc25Smrg} RCDFPLLENTRY;
86f29dbc25Smrg
87f29dbc25SmrgRCDFPLLENTRY RCDF_PLLtable[] = {
8804007ebaSmrg    {0x0018EC4D, 1, 0, 0, 0x0000099E},  /*  24.9230 */
8904007ebaSmrg    {0x00192CCC, 0, 0, 0, 0x00000037},  /*  25.1750 */
9004007ebaSmrg    {0x001C526E, 1, 0, 0, 0x000009DA},  /*  28.3220 */
9104007ebaSmrg    {0x001C8F5C, 1, 0, 0, 0x0000005E},  /*  28.5600 */
9204007ebaSmrg    {0x001F8000, 1, 0, 0, 0x000002D2},  /*  31.5000 */
9304007ebaSmrg    {0x00240000, 1, 0, 0, 0x000007E2},  /*  36.0000 */
9404007ebaSmrg    {0x00258000, 1, 0, 0, 0x0000057A},  /*  37.5000 */
9504007ebaSmrg    {0x0025E395, 1, 0, 0, 0x000007FA},  /*  37.8890 */
9604007ebaSmrg    {0x00280000, 1, 0, 0, 0x0000030A},  /*  40.0000 */
9704007ebaSmrg    {0x002B29BA, 0, 0, 0, 0x0000005F},  /*  43.1630 */
9804007ebaSmrg    {0x002CE666, 0, 0, 0, 0x00000063},  /*  44.9000 */
9904007ebaSmrg    {0x002DB851, 1, 0, 0, 0x00000BC9},  /*  45.7200 */
10004007ebaSmrg    {0x00318000, 0, 0, 0, 0x0000054B},  /*  49.5000 */
10104007ebaSmrg    {0x00320000, 0, 0, 0, 0x0000006F},  /*  50.0000 */
10204007ebaSmrg    {0x00325999, 0, 1, 0, 0x00000037},  /*  50.3500 */
10304007ebaSmrg    {0x00360000, 1, 1, 0, 0x00000B0D},  /*  54.0000 */
10404007ebaSmrg    {0x00384000, 0, 0, 0, 0x000007F7},  /*  56.2500 */
10504007ebaSmrg    {0x0038643F, 0, 0, 0, 0x000007F7},  /*  56.3916 */
10604007ebaSmrg    {0x0038A4DD, 0, 0, 0, 0x0000057B},  /*  56.6444 */
10704007ebaSmrg    {0x003B0000, 0, 1, 0, 0x00000707},  /*  59.0000 */
10804007ebaSmrg    {0x003C10A3, 0, 0, 0, 0x0000030B},  /*  60.0650 */
10904007ebaSmrg    {0x003F0000, 1, 1, 0, 0x00000B39},  /*  63.0000 */
11004007ebaSmrg    {0x00410000, 1, 0, 0, 0x00000545},  /*  65.0000 */
11104007ebaSmrg    {0x00442DD2, 1, 0, 0, 0x000002E1},  /*  68.1790 */
11204007ebaSmrg    {0x00438000, 1, 1, 0, 0x00000FC1},  /*  67.5000 */
11304007ebaSmrg    {0x0046CCCC, 1, 0, 0, 0x00000561},  /*  70.8000 */
11404007ebaSmrg    {0x00480000, 1, 0, 0, 0x000007E1},  /*  72.0000 */
11504007ebaSmrg    {0x004A7B22, 0, 1, 0, 0x00000F4A},  /*  74.4810 */
11604007ebaSmrg    {0x004B0000, 1, 0, 0, 0x000007F5},  /*  75.0000 */
11704007ebaSmrg    {0x004EC000, 1, 0, 0, 0x00000305},  /*  78.7500 */
11804007ebaSmrg    {0x00500000, 1, 1, 0, 0x00000709},  /*  80.0000 */
11904007ebaSmrg    {0x00519999, 0, 0, 0, 0x000009C6},  /*  81.6000 */
12004007ebaSmrg    {0x0059CCCC, 0, 1, 0, 0x00000262},  /*  89.8000 */
12104007ebaSmrg    {0x005E8000, 0, 0, 0, 0x000002D2},  /*  94.5000 */
12204007ebaSmrg    {0x00618560, 0, 0, 0, 0x00000546},  /*  97.5200 */
12304007ebaSmrg    {0x00630000, 0, 1, 0, 0x00000B4A},  /*  99.0000 */
12404007ebaSmrg    {0x00642FDF, 0, 0, 0, 0x0000006E},  /* 100.1870 */
12504007ebaSmrg    {0x00656B85, 0, 0, 0, 0x00000552},  /* 101.4200 */
12604007ebaSmrg    {0x006C0000, 0, 0, 0, 0x000007E2},  /* 108.0000 */
12704007ebaSmrg    {0x00708000, 0, 0, 0, 0x000007F6},  /* 112.5000 */
12804007ebaSmrg    {0x00714F1A, 0, 0, 0, 0x0000057A},  /* 113.3090 */
12904007ebaSmrg    {0x0077A666, 0, 0, 0, 0x0000030A},  /* 119.6500 */
13004007ebaSmrg    {0x00806666, 1, 0, 0, 0x00000068},  /* 128.4000 */
13104007ebaSmrg    {0x00820000, 1, 1, 0, 0x00000FB0},  /* 130.0000 */
13204007ebaSmrg    {0x00821999, 1, 0, 0, 0x00000544},  /* 130.1000 */
13304007ebaSmrg    {0x00858000, 1, 0, 0, 0x0000006C},  /* 133.5000 */
13404007ebaSmrg    {0x00870000, 1, 0, 0, 0x00000550},  /* 135.0000 */
13504007ebaSmrg    {0x00906147, 1, 0, 0, 0x000007E0},  /* 144.3800 */
13604007ebaSmrg    {0x009D8000, 1, 0, 0, 0x00000304},  /* 157.5000 */
13704007ebaSmrg    {0x00A20000, 0, 0, 0, 0x000002B1},  /* 162.0000 */
13804007ebaSmrg    {0x00A933F7, 0, 0, 0, 0x000002B9},  /* 169.2030 */
13904007ebaSmrg    {0x00ACCC49, 0, 1, 0, 0x0000002D},  /* 172.798  */
14004007ebaSmrg    {0x00AF8000, 0, 0, 0, 0x000002C1},  /* 175.5000 */
14104007ebaSmrg    {0x00BD0000, 0, 0, 0, 0x000002D1},  /* 189.0000 */
14204007ebaSmrg    {0x00BEF5C2, 0, 0, 0, 0x0000053D},  /* 190.9600 */
14304007ebaSmrg    {0x00C60000, 0, 0, 0, 0x00000549},  /* 198.0000 */
14404007ebaSmrg    {0x00CA8000, 0, 0, 0, 0x00000551},  /* 202.5000 */
14504007ebaSmrg    {0x00E58000, 0, 0, 0, 0x0000057D},  /* 229.5000 */
146f29dbc25Smrg};
147f29dbc25Smrg
148f29dbc25Smrg#define NUM_RCDF_FREQUENCIES sizeof(RCDF_PLLtable)/sizeof(RCDFPLLENTRY)
149f29dbc25Smrg
150f29dbc25Smrg/*---------------------------------------------------------------------------
151f29dbc25Smrg * gfx_reset_video (PRIVATE ROUTINE: NOT PART OF DURANGO API)
152f29dbc25Smrg *
153f29dbc25Smrg * This routine is used to disable all components of video overlay before
154f29dbc25Smrg * performing a mode switch.
155f29dbc25Smrg *---------------------------------------------------------------------------
156f29dbc25Smrg */
157f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
158f29dbc25Smrgvoid
159f29dbc25Smrgredcloud_reset_video(void)
160f29dbc25Smrg#else
161f29dbc25Smrgvoid
162f29dbc25Smrggfx_reset_video(void)
163f29dbc25Smrg#endif
164f29dbc25Smrg{
165f29dbc25Smrg    gfx_set_video_enable(0);
166f29dbc25Smrg    gfx_select_alpha_region(1);
167f29dbc25Smrg    gfx_set_alpha_enable(0);
168f29dbc25Smrg    gfx_select_alpha_region(2);
169f29dbc25Smrg    gfx_set_alpha_enable(0);
170f29dbc25Smrg
171f29dbc25Smrg    /* SET REGION 0 AFTER RESET */
172f29dbc25Smrg
173f29dbc25Smrg    gfx_select_alpha_region(0);
174f29dbc25Smrg    gfx_set_alpha_enable(0);
175f29dbc25Smrg}
176f29dbc25Smrg
177f29dbc25Smrg/*----------------------------------------------------------------------------
178f29dbc25Smrg * gfx_set_display_control (PRIVATE ROUTINE: NOT PART OF DURANGO API)
179f29dbc25Smrg *
180f29dbc25Smrg * This routine configures the display output.
181f29dbc25Smrg *
182f29dbc25Smrg * "sync_polarities" is used to set the polarities of the sync pulses
183f29dbc25Smrg * according to the following mask:
184f29dbc25Smrg *
185f29dbc25Smrg *     Bit 0: If set to 1, negative horizontal polarity is programmed,
186f29dbc25Smrg *            otherwise positive horizontal polarity is programmed.
187f29dbc25Smrg *     Bit 1: If set to 1, negative vertical polarity is programmed,
188f29dbc25Smrg *            otherwise positive vertical polarity is programmed.
189f29dbc25Smrg *
190f29dbc25Smrg *----------------------------------------------------------------------------
191f29dbc25Smrg */
192f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
193f29dbc25Smrgint
194f29dbc25Smrgredcloud_set_display_control(int sync_polarities)
195f29dbc25Smrg#else
196f29dbc25Smrgint
197f29dbc25Smrggfx_set_display_control(int sync_polarities)
198f29dbc25Smrg#endif
199f29dbc25Smrg{
200f29dbc25Smrg    unsigned long power;
201f29dbc25Smrg    unsigned long dcfg;
202f29dbc25Smrg
203f29dbc25Smrg    /* CONFIGURE DISPLAY OUTPUT FROM VIDEO PROCESSOR */
204f29dbc25Smrg
205f29dbc25Smrg    dcfg = READ_VID32(RCDF_DISPLAY_CONFIG);
206f29dbc25Smrg    dcfg &= ~(RCDF_DCFG_CRT_SYNC_SKW_MASK | RCDF_DCFG_PWR_SEQ_DLY_MASK |
20704007ebaSmrg              RCDF_DCFG_CRT_HSYNC_POL | RCDF_DCFG_CRT_VSYNC_POL |
20804007ebaSmrg              RCDF_DCFG_FP_PWR_EN | RCDF_DCFG_FP_DATA_EN);
209f29dbc25Smrg
210f29dbc25Smrg    /* Don't blindly set the PAL_BYP bit - assume that somebody along
211f29dbc25Smrg     * the line has set up the gamma correctly before this point */
212f29dbc25Smrg
213f29dbc25Smrg    dcfg |= (RCDF_DCFG_CRT_SYNC_SKW_INIT | RCDF_DCFG_PWR_SEQ_DLY_INIT);
214f29dbc25Smrg
215f29dbc25Smrg    if (PanelEnable) {
216f29dbc25Smrg        power = READ_VID32(RCDF_POWER_MANAGEMENT);
217f29dbc25Smrg        power |= RCDF_PM_PANEL_POWER_ON;
218f29dbc25Smrg        WRITE_VID32(RCDF_POWER_MANAGEMENT, power);
219f29dbc25Smrg    }
220f29dbc25Smrg
221f29dbc25Smrg    /* SET APPROPRIATE SYNC POLARITIES */
222f29dbc25Smrg
223f29dbc25Smrg    if (PanelEnable) {
22404007ebaSmrg        unsigned int pt2 = READ_VID32(0x408);
225f29dbc25Smrg
22604007ebaSmrg        pt2 &= ~((1 << 22) | (1 << 23));
22704007ebaSmrg        WRITE_VID32(0x408, pt2);
228f29dbc25Smrg    }
229f29dbc25Smrg
230f29dbc25Smrg    if (sync_polarities & 0x1)
23104007ebaSmrg        dcfg |= RCDF_DCFG_CRT_HSYNC_POL;
23204007ebaSmrg    if (sync_polarities & 0x2)
23304007ebaSmrg        dcfg |= RCDF_DCFG_CRT_VSYNC_POL;
234f29dbc25Smrg
235f29dbc25Smrg    WRITE_VID32(RCDF_DISPLAY_CONFIG, dcfg);
236f29dbc25Smrg
237f29dbc25Smrg    return (0);
238f29dbc25Smrg}
239f29dbc25Smrg
240f29dbc25Smrg/*---------------------------------------------------------------------------
241f29dbc25Smrg * gfx_set_clock_frequency
242f29dbc25Smrg *
243f29dbc25Smrg * This routine sets the clock frequency, specified as a 16.16 fixed point
244f29dbc25Smrg * value (0x00318000 = 49.5 MHz).  It will set the closest frequency found
245f29dbc25Smrg * in the lookup table.
246f29dbc25Smrg *---------------------------------------------------------------------------
247f29dbc25Smrg */
248f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
249f29dbc25Smrgvoid
250f29dbc25Smrgredcloud_set_clock_frequency(unsigned long frequency)
251f29dbc25Smrg#else
252f29dbc25Smrgvoid
253f29dbc25Smrggfx_set_clock_frequency(unsigned long frequency)
254f29dbc25Smrg#endif
255f29dbc25Smrg{
256f29dbc25Smrg    Q_WORD msr_value, sys_value;
257f29dbc25Smrg    unsigned long sys_low;
258f29dbc25Smrg    unsigned int i, index = 0;
259f29dbc25Smrg    unsigned long value;
260f29dbc25Smrg    long timeout = 1000;
261f29dbc25Smrg    long min, diff;
262f29dbc25Smrg
263f29dbc25Smrg    /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */
264f29dbc25Smrg    /* Search the table for the closest frequency (16.16 format). */
265f29dbc25Smrg
266f29dbc25Smrg    value = RCDF_PLLtable[0].pll_value;
26704007ebaSmrg    min = (long) RCDF_PLLtable[0].frequency - frequency;
268f29dbc25Smrg    if (min < 0L)
269f29dbc25Smrg        min = -min;
270f29dbc25Smrg    for (i = 1; i < NUM_RCDF_FREQUENCIES; i++) {
27104007ebaSmrg        diff = (long) RCDF_PLLtable[i].frequency - frequency;
272f29dbc25Smrg        if (diff < 0L)
273f29dbc25Smrg            diff = -diff;
274f29dbc25Smrg        if (diff < min) {
275f29dbc25Smrg            min = diff;
276f29dbc25Smrg            index = i;
277f29dbc25Smrg        }
278f29dbc25Smrg    }
279f29dbc25Smrg
280f29dbc25Smrg    /* VERIFY THAT WE ARE NOT WRITING WHAT IS ALREADY IN THE REGISTERS */
281f29dbc25Smrg    /* The Dot PLL reset bit is tied to VDD for flat panels.  This can */
282f29dbc25Smrg    /* cause a brief drop in flat panel power, which can cause serious */
283f29dbc25Smrg    /* glitches on some panels.                                        */
284f29dbc25Smrg
285f29dbc25Smrg    gfx_msr_read(RC_ID_MCP, MCP_DOTPLL, &msr_value);
286f29dbc25Smrg    gfx_msr_read(RC_ID_MCP, MCP_SYS_RSTPLL, &sys_value);
287f29dbc25Smrg
288f29dbc25Smrg    sys_low = 0;
289f29dbc25Smrg    if (RCDF_PLLtable[index].post_div3)
290f29dbc25Smrg        sys_low |= MCP_DOTPOSTDIV3;
291f29dbc25Smrg    if (RCDF_PLLtable[index].pre_div2)
292f29dbc25Smrg        sys_low |= MCP_DOTPREDIV2;
293f29dbc25Smrg    if (RCDF_PLLtable[index].pre_mul2)
294f29dbc25Smrg        sys_low |= MCP_DOTPREMULT2;
295f29dbc25Smrg
296f29dbc25Smrg    if ((msr_value.low & MCP_DOTPLL_LOCK) &&
297f29dbc25Smrg        (msr_value.high == RCDF_PLLtable[index].pll_value) &&
29804007ebaSmrg        ((sys_value.low & (MCP_DOTPOSTDIV3 | MCP_DOTPREDIV2 | MCP_DOTPREMULT2))
29904007ebaSmrg         == sys_low)) {
300f29dbc25Smrg        return;
301f29dbc25Smrg    }
302f29dbc25Smrg
303f29dbc25Smrg    /* PROGRAM THE SETTINGS WITH THE RESET BIT SET */
304f29dbc25Smrg    /* Clear the bypass bit to ensure that the programmed */
305f29dbc25Smrg    /* M, N and P values are being used.                  */
306f29dbc25Smrg
307f29dbc25Smrg    msr_value.high = RCDF_PLLtable[index].pll_value;
308f29dbc25Smrg    msr_value.low |= 0x00000001;
309f29dbc25Smrg    msr_value.low &= ~MCP_DOTPLL_BYPASS;
310f29dbc25Smrg    gfx_msr_write(RC_ID_MCP, MCP_DOTPLL, &msr_value);
311f29dbc25Smrg
312f29dbc25Smrg    /* PROGRAM THE MCP DIVIDER VALUES */
313f29dbc25Smrg
314f29dbc25Smrg    sys_value.low &= ~(MCP_DOTPOSTDIV3 | MCP_DOTPREDIV2 | MCP_DOTPREMULT2);
315f29dbc25Smrg    sys_value.low |= sys_low;
316f29dbc25Smrg    gfx_msr_write(RC_ID_MCP, MCP_SYS_RSTPLL, &sys_value);
317f29dbc25Smrg
318f29dbc25Smrg    /* CLEAR THE RESET BIT */
319f29dbc25Smrg
320f29dbc25Smrg    msr_value.low &= 0xFFFFFFFE;
321f29dbc25Smrg    gfx_msr_write(RC_ID_MCP, MCP_DOTPLL, &msr_value);
322f29dbc25Smrg
323f29dbc25Smrg    /* WAIT FOR LOCK BIT */
324f29dbc25Smrg
325f29dbc25Smrg    do {
326f29dbc25Smrg        gfx_msr_read(RC_ID_MCP, MCP_DOTPLL, &msr_value);
327f29dbc25Smrg    } while (timeout-- && !(msr_value.low & MCP_DOTPLL_LOCK));
328f29dbc25Smrg}
329f29dbc25Smrg
330f29dbc25Smrg/*---------------------------------------------------------------------------
331f29dbc25Smrg * gfx_set_crt_enable
332f29dbc25Smrg *
333f29dbc25Smrg * This routine enables or disables the CRT output from the video processor.
334f29dbc25Smrg *---------------------------------------------------------------------------
335f29dbc25Smrg */
336f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
337f29dbc25Smrgint
338f29dbc25Smrgredcloud_set_crt_enable(int enable)
339f29dbc25Smrg#else
340f29dbc25Smrgint
341f29dbc25Smrggfx_set_crt_enable(int enable)
342f29dbc25Smrg#endif
343f29dbc25Smrg{
344f29dbc25Smrg    unsigned long config, misc;
345f29dbc25Smrg
346f29dbc25Smrg    config = READ_VID32(RCDF_DISPLAY_CONFIG);
347f29dbc25Smrg    misc = READ_VID32(RCDF_VID_MISC);
348f29dbc25Smrg
349f29dbc25Smrg    switch (enable) {
35004007ebaSmrg    case CRT_DISABLE:          /* DISABLE EVERYTHING */
351f29dbc25Smrg
352f29dbc25Smrg        WRITE_VID32(RCDF_DISPLAY_CONFIG,
35304007ebaSmrg                    config & ~(RCDF_DCFG_DIS_EN | RCDF_DCFG_HSYNC_EN |
35404007ebaSmrg                               RCDF_DCFG_VSYNC_EN | RCDF_DCFG_DAC_BL_EN));
355f29dbc25Smrg        WRITE_VID32(RCDF_VID_MISC, misc | RCDF_DAC_POWER_DOWN);
356f29dbc25Smrg        break;
357f29dbc25Smrg
35804007ebaSmrg    case CRT_ENABLE:           /* ENABLE CRT DISPLAY, INCLUDING DISPLAY LOGIC */
359f29dbc25Smrg
360f29dbc25Smrg        WRITE_VID32(RCDF_DISPLAY_CONFIG,
36104007ebaSmrg                    config | RCDF_DCFG_DIS_EN | RCDF_DCFG_HSYNC_EN |
36204007ebaSmrg                    RCDF_DCFG_VSYNC_EN | RCDF_DCFG_DAC_BL_EN);
363f29dbc25Smrg        WRITE_VID32(RCDF_VID_MISC,
36404007ebaSmrg                    misc & ~RCDF_DAC_POWER_DOWN & ~RCDF_ANALOG_POWER_DOWN);
365f29dbc25Smrg        break;
366f29dbc25Smrg
36704007ebaSmrg    case CRT_STANDBY:          /* HSYNC:OFF VSYNC:ON */
368f29dbc25Smrg
369f29dbc25Smrg        WRITE_VID32(RCDF_DISPLAY_CONFIG,
37004007ebaSmrg                    (config & ~(RCDF_DCFG_DIS_EN | RCDF_DCFG_HSYNC_EN |
37104007ebaSmrg                                RCDF_DCFG_DAC_BL_EN)) | RCDF_DCFG_VSYNC_EN);
372f29dbc25Smrg        WRITE_VID32(RCDF_VID_MISC, misc | RCDF_DAC_POWER_DOWN);
373f29dbc25Smrg        break;
374f29dbc25Smrg
37504007ebaSmrg    case CRT_SUSPEND:          /* HSYNC:ON VSYNC:OFF */
376f29dbc25Smrg
377f29dbc25Smrg        WRITE_VID32(RCDF_DISPLAY_CONFIG,
37804007ebaSmrg                    (config & ~(RCDF_DCFG_DIS_EN | RCDF_DCFG_VSYNC_EN |
37904007ebaSmrg                                RCDF_DCFG_DAC_BL_EN)) | RCDF_DCFG_HSYNC_EN);
380f29dbc25Smrg        WRITE_VID32(RCDF_VID_MISC, misc | RCDF_DAC_POWER_DOWN);
381f29dbc25Smrg        break;
382f29dbc25Smrg
383f29dbc25Smrg    default:
384f29dbc25Smrg        return (GFX_STATUS_BAD_PARAMETER);
385f29dbc25Smrg    }
386f29dbc25Smrg    return (GFX_STATUS_OK);
387f29dbc25Smrg}
388f29dbc25Smrg
389f29dbc25Smrg/*----------------------------------------------------------------------------
390f29dbc25Smrg * gfx_set_video_enable
391f29dbc25Smrg *
392f29dbc25Smrg * This routine enables or disables the video overlay functionality.
393f29dbc25Smrg *----------------------------------------------------------------------------
394f29dbc25Smrg */
395f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
396f29dbc25Smrgint
397f29dbc25Smrgredcloud_set_video_enable(int enable)
398f29dbc25Smrg#else
399f29dbc25Smrgint
400f29dbc25Smrggfx_set_video_enable(int enable)
401f29dbc25Smrg#endif
402f29dbc25Smrg{
403f29dbc25Smrg    unsigned long vcfg;
404f29dbc25Smrg
405f29dbc25Smrg    /* WAIT FOR VERTICAL BLANK TO START */
406f29dbc25Smrg    /* Otherwise a glitch can be observed. */
407f29dbc25Smrg
408f29dbc25Smrg    if (gfx_test_timing_active()) {
409f29dbc25Smrg        if (!gfx_test_vertical_active()) {
41004007ebaSmrg            while (!gfx_test_vertical_active());
411f29dbc25Smrg        }
41204007ebaSmrg        while (gfx_test_vertical_active());
413f29dbc25Smrg    }
414f29dbc25Smrg
415f29dbc25Smrg    vcfg = READ_VID32(RCDF_VIDEO_CONFIG);
416f29dbc25Smrg    if (enable) {
417f29dbc25Smrg        /* ENABLE VIDEO OVERLAY FROM DISPLAY CONTROLLER */
418f29dbc25Smrg        /* Use private routine to abstract the display controller. */
419f29dbc25Smrg
420f29dbc25Smrg        gfx_set_display_video_enable(1);
421f29dbc25Smrg
422f29dbc25Smrg        /* ENABLE DISPLAY FILTER VIDEO OVERLAY */
423f29dbc25Smrg
424f29dbc25Smrg        vcfg |= RCDF_VCFG_VID_EN;
425f29dbc25Smrg        WRITE_VID32(RCDF_VIDEO_CONFIG, vcfg);
42604007ebaSmrg    }
42704007ebaSmrg    else {
428f29dbc25Smrg        /* DISABLE DISPLAY FILTER VIDEO OVERLAY */
429f29dbc25Smrg
430f29dbc25Smrg        vcfg &= ~RCDF_VCFG_VID_EN;
431f29dbc25Smrg        WRITE_VID32(RCDF_VIDEO_CONFIG, vcfg);
432f29dbc25Smrg
433f29dbc25Smrg        /* DISABLE VIDEO OVERLAY FROM DISPLAY CONTROLLER */
434f29dbc25Smrg        /* Use private routine to abstract the display controller. */
435f29dbc25Smrg
436f29dbc25Smrg        gfx_set_display_video_enable(0);
437f29dbc25Smrg    }
438f29dbc25Smrg    return (0);
439f29dbc25Smrg}
440f29dbc25Smrg
441f29dbc25Smrg/*----------------------------------------------------------------------------
442f29dbc25Smrg * gfx_set_video_format
443f29dbc25Smrg *
444f29dbc25Smrg * Sets input video format type, to one of the YUV formats or to RGB.
445f29dbc25Smrg *----------------------------------------------------------------------------
446f29dbc25Smrg */
447f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
448f29dbc25Smrgint
449f29dbc25Smrgredcloud_set_video_format(unsigned long format)
450f29dbc25Smrg#else
451f29dbc25Smrgint
452f29dbc25Smrggfx_set_video_format(unsigned long format)
453f29dbc25Smrg#endif
454f29dbc25Smrg{
455f29dbc25Smrg    unsigned long ctrl, vcfg = 0;
456f29dbc25Smrg
457f29dbc25Smrg    /* SET THE DISPLAY FILTER VIDEO INPUT FORMAT */
458f29dbc25Smrg
459f29dbc25Smrg    vcfg = READ_VID32(RCDF_VIDEO_CONFIG);
460f29dbc25Smrg    ctrl = READ_VID32(RCDF_VID_ALPHA_CONTROL);
461f29dbc25Smrg    ctrl &= ~(RCDF_VIDEO_INPUT_IS_RGB | RCDF_CSC_VIDEO_YUV_TO_RGB);
462f29dbc25Smrg    vcfg &= ~(RCDF_VCFG_VID_INP_FORMAT | RCDF_VCFG_4_2_0_MODE);
463f29dbc25Smrg    switch (format) {
464f29dbc25Smrg    case VIDEO_FORMAT_UYVY:
465f29dbc25Smrg        vcfg |= RCDF_VCFG_UYVY_FORMAT;
466f29dbc25Smrg        ctrl |= RCDF_CSC_VIDEO_YUV_TO_RGB;
467f29dbc25Smrg        break;
468f29dbc25Smrg    case VIDEO_FORMAT_YUYV:
469f29dbc25Smrg        vcfg |= RCDF_VCFG_YUYV_FORMAT;
470f29dbc25Smrg        ctrl |= RCDF_CSC_VIDEO_YUV_TO_RGB;
471f29dbc25Smrg        break;
472f29dbc25Smrg    case VIDEO_FORMAT_Y2YU:
473f29dbc25Smrg        vcfg |= RCDF_VCFG_Y2YU_FORMAT;
474f29dbc25Smrg        ctrl |= RCDF_CSC_VIDEO_YUV_TO_RGB;
475f29dbc25Smrg        break;
476f29dbc25Smrg    case VIDEO_FORMAT_YVYU:
477f29dbc25Smrg        vcfg |= RCDF_VCFG_YVYU_FORMAT;
478f29dbc25Smrg        ctrl |= RCDF_CSC_VIDEO_YUV_TO_RGB;
479f29dbc25Smrg        break;
480f29dbc25Smrg    case VIDEO_FORMAT_Y0Y1Y2Y3:
481f29dbc25Smrg        vcfg |= RCDF_VCFG_UYVY_FORMAT;
482f29dbc25Smrg        ctrl |= RCDF_CSC_VIDEO_YUV_TO_RGB;
483f29dbc25Smrg        vcfg |= RCDF_VCFG_4_2_0_MODE;
484f29dbc25Smrg        break;
485f29dbc25Smrg    case VIDEO_FORMAT_Y3Y2Y1Y0:
486f29dbc25Smrg        vcfg |= RCDF_VCFG_Y2YU_FORMAT;
487f29dbc25Smrg        ctrl |= RCDF_CSC_VIDEO_YUV_TO_RGB;
488f29dbc25Smrg        vcfg |= RCDF_VCFG_4_2_0_MODE;
489f29dbc25Smrg        break;
490f29dbc25Smrg    case VIDEO_FORMAT_Y1Y0Y3Y2:
491f29dbc25Smrg        vcfg |= RCDF_VCFG_YUYV_FORMAT;
492f29dbc25Smrg        ctrl |= RCDF_CSC_VIDEO_YUV_TO_RGB;
493f29dbc25Smrg        vcfg |= RCDF_VCFG_4_2_0_MODE;
494f29dbc25Smrg        break;
495f29dbc25Smrg    case VIDEO_FORMAT_Y1Y2Y3Y0:
496f29dbc25Smrg        vcfg |= RCDF_VCFG_YVYU_FORMAT;
497f29dbc25Smrg        ctrl |= RCDF_CSC_VIDEO_YUV_TO_RGB;
498f29dbc25Smrg        vcfg |= RCDF_VCFG_4_2_0_MODE;
499f29dbc25Smrg        break;
500f29dbc25Smrg    case VIDEO_FORMAT_RGB:
501f29dbc25Smrg        ctrl |= RCDF_VIDEO_INPUT_IS_RGB;
502f29dbc25Smrg        vcfg |= RCDF_VCFG_UYVY_FORMAT;
503f29dbc25Smrg        break;
504f29dbc25Smrg    case VIDEO_FORMAT_P2M_P2L_P1M_P1L:
505f29dbc25Smrg        ctrl |= RCDF_VIDEO_INPUT_IS_RGB;
506f29dbc25Smrg        vcfg |= RCDF_VCFG_Y2YU_FORMAT;
507f29dbc25Smrg        break;
508f29dbc25Smrg    case VIDEO_FORMAT_P1M_P1L_P2M_P2L:
509f29dbc25Smrg        ctrl |= RCDF_VIDEO_INPUT_IS_RGB;
510f29dbc25Smrg        vcfg |= RCDF_VCFG_YUYV_FORMAT;
511f29dbc25Smrg        break;
512f29dbc25Smrg    case VIDEO_FORMAT_P1M_P2L_P2M_P1L:
513f29dbc25Smrg        ctrl |= RCDF_VIDEO_INPUT_IS_RGB;
514f29dbc25Smrg        vcfg |= RCDF_VCFG_YVYU_FORMAT;
515f29dbc25Smrg        break;
516f29dbc25Smrg    default:
517f29dbc25Smrg        return GFX_STATUS_BAD_PARAMETER;
518f29dbc25Smrg    }
519f29dbc25Smrg    WRITE_VID32(RCDF_VIDEO_CONFIG, vcfg);
520f29dbc25Smrg    WRITE_VID32(RCDF_VID_ALPHA_CONTROL, ctrl);
521f29dbc25Smrg
522f29dbc25Smrg    /* SET THE VIDEO FORMAT IN THE DISPLAY CONTROLLER      */
523f29dbc25Smrg    /* Use private routine to abstract display controller. */
524f29dbc25Smrg
525f29dbc25Smrg    gfx_set_display_video_format(format);
526f29dbc25Smrg    return (0);
527f29dbc25Smrg}
528f29dbc25Smrg
529f29dbc25Smrg/*----------------------------------------------------------------------------
530f29dbc25Smrg * gfx_set_video_size
531f29dbc25Smrg *
532f29dbc25Smrg * This routine specifies the size of the source data.  It is used only
533f29dbc25Smrg * to determine how much data to transfer per frame, and is not used to
534f29dbc25Smrg * calculate the scaling value (that is handled by a separate routine).
535f29dbc25Smrg *----------------------------------------------------------------------------
536f29dbc25Smrg */
537f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
538f29dbc25Smrgint
539f29dbc25Smrgredcloud_set_video_size(unsigned short width, unsigned short height)
540f29dbc25Smrg#else
541f29dbc25Smrgint
542f29dbc25Smrggfx_set_video_size(unsigned short width, unsigned short height)
543f29dbc25Smrg#endif
544f29dbc25Smrg{
545f29dbc25Smrg    unsigned long size, vcfg, vid_420, pitch;
546f29dbc25Smrg
547f29dbc25Smrg    /* SET THE DISPLAY FILTER VIDEO LINE SIZE                            */
548f29dbc25Smrg    /* Match the DC hardware alignment requirement.  The line size must  */
549f29dbc25Smrg    /* always be 32-byte aligned.  However, we can manage smaller        */
550f29dbc25Smrg    /* alignments by decreasing the pitch and clipping the video window. */
551f29dbc25Smrg    /* The VG will fetch extra data for each line, but the decreased     */
552f29dbc25Smrg    /* pitch will ensure that it always begins fetching at the start of  */
553f29dbc25Smrg    /* the video line.                                                   */
554f29dbc25Smrg
555f29dbc25Smrg    vcfg = READ_VID32(RCDF_VIDEO_CONFIG);
556f29dbc25Smrg
557f29dbc25Smrg    vid_420 = vcfg & RCDF_VCFG_4_2_0_MODE;
558f29dbc25Smrg
559f29dbc25Smrg    vcfg &= ~(RCDF_VCFG_LINE_SIZE_LOWER_MASK | RCDF_VCFG_LINE_SIZE_UPPER);
560f29dbc25Smrg
561f29dbc25Smrg    size = ((width >> 1) + 7) & 0xFFF8;
562f29dbc25Smrg    pitch = ((width << 1) + 7) & 0xFFF8;
563f29dbc25Smrg
564f29dbc25Smrg    vcfg |= (size & 0x00FF) << 8;
565f29dbc25Smrg    if (size & 0x0100)
566f29dbc25Smrg        vcfg |= RCDF_VCFG_LINE_SIZE_UPPER;
567f29dbc25Smrg    WRITE_VID32(RCDF_VIDEO_CONFIG, vcfg);
568f29dbc25Smrg
569f29dbc25Smrg    /* SET VIDEO BUFFER LINE SIZE IN DISPLAY CONTROLLER */
570f29dbc25Smrg    /* Use private routine to abstract the display controller. */
571f29dbc25Smrg
572f29dbc25Smrg    gfx_set_display_video_size(width, height);
573f29dbc25Smrg
574f29dbc25Smrg    /* SET VIDEO PITCH */
575f29dbc25Smrg    /* We are only maintaining legacy for 4:2:2 video formats. */
576f29dbc25Smrg    /* 4:2:0 video in previous chips was inadequate for most   */
577f29dbc25Smrg    /* common video formats.                                   */
578f29dbc25Smrg
579f29dbc25Smrg    if (!vid_420)
580f29dbc25Smrg        gfx_set_video_yuv_pitch(pitch, pitch << 1);
581f29dbc25Smrg
582f29dbc25Smrg    return (0);
583f29dbc25Smrg}
584f29dbc25Smrg
585f29dbc25Smrg/*----------------------------------------------------------------------------
586f29dbc25Smrg * gfx_set_video_offset
587f29dbc25Smrg *
588f29dbc25Smrg * This routine sets the starting offset for the video buffer when only
589f29dbc25Smrg * one offset needs to be specified.
590f29dbc25Smrg *----------------------------------------------------------------------------
591f29dbc25Smrg */
592f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
593f29dbc25Smrgint
594f29dbc25Smrgredcloud_set_video_offset(unsigned long offset)
595f29dbc25Smrg#else
596f29dbc25Smrgint
597f29dbc25Smrggfx_set_video_offset(unsigned long offset)
598f29dbc25Smrg#endif
599f29dbc25Smrg{
600f29dbc25Smrg    /* SAVE VALUE FOR FUTURE CLIPPING OF THE TOP OF THE VIDEO WINDOW */
601f29dbc25Smrg
602f29dbc25Smrg    gfx_vid_offset = offset;
603f29dbc25Smrg
604f29dbc25Smrg    /* SET VIDEO BUFFER OFFSET IN DISPLAY CONTROLLER */
605f29dbc25Smrg    /* Use private routine to abstract the display controller. */
606f29dbc25Smrg
607f29dbc25Smrg    gfx_set_display_video_offset(offset);
608f29dbc25Smrg    return (0);
609f29dbc25Smrg}
610f29dbc25Smrg
611f29dbc25Smrg/*----------------------------------------------------------------------------
612f29dbc25Smrg * gfx_set_video_yuv_offsets
613f29dbc25Smrg *
614f29dbc25Smrg * This routine sets the starting offset for the video buffer when displaying
615f29dbc25Smrg * 4:2:0 video.
616f29dbc25Smrg *----------------------------------------------------------------------------
617f29dbc25Smrg */
618f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
619f29dbc25Smrgint
620f29dbc25Smrgredcloud_set_video_yuv_offsets(unsigned long yoffset, unsigned long uoffset,
62104007ebaSmrg                               unsigned long voffset)
622f29dbc25Smrg#else
623f29dbc25Smrgint
624f29dbc25Smrggfx_set_video_yuv_offsets(unsigned long yoffset, unsigned long uoffset,
62504007ebaSmrg                          unsigned long voffset)
626f29dbc25Smrg#endif
627f29dbc25Smrg{
628f29dbc25Smrg    /* SAVE VALUE FOR FUTURE CLIPPING OF THE TOP OF THE VIDEO WINDOW */
629f29dbc25Smrg
630f29dbc25Smrg    gfx_vid_offset = yoffset;
631f29dbc25Smrg    gfx_vid_uoffset = uoffset;
632f29dbc25Smrg    gfx_vid_voffset = voffset;
633f29dbc25Smrg
634f29dbc25Smrg    /* SET VIDEO BUFFER OFFSET IN DISPLAY CONTROLLER */
635f29dbc25Smrg    /* Use private routine to abstract the display controller. */
636f29dbc25Smrg
637f29dbc25Smrg    gfx_set_display_video_yuv_offsets(yoffset, uoffset, voffset);
638f29dbc25Smrg
639f29dbc25Smrg    return (0);
640f29dbc25Smrg}
641f29dbc25Smrg
642f29dbc25Smrg/*----------------------------------------------------------------------------
643f29dbc25Smrg * gfx_set_video_yuv_pitch
644f29dbc25Smrg *
645f29dbc25Smrg * This routine sets the byte offset between consecutive scanlines of YUV video data
646f29dbc25Smrg *----------------------------------------------------------------------------
647f29dbc25Smrg */
648f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
649f29dbc25Smrgint
650f29dbc25Smrgredcloud_set_video_yuv_pitch(unsigned long ypitch, unsigned long uvpitch)
651f29dbc25Smrg#else
652f29dbc25Smrgint
653f29dbc25Smrggfx_set_video_yuv_pitch(unsigned long ypitch, unsigned long uvpitch)
654f29dbc25Smrg#endif
655f29dbc25Smrg{
656f29dbc25Smrg    /* SET VIDEO PITCH IN DISPLAY CONTROLLER */
657f29dbc25Smrg    /* Use private routine to abstract the display controller. */
658f29dbc25Smrg
659f29dbc25Smrg    gfx_set_display_video_yuv_pitch(ypitch, uvpitch);
660f29dbc25Smrg
661f29dbc25Smrg    return (0);
662f29dbc25Smrg}
663f29dbc25Smrg
664f29dbc25Smrg/*---------------------------------------------------------------------------
665f29dbc25Smrg * gfx_set_video_scale
666f29dbc25Smrg *
667f29dbc25Smrg * This routine sets the scale factor for the video overlay window.  The
668f29dbc25Smrg * size of the source and destination regions are specified in pixels.
669f29dbc25Smrg *---------------------------------------------------------------------------
670f29dbc25Smrg */
671f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
672f29dbc25Smrgint
673f29dbc25Smrgredcloud_set_video_scale(unsigned short srcw, unsigned short srch,
67404007ebaSmrg                         unsigned short dstw, unsigned short dsth)
675f29dbc25Smrg#else
676f29dbc25Smrgint
677f29dbc25Smrggfx_set_video_scale(unsigned short srcw, unsigned short srch,
67804007ebaSmrg                    unsigned short dstw, unsigned short dsth)
679f29dbc25Smrg#endif
680f29dbc25Smrg{
681f29dbc25Smrg    unsigned long xscale, yscale;
682f29dbc25Smrg
683f29dbc25Smrg    /* SAVE PARAMETERS (unless don't-care zero destination arguments are used) */
684f29dbc25Smrg    /* These are needed for clipping the video window later. */
685f29dbc25Smrg
686f29dbc25Smrg    if (dstw != 0) {
687f29dbc25Smrg        gfx_vid_srcw = srcw;
688f29dbc25Smrg        gfx_vid_dstw = dstw;
689f29dbc25Smrg    }
690f29dbc25Smrg    if (dsth != 0) {
691f29dbc25Smrg        gfx_vid_srch = srch;
692f29dbc25Smrg        gfx_vid_dsth = dsth;
693f29dbc25Smrg    }
694f29dbc25Smrg
695f29dbc25Smrg    /* CALCULATE DISPLAY FILTER SCALE FACTORS */
696f29dbc25Smrg    /* Zero width and height indicate don't care conditions */
697f29dbc25Smrg    /* Downscaling is performed in a separate function.     */
698f29dbc25Smrg
699f29dbc25Smrg    if (dstw == 0)
700f29dbc25Smrg        xscale = READ_VID32(RCDF_VIDEO_SCALE) & 0xffff;
701f29dbc25Smrg    /* keep previous if don't-care argument */
702f29dbc25Smrg    else if (dstw <= srcw)
703f29dbc25Smrg        xscale = 0x2000;
704f29dbc25Smrg    /* horizontal downscaling is currently done in a separate function */
705f29dbc25Smrg    else if ((srcw == 1) || (dstw == 1))
706f29dbc25Smrg        return GFX_STATUS_BAD_PARAMETER;
707f29dbc25Smrg    else
708f29dbc25Smrg        xscale = (0x2000l * (srcw - 1l)) / (dstw - 1l);
709f29dbc25Smrg
710f29dbc25Smrg    if (dsth == 0)
711f29dbc25Smrg        yscale = (READ_VID32(RCDF_VIDEO_SCALE) & 0xffff0000) >> 16;
712f29dbc25Smrg    /* keep previous if don't-care argument */
713f29dbc25Smrg    else if (dsth <= srch)
714f29dbc25Smrg        yscale = 0x2000;
715f29dbc25Smrg    /* vertical downscaling is handled in a separate function */
716f29dbc25Smrg    else if ((srch == 1) || (dsth == 1))
717f29dbc25Smrg        return GFX_STATUS_BAD_PARAMETER;
718f29dbc25Smrg    else
719f29dbc25Smrg        yscale = (0x2000l * (srch - 1l)) / (dsth - 1l);
720f29dbc25Smrg
721f29dbc25Smrg    WRITE_VID32(RCDF_VIDEO_SCALE, (yscale << 16) | xscale);
722f29dbc25Smrg
723f29dbc25Smrg    /* CALL ROUTINE TO UPDATE WINDOW POSITION */
724f29dbc25Smrg    /* This is required because the scale values affect the number of */
725f29dbc25Smrg    /* source data pixels that need to be clipped, as well as the     */
726f29dbc25Smrg    /* amount of data that needs to be transferred.                   */
727f29dbc25Smrg
728f29dbc25Smrg    gfx_set_video_window(gfx_vid_xpos, gfx_vid_ypos, gfx_vid_width,
72904007ebaSmrg                         gfx_vid_height);
730f29dbc25Smrg    return (0);
731f29dbc25Smrg}
732f29dbc25Smrg
733f29dbc25Smrg/*---------------------------------------------------------------------------
734f29dbc25Smrg * gfx_set_video_vertical_downscale
735f29dbc25Smrg *
736f29dbc25Smrg * This routine sets the vertical downscale factor for the video overlay
737f29dbc25Smrg * window.
738f29dbc25Smrg * The height of the source and destination regions are specified in pixels.
739f29dbc25Smrg *---------------------------------------------------------------------------
740f29dbc25Smrg */
741f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
742f29dbc25Smrgint
74304007ebaSmrgredcloud_set_video_vertical_downscale(unsigned short srch, unsigned short dsth)
744f29dbc25Smrg#else
745f29dbc25Smrgint
746f29dbc25Smrggfx_set_video_vertical_downscale(unsigned short srch, unsigned short dsth)
747f29dbc25Smrg#endif
748f29dbc25Smrg{
749f29dbc25Smrg    /* SET VIDEO SCALE IN DISPLAY CONTROLLER    */
750f29dbc25Smrg    /* Use private routine to abstract hardware */
751f29dbc25Smrg
752f29dbc25Smrg    gfx_set_display_video_downscale(srch, dsth);
753f29dbc25Smrg    return 0;
754f29dbc25Smrg}
755f29dbc25Smrg
756f29dbc25Smrg/*---------------------------------------------------------------------------
757f29dbc25Smrg * gfx_set_video_vertical_downscale_enable
758f29dbc25Smrg *
759f29dbc25Smrg * This routine sets the vertical downscale enable for the video overlay
760f29dbc25Smrg * window.
761f29dbc25Smrg *---------------------------------------------------------------------------
762f29dbc25Smrg */
763f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
764f29dbc25Smrgvoid
765f29dbc25Smrgredcloud_set_video_vertical_downscale_enable(int enable)
766f29dbc25Smrg#else
767f29dbc25Smrgvoid
768f29dbc25Smrggfx_set_video_vertical_downscale_enable(int enable)
769f29dbc25Smrg#endif
770f29dbc25Smrg{
771f29dbc25Smrg    /* SET VIDEO SCALE IN DISPLAY CONTROLLER    */
772f29dbc25Smrg    /* Use private routine to abstract hardware */
773f29dbc25Smrg
774f29dbc25Smrg    gfx_set_display_video_vertical_downscale_enable(enable);
775f29dbc25Smrg}
776f29dbc25Smrg
777f29dbc25Smrg/*---------------------------------------------------------------------------
778f29dbc25Smrg * gfx_set_video_downscale_config
779f29dbc25Smrg *
780f29dbc25Smrg * This routine sets the downscale type and factor for the video overlay
781f29dbc25Smrg * window.
782f29dbc25Smrg * Note: No downscaling support for RGB565 and YUV420 video formats.
783f29dbc25Smrg *---------------------------------------------------------------------------
784f29dbc25Smrg */
785f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
786f29dbc25Smrgint
787f29dbc25Smrgredcloud_set_video_downscale_config(unsigned short type, unsigned short m)
788f29dbc25Smrg#else
789f29dbc25Smrgint
790f29dbc25Smrggfx_set_video_downscale_config(unsigned short type, unsigned short m)
791f29dbc25Smrg#endif
792f29dbc25Smrg{
793f29dbc25Smrg    unsigned long downscale;
794f29dbc25Smrg
795f29dbc25Smrg    if ((m < 1) || (m > 16))
796f29dbc25Smrg        return GFX_STATUS_BAD_PARAMETER;
797f29dbc25Smrg
798f29dbc25Smrg    downscale = READ_VID32(RCDF_VIDEO_DOWNSCALER_CONTROL);
799f29dbc25Smrg    downscale &=
800f29dbc25Smrg        ~(RCDF_VIDEO_DOWNSCALE_FACTOR_MASK | RCDF_VIDEO_DOWNSCALE_TYPE_MASK);
80104007ebaSmrg    downscale |= ((unsigned long) (m - 1) << RCDF_VIDEO_DOWNSCALE_FACTOR_POS);
802f29dbc25Smrg    switch (type) {
803f29dbc25Smrg    case VIDEO_DOWNSCALE_KEEP_1_OF:
804f29dbc25Smrg        downscale |= RCDF_VIDEO_DOWNSCALE_TYPE_A;
805f29dbc25Smrg        break;
806f29dbc25Smrg    case VIDEO_DOWNSCALE_DROP_1_OF:
807f29dbc25Smrg        downscale |= RCDF_VIDEO_DOWNSCALE_TYPE_B;
808f29dbc25Smrg        break;
809f29dbc25Smrg    default:
810f29dbc25Smrg        return GFX_STATUS_BAD_PARAMETER;
811f29dbc25Smrg    }
812f29dbc25Smrg    WRITE_VID32(RCDF_VIDEO_DOWNSCALER_CONTROL, downscale);
813f29dbc25Smrg    return (0);
814f29dbc25Smrg}
815f29dbc25Smrg
816f29dbc25Smrg/*---------------------------------------------------------------------------
817f29dbc25Smrg * gfx_set_video_downscale_coefficients
818f29dbc25Smrg *
819f29dbc25Smrg * This routine sets the downscale filter coefficients.
820f29dbc25Smrg *---------------------------------------------------------------------------
821f29dbc25Smrg */
822f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
823f29dbc25Smrgint
824f29dbc25Smrgredcloud_set_video_downscale_coefficients(unsigned short coef1,
82504007ebaSmrg                                          unsigned short coef2,
82604007ebaSmrg                                          unsigned short coef3,
82704007ebaSmrg                                          unsigned short coef4)
828f29dbc25Smrg#else
829f29dbc25Smrgint
830f29dbc25Smrggfx_set_video_downscale_coefficients(unsigned short coef1,
83104007ebaSmrg                                     unsigned short coef2, unsigned short coef3,
83204007ebaSmrg                                     unsigned short coef4)
833f29dbc25Smrg#endif
834f29dbc25Smrg{
835f29dbc25Smrg    if ((coef1 + coef2 + coef3 + coef4) != 16)
836f29dbc25Smrg        return GFX_STATUS_BAD_PARAMETER;
837f29dbc25Smrg
838f29dbc25Smrg    WRITE_VID32(RCDF_VIDEO_DOWNSCALER_COEFFICIENTS,
83904007ebaSmrg                ((unsigned long) coef1 << RCDF_VIDEO_DOWNSCALER_COEF1_POS) |
84004007ebaSmrg                ((unsigned long) coef2 << RCDF_VIDEO_DOWNSCALER_COEF2_POS) |
84104007ebaSmrg                ((unsigned long) coef3 << RCDF_VIDEO_DOWNSCALER_COEF3_POS) |
84204007ebaSmrg                ((unsigned long) coef4 << RCDF_VIDEO_DOWNSCALER_COEF4_POS));
843f29dbc25Smrg    return (0);
844f29dbc25Smrg}
845f29dbc25Smrg
846f29dbc25Smrg/*---------------------------------------------------------------------------
847f29dbc25Smrg * gfx_set_video_downscale_enable
848f29dbc25Smrg *
849f29dbc25Smrg * This routine enables or disables downscaling for the video overlay window.
850f29dbc25Smrg *---------------------------------------------------------------------------
851f29dbc25Smrg */
852f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
853f29dbc25Smrgint
854f29dbc25Smrgredcloud_set_video_downscale_enable(int enable)
855f29dbc25Smrg#else
856f29dbc25Smrgint
857f29dbc25Smrggfx_set_video_downscale_enable(int enable)
858f29dbc25Smrg#endif
859f29dbc25Smrg{
860f29dbc25Smrg    unsigned long downscale;
861f29dbc25Smrg
862f29dbc25Smrg    downscale = READ_VID32(RCDF_VIDEO_DOWNSCALER_CONTROL);
863f29dbc25Smrg    if (enable)
864f29dbc25Smrg        downscale |= RCDF_VIDEO_DOWNSCALE_ENABLE;
865f29dbc25Smrg    else
866f29dbc25Smrg        downscale &= ~RCDF_VIDEO_DOWNSCALE_ENABLE;
867f29dbc25Smrg    WRITE_VID32(RCDF_VIDEO_DOWNSCALER_CONTROL, downscale);
868f29dbc25Smrg    return (0);
869f29dbc25Smrg}
870f29dbc25Smrg
871f29dbc25Smrg/*---------------------------------------------------------------------------
872f29dbc25Smrg * gfx_set_video_window
873f29dbc25Smrg *
874f29dbc25Smrg * This routine sets the position and size of the video overlay window.  The
875f29dbc25Smrg * x and y positions are specified in screen relative coordinates, and may be
876f29dbc25Smrg * negative.
877f29dbc25Smrg * The size of destination region is specified in pixels.  The line size
878f29dbc25Smrg * indicates the number of bytes of source data per scanline.
879f29dbc25Smrg *---------------------------------------------------------------------------
880f29dbc25Smrg */
881f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
882f29dbc25Smrgint
88304007ebaSmrgredcloud_set_video_window(short x, short y, unsigned short w, unsigned short h)
884f29dbc25Smrg#else
885f29dbc25Smrgint
886f29dbc25Smrggfx_set_video_window(short x, short y, unsigned short w, unsigned short h)
887f29dbc25Smrg#endif
888f29dbc25Smrg{
889f29dbc25Smrg    unsigned long hadjust, vadjust;
890f29dbc25Smrg    unsigned long xstart, ystart, xend, yend;
891f29dbc25Smrg
892f29dbc25Smrg    /* SAVE PARAMETERS */
893f29dbc25Smrg    /* These are needed to call this routine if the scale value changes. */
894f29dbc25Smrg
895f29dbc25Smrg    gfx_vid_xpos = x;
896f29dbc25Smrg    gfx_vid_ypos = y;
897f29dbc25Smrg    gfx_vid_width = w;
898f29dbc25Smrg    gfx_vid_height = h;
899f29dbc25Smrg
900f29dbc25Smrg    /* GET ADJUSTMENT VALUES */
901f29dbc25Smrg    /* Use routines to abstract version of display controller. */
902f29dbc25Smrg
903f29dbc25Smrg    hadjust = gfx_get_htotal() - gfx_get_hsync_end() - 14l;
904f29dbc25Smrg    vadjust = gfx_get_vtotal() - gfx_get_vsync_end() + 1l;
905f29dbc25Smrg
906f29dbc25Smrg    /* LEFT CLIPPING */
907f29dbc25Smrg
908f29dbc25Smrg    if (x < 0) {
90904007ebaSmrg        gfx_set_video_left_crop((unsigned short) (-x));
910f29dbc25Smrg        xstart = hadjust;
91104007ebaSmrg    }
91204007ebaSmrg    else {
913f29dbc25Smrg        gfx_set_video_left_crop(0);
91404007ebaSmrg        xstart = (unsigned long) x + hadjust;
915f29dbc25Smrg    }
916f29dbc25Smrg
917f29dbc25Smrg    /* HORIZONTAL END */
918f29dbc25Smrg    /* End positions in register are non-inclusive (one more than the actual
919f29dbc25Smrg     * end) */
920f29dbc25Smrg
921f29dbc25Smrg    if ((x + w) < gfx_get_hactive())
92204007ebaSmrg        xend = (unsigned long) x + (unsigned long) w + hadjust;
923f29dbc25Smrg
924f29dbc25Smrg    /* RIGHT-CLIPPING */
925f29dbc25Smrg    else
92604007ebaSmrg        xend = (unsigned long) gfx_get_hactive() + hadjust;
927f29dbc25Smrg
928f29dbc25Smrg    /* VERTICAL START */
929f29dbc25Smrg
93004007ebaSmrg    ystart = (unsigned long) y + vadjust;
931f29dbc25Smrg
932f29dbc25Smrg    /* VERTICAL END */
933f29dbc25Smrg
934f29dbc25Smrg    if ((y + h) < gfx_get_vactive())
93504007ebaSmrg        yend = (unsigned long) y + (unsigned long) h + vadjust;
936f29dbc25Smrg
937f29dbc25Smrg    /* BOTTOM-CLIPPING */
938f29dbc25Smrg    else
93904007ebaSmrg        yend = (unsigned long) gfx_get_vactive() + vadjust;
940f29dbc25Smrg
941f29dbc25Smrg    /* SET VIDEO POSITION */
942f29dbc25Smrg
943f29dbc25Smrg    WRITE_VID32(RCDF_VIDEO_X_POS, (xend << 16) | xstart);
944f29dbc25Smrg    WRITE_VID32(RCDF_VIDEO_Y_POS, (yend << 16) | ystart);
945f29dbc25Smrg
946f29dbc25Smrg    return (0);
947f29dbc25Smrg}
948f29dbc25Smrg
949f29dbc25Smrg/*---------------------------------------------------------------------------
950f29dbc25Smrg * gfx_set_video_left_crop
951f29dbc25Smrg *
952f29dbc25Smrg * This routine sets the number of pixels which will be cropped from the
953f29dbc25Smrg * beginning of each video line. The video window will begin to display only
954f29dbc25Smrg * from the pixel following the cropped pixels, and the cropped pixels
955f29dbc25Smrg * will be ignored.
956f29dbc25Smrg *---------------------------------------------------------------------------
957f29dbc25Smrg */
958f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
959f29dbc25Smrgint
960f29dbc25Smrgredcloud_set_video_left_crop(unsigned short x)
961f29dbc25Smrg#else
962f29dbc25Smrgint
963f29dbc25Smrggfx_set_video_left_crop(unsigned short x)
964f29dbc25Smrg#endif
965f29dbc25Smrg{
966f29dbc25Smrg    unsigned long vcfg, initread;
967f29dbc25Smrg
968f29dbc25Smrg    vcfg = READ_VID32(RCDF_VIDEO_CONFIG);
969f29dbc25Smrg
970f29dbc25Smrg    /* CLIPPING ON LEFT */
971f29dbc25Smrg    /* Adjust initial read for scale, checking for divide by zero. Mask the
972f29dbc25Smrg     * lower three bits when clipping 4:2:0 video. By masking the bits instead
973f29dbc25Smrg     * of rounding up we ensure that we always clip less than or equal to the
974f29dbc25Smrg     * desired number of pixels.  This prevents visual artifacts from
975f29dbc25Smrg     * over-clipping. We mask three bits to meet the HW requirement that 4:2:0
976f29dbc25Smrg     * clipping be 16-byte or 8-pixel aligned.
977f29dbc25Smrg     * */
978f29dbc25Smrg
979f29dbc25Smrg    if (gfx_vid_dstw) {
98004007ebaSmrg        initread = (unsigned long) x *gfx_vid_srcw / gfx_vid_dstw;
981f29dbc25Smrg
982f29dbc25Smrg        if (vcfg & RCDF_VCFG_4_2_0_MODE)
983f29dbc25Smrg            initread &= 0xFFF8;
98404007ebaSmrg    }
98504007ebaSmrg    else
986f29dbc25Smrg        initread = 0;
987f29dbc25Smrg
988f29dbc25Smrg    /* SET INITIAL READ ADDRESS */
989f29dbc25Smrg
990f29dbc25Smrg    vcfg &= ~RCDF_VCFG_INIT_READ_MASK;
991f29dbc25Smrg    vcfg |= (initread << 15) & RCDF_VCFG_INIT_READ_MASK;
992f29dbc25Smrg    WRITE_VID32(RCDF_VIDEO_CONFIG, vcfg);
993f29dbc25Smrg    return (0);
994f29dbc25Smrg}
995f29dbc25Smrg
996f29dbc25Smrg/*---------------------------------------------------------------------------
997f29dbc25Smrg * gfx_set_video_color_key
998f29dbc25Smrg *
999f29dbc25Smrg * This routine specifies the color key value and mask for the video overlay
1000f29dbc25Smrg * hardware. To disable color key, the color and mask should both be set to
1001f29dbc25Smrg * zero. The hardware uses the color key in the following equation:
1002f29dbc25Smrg *
1003f29dbc25Smrg * ((source data) & (color key mask)) == ((color key) & (color key mask))
1004f29dbc25Smrg *
1005f29dbc25Smrg * If "graphics" is set to TRUE, the source data is graphics, and color key
1006f29dbc25Smrg * is an RGB value. If "graphics" is set to FALSE, the source data is the
1007f29dbc25Smrg * video, and color key is a YUV value.
1008f29dbc25Smrg *---------------------------------------------------------------------------
1009f29dbc25Smrg */
1010f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
1011f29dbc25Smrgint
1012f29dbc25Smrgredcloud_set_video_color_key(unsigned long key, unsigned long mask,
101304007ebaSmrg                             int graphics)
1014f29dbc25Smrg#else
1015f29dbc25Smrgint
1016f29dbc25Smrggfx_set_video_color_key(unsigned long key, unsigned long mask, int graphics)
1017f29dbc25Smrg#endif
1018f29dbc25Smrg{
1019f29dbc25Smrg    unsigned long dcfg = 0;
1020f29dbc25Smrg
1021f29dbc25Smrg    /* SET RCDF COLOR KEY VALUE */
1022f29dbc25Smrg
1023f29dbc25Smrg    WRITE_VID32(RCDF_VIDEO_COLOR_KEY, key);
1024f29dbc25Smrg    WRITE_VID32(RCDF_VIDEO_COLOR_MASK, mask);
1025f29dbc25Smrg
1026f29dbc25Smrg    /* SELECT GRAPHICS OR VIDEO DATA TO COMPARE TO THE COLOR KEY */
1027f29dbc25Smrg
1028f29dbc25Smrg    dcfg = READ_VID32(RCDF_DISPLAY_CONFIG);
1029f29dbc25Smrg    if (graphics & 0x01)
1030f29dbc25Smrg        dcfg &= ~RCDF_DCFG_VG_CK;
1031f29dbc25Smrg    else
1032f29dbc25Smrg        dcfg |= RCDF_DCFG_VG_CK;
1033f29dbc25Smrg    WRITE_VID32(RCDF_DISPLAY_CONFIG, dcfg);
1034f29dbc25Smrg    return (0);
1035f29dbc25Smrg}
1036f29dbc25Smrg
1037f29dbc25Smrg/*---------------------------------------------------------------------------
1038f29dbc25Smrg * gfx_set_video_filter
1039f29dbc25Smrg *
1040f29dbc25Smrg * This routine enables or disables the video overlay filters.
1041f29dbc25Smrg *---------------------------------------------------------------------------
1042f29dbc25Smrg */
1043f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
1044f29dbc25Smrgint
1045f29dbc25Smrgredcloud_set_video_filter(int xfilter, int yfilter)
1046f29dbc25Smrg#else
1047f29dbc25Smrgint
1048f29dbc25Smrggfx_set_video_filter(int xfilter, int yfilter)
1049f29dbc25Smrg#endif
1050f29dbc25Smrg{
1051f29dbc25Smrg    unsigned long vcfg = 0;
1052f29dbc25Smrg
1053f29dbc25Smrg    /* ENABLE OR DISABLE DISPLAY FILTER VIDEO OVERLAY FILTERS */
1054f29dbc25Smrg
1055f29dbc25Smrg    vcfg = READ_VID32(RCDF_VIDEO_CONFIG);
1056f29dbc25Smrg    vcfg &= ~(RCDF_VCFG_X_FILTER_EN | RCDF_VCFG_Y_FILTER_EN);
1057f29dbc25Smrg    if (xfilter)
1058f29dbc25Smrg        vcfg |= RCDF_VCFG_X_FILTER_EN;
1059f29dbc25Smrg    if (yfilter)
1060f29dbc25Smrg        vcfg |= RCDF_VCFG_Y_FILTER_EN;
1061f29dbc25Smrg    WRITE_VID32(RCDF_VIDEO_CONFIG, vcfg);
1062f29dbc25Smrg    return (0);
1063f29dbc25Smrg}
1064f29dbc25Smrg
1065f29dbc25Smrg/*---------------------------------------------------------------------------
1066f29dbc25Smrg * gfx_set_video_palette
1067f29dbc25Smrg *
1068f29dbc25Smrg * This routine loads the video hardware palette.  If a NULL pointer is
1069f29dbc25Smrg * specified, the palette is bypassed (for Redcloud, this means loading the
1070f29dbc25Smrg * palette with identity values).
1071f29dbc25Smrg *---------------------------------------------------------------------------
1072f29dbc25Smrg */
1073f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
1074f29dbc25Smrgint
1075f29dbc25Smrgredcloud_set_video_palette(unsigned long *palette)
1076f29dbc25Smrg#else
1077f29dbc25Smrgint
1078f29dbc25Smrggfx_set_video_palette(unsigned long *palette)
1079f29dbc25Smrg#endif
1080f29dbc25Smrg{
1081f29dbc25Smrg    unsigned long i, entry;
1082f29dbc25Smrg    unsigned long misc, dcfg;
1083f29dbc25Smrg
1084f29dbc25Smrg    /* ENABLE THE VIDEO PALETTE */
1085f29dbc25Smrg    /* Ensure that the video palette has an effect by routing video data */
1086f29dbc25Smrg    /* through the palette RAM and clearing the 'Bypass Both' bit.       */
1087f29dbc25Smrg
1088f29dbc25Smrg    dcfg = READ_VID32(RCDF_DISPLAY_CONFIG);
1089f29dbc25Smrg    misc = READ_VID32(RCDF_VID_MISC);
1090f29dbc25Smrg
1091f29dbc25Smrg    dcfg |= RCDF_DCFG_GV_PAL_BYP;
1092f29dbc25Smrg    misc &= ~RCDF_GAMMA_BYPASS_BOTH;
1093f29dbc25Smrg
1094f29dbc25Smrg    WRITE_VID32(RCDF_DISPLAY_CONFIG, dcfg);
1095f29dbc25Smrg    WRITE_VID32(RCDF_VID_MISC, misc);
1096f29dbc25Smrg
1097f29dbc25Smrg    if (gfx_test_timing_active()) {
109804007ebaSmrg        while (!gfx_test_vertical_active());
109904007ebaSmrg        while (gfx_test_vertical_active());
110004007ebaSmrg        while (!gfx_test_vertical_active());
1101f29dbc25Smrg    }
1102f29dbc25Smrg
1103f29dbc25Smrg    /* LOAD REDCLOUD VIDEO PALETTE */
1104f29dbc25Smrg
1105f29dbc25Smrg    WRITE_VID32(RCDF_PALETTE_ADDRESS, 0);
1106f29dbc25Smrg    for (i = 0; i < 256; i++) {
1107f29dbc25Smrg        if (palette)
1108f29dbc25Smrg            entry = palette[i];
1109f29dbc25Smrg        else
1110f29dbc25Smrg            entry = gfx_gamma_ram_redcloud[i];
1111f29dbc25Smrg        WRITE_VID32(RCDF_PALETTE_DATA, entry);
1112f29dbc25Smrg    }
1113f29dbc25Smrg
1114f29dbc25Smrg    return (0);
1115f29dbc25Smrg}
1116f29dbc25Smrg
1117f29dbc25Smrg/*---------------------------------------------------------------------------
1118f29dbc25Smrg * gfx_set_graphics_palette
1119f29dbc25Smrg *
1120f29dbc25Smrg * This routine loads the video hardware palette.  If a NULL pointer is
1121f29dbc25Smrg * specified, the palette is bypassed (for Redcloud, this means loading the
1122f29dbc25Smrg * palette with identity values).  Note that this routine is identical to
1123f29dbc25Smrg * gfx_set_video_palette, except that the hardware is updated to route
1124f29dbc25Smrg * graphics data through the palette.
1125f29dbc25Smrg *---------------------------------------------------------------------------
1126f29dbc25Smrg */
1127f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
1128f29dbc25Smrgint
1129f29dbc25Smrgredcloud_set_graphics_palette(unsigned long *palette)
1130f29dbc25Smrg#else
1131f29dbc25Smrgint
1132f29dbc25Smrggfx_set_graphics_palette(unsigned long *palette)
1133f29dbc25Smrg#endif
1134f29dbc25Smrg{
1135f29dbc25Smrg    unsigned long i, entry;
1136f29dbc25Smrg    unsigned long misc, dcfg;
1137f29dbc25Smrg
1138f29dbc25Smrg    /* ENABLE THE VIDEO PALETTE */
1139f29dbc25Smrg    /* Ensure that the video palette has an effect by routing video data */
1140f29dbc25Smrg    /* through the palette RAM and clearing the 'Bypass Both' bit.       */
1141f29dbc25Smrg
1142f29dbc25Smrg    dcfg = READ_VID32(RCDF_DISPLAY_CONFIG);
1143f29dbc25Smrg    misc = READ_VID32(RCDF_VID_MISC);
1144f29dbc25Smrg
1145f29dbc25Smrg    dcfg &= ~RCDF_DCFG_GV_PAL_BYP;
1146f29dbc25Smrg    misc &= ~RCDF_GAMMA_BYPASS_BOTH;
1147f29dbc25Smrg
1148f29dbc25Smrg    WRITE_VID32(RCDF_DISPLAY_CONFIG, dcfg);
1149f29dbc25Smrg    WRITE_VID32(RCDF_VID_MISC, misc);
1150f29dbc25Smrg
1151f29dbc25Smrg    if (gfx_test_timing_active()) {
115204007ebaSmrg        while (!gfx_test_vertical_active());
115304007ebaSmrg        while (gfx_test_vertical_active());
115404007ebaSmrg        while (!gfx_test_vertical_active());
1155f29dbc25Smrg    }
1156f29dbc25Smrg
1157f29dbc25Smrg    /* LOAD REDCLOUD VIDEO PALETTE */
1158f29dbc25Smrg
1159f29dbc25Smrg    WRITE_VID32(RCDF_PALETTE_ADDRESS, 0);
1160f29dbc25Smrg    for (i = 0; i < 256; i++) {
1161f29dbc25Smrg        if (palette)
1162f29dbc25Smrg            entry = palette[i];
1163f29dbc25Smrg        else
1164f29dbc25Smrg            entry = gfx_gamma_ram_redcloud[i];
1165f29dbc25Smrg        WRITE_VID32(RCDF_PALETTE_DATA, entry);
1166f29dbc25Smrg    }
1167f29dbc25Smrg
1168f29dbc25Smrg    return (0);
1169f29dbc25Smrg}
1170f29dbc25Smrg
1171f29dbc25Smrg/*---------------------------------------------------------------------------
1172f29dbc25Smrg * gfx_set_graphics_palette_entry
1173f29dbc25Smrg *
1174f29dbc25Smrg * This routine loads a single entry of the video hardware palette.
1175f29dbc25Smrg *---------------------------------------------------------------------------
1176f29dbc25Smrg */
1177f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
1178f29dbc25Smrgint
117904007ebaSmrgredcloud_set_graphics_palette_entry(unsigned long index, unsigned long palette)
1180f29dbc25Smrg#else
1181f29dbc25Smrgint
1182f29dbc25Smrggfx_set_graphics_palette_entry(unsigned long index, unsigned long palette)
1183f29dbc25Smrg#endif
1184f29dbc25Smrg{
1185f29dbc25Smrg    unsigned long dcfg, misc;
1186f29dbc25Smrg
1187f29dbc25Smrg    if (index > 0xFF)
1188f29dbc25Smrg        return GFX_STATUS_BAD_PARAMETER;
1189f29dbc25Smrg
1190f29dbc25Smrg    /* ENABLE THE VIDEO PALETTE */
1191f29dbc25Smrg    /* Ensure that the video palette has an effect by routing video data */
1192f29dbc25Smrg    /* through the palette RAM and clearing the 'Bypass Both' bit.       */
1193f29dbc25Smrg
1194f29dbc25Smrg    dcfg = READ_VID32(RCDF_DISPLAY_CONFIG);
1195f29dbc25Smrg    misc = READ_VID32(RCDF_VID_MISC);
1196f29dbc25Smrg
1197f29dbc25Smrg    dcfg &= ~RCDF_DCFG_GV_PAL_BYP;
1198f29dbc25Smrg    misc &= ~RCDF_GAMMA_BYPASS_BOTH;
1199f29dbc25Smrg
1200f29dbc25Smrg    WRITE_VID32(RCDF_DISPLAY_CONFIG, dcfg);
1201f29dbc25Smrg    WRITE_VID32(RCDF_VID_MISC, misc);
1202f29dbc25Smrg
1203f29dbc25Smrg    /* SET A SINGLE ENTRY */
1204f29dbc25Smrg
1205f29dbc25Smrg    WRITE_VID32(RCDF_PALETTE_ADDRESS, index);
1206f29dbc25Smrg    WRITE_VID32(RCDF_PALETTE_DATA, palette);
1207f29dbc25Smrg
1208f29dbc25Smrg    return (0);
1209f29dbc25Smrg}
1210f29dbc25Smrg
1211f29dbc25Smrg/*---------------------------------------------------------------------------
1212f29dbc25Smrg * gfx_set_video_palette_entry
1213f29dbc25Smrg *
1214f29dbc25Smrg * This routine loads a single entry of the video hardware palette.
1215f29dbc25Smrg *---------------------------------------------------------------------------
1216f29dbc25Smrg */
1217f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
1218f29dbc25Smrgint
1219f29dbc25Smrgredcloud_set_video_palette_entry(unsigned long index, unsigned long palette)
1220f29dbc25Smrg#else
1221f29dbc25Smrgint
1222f29dbc25Smrggfx_set_video_palette_entry(unsigned long index, unsigned long palette)
1223f29dbc25Smrg#endif
1224f29dbc25Smrg{
1225f29dbc25Smrg    unsigned long dcfg, misc;
1226f29dbc25Smrg
1227f29dbc25Smrg    if (index > 0xFF)
1228f29dbc25Smrg        return GFX_STATUS_BAD_PARAMETER;
1229f29dbc25Smrg
1230f29dbc25Smrg    /* ENABLE THE VIDEO PALETTE */
1231f29dbc25Smrg    /* Ensure that the video palette has an effect by routing video data */
1232f29dbc25Smrg    /* through the palette RAM and clearing the 'Bypass Both' bit.       */
1233f29dbc25Smrg
1234f29dbc25Smrg    dcfg = READ_VID32(RCDF_DISPLAY_CONFIG);
1235f29dbc25Smrg    misc = READ_VID32(RCDF_VID_MISC);
1236f29dbc25Smrg
1237f29dbc25Smrg    dcfg |= RCDF_DCFG_GV_PAL_BYP;
1238f29dbc25Smrg    misc &= ~RCDF_GAMMA_BYPASS_BOTH;
1239f29dbc25Smrg
1240f29dbc25Smrg    WRITE_VID32(RCDF_DISPLAY_CONFIG, dcfg);
1241f29dbc25Smrg    WRITE_VID32(RCDF_VID_MISC, misc);
1242f29dbc25Smrg
1243f29dbc25Smrg    /* SET A SINGLE ENTRY */
1244f29dbc25Smrg
1245f29dbc25Smrg    WRITE_VID32(RCDF_PALETTE_ADDRESS, index);
1246f29dbc25Smrg    WRITE_VID32(RCDF_PALETTE_DATA, palette);
1247f29dbc25Smrg
1248f29dbc25Smrg    return (0);
1249f29dbc25Smrg}
1250f29dbc25Smrg
1251f29dbc25Smrg/*---------------------------------------------------------------------------
1252f29dbc25Smrg * gfx_set_video_palette_bypass
1253f29dbc25Smrg *
125479d5fcd7Smrg * This routine enables/disables the palette RAM bypass.
1255f29dbc25Smrg *---------------------------------------------------------------------------
1256f29dbc25Smrg */
1257f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
1258f29dbc25Smrgint
1259f29dbc25Smrgredcloud_set_video_palette_bypass(int enable)
1260f29dbc25Smrg#else
1261f29dbc25Smrgint
1262f29dbc25Smrggfx_set_video_palette_bypass(int enable)
1263f29dbc25Smrg#endif
1264f29dbc25Smrg{
1265f29dbc25Smrg    unsigned long misc;
1266f29dbc25Smrg
1267f29dbc25Smrg    misc = READ_VID32(RCDF_VID_MISC);
1268f29dbc25Smrg
1269f29dbc25Smrg    if (enable)
1270f29dbc25Smrg        misc |= RCDF_GAMMA_BYPASS_BOTH;
1271f29dbc25Smrg    else
1272f29dbc25Smrg        misc &= ~RCDF_GAMMA_BYPASS_BOTH;
1273f29dbc25Smrg
1274f29dbc25Smrg    WRITE_VID32(RCDF_VID_MISC, misc);
1275f29dbc25Smrg
1276f29dbc25Smrg    return 0;
1277f29dbc25Smrg}
1278f29dbc25Smrg
1279f29dbc25Smrg/*---------------------------------------------------------------------------
1280f29dbc25Smrg * gfx_set_video_request()
1281f29dbc25Smrg *
1282f29dbc25Smrg * This routine sets the horizontal (pixel) and vertical (line) video request
1283f29dbc25Smrg * values.
1284f29dbc25Smrg *---------------------------------------------------------------------------
1285f29dbc25Smrg */
1286f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
1287f29dbc25Smrgint
1288f29dbc25Smrgredcloud_set_video_request(short x, short y)
1289f29dbc25Smrg#else
1290f29dbc25Smrgint
1291f29dbc25Smrggfx_set_video_request(short x, short y)
1292f29dbc25Smrg#endif
1293f29dbc25Smrg{
1294f29dbc25Smrg    /* SET DISPLAY FILTER VIDEO REQUEST */
1295f29dbc25Smrg
1296f29dbc25Smrg    x += gfx_get_htotal() - gfx_get_hsync_end() - 2;
1297f29dbc25Smrg    y += gfx_get_vtotal() - gfx_get_vsync_end() + 1;
1298f29dbc25Smrg
1299f29dbc25Smrg    if ((x < 0) || (x > RCDF_VIDEO_REQUEST_MASK) ||
1300f29dbc25Smrg        (y < 0) || (y > RCDF_VIDEO_REQUEST_MASK))
1301f29dbc25Smrg        return GFX_STATUS_BAD_PARAMETER;
1302f29dbc25Smrg
1303f29dbc25Smrg    WRITE_VID32(RCDF_VIDEO_REQUEST,
130404007ebaSmrg                ((unsigned long) x << RCDF_VIDEO_X_REQUEST_POS) |
130504007ebaSmrg                ((unsigned long) y << RCDF_VIDEO_Y_REQUEST_POS));
1306f29dbc25Smrg    return (0);
1307f29dbc25Smrg}
1308f29dbc25Smrg
1309f29dbc25Smrg/*---------------------------------------------------------------------------
1310f29dbc25Smrg * gfx_set_video_cursor()
1311f29dbc25Smrg *
1312f29dbc25Smrg * This routine configures the video hardware cursor.
1313f29dbc25Smrg * If the "mask"ed bits in the graphics pixel match "key", then either
1314f29dbc25Smrg * "color1" or "color2" will be used for this pixel, according to the value of
1315f29dbc25Smrg * bit number "select_color2" of the graphics pixel.
1316f29dbc25Smrg *
1317f29dbc25Smrg * key - 24 bit RGB value
1318f29dbc25Smrg * mask - 24 bit mask
1319f29dbc25Smrg * color1, color2 - RGB or YUV, depending on the current color space
1320f29dbc25Smrg * conversion select_color2 - value between 0 to 23
1321f29dbc25Smrg *
1322f29dbc25Smrg * To disable match, a "mask" and "key" value of 0xffffff should be set,
1323f29dbc25Smrg * because the graphics pixels incoming to the video processor have maximum 16
1324f29dbc25Smrg * bits set (0xF8FCF8).
1325f29dbc25Smrg *
1326f29dbc25Smrg * This feature is useful for disabling alpha blending of the cursor.
1327f29dbc25Smrg * Otherwise cursor image would be blurred (or completely invisible if video
1328f29dbc25Smrg * alpha is maximum value).
1329f29dbc25Smrg * Note: the cursor pixel replacements take place both inside and outside the
1330f29dbc25Smrg * video overlay window.
1331f29dbc25Smrg *---------------------------------------------------------------------------
1332f29dbc25Smrg */
1333f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
1334f29dbc25Smrgint
1335f29dbc25Smrgredcloud_set_video_cursor(unsigned long key, unsigned long mask,
133604007ebaSmrg                          unsigned short select_color2, unsigned long color1,
133704007ebaSmrg                          unsigned long color2)
1338f29dbc25Smrg#else
1339f29dbc25Smrgint
1340f29dbc25Smrggfx_set_video_cursor(unsigned long key, unsigned long mask,
134104007ebaSmrg                     unsigned short select_color2, unsigned long color1,
134204007ebaSmrg                     unsigned long color2)
1343f29dbc25Smrg#endif
1344f29dbc25Smrg{
1345f29dbc25Smrg    if (select_color2 > RCDF_CURSOR_COLOR_BITS)
1346f29dbc25Smrg        return GFX_STATUS_BAD_PARAMETER;
1347f29dbc25Smrg    key =
134804007ebaSmrg        (key & RCDF_COLOR_MASK) | ((unsigned long) select_color2 <<
134904007ebaSmrg                                   RCDF_CURSOR_COLOR_KEY_OFFSET_POS);
1350f29dbc25Smrg    WRITE_VID32(RCDF_CURSOR_COLOR_KEY, key);
1351f29dbc25Smrg    WRITE_VID32(RCDF_CURSOR_COLOR_MASK, mask);
1352f29dbc25Smrg    WRITE_VID32(RCDF_CURSOR_COLOR_1, color1);
1353f29dbc25Smrg    WRITE_VID32(RCDF_CURSOR_COLOR_2, color2);
1354f29dbc25Smrg    return (0);
1355f29dbc25Smrg}
1356f29dbc25Smrg
1357f29dbc25Smrg/*---------------------------------------------------------------------------
1358f29dbc25Smrg * gfx_set_video_cursor()
1359f29dbc25Smrg *
1360f29dbc25Smrg * This routine configures the video hardware cursor.
1361f29dbc25Smrg * If the "mask"ed bits in the graphics pixel match "key", then either
1362f29dbc25Smrg * "color1"or "color2" will be used for this pixel, according to the value of
1363f29dbc25Smrg * bit number "select_color2" of the graphics pixel.
1364f29dbc25Smrg *
1365f29dbc25Smrg * key - 24 bit RGB value
1366f29dbc25Smrg * mask - 24 bit mask
1367f29dbc25Smrg * color1, color2 - RGB or YUV, depending on the current color space
1368f29dbc25Smrg * conversion select_color2 - value between 0 to 23
1369f29dbc25Smrg *
1370f29dbc25Smrg * To disable match, a "mask" and "key" value of 0xffffff should be set,
1371f29dbc25Smrg * because the graphics pixels incoming to the video processor have maximum 16
1372f29dbc25Smrg * bits set (0xF8FCF8).
1373f29dbc25Smrg *
1374f29dbc25Smrg * This feature is useful for disabling alpha blending of the cursor.
1375f29dbc25Smrg * Otherwise cursor image would be blurred (or completely invisible if video
1376f29dbc25Smrg * alpha is maximum value).
1377f29dbc25Smrg * Note: the cursor pixel replacements take place both inside and outside the
1378f29dbc25Smrg * video overlay window.
1379f29dbc25Smrg *---------------------------------------------------------------------------
1380f29dbc25Smrg */
1381f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
1382f29dbc25Smrgint
1383f29dbc25Smrgredcloud_set_video_cursor_enable(int enable)
1384f29dbc25Smrg#else
1385f29dbc25Smrgint
1386f29dbc25Smrggfx_set_video_cursor_enable(int enable)
1387f29dbc25Smrg#endif
1388f29dbc25Smrg{
1389f29dbc25Smrg    unsigned long temp = READ_VID32(RCDF_CURSOR_COLOR_KEY);
1390f29dbc25Smrg
1391f29dbc25Smrg    if (enable)
1392f29dbc25Smrg        temp |= RCDF_CURSOR_COLOR_KEY_ENABLE;
1393f29dbc25Smrg    else
1394f29dbc25Smrg        temp &= ~RCDF_CURSOR_COLOR_KEY_ENABLE;
1395f29dbc25Smrg
1396f29dbc25Smrg    WRITE_VID32(RCDF_CURSOR_COLOR_KEY, temp);
1397f29dbc25Smrg    return (0);
1398f29dbc25Smrg}
1399f29dbc25Smrg
1400f29dbc25Smrg/*---------------------------------------------------------------------------
1401f29dbc25Smrg * gfx_set_alpha_enable
1402f29dbc25Smrg *
1403f29dbc25Smrg * This routine enables or disables the currently selected alpha region.
1404f29dbc25Smrg *---------------------------------------------------------------------------
1405f29dbc25Smrg */
1406f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
1407f29dbc25Smrgint
1408f29dbc25Smrgredcloud_set_alpha_enable(int enable)
1409f29dbc25Smrg#else
1410f29dbc25Smrgint
1411f29dbc25Smrggfx_set_alpha_enable(int enable)
1412f29dbc25Smrg#endif
1413f29dbc25Smrg{
1414f29dbc25Smrg    unsigned long address = 0, value = 0;
1415f29dbc25Smrg
1416f29dbc25Smrg    if (gfx_alpha_select > 2)
1417f29dbc25Smrg        return (GFX_STATUS_UNSUPPORTED);
141804007ebaSmrg    address = RCDF_ALPHA_CONTROL_1 + ((unsigned long) gfx_alpha_select << 5);
1419f29dbc25Smrg    value = READ_VID32(address);
1420f29dbc25Smrg    if (enable)
1421f29dbc25Smrg        value |= RCDF_ACTRL_WIN_ENABLE;
1422f29dbc25Smrg    else
1423f29dbc25Smrg        value &= ~(RCDF_ACTRL_WIN_ENABLE);
1424f29dbc25Smrg    WRITE_VID32(address, value);
1425f29dbc25Smrg    return (GFX_STATUS_OK);
1426f29dbc25Smrg}
1427f29dbc25Smrg
1428f29dbc25Smrg/*---------------------------------------------------------------------------
1429f29dbc25Smrg * gfx_set_alpha_window
1430f29dbc25Smrg *
1431f29dbc25Smrg * This routine sets the size of the currently selected alpha region.
1432f29dbc25Smrg * Note: "x" and "y" are signed to enable using negative values needed for
1433f29dbc25Smrg * implementing workarounds of hardware issues.
1434f29dbc25Smrg *---------------------------------------------------------------------------
1435f29dbc25Smrg */
1436f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
1437f29dbc25Smrgint
1438f29dbc25Smrgredcloud_set_alpha_window(short x, short y,
143904007ebaSmrg                          unsigned short width, unsigned short height)
1440f29dbc25Smrg#else
1441f29dbc25Smrgint
1442f29dbc25Smrggfx_set_alpha_window(short x, short y,
144304007ebaSmrg                     unsigned short width, unsigned short height)
1444f29dbc25Smrg#endif
1445f29dbc25Smrg{
1446f29dbc25Smrg    unsigned long address = 0;
1447f29dbc25Smrg
1448f29dbc25Smrg    /* CHECK FOR CLIPPING */
1449f29dbc25Smrg
1450f29dbc25Smrg    if ((x + width) > gfx_get_hactive())
1451f29dbc25Smrg        width = gfx_get_hactive() - x;
1452f29dbc25Smrg    if ((y + height) > gfx_get_vactive())
1453f29dbc25Smrg        height = gfx_get_vactive() - y;
1454f29dbc25Smrg
1455f29dbc25Smrg    /* ADJUST POSITIONS */
1456f29dbc25Smrg
1457f29dbc25Smrg    x += gfx_get_htotal() - gfx_get_hsync_end() - 2;
1458f29dbc25Smrg    y += gfx_get_vtotal() - gfx_get_vsync_end() + 1;
1459f29dbc25Smrg
1460f29dbc25Smrg    if (gfx_alpha_select > 2)
1461f29dbc25Smrg        return (GFX_STATUS_UNSUPPORTED);
146204007ebaSmrg    address = RCDF_ALPHA_XPOS_1 + ((unsigned long) gfx_alpha_select << 5);
1463f29dbc25Smrg
1464f29dbc25Smrg    /* END POSITIONS IN REGISTERS ARE NON-INCLUSIVE (ONE MORE THAN ACTUAL END)
1465f29dbc25Smrg     * */
1466f29dbc25Smrg
146704007ebaSmrg    WRITE_VID32(address, (unsigned long) x |
146804007ebaSmrg                ((unsigned long) (x + width) << 16));
146904007ebaSmrg    WRITE_VID32(address + 8, (unsigned long) y |
147004007ebaSmrg                ((unsigned long) (y + height) << 16));
1471f29dbc25Smrg    return (GFX_STATUS_OK);
1472f29dbc25Smrg}
1473f29dbc25Smrg
1474f29dbc25Smrg/*---------------------------------------------------------------------------
1475f29dbc25Smrg * gfx_set_alpha_value
1476f29dbc25Smrg *
1477f29dbc25Smrg * This routine sets the alpha value for the currently selected alpha
1478f29dbc25Smrg * region.  It also specifies an increment/decrement value for fading.
1479f29dbc25Smrg *---------------------------------------------------------------------------
1480f29dbc25Smrg */
1481f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
1482f29dbc25Smrgint
1483f29dbc25Smrgredcloud_set_alpha_value(unsigned char alpha, char delta)
1484f29dbc25Smrg#else
1485f29dbc25Smrgint
1486f29dbc25Smrggfx_set_alpha_value(unsigned char alpha, char delta)
1487f29dbc25Smrg#endif
1488f29dbc25Smrg{
1489f29dbc25Smrg    unsigned long address = 0, value = 0;
1490f29dbc25Smrg
1491f29dbc25Smrg    if (gfx_alpha_select > 2)
1492f29dbc25Smrg        return (GFX_STATUS_UNSUPPORTED);
149304007ebaSmrg    address = RCDF_ALPHA_CONTROL_1 + ((unsigned long) gfx_alpha_select << 5);
1494f29dbc25Smrg    value = READ_VID32(address);
149504007ebaSmrg    value &= RCDF_ACTRL_WIN_ENABLE;     /* keep only enable bit */
149604007ebaSmrg    value |= (unsigned long) alpha;
149704007ebaSmrg    value |= (((unsigned long) delta) & 0xff) << 8;
1498f29dbc25Smrg    value |= RCDF_ACTRL_LOAD_ALPHA;
1499f29dbc25Smrg    WRITE_VID32(address, value);
1500f29dbc25Smrg    return (GFX_STATUS_OK);
1501f29dbc25Smrg}
1502f29dbc25Smrg
1503f29dbc25Smrg/*---------------------------------------------------------------------------
1504f29dbc25Smrg * gfx_set_alpha_priority
1505f29dbc25Smrg *
1506f29dbc25Smrg * This routine sets the priority of the currently selected alpha region.
1507f29dbc25Smrg * A higher value indicates a higher priority.
1508f29dbc25Smrg * Note: Priority of enabled alpha windows must be different.
1509f29dbc25Smrg *---------------------------------------------------------------------------
1510f29dbc25Smrg */
1511f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
1512f29dbc25Smrgint
1513f29dbc25Smrgredcloud_set_alpha_priority(int priority)
1514f29dbc25Smrg#else
1515f29dbc25Smrgint
1516f29dbc25Smrggfx_set_alpha_priority(int priority)
1517f29dbc25Smrg#endif
1518f29dbc25Smrg{
1519f29dbc25Smrg    unsigned long pos = 0, value = 0;
1520f29dbc25Smrg
1521f29dbc25Smrg    if (priority > 3)
1522f29dbc25Smrg        return (GFX_STATUS_BAD_PARAMETER);
1523f29dbc25Smrg    if (gfx_alpha_select > 2)
1524f29dbc25Smrg        return (GFX_STATUS_UNSUPPORTED);
1525f29dbc25Smrg    value = READ_VID32(RCDF_VID_ALPHA_CONTROL);
1526f29dbc25Smrg    pos = 16 + (gfx_alpha_select << 1);
1527f29dbc25Smrg    value &= ~(0x03l << pos);
152804007ebaSmrg    value |= (unsigned long) priority << pos;
1529f29dbc25Smrg    WRITE_VID32(RCDF_VID_ALPHA_CONTROL, value);
1530f29dbc25Smrg    return (GFX_STATUS_OK);
1531f29dbc25Smrg}
1532f29dbc25Smrg
1533f29dbc25Smrg/*---------------------------------------------------------------------------
1534f29dbc25Smrg * gfx_set_alpha_color
1535f29dbc25Smrg *
1536f29dbc25Smrg * This routine sets the color to be displayed inside the currently selected
1537f29dbc25Smrg * alpha window when there is a color key match (when the alpha color
1538f29dbc25Smrg * mechanism is enabled).
1539f29dbc25Smrg * "color" is an RGB value (for RGB blending) or a YUV value (for YUV
1540f29dbc25Smrg * blending).
1541f29dbc25Smrg * In Interlaced YUV blending mode, Y/2 value should be used.
1542f29dbc25Smrg *---------------------------------------------------------------------------
1543f29dbc25Smrg */
1544f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
1545f29dbc25Smrgint
1546f29dbc25Smrgredcloud_set_alpha_color(unsigned long color)
1547f29dbc25Smrg#else
1548f29dbc25Smrgint
1549f29dbc25Smrggfx_set_alpha_color(unsigned long color)
1550f29dbc25Smrg#endif
1551f29dbc25Smrg{
1552f29dbc25Smrg    unsigned long address = 0;
1553f29dbc25Smrg
1554f29dbc25Smrg    if (gfx_alpha_select > 2)
1555f29dbc25Smrg        return (GFX_STATUS_UNSUPPORTED);
155604007ebaSmrg    address = RCDF_ALPHA_COLOR_1 + ((unsigned long) gfx_alpha_select << 5);
1557f29dbc25Smrg    WRITE_VID32(address, color);
1558f29dbc25Smrg    return (GFX_STATUS_OK);
1559f29dbc25Smrg}
1560f29dbc25Smrg
1561f29dbc25Smrg/*---------------------------------------------------------------------------
1562f29dbc25Smrg * gfx_set_alpha_color_enable
1563f29dbc25Smrg *
1564f29dbc25Smrg * Enable or disable the color mechanism in the alpha window.
1565f29dbc25Smrg *---------------------------------------------------------------------------
1566f29dbc25Smrg */
1567f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
1568f29dbc25Smrgint
1569f29dbc25Smrgredcloud_set_alpha_color_enable(int enable)
1570f29dbc25Smrg#else
1571f29dbc25Smrgint
1572f29dbc25Smrggfx_set_alpha_color_enable(int enable)
1573f29dbc25Smrg#endif
1574f29dbc25Smrg{
1575f29dbc25Smrg    unsigned long color;
1576f29dbc25Smrg    unsigned long address = 0;
1577f29dbc25Smrg
1578f29dbc25Smrg    if (gfx_alpha_select > 2)
1579f29dbc25Smrg        return (GFX_STATUS_UNSUPPORTED);
158004007ebaSmrg    address = RCDF_ALPHA_COLOR_1 + ((unsigned long) gfx_alpha_select << 5);
1581f29dbc25Smrg    color = READ_VID32(address);
1582f29dbc25Smrg    if (enable)
1583f29dbc25Smrg        color |= RCDF_ALPHA_COLOR_ENABLE;
1584f29dbc25Smrg    else
1585f29dbc25Smrg        color &= ~RCDF_ALPHA_COLOR_ENABLE;
1586f29dbc25Smrg    WRITE_VID32(address, color);
1587f29dbc25Smrg    return (GFX_STATUS_OK);
1588f29dbc25Smrg}
1589f29dbc25Smrg
1590f29dbc25Smrg/*---------------------------------------------------------------------------
1591f29dbc25Smrg * gfx_set_no_ck_outside_alpha
1592f29dbc25Smrg *
1593f29dbc25Smrg * This function affects where inside the video window color key or chroma
1594f29dbc25Smrg * key comparison is done:
1595f29dbc25Smrg * If enable is TRUE, color/chroma key comparison is performed only inside
1596f29dbc25Smrg * the enabled alpha windows. Outside the (enabled) alpha windows, only video
1597f29dbc25Smrg * is displayed if color key is used, and only graphics is displayed if chroma
1598f29dbc25Smrg * key is used.
1599f29dbc25Smrg * If enable is FALSE, color/chroma key comparison is performed in all the
1600f29dbc25Smrg * video window area.
1601f29dbc25Smrg *---------------------------------------------------------------------------
1602f29dbc25Smrg */
1603f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
1604f29dbc25Smrgint
1605f29dbc25Smrgredcloud_set_no_ck_outside_alpha(int enable)
1606f29dbc25Smrg#else
1607f29dbc25Smrgint
1608f29dbc25Smrggfx_set_no_ck_outside_alpha(int enable)
1609f29dbc25Smrg#endif
1610f29dbc25Smrg{
1611f29dbc25Smrg    unsigned long value;
1612f29dbc25Smrg
1613f29dbc25Smrg    value = READ_VID32(RCDF_VID_ALPHA_CONTROL);
1614f29dbc25Smrg    if (enable)
1615f29dbc25Smrg        WRITE_VID32(RCDF_VID_ALPHA_CONTROL, value | RCDF_NO_CK_OUTSIDE_ALPHA);
1616f29dbc25Smrg    else
161704007ebaSmrg        WRITE_VID32(RCDF_VID_ALPHA_CONTROL, value & ~RCDF_NO_CK_OUTSIDE_ALPHA);
1618f29dbc25Smrg    return (0);
1619f29dbc25Smrg}
1620f29dbc25Smrg
1621f29dbc25Smrg/*---------------------------------------------------------------------------
1622f29dbc25Smrg * gfx_get_clock_frequency
1623f29dbc25Smrg *
1624f29dbc25Smrg * This routine returns the current clock frequency in 16.16 format.
1625f29dbc25Smrg * It reads the current register value and finds the match in the table.
1626f29dbc25Smrg * If no match is found, this routine returns 0.
1627f29dbc25Smrg *---------------------------------------------------------------------------
1628f29dbc25Smrg */
1629f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
1630f29dbc25Smrgunsigned long
1631f29dbc25Smrgredcloud_get_clock_frequency(void)
1632f29dbc25Smrg#else
1633f29dbc25Smrgunsigned long
1634f29dbc25Smrggfx_get_clock_frequency(void)
1635f29dbc25Smrg#endif
1636f29dbc25Smrg{
1637f29dbc25Smrg    Q_WORD msr_value;
1638f29dbc25Smrg    unsigned int index;
1639f29dbc25Smrg    unsigned long value, mask = 0x00001FFF;
1640f29dbc25Smrg    unsigned long post_div3 = 0, pre_mult2 = 0;
1641f29dbc25Smrg
1642f29dbc25Smrg    /* READ PLL SETTING */
1643f29dbc25Smrg
1644f29dbc25Smrg    gfx_msr_read(RC_ID_MCP, MCP_DOTPLL, &msr_value);
1645f29dbc25Smrg    value = msr_value.high & mask;
1646f29dbc25Smrg
1647f29dbc25Smrg    /* READ DIVISOR SETTINGS */
1648f29dbc25Smrg
1649f29dbc25Smrg    gfx_msr_read(RC_ID_MCP, MCP_SYS_RSTPLL, &msr_value);
1650f29dbc25Smrg    post_div3 = (msr_value.low & MCP_DOTPOSTDIV3) ? 1 : 0;
1651f29dbc25Smrg    pre_mult2 = (msr_value.low & MCP_DOTPREMULT2) ? 1 : 0;
1652f29dbc25Smrg
1653f29dbc25Smrg    /* SEARCH FOR A MATCH */
1654f29dbc25Smrg
1655f29dbc25Smrg    for (index = 0; index < NUM_RCDF_FREQUENCIES; index++) {
1656f29dbc25Smrg        if ((RCDF_PLLtable[index].pll_value & mask) == value &&
1657f29dbc25Smrg            post_div3 == RCDF_PLLtable[index].post_div3 &&
1658f29dbc25Smrg            pre_mult2 == RCDF_PLLtable[index].pre_mul2)
1659f29dbc25Smrg            return (RCDF_PLLtable[index].frequency);
1660f29dbc25Smrg    }
1661f29dbc25Smrg    return (0);
1662f29dbc25Smrg}
1663f29dbc25Smrg
1664f29dbc25Smrg/*************************************************************/
1665f29dbc25Smrg/*  READ ROUTINES  |  INCLUDED FOR DIAGNOSTIC PURPOSES ONLY  */
1666f29dbc25Smrg/*************************************************************/
1667f29dbc25Smrg
1668f29dbc25Smrg#if GFX_READ_ROUTINES
1669f29dbc25Smrg
1670f29dbc25Smrg/*---------------------------------------------------------------------------
1671f29dbc25Smrg * gfx_get_sync_polarities
1672f29dbc25Smrg *
1673f29dbc25Smrg * This routine returns the polarities of the sync pulses:
1674f29dbc25Smrg *     Bit 0: Set if negative horizontal polarity.
1675f29dbc25Smrg *     Bit 1: Set if negative vertical polarity.
1676f29dbc25Smrg *---------------------------------------------------------------------------
1677f29dbc25Smrg */
1678f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
1679f29dbc25Smrgint
1680f29dbc25Smrgredcloud_get_sync_polarities(void)
1681f29dbc25Smrg#else
1682f29dbc25Smrgint
1683f29dbc25Smrggfx_get_sync_polarities(void)
1684f29dbc25Smrg#endif
1685f29dbc25Smrg{
1686f29dbc25Smrg    int polarities = 0;
1687f29dbc25Smrg
1688f29dbc25Smrg    if (READ_VID32(RCDF_DISPLAY_CONFIG) & RCDF_DCFG_CRT_HSYNC_POL)
1689f29dbc25Smrg        polarities |= 1;
1690f29dbc25Smrg    if (READ_VID32(RCDF_DISPLAY_CONFIG) & RCDF_DCFG_CRT_VSYNC_POL)
1691f29dbc25Smrg        polarities |= 2;
1692f29dbc25Smrg    return (polarities);
1693f29dbc25Smrg}
1694f29dbc25Smrg
1695f29dbc25Smrg/*---------------------------------------------------------------------------
1696f29dbc25Smrg * gfx_get_video_palette_entry
1697f29dbc25Smrg *
1698f29dbc25Smrg * This routine returns a single palette entry.
1699f29dbc25Smrg *---------------------------------------------------------------------------
1700f29dbc25Smrg */
1701f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
1702f29dbc25Smrgint
1703f29dbc25Smrgredcloud_get_video_palette_entry(unsigned long index, unsigned long *palette)
1704f29dbc25Smrg#else
1705f29dbc25Smrgint
1706f29dbc25Smrggfx_get_video_palette_entry(unsigned long index, unsigned long *palette)
1707f29dbc25Smrg#endif
1708f29dbc25Smrg{
1709f29dbc25Smrg    if (index > 0xFF)
1710f29dbc25Smrg        return GFX_STATUS_BAD_PARAMETER;
1711f29dbc25Smrg
1712f29dbc25Smrg    /* READ A SINGLE ENTRY */
1713f29dbc25Smrg
1714f29dbc25Smrg    WRITE_VID32(RCDF_PALETTE_ADDRESS, index);
1715f29dbc25Smrg    *palette = READ_VID32(RCDF_PALETTE_DATA);
1716f29dbc25Smrg
1717f29dbc25Smrg    return (GFX_STATUS_OK);
1718f29dbc25Smrg}
1719f29dbc25Smrg
1720f29dbc25Smrg/*----------------------------------------------------------------------------
1721f29dbc25Smrg * gfx_get_video_enable
1722f29dbc25Smrg *
1723f29dbc25Smrg * This routine returns the value "one" if video overlay is currently enabled,
1724f29dbc25Smrg * otherwise it returns the value "zero".
1725f29dbc25Smrg *----------------------------------------------------------------------------
1726f29dbc25Smrg */
1727f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
1728f29dbc25Smrgint
1729f29dbc25Smrgredcloud_get_video_enable(void)
1730f29dbc25Smrg#else
1731f29dbc25Smrgint
1732f29dbc25Smrggfx_get_video_enable(void)
1733f29dbc25Smrg#endif
1734f29dbc25Smrg{
1735f29dbc25Smrg    if (READ_VID32(RCDF_VIDEO_CONFIG) & RCDF_VCFG_VID_EN)
1736f29dbc25Smrg        return (1);
1737f29dbc25Smrg    return (0);
1738f29dbc25Smrg}
1739f29dbc25Smrg
1740f29dbc25Smrg/*----------------------------------------------------------------------------
1741f29dbc25Smrg * gfx_get_video_format
1742f29dbc25Smrg *
1743f29dbc25Smrg * This routine returns the current video overlay format.
1744f29dbc25Smrg *----------------------------------------------------------------------------
1745f29dbc25Smrg */
1746f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
1747f29dbc25Smrgint
1748f29dbc25Smrgredcloud_get_video_format(void)
1749f29dbc25Smrg#else
1750f29dbc25Smrgint
1751f29dbc25Smrggfx_get_video_format(void)
1752f29dbc25Smrg#endif
1753f29dbc25Smrg{
1754f29dbc25Smrg    unsigned long ctrl, vcfg;
1755f29dbc25Smrg
1756f29dbc25Smrg    ctrl = READ_VID32(RCDF_VID_ALPHA_CONTROL);
1757f29dbc25Smrg    vcfg = READ_VID32(RCDF_VIDEO_CONFIG);
1758f29dbc25Smrg
1759f29dbc25Smrg    if (ctrl & RCDF_VIDEO_INPUT_IS_RGB) {
1760f29dbc25Smrg        switch (vcfg & RCDF_VCFG_VID_INP_FORMAT) {
1761f29dbc25Smrg        case RCDF_VCFG_UYVY_FORMAT:
1762f29dbc25Smrg            return VIDEO_FORMAT_RGB;
1763f29dbc25Smrg        case RCDF_VCFG_Y2YU_FORMAT:
1764f29dbc25Smrg            return VIDEO_FORMAT_P2M_P2L_P1M_P1L;
1765f29dbc25Smrg        case RCDF_VCFG_YUYV_FORMAT:
1766f29dbc25Smrg            return VIDEO_FORMAT_P1M_P1L_P2M_P2L;
1767f29dbc25Smrg        case RCDF_VCFG_YVYU_FORMAT:
1768f29dbc25Smrg            return VIDEO_FORMAT_P1M_P2L_P2M_P1L;
1769f29dbc25Smrg        }
1770f29dbc25Smrg    }
1771f29dbc25Smrg
1772f29dbc25Smrg    if (vcfg & RCDF_VCFG_4_2_0_MODE) {
1773f29dbc25Smrg        switch (vcfg & RCDF_VCFG_VID_INP_FORMAT) {
1774f29dbc25Smrg        case RCDF_VCFG_UYVY_FORMAT:
1775f29dbc25Smrg            return VIDEO_FORMAT_Y0Y1Y2Y3;
1776f29dbc25Smrg        case RCDF_VCFG_Y2YU_FORMAT:
1777f29dbc25Smrg            return VIDEO_FORMAT_Y3Y2Y1Y0;
1778f29dbc25Smrg        case RCDF_VCFG_YUYV_FORMAT:
1779f29dbc25Smrg            return VIDEO_FORMAT_Y1Y0Y3Y2;
1780f29dbc25Smrg        case RCDF_VCFG_YVYU_FORMAT:
1781f29dbc25Smrg            return VIDEO_FORMAT_Y1Y2Y3Y0;
1782f29dbc25Smrg        }
178304007ebaSmrg    }
178404007ebaSmrg    else {
1785f29dbc25Smrg        switch (vcfg & RCDF_VCFG_VID_INP_FORMAT) {
1786f29dbc25Smrg        case RCDF_VCFG_UYVY_FORMAT:
1787f29dbc25Smrg            return VIDEO_FORMAT_UYVY;
1788f29dbc25Smrg        case RCDF_VCFG_Y2YU_FORMAT:
1789f29dbc25Smrg            return VIDEO_FORMAT_Y2YU;
1790f29dbc25Smrg        case RCDF_VCFG_YUYV_FORMAT:
1791f29dbc25Smrg            return VIDEO_FORMAT_YUYV;
1792f29dbc25Smrg        case RCDF_VCFG_YVYU_FORMAT:
1793f29dbc25Smrg            return VIDEO_FORMAT_YVYU;
1794f29dbc25Smrg        }
1795f29dbc25Smrg    }
1796f29dbc25Smrg    return (GFX_STATUS_ERROR);
1797f29dbc25Smrg}
1798f29dbc25Smrg
1799f29dbc25Smrg/*----------------------------------------------------------------------------
1800f29dbc25Smrg * gfx_get_video_src_size
1801f29dbc25Smrg *
1802f29dbc25Smrg * This routine returns the size of the source video overlay buffer.  The
1803f29dbc25Smrg * return value is (height << 16) | width.
1804f29dbc25Smrg *----------------------------------------------------------------------------
1805f29dbc25Smrg */
1806f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
1807f29dbc25Smrgunsigned long
1808f29dbc25Smrgredcloud_get_video_src_size(void)
1809f29dbc25Smrg#else
1810f29dbc25Smrgunsigned long
1811f29dbc25Smrggfx_get_video_src_size(void)
1812f29dbc25Smrg#endif
1813f29dbc25Smrg{
1814f29dbc25Smrg    unsigned long width, height, scale, delta;
1815f29dbc25Smrg    int down_enable;
1816f29dbc25Smrg
1817f29dbc25Smrg    /* DETERMINE SOURCE WIDTH FROM THE DISPLAY FILTER VIDEO LINE SIZE */
1818f29dbc25Smrg
1819f29dbc25Smrg    width = (READ_VID32(RCDF_VIDEO_CONFIG) >> 7) & 0x000001FE;
1820f29dbc25Smrg    if (READ_VID32(RCDF_VIDEO_CONFIG) & RCDF_VCFG_LINE_SIZE_UPPER)
1821f29dbc25Smrg        width += 512l;
1822f29dbc25Smrg
1823f29dbc25Smrg    /* DETERMINE SOURCE HEIGHT FROM THE DISPLAY FILTER HEIGHT AND SCALE VALUES
1824f29dbc25Smrg     * There is no true "source buffer size" in Redcloud.  Instead, the VG
1825f29dbc25Smrg     * module provides video data as needed on a per-line basis.  The source
1826f29dbc25Smrg     * buffer size is always assumed to equal the amount of required video
1827f29dbc25Smrg     * data. The returned height is equal to the height of the required video
1828f29dbc25Smrg     * buffer data (before all scaling.)
1829f29dbc25Smrg     * */
1830f29dbc25Smrg
1831f29dbc25Smrg    scale = (READ_VID32(RCDF_VIDEO_SCALE) >> 16) & 0x3FFF;
1832f29dbc25Smrg    height = ((READ_VID32(RCDF_VIDEO_Y_POS) >> 16) & 0x7FF) -
1833f29dbc25Smrg        (READ_VID32(RCDF_VIDEO_Y_POS) & 0x7FF);
1834f29dbc25Smrg    delta = gfx_get_video_downscale_delta();
1835f29dbc25Smrg    down_enable = gfx_get_video_vertical_downscale_enable();
1836f29dbc25Smrg
1837f29dbc25Smrg    /* REVERSE UPSCALING */
1838f29dbc25Smrg
1839f29dbc25Smrg    if (height)
1840f29dbc25Smrg        height = ((scale * (height - 1l)) / 0x2000l) + 2l;
1841f29dbc25Smrg
1842f29dbc25Smrg    /* REVERSE DOWNSCALING */
1843f29dbc25Smrg    /* Original lines = height * (0x3FFF + delta) / 0x3FFF */
1844f29dbc25Smrg    /* As this may cause rounding errors, we add 1 to the  */
1845f29dbc25Smrg    /* returned source size.  The return value of this     */
1846f29dbc25Smrg    /* function could thus be off by 1.                    */
1847f29dbc25Smrg
1848f29dbc25Smrg    if (down_enable && height)
1849f29dbc25Smrg        height = ((height * (0x3FFFl + delta)) / 0x3FFFl) + 1;
1850f29dbc25Smrg
1851f29dbc25Smrg    return ((height << 16) | width);
1852f29dbc25Smrg}
1853f29dbc25Smrg
1854f29dbc25Smrg/*----------------------------------------------------------------------------
1855f29dbc25Smrg * gfx_get_video_line_size
1856f29dbc25Smrg *
1857f29dbc25Smrg * This routine returns the line size of the source video overlay buffer, in
1858f29dbc25Smrg * pixels.
1859f29dbc25Smrg *----------------------------------------------------------------------------
1860f29dbc25Smrg */
1861f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
1862f29dbc25Smrgunsigned long
1863f29dbc25Smrgredcloud_get_video_line_size(void)
1864f29dbc25Smrg#else
1865f29dbc25Smrgunsigned long
1866f29dbc25Smrggfx_get_video_line_size(void)
1867f29dbc25Smrg#endif
1868f29dbc25Smrg{
1869f29dbc25Smrg    unsigned long width = 0;
1870f29dbc25Smrg
1871f29dbc25Smrg    /* DETERMINE SOURCE WIDTH FROM THE RCDF VIDEO LINE SIZE */
1872f29dbc25Smrg
1873f29dbc25Smrg    width = (READ_VID32(RCDF_VIDEO_CONFIG) >> 7) & 0x000001FE;
1874f29dbc25Smrg    if (READ_VID32(RCDF_VIDEO_CONFIG) & RCDF_VCFG_LINE_SIZE_UPPER)
1875f29dbc25Smrg        width += 512l;
1876f29dbc25Smrg    return (width);
1877f29dbc25Smrg}
1878f29dbc25Smrg
1879f29dbc25Smrg/*----------------------------------------------------------------------------
1880f29dbc25Smrg * gfx_get_video_xclip
1881f29dbc25Smrg *
1882f29dbc25Smrg * This routine returns the number of bytes clipped on the left side of a
1883f29dbc25Smrg * video overlay line (skipped at beginning).
1884f29dbc25Smrg *----------------------------------------------------------------------------
1885f29dbc25Smrg */
1886f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
1887f29dbc25Smrgunsigned long
1888f29dbc25Smrgredcloud_get_video_xclip(void)
1889f29dbc25Smrg#else
1890f29dbc25Smrgunsigned long
1891f29dbc25Smrggfx_get_video_xclip(void)
1892f29dbc25Smrg#endif
1893f29dbc25Smrg{
1894f29dbc25Smrg    unsigned long clip = 0;
1895f29dbc25Smrg
1896f29dbc25Smrg    /* DETERMINE SOURCE WIDTH FROM THE RCDF VIDEO LINE SIZE */
1897f29dbc25Smrg
1898f29dbc25Smrg    clip = (READ_VID32(RCDF_VIDEO_CONFIG) >> 14) & 0x000007FC;
1899f29dbc25Smrg    return (clip);
1900f29dbc25Smrg}
1901f29dbc25Smrg
1902f29dbc25Smrg/*----------------------------------------------------------------------------
1903f29dbc25Smrg * gfx_get_video_offset
1904f29dbc25Smrg *
1905f29dbc25Smrg * This routine returns the current offset for the video overlay buffer.
1906f29dbc25Smrg *----------------------------------------------------------------------------
1907f29dbc25Smrg */
1908f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
1909f29dbc25Smrgunsigned long
1910f29dbc25Smrgredcloud_get_video_offset(void)
1911f29dbc25Smrg#else
1912f29dbc25Smrgunsigned long
1913f29dbc25Smrggfx_get_video_offset(void)
1914f29dbc25Smrg#endif
1915f29dbc25Smrg{
1916f29dbc25Smrg    return (gfx_get_display_video_offset());
1917f29dbc25Smrg}
1918f29dbc25Smrg
1919f29dbc25Smrg/*----------------------------------------------------------------------------
1920f29dbc25Smrg * gfx_get_video_yuv_offsets
1921f29dbc25Smrg *
1922f29dbc25Smrg * This routine returns the current offsets for the video overlay buffer when in 4:2:0.
1923f29dbc25Smrg *----------------------------------------------------------------------------
1924f29dbc25Smrg */
1925f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
1926f29dbc25Smrgvoid
1927f29dbc25Smrgredcloud_get_video_yuv_offsets(unsigned long *yoffset, unsigned long *uoffset,
192804007ebaSmrg                               unsigned long *voffset)
1929f29dbc25Smrg#else
1930f29dbc25Smrgvoid
1931f29dbc25Smrggfx_get_video_yuv_offsets(unsigned long *yoffset, unsigned long *uoffset,
193204007ebaSmrg                          unsigned long *voffset)
1933f29dbc25Smrg#endif
1934f29dbc25Smrg{
1935f29dbc25Smrg    gfx_get_display_video_yuv_offsets(yoffset, uoffset, voffset);
1936f29dbc25Smrg}
1937f29dbc25Smrg
1938f29dbc25Smrg/*----------------------------------------------------------------------------
1939f29dbc25Smrg * gfx_get_video_yuv_pitch
1940f29dbc25Smrg *
1941f29dbc25Smrg * This routine returns the current pitch values for the video overlay buffer.
1942f29dbc25Smrg *----------------------------------------------------------------------------
1943f29dbc25Smrg */
1944f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
1945f29dbc25Smrgvoid
1946f29dbc25Smrgredcloud_get_video_yuv_pitch(unsigned long *ypitch, unsigned long *uvpitch)
1947f29dbc25Smrg#else
1948f29dbc25Smrgvoid
1949f29dbc25Smrggfx_get_video_yuv_pitch(unsigned long *ypitch, unsigned long *uvpitch)
1950f29dbc25Smrg#endif
1951f29dbc25Smrg{
1952f29dbc25Smrg    gfx_get_display_video_yuv_pitch(ypitch, uvpitch);
1953f29dbc25Smrg}
1954f29dbc25Smrg
1955f29dbc25Smrg/*---------------------------------------------------------------------------
1956f29dbc25Smrg * gfx_get_video_scale
1957f29dbc25Smrg *
1958f29dbc25Smrg * This routine returns the scale factor for the video overlay window.
1959f29dbc25Smrg *---------------------------------------------------------------------------
1960f29dbc25Smrg */
1961f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
1962f29dbc25Smrgunsigned long
1963f29dbc25Smrgredcloud_get_video_scale(void)
1964f29dbc25Smrg#else
1965f29dbc25Smrgunsigned long
1966f29dbc25Smrggfx_get_video_scale(void)
1967f29dbc25Smrg#endif
1968f29dbc25Smrg{
1969f29dbc25Smrg    return (READ_VID32(RCDF_VIDEO_SCALE));
1970f29dbc25Smrg}
1971f29dbc25Smrg
1972f29dbc25Smrg/*---------------------------------------------------------------------------
1973f29dbc25Smrg * gfx_get_video_downscale_delta
1974f29dbc25Smrg *
1975f29dbc25Smrg * This routine returns the vertical downscale factor for the video overlay
1976f29dbc25Smrg * window.
1977f29dbc25Smrg *---------------------------------------------------------------------------
1978f29dbc25Smrg */
1979f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
1980f29dbc25Smrgunsigned long
1981f29dbc25Smrgredcloud_get_video_downscale_delta(void)
1982f29dbc25Smrg#else
1983f29dbc25Smrgunsigned long
1984f29dbc25Smrggfx_get_video_downscale_delta(void)
1985f29dbc25Smrg#endif
1986f29dbc25Smrg{
1987f29dbc25Smrg    /* USE PRIVATE ROUTINE TO ABSTRACT THE DIPSLAY CONTROLLER */
1988f29dbc25Smrg
1989f29dbc25Smrg    return (gfx_get_display_video_downscale_delta());
1990f29dbc25Smrg}
1991f29dbc25Smrg
1992f29dbc25Smrg/*---------------------------------------------------------------------------
1993f29dbc25Smrg * gfx_get_video_vertical_downscale_enable
1994f29dbc25Smrg *
1995f29dbc25Smrg * This routine returns the vertical downscale enable for the video overlay
1996f29dbc25Smrg * window.
1997f29dbc25Smrg *---------------------------------------------------------------------------
1998f29dbc25Smrg */
1999f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
2000f29dbc25Smrgint
2001f29dbc25Smrgredcloud_get_video_vertical_downscale_enable(void)
2002f29dbc25Smrg#else
2003f29dbc25Smrgint
2004f29dbc25Smrggfx_get_video_vertical_downscale_enable(void)
2005f29dbc25Smrg#endif
2006f29dbc25Smrg{
2007f29dbc25Smrg    /* USE PRIVATE ROUTINE TO ABSTRACT THE DIPSLAY CONTROLLER */
2008f29dbc25Smrg
2009f29dbc25Smrg    return (gfx_get_display_video_downscale_enable());
2010f29dbc25Smrg}
2011f29dbc25Smrg
2012f29dbc25Smrg/*---------------------------------------------------------------------------
2013f29dbc25Smrg * gfx_get_video_downscale_config
2014f29dbc25Smrg *
2015f29dbc25Smrg * This routine returns the current type and value of video downscaling.
2016f29dbc25Smrg *---------------------------------------------------------------------------
2017f29dbc25Smrg */
2018f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
2019f29dbc25Smrgint
2020f29dbc25Smrgredcloud_get_video_downscale_config(unsigned short *type, unsigned short *m)
2021f29dbc25Smrg#else
2022f29dbc25Smrgint
2023f29dbc25Smrggfx_get_video_downscale_config(unsigned short *type, unsigned short *m)
2024f29dbc25Smrg#endif
2025f29dbc25Smrg{
2026f29dbc25Smrg    unsigned long downscale;
2027f29dbc25Smrg
2028f29dbc25Smrg    downscale = READ_VID32(RCDF_VIDEO_DOWNSCALER_CONTROL);
202904007ebaSmrg    *m = (unsigned short) ((downscale & RCDF_VIDEO_DOWNSCALE_FACTOR_MASK) >>
203004007ebaSmrg                           RCDF_VIDEO_DOWNSCALE_FACTOR_POS) + 1;
2031f29dbc25Smrg
2032f29dbc25Smrg    switch (downscale & RCDF_VIDEO_DOWNSCALE_TYPE_MASK) {
2033f29dbc25Smrg    case RCDF_VIDEO_DOWNSCALE_TYPE_A:
2034f29dbc25Smrg        *type = VIDEO_DOWNSCALE_KEEP_1_OF;
2035f29dbc25Smrg        break;
2036f29dbc25Smrg    case RCDF_VIDEO_DOWNSCALE_TYPE_B:
2037f29dbc25Smrg        *type = VIDEO_DOWNSCALE_DROP_1_OF;
2038f29dbc25Smrg        break;
2039f29dbc25Smrg    default:
2040f29dbc25Smrg        return GFX_STATUS_ERROR;
2041f29dbc25Smrg        break;
2042f29dbc25Smrg    }
2043f29dbc25Smrg    return (0);
2044f29dbc25Smrg}
2045f29dbc25Smrg
2046f29dbc25Smrg/*---------------------------------------------------------------------------
2047f29dbc25Smrg * gfx_get_video_downscale_coefficients
2048f29dbc25Smrg *
2049f29dbc25Smrg * This routine returns the current video downscaling coefficients.
2050f29dbc25Smrg *---------------------------------------------------------------------------
2051f29dbc25Smrg */
2052f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
2053f29dbc25Smrgvoid
2054f29dbc25Smrgredcloud_get_video_downscale_coefficients(unsigned short *coef1,
205504007ebaSmrg                                          unsigned short *coef2,
205604007ebaSmrg                                          unsigned short *coef3,
205704007ebaSmrg                                          unsigned short *coef4)
2058f29dbc25Smrg#else
2059f29dbc25Smrgvoid
2060f29dbc25Smrggfx_get_video_downscale_coefficients(unsigned short *coef1,
206104007ebaSmrg                                     unsigned short *coef2,
206204007ebaSmrg                                     unsigned short *coef3,
206304007ebaSmrg                                     unsigned short *coef4)
2064f29dbc25Smrg#endif
2065f29dbc25Smrg{
2066f29dbc25Smrg    unsigned long coef;
2067f29dbc25Smrg
2068f29dbc25Smrg    coef = READ_VID32(RCDF_VIDEO_DOWNSCALER_COEFFICIENTS);
2069f29dbc25Smrg    *coef1 =
207004007ebaSmrg        (unsigned short) ((coef >> RCDF_VIDEO_DOWNSCALER_COEF1_POS) &
207104007ebaSmrg                          RCDF_VIDEO_DOWNSCALER_COEF_MASK);
2072f29dbc25Smrg    *coef2 =
207304007ebaSmrg        (unsigned short) ((coef >> RCDF_VIDEO_DOWNSCALER_COEF2_POS) &
207404007ebaSmrg                          RCDF_VIDEO_DOWNSCALER_COEF_MASK);
2075f29dbc25Smrg    *coef3 =
207604007ebaSmrg        (unsigned short) ((coef >> RCDF_VIDEO_DOWNSCALER_COEF3_POS) &
207704007ebaSmrg                          RCDF_VIDEO_DOWNSCALER_COEF_MASK);
2078f29dbc25Smrg    *coef4 =
207904007ebaSmrg        (unsigned short) ((coef >> RCDF_VIDEO_DOWNSCALER_COEF4_POS) &
208004007ebaSmrg                          RCDF_VIDEO_DOWNSCALER_COEF_MASK);
2081f29dbc25Smrg    return;
2082f29dbc25Smrg}
2083f29dbc25Smrg
2084f29dbc25Smrg/*---------------------------------------------------------------------------
2085f29dbc25Smrg * gfx_get_video_downscale_enable
2086f29dbc25Smrg *
2087f29dbc25Smrg * This routine returns 1 if video downscaling is currently enabled,
2088f29dbc25Smrg * or 0 if it is currently disabled.
2089f29dbc25Smrg *---------------------------------------------------------------------------
2090f29dbc25Smrg */
2091f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
2092f29dbc25Smrgvoid
2093f29dbc25Smrgredcloud_get_video_downscale_enable(int *enable)
2094f29dbc25Smrg#else
2095f29dbc25Smrgvoid
2096f29dbc25Smrggfx_get_video_downscale_enable(int *enable)
2097f29dbc25Smrg#endif
2098f29dbc25Smrg{
209904007ebaSmrg    if (READ_VID32(RCDF_VIDEO_DOWNSCALER_CONTROL) & RCDF_VIDEO_DOWNSCALE_ENABLE)
2100f29dbc25Smrg        *enable = 1;
2101f29dbc25Smrg    else
2102f29dbc25Smrg        *enable = 0;
2103f29dbc25Smrg    return;
2104f29dbc25Smrg}
2105f29dbc25Smrg
2106f29dbc25Smrg/*---------------------------------------------------------------------------
2107f29dbc25Smrg * gfx_get_video_dst_size
2108f29dbc25Smrg *
2109f29dbc25Smrg * This routine returns the size of the displayed video overlay window.
2110f29dbc25Smrg *---------------------------------------------------------------------------
2111f29dbc25Smrg */
2112f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
2113f29dbc25Smrgunsigned long
2114f29dbc25Smrgredcloud_get_video_dst_size(void)
2115f29dbc25Smrg#else
2116f29dbc25Smrgunsigned long
2117f29dbc25Smrggfx_get_video_dst_size(void)
2118f29dbc25Smrg#endif
2119f29dbc25Smrg{
2120f29dbc25Smrg    unsigned long xsize, ysize;
2121f29dbc25Smrg
2122f29dbc25Smrg    xsize = READ_VID32(RCDF_VIDEO_X_POS);
2123f29dbc25Smrg    xsize = ((xsize >> 16) & 0x7FF) - (xsize & 0x7FF);
2124f29dbc25Smrg    ysize = READ_VID32(RCDF_VIDEO_Y_POS);
2125f29dbc25Smrg    ysize = ((ysize >> 16) & 0x7FF) - (ysize & 0x7FF);
2126f29dbc25Smrg    return ((ysize << 16) | xsize);
2127f29dbc25Smrg}
2128f29dbc25Smrg
2129f29dbc25Smrg/*---------------------------------------------------------------------------
2130f29dbc25Smrg * gfx_get_video_position
2131f29dbc25Smrg *
2132f29dbc25Smrg * This routine returns the position of the video overlay window.  The
2133f29dbc25Smrg * return value is (ypos << 16) | xpos.
2134f29dbc25Smrg *---------------------------------------------------------------------------
2135f29dbc25Smrg */
2136f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
2137f29dbc25Smrgunsigned long
2138f29dbc25Smrgredcloud_get_video_position(void)
2139f29dbc25Smrg#else
2140f29dbc25Smrgunsigned long
2141f29dbc25Smrggfx_get_video_position(void)
2142f29dbc25Smrg#endif
2143f29dbc25Smrg{
2144f29dbc25Smrg    unsigned long hadjust, vadjust;
2145f29dbc25Smrg    unsigned long xpos, ypos;
2146f29dbc25Smrg
2147f29dbc25Smrg    /* READ HARDWARE POSITION */
2148f29dbc25Smrg
2149f29dbc25Smrg    xpos = READ_VID32(RCDF_VIDEO_X_POS) & 0x000007FF;
2150f29dbc25Smrg    ypos = READ_VID32(RCDF_VIDEO_Y_POS) & 0x000007FF;
2151f29dbc25Smrg
2152f29dbc25Smrg    /* GET ADJUSTMENT VALUES */
2153f29dbc25Smrg    /* Use routines to abstract version of display controller. */
2154f29dbc25Smrg
2155f29dbc25Smrg    hadjust =
215604007ebaSmrg        (unsigned long) gfx_get_htotal() - (unsigned long) gfx_get_hsync_end() -
2157f29dbc25Smrg        14l;
2158f29dbc25Smrg    vadjust =
215904007ebaSmrg        (unsigned long) gfx_get_vtotal() - (unsigned long) gfx_get_vsync_end() +
2160f29dbc25Smrg        1l;
2161f29dbc25Smrg    xpos -= hadjust;
2162f29dbc25Smrg    ypos -= vadjust;
2163f29dbc25Smrg    return ((ypos << 16) | (xpos & 0x0000FFFF));
2164f29dbc25Smrg}
2165f29dbc25Smrg
2166f29dbc25Smrg/*---------------------------------------------------------------------------
2167f29dbc25Smrg * gfx_get_video_color_key
2168f29dbc25Smrg *
2169f29dbc25Smrg * This routine returns the current video color key value.
2170f29dbc25Smrg *---------------------------------------------------------------------------
2171f29dbc25Smrg */
2172f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
2173f29dbc25Smrgunsigned long
2174f29dbc25Smrgredcloud_get_video_color_key(void)
2175f29dbc25Smrg#else
2176f29dbc25Smrgunsigned long
2177f29dbc25Smrggfx_get_video_color_key(void)
2178f29dbc25Smrg#endif
2179f29dbc25Smrg{
2180f29dbc25Smrg    return (READ_VID32(RCDF_VIDEO_COLOR_KEY));
2181f29dbc25Smrg}
2182f29dbc25Smrg
2183f29dbc25Smrg/*---------------------------------------------------------------------------
2184f29dbc25Smrg * gfx_get_video_color_key_mask
2185f29dbc25Smrg *
2186f29dbc25Smrg * This routine returns the current video color mask value.
2187f29dbc25Smrg *---------------------------------------------------------------------------
2188f29dbc25Smrg */
2189f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
2190f29dbc25Smrgunsigned long
2191f29dbc25Smrgredcloud_get_video_color_key_mask(void)
2192f29dbc25Smrg#else
2193f29dbc25Smrgunsigned long
2194f29dbc25Smrggfx_get_video_color_key_mask(void)
2195f29dbc25Smrg#endif
2196f29dbc25Smrg{
2197f29dbc25Smrg    return (READ_VID32(RCDF_VIDEO_COLOR_MASK));
2198f29dbc25Smrg}
2199f29dbc25Smrg
2200f29dbc25Smrg/*---------------------------------------------------------------------------
2201f29dbc25Smrg * gfx_get_video_color_key_src
2202f29dbc25Smrg *
2203f29dbc25Smrg * This routine returns 0 for video data compare, 1 for graphics data.
2204f29dbc25Smrg *---------------------------------------------------------------------------
2205f29dbc25Smrg */
2206f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
2207f29dbc25Smrgint
2208f29dbc25Smrgredcloud_get_video_color_key_src(void)
2209f29dbc25Smrg#else
2210f29dbc25Smrgint
2211f29dbc25Smrggfx_get_video_color_key_src(void)
2212f29dbc25Smrg#endif
2213f29dbc25Smrg{
2214f29dbc25Smrg    if (READ_VID32(RCDF_DISPLAY_CONFIG) & RCDF_DCFG_VG_CK)
2215f29dbc25Smrg        return (0);
2216f29dbc25Smrg    return (1);
2217f29dbc25Smrg}
2218f29dbc25Smrg
2219f29dbc25Smrg/*---------------------------------------------------------------------------
2220f29dbc25Smrg * gfx_get_video_filter
2221f29dbc25Smrg *
2222f29dbc25Smrg * This routine returns if the filters are currently enabled.
2223f29dbc25Smrg *---------------------------------------------------------------------------
2224f29dbc25Smrg */
2225f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
2226f29dbc25Smrgint
2227f29dbc25Smrgredcloud_get_video_filter(void)
2228f29dbc25Smrg#else
2229f29dbc25Smrgint
2230f29dbc25Smrggfx_get_video_filter(void)
2231f29dbc25Smrg#endif
2232f29dbc25Smrg{
2233f29dbc25Smrg    int retval = 0;
2234f29dbc25Smrg
2235f29dbc25Smrg    if (READ_VID32(RCDF_VIDEO_CONFIG) & RCDF_VCFG_X_FILTER_EN)
2236f29dbc25Smrg        retval |= 1;
2237f29dbc25Smrg    if (READ_VID32(RCDF_VIDEO_CONFIG) & RCDF_VCFG_Y_FILTER_EN)
2238f29dbc25Smrg        retval |= 2;
2239f29dbc25Smrg    return (retval);
2240f29dbc25Smrg}
2241f29dbc25Smrg
2242f29dbc25Smrg/*---------------------------------------------------------------------------
2243f29dbc25Smrg * gfx_get_video_request
2244f29dbc25Smrg *
2245f29dbc25Smrg * This routine returns the horizontal (pixel) and vertical (lines) video
2246f29dbc25Smrg * request values.
2247f29dbc25Smrg *---------------------------------------------------------------------------
2248f29dbc25Smrg */
2249f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
2250f29dbc25Smrgint
2251f29dbc25Smrgredcloud_get_video_request(short *x, short *y)
2252f29dbc25Smrg#else
2253f29dbc25Smrgint
2254f29dbc25Smrggfx_get_video_request(short *x, short *y)
2255f29dbc25Smrg#endif
2256f29dbc25Smrg{
2257f29dbc25Smrg    unsigned long request = 0;
2258f29dbc25Smrg
2259f29dbc25Smrg    request = (READ_VID32(RCDF_VIDEO_REQUEST));
226004007ebaSmrg    *x = (short) ((request >> RCDF_VIDEO_X_REQUEST_POS) &
226104007ebaSmrg                  RCDF_VIDEO_REQUEST_MASK);
226204007ebaSmrg    *y = (short) ((request >> RCDF_VIDEO_Y_REQUEST_POS) &
226304007ebaSmrg                  RCDF_VIDEO_REQUEST_MASK);
2264f29dbc25Smrg
2265f29dbc25Smrg    *x -= gfx_get_htotal() - gfx_get_hsync_end() - 2;
2266f29dbc25Smrg    *y -= gfx_get_vtotal() - gfx_get_vsync_end() + 1;
2267f29dbc25Smrg
2268f29dbc25Smrg    return (0);
2269f29dbc25Smrg}
2270f29dbc25Smrg
2271f29dbc25Smrg/*---------------------------------------------------------------------------
2272f29dbc25Smrg * gfx_get_video_cursor()
2273f29dbc25Smrg *
2274f29dbc25Smrg * This routine configures the video hardware cursor.
2275f29dbc25Smrg * If the "mask"ed bits in the graphics pixel match "key", then either
2276f29dbc25Smrg * "color1" or "color2" will be used for this pixel, according to the value of
2277f29dbc25Smrg * the bit in offset "select_color2".
2278f29dbc25Smrg *---------------------------------------------------------------------------
2279f29dbc25Smrg */
2280f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
2281f29dbc25Smrgint
2282f29dbc25Smrgredcloud_get_video_cursor(unsigned long *key, unsigned long *mask,
228304007ebaSmrg                          unsigned short *select_color2, unsigned long *color1,
228404007ebaSmrg                          unsigned short *color2)
2285f29dbc25Smrg#else
2286f29dbc25Smrgint
2287f29dbc25Smrggfx_get_video_cursor(unsigned long *key, unsigned long *mask,
228804007ebaSmrg                     unsigned short *select_color2, unsigned long *color1,
228904007ebaSmrg                     unsigned short *color2)
2290f29dbc25Smrg#endif
2291f29dbc25Smrg{
2292f29dbc25Smrg    *select_color2 =
229304007ebaSmrg        (unsigned short) (READ_VID32(RCDF_CURSOR_COLOR_KEY) >>
229404007ebaSmrg                          RCDF_CURSOR_COLOR_KEY_OFFSET_POS);
2295f29dbc25Smrg    *key = READ_VID32(RCDF_CURSOR_COLOR_KEY) & RCDF_COLOR_MASK;
2296f29dbc25Smrg    *mask = READ_VID32(RCDF_CURSOR_COLOR_MASK) & RCDF_COLOR_MASK;
2297f29dbc25Smrg    *color1 = READ_VID32(RCDF_CURSOR_COLOR_1) & RCDF_COLOR_MASK;
2298f29dbc25Smrg    *color2 =
229904007ebaSmrg        (unsigned short) (READ_VID32(RCDF_CURSOR_COLOR_2) & RCDF_COLOR_MASK);
2300f29dbc25Smrg    return (0);
2301f29dbc25Smrg}
2302f29dbc25Smrg
2303f29dbc25Smrg/*---------------------------------------------------------------------------
2304f29dbc25Smrg * gfx_read_crc
2305f29dbc25Smrg *
2306f29dbc25Smrg * This routine returns the hardware CRC value, which is used for automated
2307f29dbc25Smrg * testing.  The value is like a checksum, but will change if pixels move
2308f29dbc25Smrg * locations.
2309f29dbc25Smrg *---------------------------------------------------------------------------
2310f29dbc25Smrg */
2311f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
2312f29dbc25Smrgunsigned long
2313f29dbc25Smrgredcloud_read_crc(void)
2314f29dbc25Smrg#else
2315f29dbc25Smrgunsigned long
2316f29dbc25Smrggfx_read_crc(void)
2317f29dbc25Smrg#endif
2318f29dbc25Smrg{
2319f29dbc25Smrg    Q_WORD msr_value;
2320f29dbc25Smrg    unsigned long crc = 0xFFFFFFFF;
2321f29dbc25Smrg
2322f29dbc25Smrg    /* DISABLE 32-BIT CRCS */
2323f29dbc25Smrg    /* For GX1.x, this is a reserved bit, and is assumed to be a benign
2324f29dbc25Smrg     * access */
2325f29dbc25Smrg
2326f29dbc25Smrg    gfx_msr_read(RC_ID_DF, RCDF_MBD_MSR_DIAG_DF, &msr_value);
2327f29dbc25Smrg    msr_value.low &= ~RCDF_DIAG_32BIT_CRC;
2328f29dbc25Smrg    gfx_msr_write(RC_ID_DF, RCDF_MBD_MSR_DIAG_DF, &msr_value);
2329f29dbc25Smrg
2330f29dbc25Smrg    if (gfx_test_timing_active()) {
2331f29dbc25Smrg        /* WAIT UNTIL ACTIVE DISPLAY */
2332f29dbc25Smrg
233304007ebaSmrg        while (!gfx_test_vertical_active());
2334f29dbc25Smrg
2335f29dbc25Smrg        /* RESET CRC DURING ACTIVE DISPLAY */
2336f29dbc25Smrg
2337f29dbc25Smrg        WRITE_VID32(RCDF_VID_CRC, 0);
2338f29dbc25Smrg        WRITE_VID32(RCDF_VID_CRC, 1);
2339f29dbc25Smrg
2340f29dbc25Smrg        /* WAIT UNTIL NOT ACTIVE, THEN ACTIVE, NOT ACTIVE, THEN ACTIVE */
2341f29dbc25Smrg
234204007ebaSmrg        while (!gfx_test_vertical_active());
234304007ebaSmrg        while (gfx_test_vertical_active());
234404007ebaSmrg        while (!gfx_test_vertical_active());
234504007ebaSmrg        while (gfx_test_vertical_active());
234604007ebaSmrg        while (!gfx_test_vertical_active());
2347f29dbc25Smrg        crc = READ_VID32(RCDF_VID_CRC) >> 8;
2348f29dbc25Smrg    }
2349f29dbc25Smrg    return (crc);
2350f29dbc25Smrg}
2351f29dbc25Smrg
2352f29dbc25Smrg/*---------------------------------------------------------------------------
2353f29dbc25Smrg * gfx_read_crc32
2354f29dbc25Smrg *
2355f29dbc25Smrg * This routine returns the 32-bit hardware CRC value, which is used for
2356f29dbc25Smrg * automated testing.  The value is like a checksum, but will change if pixels
2357f29dbc25Smrg * move locations.
2358f29dbc25Smrg *---------------------------------------------------------------------------
2359f29dbc25Smrg */
2360f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
2361f29dbc25Smrgunsigned long
2362f29dbc25Smrgredcloud_read_crc32(void)
2363f29dbc25Smrg#else
2364f29dbc25Smrgunsigned long
2365f29dbc25Smrggfx_read_crc32(void)
2366f29dbc25Smrg#endif
2367f29dbc25Smrg{
2368f29dbc25Smrg    Q_WORD msr_value;
2369f29dbc25Smrg    unsigned long crc = 0xFFFFFFFF;
2370f29dbc25Smrg
2371f29dbc25Smrg    /* ENABLE 32-BIT CRCS */
2372f29dbc25Smrg    /* For GX1.x, this is a reserved bit, and is assumed to be a benign
2373f29dbc25Smrg     * access */
2374f29dbc25Smrg
2375f29dbc25Smrg    gfx_msr_read(RC_ID_DF, RCDF_MBD_MSR_DIAG_DF, &msr_value);
2376f29dbc25Smrg    msr_value.low |= RCDF_DIAG_32BIT_CRC;
2377f29dbc25Smrg    gfx_msr_write(RC_ID_DF, RCDF_MBD_MSR_DIAG_DF, &msr_value);
2378f29dbc25Smrg
2379f29dbc25Smrg    if (gfx_test_timing_active()) {
2380f29dbc25Smrg        /* WAIT UNTIL ACTIVE DISPLAY */
2381f29dbc25Smrg
238204007ebaSmrg        while (!gfx_test_vertical_active());
2383f29dbc25Smrg
2384f29dbc25Smrg        /* RESET CRC DURING ACTIVE DISPLAY */
2385f29dbc25Smrg
2386f29dbc25Smrg        WRITE_VID32(RCDF_VID_CRC, 0);
2387f29dbc25Smrg        WRITE_VID32(RCDF_VID_CRC, 1);
2388f29dbc25Smrg
2389f29dbc25Smrg        /* WAIT UNTIL NOT ACTIVE, THEN ACTIVE, NOT ACTIVE, THEN ACTIVE */
2390f29dbc25Smrg
239104007ebaSmrg        while (!gfx_test_vertical_active());
239204007ebaSmrg        while (gfx_test_vertical_active());
239304007ebaSmrg        while (!gfx_test_vertical_active());
239404007ebaSmrg        while (gfx_test_vertical_active());
239504007ebaSmrg        while (!gfx_test_vertical_active());
2396f29dbc25Smrg        crc = READ_VID32(RCDF_VID_CRC32);
2397f29dbc25Smrg    }
2398f29dbc25Smrg    return (crc);
2399f29dbc25Smrg}
2400f29dbc25Smrg
2401f29dbc25Smrg/*---------------------------------------------------------------------------
2402f29dbc25Smrg * gfx_read_window_crc
2403f29dbc25Smrg *
2404f29dbc25Smrg * This routine returns the hardware CRC value for a subsection of the display
2405f29dbc25Smrg * This value is used to debug whole-screen CRC failures.
2406f29dbc25Smrg *---------------------------------------------------------------------------
2407f29dbc25Smrg */
2408f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
2409f29dbc25Smrgunsigned long
2410f29dbc25Smrgredcloud_read_window_crc(int source, unsigned short x, unsigned short y,
241104007ebaSmrg                         unsigned short width, unsigned short height, int crc32)
2412f29dbc25Smrg#else
2413f29dbc25Smrgunsigned long
2414f29dbc25Smrggfx_read_window_crc(int source, unsigned short x, unsigned short y,
241504007ebaSmrg                    unsigned short width, unsigned short height, int crc32)
2416f29dbc25Smrg#endif
2417f29dbc25Smrg{
2418f29dbc25Smrg    Q_WORD msr_value;
2419f29dbc25Smrg    unsigned long xpos, ypos, crc = 0;
2420f29dbc25Smrg    unsigned long old_fmt = 0;
2421f29dbc25Smrg    unsigned int vsync_active_base, vsync_inactive_base, hsync_active_base;
2422f29dbc25Smrg    unsigned int vsync_active_shift, vsync_inactive_shift, hsync_active_shift;
2423f29dbc25Smrg    unsigned int vsync_bit, hsync_bit, sync_polarities = 0;
2424f29dbc25Smrg
2425f29dbc25Smrg    /* CONFIGURE DISPLAY FILTER TO LOAD DATA ONTO LOWER 32-BITS */
2426f29dbc25Smrg
2427f29dbc25Smrg    msr_value.high = 0;
2428f29dbc25Smrg    msr_value.low =
2429f29dbc25Smrg        (source == CRC_SOURCE_GFX_DATA) ? (RCDF_MBD_DIAG_EN0 | 0x0000000F)
2430f29dbc25Smrg        : (RCDF_MBD_DIAG_EN0 | 0x0000000B);
2431f29dbc25Smrg    gfx_msr_write(RC_ID_DF, MBD_MSR_DIAG, &msr_value);
2432f29dbc25Smrg
2433f29dbc25Smrg    /* CONFIGURE DISPLAY FILTER FOR APPROPRIATE OUTPUT */
2434f29dbc25Smrg
2435f29dbc25Smrg    if (source != CRC_SOURCE_GFX_DATA) {
2436f29dbc25Smrg        gfx_msr_read(RC_ID_DF, MBD_MSR_CONFIG, &msr_value);
2437f29dbc25Smrg        old_fmt = msr_value.low;
2438f29dbc25Smrg        msr_value.low &= ~(RCDF_CONFIG_FMT_MASK);
2439f29dbc25Smrg        msr_value.low |=
2440f29dbc25Smrg            ((source ==
244104007ebaSmrg              CRC_SOURCE_FP_DATA) ? RCDF_CONFIG_FMT_FP : RCDF_CONFIG_FMT_CRT);
2442f29dbc25Smrg        gfx_msr_write(RC_ID_DF, MBD_MSR_CONFIG, &msr_value);
2443f29dbc25Smrg    }
2444f29dbc25Smrg
2445f29dbc25Smrg    /* CONFIGURE MCP TO LOAD REGB DATA ONTO UPPER 32-BITS */
2446f29dbc25Smrg
2447f29dbc25Smrg    msr_value.low = MCP_MBD_DIAG_EN1 | 0x00050000;
2448f29dbc25Smrg    gfx_msr_write(RC_ID_MCP, MBD_MSR_DIAG, &msr_value);
2449f29dbc25Smrg
2450f29dbc25Smrg    /* ENABLE HW CLOCK GATING AND SET MCP CLOCK TO DOT CLOCK */
2451f29dbc25Smrg
2452f29dbc25Smrg    msr_value.low = 1l;
2453f29dbc25Smrg    gfx_msr_write(RC_ID_MCP, MBD_MSR_PM, &msr_value);
2454f29dbc25Smrg    msr_value.low = 0;
2455f29dbc25Smrg    gfx_msr_write(RC_ID_MCP, MCP_DBGCLKCTL, &msr_value);
2456f29dbc25Smrg    msr_value.low = 3;
2457f29dbc25Smrg    gfx_msr_write(RC_ID_MCP, MCP_DBGCLKCTL, &msr_value);
2458f29dbc25Smrg
2459f29dbc25Smrg    /* DISABLE MCP ACTIONS */
2460f29dbc25Smrg
2461f29dbc25Smrg    msr_value.high = 0x00000000;
2462f29dbc25Smrg    msr_value.low = 0x00000000;
2463f29dbc25Smrg    gfx_msr_write(RC_ID_MCP, MCP_DIAGCTL, &msr_value);
2464f29dbc25Smrg
2465f29dbc25Smrg    /* SET APPROPRIATE BASE ADDRESS */
2466f29dbc25Smrg    /* M-Sets use normal diag bits, while N-Sets use inverted diag bits */
2467f29dbc25Smrg    /* We thus use the M-sets when polling for a high signal and the N  */
2468f29dbc25Smrg    /* sets when polling for a low signal.                              */
2469f29dbc25Smrg
2470f29dbc25Smrg    if (source != CRC_SOURCE_GFX_DATA) {
2471f29dbc25Smrg        sync_polarities = gfx_get_sync_polarities();
2472f29dbc25Smrg        vsync_bit = 29;
2473f29dbc25Smrg        hsync_bit = 30;
247404007ebaSmrg    }
247504007ebaSmrg    else {
2476f29dbc25Smrg        vsync_bit = 25;
2477f29dbc25Smrg        hsync_bit = 26;
2478f29dbc25Smrg    }
2479f29dbc25Smrg
2480f29dbc25Smrg    if (sync_polarities & 1) {
2481f29dbc25Smrg        hsync_active_base = MCP_SETM0CTL;
2482f29dbc25Smrg        hsync_active_shift = 2;
248304007ebaSmrg    }
248404007ebaSmrg    else {
2485f29dbc25Smrg        hsync_active_base = MCP_SETN0CTL;
2486f29dbc25Smrg        hsync_active_shift = 1;
2487f29dbc25Smrg    }
2488f29dbc25Smrg    if (sync_polarities & 2) {
2489f29dbc25Smrg        vsync_active_base = MCP_SETM0CTL;
2490f29dbc25Smrg        vsync_inactive_base = MCP_SETN0CTL;
2491f29dbc25Smrg        vsync_active_shift = 2;
2492f29dbc25Smrg        vsync_inactive_shift = 1;
249304007ebaSmrg    }
249404007ebaSmrg    else {
2495f29dbc25Smrg        vsync_active_base = MCP_SETN0CTL;
2496f29dbc25Smrg        vsync_inactive_base = MCP_SETM0CTL;
2497f29dbc25Smrg        vsync_active_shift = 1;
2498f29dbc25Smrg        vsync_inactive_shift = 2;
2499f29dbc25Smrg    }
2500f29dbc25Smrg
2501f29dbc25Smrg    /* SET STATE TRANSITIONS          */
2502f29dbc25Smrg
2503f29dbc25Smrg    /* STATE 0-1 TRANSITION (SET 0)      */
2504f29dbc25Smrg    /* XState = 00 and VSync Inactive    */
2505f29dbc25Smrg    /* Note: DF VSync = Diag Bus Bit 29  */
2506f29dbc25Smrg    /*       VG VSync = Diag Bus Bit 25  */
2507f29dbc25Smrg
2508f29dbc25Smrg    msr_value.low = 0x000000A0;
250904007ebaSmrg    msr_value.high = 0x00008000 | ((unsigned long) vsync_bit << 16) |
251004007ebaSmrg        ((unsigned long) vsync_bit << 21) | ((unsigned long) vsync_bit << 26);
2511f29dbc25Smrg    gfx_msr_write(RC_ID_MCP, vsync_inactive_base, &msr_value);
2512f29dbc25Smrg
2513f29dbc25Smrg    /* STATE 1-2 TRANSITION (SET 4)   */
2514f29dbc25Smrg    /* XState = 01 and VSync Active   */
2515f29dbc25Smrg
2516f29dbc25Smrg    msr_value.low = 0x000000C0;
2517f29dbc25Smrg    gfx_msr_write(RC_ID_MCP, vsync_active_base + 4, &msr_value);
2518f29dbc25Smrg
2519f29dbc25Smrg    /* STATE 2-3 TRANSITION (SET 1)   */
2520f29dbc25Smrg    /* XState = 10 and VSync Inactive */
2521f29dbc25Smrg
2522f29dbc25Smrg    msr_value.low = 0x00000120;
2523f29dbc25Smrg    gfx_msr_write(RC_ID_MCP, vsync_inactive_base + 1, &msr_value);
2524f29dbc25Smrg
2525f29dbc25Smrg    /* HORIZONTAL COUNTER (SET 5)         */
2526f29dbc25Smrg    /* XState = 10 and HSync Active       */
2527f29dbc25Smrg    /* Notes: DF HSync = Diag Bus Bit 30  */
2528f29dbc25Smrg    /*        VG HSync = Diag Bus Bit 26  */
2529f29dbc25Smrg
253004007ebaSmrg    msr_value.high = 0x00008000 | ((unsigned long) hsync_bit << 16) |
253104007ebaSmrg        ((unsigned long) hsync_bit << 21) | ((unsigned long) hsync_bit << 26);
2532f29dbc25Smrg    msr_value.low = 0x00000120;
2533f29dbc25Smrg    gfx_msr_write(RC_ID_MCP, hsync_active_base + 5, &msr_value);
2534f29dbc25Smrg
2535f29dbc25Smrg    /* HORIZONTAL COUNTER RESET (SET 4)     */
2536f29dbc25Smrg    /* XState = 10 and H. Counter = limit   */
2537f29dbc25Smrg    /* Note: H. Counter is lower 16-bits of */
2538f29dbc25Smrg    /*       RegB.                          */
2539f29dbc25Smrg
2540f29dbc25Smrg    msr_value.high = 0x00000000;
2541f29dbc25Smrg    msr_value.low = 0x00000128;
2542f29dbc25Smrg    gfx_msr_write(RC_ID_MCP, vsync_inactive_base + 4, &msr_value);
2543f29dbc25Smrg
2544f29dbc25Smrg    /* CRC TRIGGER (SET 0)   */
2545f29dbc25Smrg    /* Cmp0 <= xpos <  Cmp1  */
2546f29dbc25Smrg    /* Cmp2 <= ypos <  Cmp2  */
2547f29dbc25Smrg
2548f29dbc25Smrg    msr_value.high = 0x00000000;
2549f29dbc25Smrg    msr_value.low = 0x10C20120;
2550f29dbc25Smrg    gfx_msr_write(RC_ID_MCP, vsync_active_base, &msr_value);
2551f29dbc25Smrg
2552f29dbc25Smrg    /* SET COMPARATOR VALUES */
2553f29dbc25Smrg    /* Note: The VG data outputs from the DF are delayed by one pixel clock. */
2554f29dbc25Smrg    /*       In this mode, we thus add one to horizontal comparator limits. */
2555f29dbc25Smrg
2556f29dbc25Smrg    /* COMPARATOR 0                                        */
2557f29dbc25Smrg    /* Lower limit = xpos + (h_blank_pixels - 1) - 3       */
2558f29dbc25Smrg    /* Notes:                                              */
2559f29dbc25Smrg    /*   1. 3 is the pipeline delay for MCP register       */
2560f29dbc25Smrg    /*      data to access the diag bus                    */
2561f29dbc25Smrg    /*   2. h_blank_pixels = HTOTAL - HSYNC_END            */
2562f29dbc25Smrg
256304007ebaSmrg    xpos = (unsigned long) x + ((unsigned long) gfx_get_htotal() -
256404007ebaSmrg                                (unsigned long) gfx_get_hsync_end() - 1l) - 3l;
2565f29dbc25Smrg    if (source == CRC_SOURCE_GFX_DATA)
2566f29dbc25Smrg        xpos++;
2567f29dbc25Smrg    msr_value.high = 0x00000000;
2568f29dbc25Smrg    msr_value.low = xpos;
2569f29dbc25Smrg    gfx_msr_write(RC_ID_MCP, MCP_CMPVAL0, &msr_value);
2570f29dbc25Smrg
2571f29dbc25Smrg    /* COMPARATOR 1                                          */
2572f29dbc25Smrg    /* Upper limit = xpos + width + (h_blank_pixels - 1) - 3 */
2573f29dbc25Smrg
257404007ebaSmrg    msr_value.low = xpos + (unsigned long) width;
2575f29dbc25Smrg    gfx_msr_write(RC_ID_MCP, MCP_CMPVAL0 + 2, &msr_value);
2576f29dbc25Smrg
2577f29dbc25Smrg    /* COMPARATOR 2                                  */
2578f29dbc25Smrg    /* Lower limit = ypos + v_blank_pixels           */
2579f29dbc25Smrg    /* Notes:                                        */
2580f29dbc25Smrg    /*   1. v_blank_pixels = VTOTAL - VSYNC_END      */
2581f29dbc25Smrg
2582f29dbc25Smrg    ypos =
258304007ebaSmrg        (unsigned long) y + (unsigned long) gfx_get_vtotal() -
258404007ebaSmrg        (unsigned long) gfx_get_vsync_end();
2585f29dbc25Smrg    msr_value.low = ypos << 16;
2586f29dbc25Smrg    gfx_msr_write(RC_ID_MCP, MCP_CMPVAL0 + 4, &msr_value);
2587f29dbc25Smrg
2588f29dbc25Smrg    /* COMPARATOR 3                                  */
2589f29dbc25Smrg    /* Upper limit = ypos + height + v_blank_pixels  */
2590f29dbc25Smrg
259104007ebaSmrg    msr_value.low = (ypos + (unsigned long) height) << 16;
2592f29dbc25Smrg    gfx_msr_write(RC_ID_MCP, MCP_CMPVAL0 + 6, &msr_value);
2593f29dbc25Smrg
2594f29dbc25Smrg    /* SET COMPARATOR MASKS */
2595f29dbc25Smrg
2596f29dbc25Smrg    /* COMPARATORS 0 AND 1 REFER TO LOWER 16 BITS OF REGB */
2597f29dbc25Smrg
2598f29dbc25Smrg    msr_value.high = 0x00000000;
2599f29dbc25Smrg    msr_value.low = 0x0000FFFF;
2600f29dbc25Smrg    gfx_msr_write(RC_ID_MCP, MCP_CMPMASK0, &msr_value);
2601f29dbc25Smrg    gfx_msr_write(RC_ID_MCP, MCP_CMPMASK0 + 2, &msr_value);
2602f29dbc25Smrg
2603f29dbc25Smrg    /* COMPARATORS 2 AND 3 REFER TO UPPER 16 BITS OF REGB */
2604f29dbc25Smrg
2605f29dbc25Smrg    msr_value.low = 0xFFFF0000;
2606f29dbc25Smrg    gfx_msr_write(RC_ID_MCP, MCP_CMPMASK0 + 4, &msr_value);
2607f29dbc25Smrg    gfx_msr_write(RC_ID_MCP, MCP_CMPMASK0 + 6, &msr_value);
2608f29dbc25Smrg
2609f29dbc25Smrg    /* SET REGA MASK TO CRC ONLY 24 BITS OF DATA */
2610f29dbc25Smrg
2611f29dbc25Smrg    msr_value.high = 0x00000000;
2612f29dbc25Smrg    msr_value.low = 0x00FFFFFF;
2613f29dbc25Smrg    gfx_msr_write(RC_ID_MCP, MCP_REGAMASK, &msr_value);
2614f29dbc25Smrg
2615f29dbc25Smrg    /* SET REGB VALUE */
2616f29dbc25Smrg    /* Lower 16 bits use HTOTAL - SYNC TIME - 1 to set the counter rollover
2617f29dbc25Smrg     * limit. */
2618f29dbc25Smrg    /* Upper 16 bits use 0xFFFF to remove auto-clear behavior.     */
2619f29dbc25Smrg
2620f29dbc25Smrg    msr_value.high = 0x00000000;
2621f29dbc25Smrg    msr_value.low = 0xFFFF0000 |
2622f29dbc25Smrg        ((gfx_get_htotal() - (gfx_get_hsync_end() - gfx_get_hsync_start()) -
262304007ebaSmrg          1) & 0xFFFF);
2624f29dbc25Smrg    gfx_msr_write(RC_ID_MCP, MCP_REGBVAL, &msr_value);
2625f29dbc25Smrg
2626f29dbc25Smrg    /* PROGRAM ACTIONS */
2627f29dbc25Smrg
2628f29dbc25Smrg    /* GOTO STATE 01 */
2629f29dbc25Smrg
2630f29dbc25Smrg    msr_value.high = 0x00000000;
2631f29dbc25Smrg    msr_value.low = 0x00000008 | (1l << vsync_inactive_shift);
2632f29dbc25Smrg    gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 14, &msr_value);
2633f29dbc25Smrg
2634f29dbc25Smrg    /* GOTO STATE 10 */
2635f29dbc25Smrg
2636f29dbc25Smrg    msr_value.low = 0x00080000 | (1l << (vsync_active_shift + 16));
2637f29dbc25Smrg    gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 15, &msr_value);
2638f29dbc25Smrg
2639f29dbc25Smrg    /* GOTO STATE 11 */
2640f29dbc25Smrg
2641f29dbc25Smrg    msr_value.low = 0x00000080 | (1l << (vsync_inactive_shift + 4));
2642f29dbc25Smrg    gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 16, &msr_value);
2643f29dbc25Smrg
2644f29dbc25Smrg    /* CLEAR REGB (COUNTERS)  */
2645f29dbc25Smrg    /* RegB is cleared upon transitioning to state 10              */
2646f29dbc25Smrg    /* RegA is not cleared as the initial value must be 0x00000001 */
2647f29dbc25Smrg
2648f29dbc25Smrg    msr_value.low = 0x00080000 | (1l << (vsync_active_shift + 16));
2649f29dbc25Smrg    gfx_msr_write(RC_ID_MCP, MCP_ACTION0, &msr_value);
2650f29dbc25Smrg
2651f29dbc25Smrg    /* CRC INTO REGA        */
2652f29dbc25Smrg    /* INCREMENT H. COUNTER */
2653f29dbc25Smrg    /* cmp0 <= xpos < cmp1  */
2654f29dbc25Smrg    /* cmp2 <= ypos < cmp3  */
2655f29dbc25Smrg    /* XState = 10          */
2656f29dbc25Smrg
2657f29dbc25Smrg    msr_value.low = 0x00000008 | (1l << vsync_active_shift) |
2658f29dbc25Smrg        0x00800000 | (1l << (hsync_active_shift + 20));
2659f29dbc25Smrg    gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 1, &msr_value);
2660f29dbc25Smrg
2661f29dbc25Smrg    /* INCREMENT V. COUNTER */
2662f29dbc25Smrg    /* V. Counter is incremented when the H. Counter */
2663f29dbc25Smrg    /* rolls over.                                   */
2664f29dbc25Smrg
2665f29dbc25Smrg    msr_value.low = 0x00080000 | (1l << (vsync_inactive_shift + 16));
2666f29dbc25Smrg    gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 2, &msr_value);
2667f29dbc25Smrg
2668f29dbc25Smrg    /* CLEAR ALL OTHER ACTIONS */
2669f29dbc25Smrg    /* This prevents side-effects from previous accesses to the MCP */
2670f29dbc25Smrg    /* debug logic.                                                 */
2671f29dbc25Smrg    msr_value.low = 0x00000000;
2672f29dbc25Smrg    msr_value.high = 0x00000000;
2673f29dbc25Smrg    gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 3, &msr_value);
2674f29dbc25Smrg    gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 4, &msr_value);
2675f29dbc25Smrg    gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 5, &msr_value);
2676f29dbc25Smrg    gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 6, &msr_value);
2677f29dbc25Smrg    gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 7, &msr_value);
2678f29dbc25Smrg    gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 8, &msr_value);
2679f29dbc25Smrg    gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 9, &msr_value);
2680f29dbc25Smrg    gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 10, &msr_value);
2681f29dbc25Smrg    gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 11, &msr_value);
2682f29dbc25Smrg    gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 12, &msr_value);
2683f29dbc25Smrg    gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 13, &msr_value);
2684f29dbc25Smrg    gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 17, &msr_value);
2685f29dbc25Smrg    gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 18, &msr_value);
2686f29dbc25Smrg    gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 19, &msr_value);
2687f29dbc25Smrg    gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 20, &msr_value);
2688f29dbc25Smrg
2689f29dbc25Smrg    /* SET REGA CRC VALUE TO 1 OR 0 */
2690f29dbc25Smrg
2691f29dbc25Smrg    if (!crc32)
2692f29dbc25Smrg        msr_value.low = 0x00000001;
2693f29dbc25Smrg    gfx_msr_write(RC_ID_MCP, MCP_REGA, &msr_value);
2694f29dbc25Smrg
2695f29dbc25Smrg    /* SET XSTATE TO 0 */
2696f29dbc25Smrg
2697f29dbc25Smrg    msr_value.low = 0;
2698f29dbc25Smrg    msr_value.high = 0;
2699f29dbc25Smrg    gfx_msr_write(RC_ID_MCP, MCP_XSTATE, &msr_value);
2700f29dbc25Smrg
2701f29dbc25Smrg    /* CONFIGURE DIAG CONTROL */
2702f29dbc25Smrg    /* Set all four comparators to watch the upper diag bus.           */
2703f29dbc25Smrg    /* Set REGA action1 to legacy CRC or 32-bit CRC.                   */
2704f29dbc25Smrg    /* Set REGB action1 to increment lower 16 bits and clear at limit. */
2705f29dbc25Smrg    /* Set REGB action2 to increment upper 16 bits.                    */
2706f29dbc25Smrg    /* Enable all actions.                                             */
2707f29dbc25Smrg
2708f29dbc25Smrg    if (crc32)
2709f29dbc25Smrg        msr_value.low = 0x9A820055;
2710f29dbc25Smrg    else
2711f29dbc25Smrg        msr_value.low = 0x9A840055;
2712f29dbc25Smrg    msr_value.high = 0x00000000;
2713f29dbc25Smrg    gfx_msr_write(RC_ID_MCP, MCP_DIAGCTL, &msr_value);
2714f29dbc25Smrg
2715f29dbc25Smrg    /* DELAY TWO FRAMES */
2716f29dbc25Smrg
271704007ebaSmrg    while (!gfx_test_vertical_active());
271804007ebaSmrg    while (gfx_test_vertical_active());
271904007ebaSmrg    while (!gfx_test_vertical_active());
272004007ebaSmrg    while (gfx_test_vertical_active());
272104007ebaSmrg    while (!gfx_test_vertical_active());
2722f29dbc25Smrg
2723f29dbc25Smrg    /* VERIFY THAT XSTATE = 11 */
2724f29dbc25Smrg
2725f29dbc25Smrg    gfx_msr_read(RC_ID_MCP, MCP_XSTATE, &msr_value);
2726f29dbc25Smrg    if ((msr_value.low & 3) == 3) {
2727f29dbc25Smrg        gfx_msr_read(RC_ID_MCP, MCP_REGA, &msr_value);
2728f29dbc25Smrg
2729f29dbc25Smrg        crc = msr_value.low;
2730f29dbc25Smrg        if (!crc32)
2731f29dbc25Smrg            crc &= 0xFFFFFF;
2732f29dbc25Smrg    }
2733f29dbc25Smrg
2734f29dbc25Smrg    /* DISABLE MCP AND DF DIAG BUS OUTPUTS */
2735f29dbc25Smrg
2736f29dbc25Smrg    msr_value.low = 0x00000000;
2737f29dbc25Smrg    msr_value.high = 0x00000000;
2738f29dbc25Smrg    gfx_msr_write(RC_ID_DF, MBD_MSR_DIAG, &msr_value);
2739f29dbc25Smrg    gfx_msr_write(RC_ID_MCP, MBD_MSR_DIAG, &msr_value);
2740f29dbc25Smrg
2741f29dbc25Smrg    /* DISABLE MCP ACTIONS */
2742f29dbc25Smrg
2743f29dbc25Smrg    msr_value.high = 0x00000000;
2744f29dbc25Smrg    msr_value.low = 0x00000000;
2745f29dbc25Smrg    gfx_msr_write(RC_ID_MCP, MCP_DIAGCTL, &msr_value);
2746f29dbc25Smrg
2747f29dbc25Smrg    /* RESTORE PREVIOUS OUTPUT FORMAT */
2748f29dbc25Smrg
2749f29dbc25Smrg    if (source != CRC_SOURCE_GFX_DATA) {
2750f29dbc25Smrg        gfx_msr_read(RC_ID_DF, MBD_MSR_CONFIG, &msr_value);
2751f29dbc25Smrg        msr_value.low = old_fmt;
2752f29dbc25Smrg        gfx_msr_write(RC_ID_DF, MBD_MSR_CONFIG, &msr_value);
2753f29dbc25Smrg    }
2754f29dbc25Smrg    return crc;
2755f29dbc25Smrg}
2756f29dbc25Smrg
2757f29dbc25Smrg/*---------------------------------------------------------------------------
2758f29dbc25Smrg * gfx_get_alpha_enable
2759f29dbc25Smrg *
2760f29dbc25Smrg * This routine returns 1 if the selected alpha window is currently
2761f29dbc25Smrg * enabled, or 0 if it is currently disabled.
2762f29dbc25Smrg *---------------------------------------------------------------------------
2763f29dbc25Smrg */
2764f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
2765f29dbc25Smrgvoid
2766f29dbc25Smrgredcloud_get_alpha_enable(int *enable)
2767f29dbc25Smrg#else
2768f29dbc25Smrgvoid
2769f29dbc25Smrggfx_get_alpha_enable(int *enable)
2770f29dbc25Smrg#endif
2771f29dbc25Smrg{
2772f29dbc25Smrg    unsigned long value = 0;
2773f29dbc25Smrg
2774f29dbc25Smrg    *enable = 0;
2775f29dbc25Smrg    if (gfx_alpha_select <= 2) {
2776f29dbc25Smrg        value =
2777f29dbc25Smrg            READ_VID32(RCDF_ALPHA_CONTROL_1 +
277804007ebaSmrg                       ((unsigned long) gfx_alpha_select << 5));
2779f29dbc25Smrg        if (value & RCDF_ACTRL_WIN_ENABLE)
2780f29dbc25Smrg            *enable = 1;
2781f29dbc25Smrg    }
2782f29dbc25Smrg    return;
2783f29dbc25Smrg}
2784f29dbc25Smrg
2785f29dbc25Smrg/*---------------------------------------------------------------------------
2786f29dbc25Smrg * gfx_get_alpha_size
2787f29dbc25Smrg *
2788f29dbc25Smrg * This routine returns the size of the currently selected alpha region.
2789f29dbc25Smrg *---------------------------------------------------------------------------
2790f29dbc25Smrg */
2791f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
2792f29dbc25Smrgvoid
2793f29dbc25Smrgredcloud_get_alpha_size(unsigned short *x, unsigned short *y,
279404007ebaSmrg                        unsigned short *width, unsigned short *height)
2795f29dbc25Smrg#else
2796f29dbc25Smrgvoid
2797f29dbc25Smrggfx_get_alpha_size(unsigned short *x, unsigned short *y,
279804007ebaSmrg                   unsigned short *width, unsigned short *height)
2799f29dbc25Smrg#endif
2800f29dbc25Smrg{
2801f29dbc25Smrg    unsigned long value = 0;
2802f29dbc25Smrg
2803f29dbc25Smrg    *x = 0;
2804f29dbc25Smrg    *y = 0;
2805f29dbc25Smrg    *width = 0;
2806f29dbc25Smrg    *height = 0;
2807f29dbc25Smrg    if (gfx_alpha_select <= 2) {
2808f29dbc25Smrg        value =
2809f29dbc25Smrg            READ_VID32(RCDF_ALPHA_XPOS_1 +
281004007ebaSmrg                       ((unsigned long) gfx_alpha_select << 5));
281104007ebaSmrg        *x = (unsigned short) (value & 0x000007FF);
281204007ebaSmrg        *width = (unsigned short) ((value >> 16) & 0x000007FF) - *x;
2813f29dbc25Smrg        value =
2814f29dbc25Smrg            READ_VID32(RCDF_ALPHA_YPOS_1 +
281504007ebaSmrg                       ((unsigned long) gfx_alpha_select << 5));
281604007ebaSmrg        *y = (unsigned short) (value & 0x000007FF);
281704007ebaSmrg        *height = (unsigned short) ((value >> 16) & 0x000007FF) - *y;
2818f29dbc25Smrg    }
2819f29dbc25Smrg    *x -= gfx_get_htotal() - gfx_get_hsync_end() - 2;
2820f29dbc25Smrg    *y -= gfx_get_vtotal() - gfx_get_vsync_end() + 1;
2821f29dbc25Smrg    return;
2822f29dbc25Smrg}
2823f29dbc25Smrg
2824f29dbc25Smrg/*---------------------------------------------------------------------------
2825f29dbc25Smrg * gfx_get_alpha_value
2826f29dbc25Smrg *
2827f29dbc25Smrg * This routine returns the alpha value and increment/decrement value of
2828f29dbc25Smrg * the currently selected alpha region.
2829f29dbc25Smrg *---------------------------------------------------------------------------
2830f29dbc25Smrg */
2831f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
2832f29dbc25Smrgvoid
2833f29dbc25Smrgredcloud_get_alpha_value(unsigned char *alpha, char *delta)
2834f29dbc25Smrg#else
2835f29dbc25Smrgvoid
2836f29dbc25Smrggfx_get_alpha_value(unsigned char *alpha, char *delta)
2837f29dbc25Smrg#endif
2838f29dbc25Smrg{
2839f29dbc25Smrg    unsigned long value = 0;
2840f29dbc25Smrg
2841f29dbc25Smrg    *alpha = 0;
2842f29dbc25Smrg    *delta = 0;
2843f29dbc25Smrg    if (gfx_alpha_select <= 2) {
2844f29dbc25Smrg        value =
2845f29dbc25Smrg            READ_VID32(RCDF_ALPHA_CONTROL_1 +
284604007ebaSmrg                       ((unsigned long) gfx_alpha_select << 5));
284704007ebaSmrg        *alpha = (unsigned char) (value & 0x00FF);
284804007ebaSmrg        *delta = (char) ((value >> 8) & 0x00FF);
2849f29dbc25Smrg    }
2850f29dbc25Smrg    return;
2851f29dbc25Smrg}
2852f29dbc25Smrg
2853f29dbc25Smrg/*---------------------------------------------------------------------------
2854f29dbc25Smrg * gfx_get_alpha_priority
2855f29dbc25Smrg *
2856f29dbc25Smrg * This routine returns the priority of the currently selected alpha region.
2857f29dbc25Smrg *---------------------------------------------------------------------------
2858f29dbc25Smrg */
2859f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
2860f29dbc25Smrgvoid
2861f29dbc25Smrgredcloud_get_alpha_priority(int *priority)
2862f29dbc25Smrg#else
2863f29dbc25Smrgvoid
2864f29dbc25Smrggfx_get_alpha_priority(int *priority)
2865f29dbc25Smrg#endif
2866f29dbc25Smrg{
2867f29dbc25Smrg    unsigned long pos = 0, value = 0;
2868f29dbc25Smrg
2869f29dbc25Smrg    *priority = 0;
2870f29dbc25Smrg    if (gfx_alpha_select <= 2) {
2871f29dbc25Smrg        value = READ_VID32(RCDF_VID_ALPHA_CONTROL);
2872f29dbc25Smrg        pos = 16 + (gfx_alpha_select << 1);
287304007ebaSmrg        *priority = (int) ((value >> pos) & 3);
2874f29dbc25Smrg    }
2875f29dbc25Smrg    return;
2876f29dbc25Smrg}
2877f29dbc25Smrg
2878f29dbc25Smrg/*---------------------------------------------------------------------------
2879f29dbc25Smrg * gfx_get_alpha_color
2880f29dbc25Smrg *
2881f29dbc25Smrg * This routine returns the color register value for the currently selected
2882f29dbc25Smrg * alpha region.  Bit 24 is set if the color register is enabled.
2883f29dbc25Smrg *---------------------------------------------------------------------------
2884f29dbc25Smrg */
2885f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
2886f29dbc25Smrgvoid
2887f29dbc25Smrgredcloud_get_alpha_color(unsigned long *color)
2888f29dbc25Smrg#else
2889f29dbc25Smrgvoid
2890f29dbc25Smrggfx_get_alpha_color(unsigned long *color)
2891f29dbc25Smrg#endif
2892f29dbc25Smrg{
2893f29dbc25Smrg    *color = 0;
2894f29dbc25Smrg    if (gfx_alpha_select <= 2) {
2895f29dbc25Smrg        *color =
2896f29dbc25Smrg            READ_VID32(RCDF_ALPHA_COLOR_1 +
289704007ebaSmrg                       ((unsigned long) gfx_alpha_select << 5));
2898f29dbc25Smrg    }
2899f29dbc25Smrg    return;
2900f29dbc25Smrg}
2901f29dbc25Smrg
290204007ebaSmrg#endif                          /* GFX_READ_ROUTINES */
2903f29dbc25Smrg
2904f29dbc25Smrg/* END OF FILE */
2905