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