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