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