vid_1200.c revision 71d7fec4
1/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/vid_1200.c,v 1.2 2003/01/14 09:34:34 alanh Exp $ */ 2/* 3 * $Workfile: vid_1200.c $ 4 * 5 * This file contains routines to control the SC1200 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/*---------------------------------------------------------------------------- 132 * SC1200 PLL TABLE 133 *---------------------------------------------------------------------------- 134 */ 135 136typedef struct tagSC1200PLL 137{ 138 long frequency; /* 16.16 fixed point frequency */ 139 unsigned long clock_select; /* clock select register (0x2C) */ 140} 141SC1200PLL; 142 143SC1200PLL gfx_sc1200_clock_table[] = { 144 {(25L << 16) | ((1750L * 65536L) / 10000L), 0x0070E00C}, /* 25.1750 (sc=24.9231) */ 145 {(27L << 16) | ((0000L * 65536L) / 10000L), 0x00300100}, /* 27.0000 */ 146 {(28L << 16) | ((3220L * 65536L) / 10000L), 0x0070EC0C}, /* 28.3220 (SC=27.000) */ 147 {(31L << 16) | ((5000L * 65536L) / 10000L), 0x00500D02}, /* 31.5000 */ 148 {(36L << 16) | ((0000L * 65536L) / 10000L), 0x00500F02}, /* 36.0000 */ 149 {(37L << 16) | ((5000L * 65536L) / 10000L), 0x0050B108}, /* 37.5000 */ 150 {(40L << 16) | ((0000L * 65536L) / 10000L), 0x0050D20D}, /* 40.0000 */ 151 {(44L << 16) | ((9000L * 65536L) / 10000L), 0x0050DC0D}, /* 44.9000 */ 152 {(49L << 16) | ((5000L * 65536L) / 10000L), 0x00501502}, /* 49.5000 */ 153 {(50L << 16) | ((0000L * 65536L) / 10000L), 0x0050A404}, /* 50.0000 */ 154 {(50L << 16) | ((3500L * 65536L) / 10000L), 0x0050E00C}, /* 50.3500 */ 155 {(54L << 16) | ((0000L * 65536L) / 10000L), 0x00300300}, /* 54.0000 */ 156 {(56L << 16) | ((3916L * 65536L) / 10000L), 0x0050F40D}, /* 56.3916 */ 157 {(56L << 16) | ((6440L * 65536L) / 10000L), 0x0050EC0C}, /* 56.6440 */ 158 {(59L << 16) | ((0000L * 65536L) / 10000L), 0x0030A207}, /* 59.0000 */ 159 {(63L << 16) | ((0000L * 65536L) / 10000L), 0x00300D02}, /* 63.0000 */ 160 {(65L << 16) | ((0000L * 65536L) / 10000L), 0x0030CC0F}, /* 65.0000 */ 161 {(67L << 16) | ((5000L * 65536L) / 10000L), 0x00300400}, /* 67.5000 */ 162 {(70L << 16) | ((8000L * 65536L) / 10000L), 0x00301403}, /* 70.8000 */ 163 {(72L << 16) | ((0000L * 65536L) / 10000L), 0x00300F02}, /* 72.0000 */ 164 {(75L << 16) | ((0000L * 65536L) / 10000L), 0x0030B108}, /* 75.0000 */ 165 {(78L << 16) | ((7500L * 65536L) / 10000L), 0x0030A205}, /* 78.7500 */ 166 {(80L << 16) | ((0000L * 65536L) / 10000L), 0x0030D20D}, /* 80.0000 */ 167 {(87L << 16) | ((2728L * 65536L) / 10000L), 0x0030E00E}, /* 87.2728 */ 168 {(89L << 16) | ((8000L * 65536L) / 10000L), 0x0030DC0D}, /* 89.8000 */ 169 {(94L << 16) | ((5000L * 65536L) / 10000L), 0x00300600}, /* 99.0000 */ 170 {(99L << 16) | ((0000L * 65536L) / 10000L), 0x00301502}, /* 99.0000 */ 171 {(100L << 16) | ((0000L * 65536L) / 10000L), 0x0030A404}, /* 100.00 */ 172 {(108L << 16) | ((0000L * 65536L) / 10000L), 0x00100300}, /* 108.00 */ 173 {(112L << 16) | ((5000L * 65536L) / 10000L), 0x00301802}, /* 108.00 */ 174 {(130L << 16) | ((0000L * 65536L) / 10000L), 0x0010CC0F}, /* 130.00 */ 175 {(135L << 16) | ((0000L * 65536L) / 10000L), 0x00100400}, /* 135.00 */ 176 {(157L << 16) | ((5000L * 65536L) / 10000L), 0x0010A205}, /* 157.50 */ 177 {(162L << 16) | ((0000L * 65536L) / 10000L), 0x00100500}, /* 162.00 */ 178 {(175L << 16) | ((0000L * 65536L) / 10000L), 0x0010E00E}, /* 175.50 */ 179 {(189L << 16) | ((0000L * 65536L) / 10000L), 0x00100600}, /* 189.00 */ 180 {(202L << 16) | ((0000L * 65536L) / 10000L), 0x0010EF0E}, /* 202.50 */ 181 {(232L << 16) | ((0000L * 65536L) / 10000L), 0x0010AA04}, /* 232.50 */ 182 183 /* Precomputed inidces in the hardware */ 184 {0x0018EC4D, 0x000F0000}, /* 24.923052 */ 185 {0x00192CCC, 0x00000000}, /* 25.1750 */ 186 {0x001B0000, 0x00300100}, /* 27.0000 */ 187 {0x001F8000, 0x00010000}, /* 31.5000 */ 188 {0x00240000, 0x00020000}, /* 36.0000 */ 189 {0x00280000, 0x00030000}, /* 40.0000 */ 190 {0x00318000, 0x00050000}, /* 49.5000 */ 191 {0x00320000, 0x00040000}, /* 50.0000 */ 192 {0x00384000, 0x00060000}, /* 56.2500 */ 193 {0x00410000, 0x00080000}, /* 65.0000 */ 194 {0x004E8000, 0x000A0000}, /* 78.5000 */ 195 {0x005E8000, 0x000B0000}, /* 94.5000 */ 196 {0x006C0000, 0x000C0000}, /* 108.0000 */ 197 {0x00870000, 0x000D0000}, /* 135.0000 */ 198}; 199 200#define NUM_SC1200_FREQUENCIES sizeof(gfx_sc1200_clock_table)/sizeof(SC1200PLL) 201 202int sc1200_set_video_enable(int enable); 203int sc1200_set_video_format(unsigned long format); 204int sc1200_set_video_size(unsigned short width, unsigned short height); 205int sc1200_set_video_yuv_pitch(unsigned long ypitch, unsigned long uvpitch); 206int sc1200_set_video_offset(unsigned long offset); 207int sc1200_set_video_yuv_offsets(unsigned long yoffset, unsigned long uoffset, 208 unsigned long voffset); 209int sc1200_set_video_window(short x, short y, unsigned short w, 210 unsigned short h); 211int sc1200_set_video_left_crop(unsigned short x); 212int sc1200_set_video_upscale(unsigned short srcw, unsigned short srch, 213 unsigned short dstw, unsigned short dsth); 214int sc1200_set_video_scale(unsigned short srcw, unsigned short srch, 215 unsigned short dstw, unsigned short dsth); 216int sc1200_set_video_vertical_downscale(unsigned short srch, 217 unsigned short dsth); 218void sc1200_set_video_vertical_downscale_enable(int enable); 219int sc1200_set_video_downscale_config(unsigned short type, unsigned short m); 220int sc1200_set_video_color_key(unsigned long key, unsigned long mask, 221 int bluescreen); 222int sc1200_set_video_filter(int xfilter, int yfilter); 223int sc1200_set_video_palette(unsigned long *palette); 224int sc1200_set_video_palette_entry(unsigned long index, unsigned long color); 225int sc1200_set_video_downscale_coefficients(unsigned short coef1, 226 unsigned short coef2, 227 unsigned short coef3, 228 unsigned short coef4); 229int sc1200_set_video_downscale_enable(int enable); 230int sc1200_set_video_source(VideoSourceType source); 231int sc1200_set_vbi_source(VbiSourceType source); 232int sc1200_set_vbi_lines(unsigned long even, unsigned long odd); 233int sc1200_set_vbi_total(unsigned long even, unsigned long odd); 234int sc1200_set_video_interlaced(int enable); 235int sc1200_set_color_space_YUV(int enable); 236int sc1200_set_vertical_scaler_offset(char offset); 237int sc1200_set_top_line_in_odd(int enable); 238int sc1200_set_genlock_delay(unsigned long delay); 239int sc1200_set_genlock_enable(int flags); 240int sc1200_set_video_cursor(unsigned long key, unsigned long mask, 241 unsigned short select_color2, 242 unsigned long color1, unsigned long color2); 243int sc1200_set_video_cursor_enable(int enable); 244int sc1200_set_video_request(short x, short y); 245 246int sc1200_select_alpha_region(int region); 247int sc1200_set_alpha_enable(int enable); 248int sc1200_set_alpha_window(short x, short y, 249 unsigned short width, unsigned short height); 250int sc1200_set_alpha_value(unsigned char alpha, char delta); 251int sc1200_set_alpha_priority(int priority); 252int sc1200_set_alpha_color(unsigned long color); 253int sc1200_set_alpha_color_enable(int enable); 254int sc1200_set_no_ck_outside_alpha(int enable); 255int sc1200_disable_softvga(void); 256int sc1200_enable_softvga(void); 257int sc1200_set_macrovision_enable(int enable); 258void sc1200_reset_video(void); 259int sc1200_set_display_control(int sync_polarities); 260void sc1200_set_clock_frequency(unsigned long frequency); 261int sc1200_set_screen_enable(int enable); 262int sc1200_set_crt_enable(int enable); 263 264/* READ ROUTINES IN GFX_VID.C */ 265 266int sc1200_get_video_enable(void); 267int sc1200_get_video_format(void); 268unsigned long sc1200_get_video_src_size(void); 269unsigned long sc1200_get_video_line_size(void); 270unsigned long sc1200_get_video_xclip(void); 271unsigned long sc1200_get_video_offset(void); 272void sc1200_get_video_yuv_offsets(unsigned long *yoffset, 273 unsigned long *uoffset, 274 unsigned long *voffset); 275void sc1200_get_video_yuv_pitch(unsigned long *ypitch, 276 unsigned long *uvpitch); 277unsigned long sc1200_get_video_upscale(void); 278unsigned long sc1200_get_video_scale(void); 279unsigned long sc1200_get_video_downscale_delta(void); 280int sc1200_get_video_vertical_downscale_enable(void); 281int sc1200_get_video_downscale_config(unsigned short *type, 282 unsigned short *m); 283void sc1200_get_video_downscale_coefficients(unsigned short *coef1, 284 unsigned short *coef2, 285 unsigned short *coef3, 286 unsigned short *coef4); 287void sc1200_get_video_downscale_enable(int *enable); 288unsigned long sc1200_get_video_dst_size(void); 289unsigned long sc1200_get_video_position(void); 290unsigned long sc1200_get_video_color_key(void); 291unsigned long sc1200_get_video_color_key_mask(void); 292int sc1200_get_video_palette_entry(unsigned long index, 293 unsigned long *palette); 294int sc1200_get_video_color_key_src(void); 295int sc1200_get_video_filter(void); 296int sc1200_get_video_request(short *x, short *y); 297int sc1200_get_video_source(VideoSourceType * source); 298int sc1200_get_vbi_source(VbiSourceType * source); 299unsigned long sc1200_get_vbi_lines(int odd); 300unsigned long sc1200_get_vbi_total(int odd); 301int sc1200_get_video_interlaced(void); 302int sc1200_get_color_space_YUV(void); 303int sc1200_get_vertical_scaler_offset(char *offset); 304unsigned long sc1200_get_genlock_delay(void); 305int sc1200_get_genlock_enable(void); 306int sc1200_get_video_cursor(unsigned long *key, unsigned long *mask, 307 unsigned short *select_color2, 308 unsigned long *color1, unsigned short *color2); 309unsigned long sc1200_read_crc(void); 310unsigned long sc1200_read_crc32(void); 311unsigned long sc1200_read_window_crc(int source, unsigned short x, 312 unsigned short y, unsigned short width, 313 unsigned short height, int crc32); 314int sc1200_get_macrovision_enable(void); 315 316void sc1200_get_alpha_enable(int *enable); 317void sc1200_get_alpha_size(unsigned short *x, unsigned short *y, 318 unsigned short *width, unsigned short *height); 319void sc1200_get_alpha_value(unsigned char *alpha, char *delta); 320void sc1200_get_alpha_priority(int *priority); 321void sc1200_get_alpha_color(unsigned long *color); 322unsigned long sc1200_get_clock_frequency(void); 323int sc1200_get_vsa2_softvga_enable(void); 324int sc1200_get_sync_polarities(void); 325 326/*--------------------------------------------------------------------------- 327 * gfx_reset_video (PRIVATE ROUTINE: NOT PART OF DURANGO API) 328 * 329 * This routine is used to disable all components of video overlay before 330 * performing a mode switch. 331 *--------------------------------------------------------------------------- 332 */ 333#if GFX_VIDEO_DYNAMIC 334void 335sc1200_reset_video(void) 336#else 337void 338gfx_reset_video(void) 339#endif 340{ 341 int i; 342 343 gfx_set_video_enable(0); 344 345 /* SET WINDOW 0 AFTER RESET */ 346 347 for (i = 2; i >= 0; i--) { 348 gfx_select_alpha_region(i); 349 gfx_set_alpha_enable(0); 350 gfx_set_alpha_color_enable(0); 351 } 352} 353 354/*----------------------------------------------------------------------------- 355 * gfx_set_display_control (PRIVATE ROUTINE: NOT PART OF DURANGO API) 356 * 357 * This routine configures the display output. 358 * 359 * "sync_polarities" is used to set the polarities of the sync pulses according 360 * to the following mask: 361 * 362 * Bit 0: If set to 1, negative horizontal polarity is programmed, 363 * otherwise positive horizontal polarity is programmed. 364 * Bit 1: If set to 1, negative vertical polarity is programmed, 365 * otherwise positive vertical polarity is programmed. 366 * 367 *----------------------------------------------------------------------------- 368 */ 369#if GFX_VIDEO_DYNAMIC 370int 371sc1200_set_display_control(int sync_polarities) 372#else 373int 374gfx_set_display_control(int sync_polarities) 375#endif 376{ 377 unsigned long dcfg; 378 379 /* CONFIGURE DISPLAY OUTPUT FROM VIDEO PROCESSOR */ 380 381 dcfg = READ_VID32(SC1200_DISPLAY_CONFIG); 382 dcfg &= ~(SC1200_DCFG_CRT_SYNC_SKW_MASK | SC1200_DCFG_PWR_SEQ_DLY_MASK | 383 SC1200_DCFG_CRT_HSYNC_POL | SC1200_DCFG_CRT_VSYNC_POL | 384 SC1200_DCFG_FP_PWR_EN | SC1200_DCFG_FP_DATA_EN); 385 386 dcfg |= (SC1200_DCFG_CRT_SYNC_SKW_INIT | 387 SC1200_DCFG_PWR_SEQ_DLY_INIT | SC1200_DCFG_GV_PAL_BYP); 388 389 if (PanelEnable) 390 dcfg |= SC1200_DCFG_FP_PWR_EN; 391 392 /* SET APPROPRIATE SYNC POLARITIES */ 393 394 if (sync_polarities & 0x1) 395 dcfg |= SC1200_DCFG_CRT_HSYNC_POL; 396 if (sync_polarities & 0x2) 397 dcfg |= SC1200_DCFG_CRT_VSYNC_POL; 398 399 WRITE_VID32(SC1200_DISPLAY_CONFIG, dcfg); 400 401 return (0); 402} 403 404/*--------------------------------------------------------------------------- 405 * gfx_set_clock_frequency 406 * 407 * This routine sets the clock frequency, specified as a 16.16 fixed point 408 * value (0x00318000 = 49.5 MHz). It will set the closest frequency found 409 * in the lookup table. 410 *--------------------------------------------------------------------------- 411 */ 412#if GFX_VIDEO_DYNAMIC 413void 414sc1200_set_clock_frequency(unsigned long frequency) 415#else 416void 417gfx_set_clock_frequency(unsigned long frequency) 418#endif 419{ 420 unsigned int index; 421 unsigned long value, pll; 422 long min, diff; 423 424 /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */ 425 /* Search the table for the closest frequency (16.16 format). */ 426 427 value = gfx_sc1200_clock_table[0].clock_select; 428 min = (long)gfx_sc1200_clock_table[0].frequency - frequency; 429 if (min < 0L) 430 min = -min; 431 for (index = 1; index < NUM_SC1200_FREQUENCIES; index++) { 432 diff = (long)gfx_sc1200_clock_table[index].frequency - frequency; 433 if (diff < 0L) 434 diff = -diff; 435 if (diff < min) { 436 min = diff; 437 value = gfx_sc1200_clock_table[index].clock_select; 438 } 439 } 440 441 /* SET THE DOT CLOCK REGISTER */ 442 443 pll = READ_VID32(SC1200_VID_MISC); 444 WRITE_VID32(SC1200_VID_MISC, pll | SC1200_PLL_POWER_NORMAL); 445 WRITE_VID32(SC1200_VID_CLOCK_SELECT, value); 446 return; 447} 448 449/*--------------------------------------------------------------------------- 450 * gfx_set_screen_enable (PRIVATE ROUTINE - NOT PART OF API) 451 * 452 * This routine enables or disables the graphics display logic of the video processor. 453 *--------------------------------------------------------------------------- 454 */ 455#if GFX_VIDEO_DYNAMIC 456int 457sc1200_set_screen_enable(int enable) 458#else 459int 460gfx_set_screen_enable(int enable) 461#endif 462{ 463 unsigned long config; 464 465 config = READ_VID32(SC1200_DISPLAY_CONFIG); 466 if (enable) 467 WRITE_VID32(SC1200_DISPLAY_CONFIG, config | SC1200_DCFG_DIS_EN); 468 else 469 WRITE_VID32(SC1200_DISPLAY_CONFIG, config & ~SC1200_DCFG_DIS_EN); 470 return (GFX_STATUS_OK); 471} 472 473/*--------------------------------------------------------------------------- 474 * gfx_set_crt_enable 475 * 476 * This routine enables or disables the CRT output from the video processor. 477 *--------------------------------------------------------------------------- 478 */ 479#if GFX_VIDEO_DYNAMIC 480int 481sc1200_set_crt_enable(int enable) 482#else 483int 484gfx_set_crt_enable(int enable) 485#endif 486{ 487 unsigned long config, misc; 488 489 config = READ_VID32(SC1200_DISPLAY_CONFIG); 490 misc = READ_VID32(SC1200_VID_MISC); 491 492 /* 493 * IMPORTANT: For all modes do NOT disable the graphics display logic 494 * because it might be needed for TV 495 */ 496 497 switch (enable) { 498 case CRT_DISABLE: /* HSync:Off VSync:Off */ 499 WRITE_VID32(SC1200_DISPLAY_CONFIG, config & ~(SC1200_DCFG_HSYNC_EN 500 | SC1200_DCFG_VSYNC_EN 501 | SC1200_DCFG_DAC_BL_EN)); 502 WRITE_VID32(SC1200_VID_MISC, misc | SC1200_DAC_POWER_DOWN); 503 break; 504 case CRT_ENABLE: /* Enable CRT display, including display logic */ 505 WRITE_VID32(SC1200_DISPLAY_CONFIG, config | SC1200_DCFG_HSYNC_EN 506 | SC1200_DCFG_VSYNC_EN | SC1200_DCFG_DAC_BL_EN); 507 WRITE_VID32(SC1200_VID_MISC, misc & ~SC1200_DAC_POWER_DOWN); 508 509 /* ENABLE GRAPHICS DISPLAY LOGIC */ 510 gfx_set_screen_enable(1); 511 break; 512 case CRT_STANDBY: /* HSync:Off VSync:On */ 513 WRITE_VID32(SC1200_DISPLAY_CONFIG, (config & ~(SC1200_DCFG_HSYNC_EN 514 | SC1200_DCFG_DAC_BL_EN)) 515 | SC1200_DCFG_VSYNC_EN); 516 WRITE_VID32(SC1200_VID_MISC, misc | SC1200_DAC_POWER_DOWN); 517 break; 518 case CRT_SUSPEND: /* HSync:On VSync:Off */ 519 WRITE_VID32(SC1200_DISPLAY_CONFIG, (config & ~(SC1200_DCFG_VSYNC_EN 520 | SC1200_DCFG_DAC_BL_EN)) 521 | SC1200_DCFG_HSYNC_EN); 522 WRITE_VID32(SC1200_VID_MISC, misc | SC1200_DAC_POWER_DOWN); 523 break; 524 default: 525 return GFX_STATUS_BAD_PARAMETER; 526 } 527 return (GFX_STATUS_OK); 528} 529 530/*----------------------------------------------------------------------------- 531 * gfx_set_video_enable 532 * 533 * This routine enables or disables the video overlay functionality. 534 *----------------------------------------------------------------------------- 535 */ 536#if GFX_VIDEO_DYNAMIC 537int 538sc1200_set_video_enable(int enable) 539#else 540int 541gfx_set_video_enable(int enable) 542#endif 543{ 544 unsigned long vcfg; 545 546 /* WAIT FOR VERTICAL BLANK TO START */ 547 /* Otherwise a glitch can be observed. */ 548 549 if (gfx_test_timing_active()) { 550 if (!gfx_test_vertical_active()) { 551 while (!gfx_test_vertical_active()) ; 552 } 553 while (gfx_test_vertical_active()) ; 554 } 555 556 vcfg = READ_VID32(SC1200_VIDEO_CONFIG); 557 if (enable) { 558 /* ENABLE VIDEO OVERLAY FROM DISPLAY CONTROLLER */ 559 /* Use private routine to abstract the display controller. */ 560 561 gfx_set_display_video_enable(1); 562 563 /* ENABLE SC1200 VIDEO OVERLAY */ 564 565 vcfg |= SC1200_VCFG_VID_EN; 566 WRITE_VID32(SC1200_VIDEO_CONFIG, vcfg); 567 } else { 568 /* DISABLE SC1200 VIDEO OVERLAY */ 569 570 vcfg &= ~SC1200_VCFG_VID_EN; 571 WRITE_VID32(SC1200_VIDEO_CONFIG, vcfg); 572 573 /* DISABLE VIDEO OVERLAY FROM DISPLAY CONTROLLER */ 574 /* Use private routine to abstract the display controller. */ 575 576 gfx_set_display_video_enable(0); 577 } 578 return (0); 579} 580 581/*----------------------------------------------------------------------------- 582 * gfx_set_video_format 583 * 584 * Sets input video format type, to one of the YUV formats or to RGB. 585 *----------------------------------------------------------------------------- 586 */ 587#if GFX_VIDEO_DYNAMIC 588int 589sc1200_set_video_format(unsigned long format) 590#else 591int 592gfx_set_video_format(unsigned long format) 593#endif 594{ 595 unsigned long ctrl, vcfg = 0; 596 597 /* SET THE SC1200 VIDEO INPUT FORMAT */ 598 599 vcfg = READ_VID32(SC1200_VIDEO_CONFIG); 600 ctrl = READ_VID32(SC1200_VID_ALPHA_CONTROL); 601 ctrl &= ~(SC1200_VIDEO_INPUT_IS_RGB); 602 vcfg &= ~(SC1200_VCFG_VID_INP_FORMAT | SC1200_VCFG_4_2_0_MODE); 603 switch (format) { 604 case VIDEO_FORMAT_UYVY: 605 vcfg |= SC1200_VCFG_UYVY_FORMAT; 606 break; 607 case VIDEO_FORMAT_YUYV: 608 vcfg |= SC1200_VCFG_YUYV_FORMAT; 609 break; 610 case VIDEO_FORMAT_Y2YU: 611 vcfg |= SC1200_VCFG_Y2YU_FORMAT; 612 break; 613 case VIDEO_FORMAT_YVYU: 614 vcfg |= SC1200_VCFG_YVYU_FORMAT; 615 break; 616 case VIDEO_FORMAT_Y0Y1Y2Y3: 617 vcfg |= SC1200_VCFG_UYVY_FORMAT; 618 vcfg |= SC1200_VCFG_4_2_0_MODE; 619 break; 620 case VIDEO_FORMAT_Y3Y2Y1Y0: 621 vcfg |= SC1200_VCFG_Y2YU_FORMAT; 622 vcfg |= SC1200_VCFG_4_2_0_MODE; 623 break; 624 case VIDEO_FORMAT_Y1Y0Y3Y2: 625 vcfg |= SC1200_VCFG_YUYV_FORMAT; 626 vcfg |= SC1200_VCFG_4_2_0_MODE; 627 break; 628 case VIDEO_FORMAT_Y1Y2Y3Y0: 629 vcfg |= SC1200_VCFG_YVYU_FORMAT; 630 vcfg |= SC1200_VCFG_4_2_0_MODE; 631 break; 632 case VIDEO_FORMAT_RGB: 633 ctrl |= SC1200_VIDEO_INPUT_IS_RGB; 634 vcfg |= SC1200_VCFG_UYVY_FORMAT; 635 break; 636 case VIDEO_FORMAT_P2M_P2L_P1M_P1L: 637 ctrl |= SC1200_VIDEO_INPUT_IS_RGB; 638 vcfg |= SC1200_VCFG_Y2YU_FORMAT; 639 break; 640 case VIDEO_FORMAT_P1M_P1L_P2M_P2L: 641 ctrl |= SC1200_VIDEO_INPUT_IS_RGB; 642 vcfg |= SC1200_VCFG_YUYV_FORMAT; 643 break; 644 case VIDEO_FORMAT_P1M_P2L_P2M_P1L: 645 ctrl |= SC1200_VIDEO_INPUT_IS_RGB; 646 vcfg |= SC1200_VCFG_YVYU_FORMAT; 647 break; 648 default: 649 return GFX_STATUS_BAD_PARAMETER; 650 } 651 652 /* ALWAYS DISABLE GRAPHICS CSC */ 653 /* This is enabled in the function gfx_set_color_space_YUV for */ 654 /* YUV blending on TV. */ 655 656 ctrl &= ~SC1200_CSC_GFX_RGB_TO_YUV; 657 658 if (ctrl & SC1200_VIDEO_INPUT_IS_RGB) 659 ctrl &= ~SC1200_CSC_VIDEO_YUV_TO_RGB; 660 else 661 ctrl |= SC1200_CSC_VIDEO_YUV_TO_RGB; 662 663 WRITE_VID32(SC1200_VIDEO_CONFIG, vcfg); 664 WRITE_VID32(SC1200_VID_ALPHA_CONTROL, ctrl); 665 666 return (0); 667} 668 669/*----------------------------------------------------------------------------- 670 * gfx_set_video_size 671 * 672 * This routine specifies the size of the source data. It is used only 673 * to determine how much data to transfer per frame, and is not used to 674 * calculate the scaling value (that is handled by a separate routine). 675 *----------------------------------------------------------------------------- 676 */ 677#if GFX_VIDEO_DYNAMIC 678int 679sc1200_set_video_size(unsigned short width, unsigned short height) 680#else 681int 682gfx_set_video_size(unsigned short width, unsigned short height) 683#endif 684{ 685 unsigned long size, vcfg; 686 687 /* SET THE SC1200 VIDEO LINE SIZE */ 688 689 vcfg = READ_VID32(SC1200_VIDEO_CONFIG); 690 vcfg &= ~(SC1200_VCFG_LINE_SIZE_LOWER_MASK | SC1200_VCFG_LINE_SIZE_UPPER); 691 size = (width >> 1); 692 vcfg |= (size & 0x00FF) << 8; 693 if (size & 0x0100) 694 vcfg |= SC1200_VCFG_LINE_SIZE_UPPER; 695 WRITE_VID32(SC1200_VIDEO_CONFIG, vcfg); 696 697 /* SET TOTAL VIDEO BUFFER SIZE IN DISPLAY CONTROLLER */ 698 /* Use private routine to abstract the display controller. */ 699 700 /* Add 1 line to bypass issue #803 */ 701 gfx_set_display_video_size(width, (unsigned short)(height + 2)); 702 return (0); 703} 704 705/*----------------------------------------------------------------------------- 706 * gfx_set_video_offset 707 * 708 * This routine sets the starting offset for the video buffer when only 709 * one offset needs to be specified. 710 *----------------------------------------------------------------------------- 711 */ 712#if GFX_VIDEO_DYNAMIC 713int 714sc1200_set_video_offset(unsigned long offset) 715#else 716int 717gfx_set_video_offset(unsigned long offset) 718#endif 719{ 720 /* SAVE VALUE FOR FUTURE CLIPPING OF THE TOP OF THE VIDEO WINDOW */ 721 722 gfx_vid_offset = offset; 723 724 /* SET VIDEO BUFFER OFFSET IN DISPLAY CONTROLLER */ 725 /* Use private routine to abstract the display controller. */ 726 727 gfx_set_display_video_offset(offset); 728 return (0); 729} 730 731/*--------------------------------------------------------------------------- 732 * gfx_set_video_upscale 733 * 734 * This routine sets the scale factor for the video overlay window. The 735 * size of the source and destination regions are specified in pixels. 736 *--------------------------------------------------------------------------- 737 */ 738#if GFX_VIDEO_DYNAMIC 739int 740sc1200_set_video_upscale(unsigned short srcw, unsigned short srch, 741 unsigned short dstw, unsigned short dsth) 742#else 743int 744gfx_set_video_upscale(unsigned short srcw, unsigned short srch, 745 unsigned short dstw, unsigned short dsth) 746#endif 747{ 748 unsigned long xscale, yscale; 749 750 /* SAVE PARAMETERS (unless don't-care zero destination arguments are used) */ 751 /* These are needed for clipping the video window later. */ 752 753 if (dstw != 0) { 754 gfx_vid_srcw = srcw; 755 gfx_vid_dstw = dstw; 756 } 757 if (dsth != 0) { 758 gfx_vid_srch = srch; 759 gfx_vid_dsth = dsth; 760 } 761 762 /* CALCULATE SC1200 SCALE FACTORS */ 763 764 if (dstw == 0) 765 xscale = READ_VID32(SC1200_VIDEO_UPSCALE) & 0xffff; /* keep previous if don't-care argument */ 766 else if (dstw <= srcw) 767 xscale = 0x2000l; /* horizontal downscaling is currently done in a separate function */ 768 else if ((srcw == 1) || (dstw == 1)) 769 return GFX_STATUS_BAD_PARAMETER; 770 else 771 xscale = (0x2000l * (srcw - 1l)) / (dstw - 1l); 772 773 if (dsth == 0) 774 yscale = (READ_VID32(SC1200_VIDEO_UPSCALE) & 0xffff0000) >> 16; /* keep previous if don't-care argument */ 775 else if (dsth <= srch) 776 yscale = 0x2000l; /* No vertical downscaling in SC1200 so force to 1x if attempted */ 777 else if ((srch == 1) || (dsth == 1)) 778 return GFX_STATUS_BAD_PARAMETER; 779 else 780 yscale = (0x2000l * (srch - 1l)) / (dsth - 1l); 781 782 WRITE_VID32(SC1200_VIDEO_UPSCALE, (yscale << 16) | xscale); 783 784 /* CALL ROUTINE TO UPDATE WINDOW POSITION */ 785 /* This is required because the scale values effect the number of */ 786 /* source data pixels that need to be clipped, as well as the */ 787 /* amount of data that needs to be transferred. */ 788 789 gfx_set_video_window(gfx_vid_xpos, gfx_vid_ypos, gfx_vid_width, 790 gfx_vid_height); 791 return (0); 792} 793 794/*--------------------------------------------------------------------------- 795 * gfx_set_video_scale 796 * 797 * This routine sets the scale factor for the video overlay window. The 798 * size of the source and destination regions are specified in pixels. 799 *--------------------------------------------------------------------------- 800 */ 801#if GFX_VIDEO_DYNAMIC 802int 803sc1200_set_video_scale(unsigned short srcw, unsigned short srch, 804 unsigned short dstw, unsigned short dsth) 805#else 806int 807gfx_set_video_scale(unsigned short srcw, unsigned short srch, 808 unsigned short dstw, unsigned short dsth) 809#endif 810{ 811 return gfx_set_video_upscale(srcw, srch, dstw, dsth); 812} 813 814/*--------------------------------------------------------------------------- 815 * gfx_set_video_downscale_config 816 * 817 * This routine sets the downscale type and factor for the video overlay window. 818 * Note: No downscaling support for RGB565 and YUV420 video formats. 819 *--------------------------------------------------------------------------- 820 */ 821#if GFX_VIDEO_DYNAMIC 822int 823sc1200_set_video_downscale_config(unsigned short type, unsigned short m) 824#else 825int 826gfx_set_video_downscale_config(unsigned short type, unsigned short m) 827#endif 828{ 829 unsigned long downscale; 830 831 if ((m < 1) || (m > 16)) 832 return GFX_STATUS_BAD_PARAMETER; 833 834 downscale = READ_VID32(SC1200_VIDEO_DOWNSCALER_CONTROL); 835 downscale &= 836 ~(SC1200_VIDEO_DOWNSCALE_FACTOR_MASK | 837 SC1200_VIDEO_DOWNSCALE_TYPE_MASK); 838 downscale |= ((m - 1l) << SC1200_VIDEO_DOWNSCALE_FACTOR_POS); 839 switch (type) { 840 case VIDEO_DOWNSCALE_KEEP_1_OF: 841 downscale |= SC1200_VIDEO_DOWNSCALE_TYPE_A; 842 break; 843 case VIDEO_DOWNSCALE_DROP_1_OF: 844 downscale |= SC1200_VIDEO_DOWNSCALE_TYPE_B; 845 break; 846 default: 847 return GFX_STATUS_BAD_PARAMETER; 848 } 849 WRITE_VID32(SC1200_VIDEO_DOWNSCALER_CONTROL, downscale); 850 return (0); 851} 852 853/*--------------------------------------------------------------------------- 854 * gfx_set_video_downscale_coefficients 855 * 856 * This routine sets the downscale filter coefficients. 857 *--------------------------------------------------------------------------- 858 */ 859#if GFX_VIDEO_DYNAMIC 860int 861sc1200_set_video_downscale_coefficients(unsigned short coef1, 862 unsigned short coef2, 863 unsigned short coef3, 864 unsigned short coef4) 865#else 866int 867gfx_set_video_downscale_coefficients(unsigned short coef1, 868 unsigned short coef2, 869 unsigned short coef3, 870 unsigned short coef4) 871#endif 872{ 873 if ((coef1 + coef2 + coef3 + coef4) != 16) 874 return GFX_STATUS_BAD_PARAMETER; 875 876 WRITE_VID32(SC1200_VIDEO_DOWNSCALER_COEFFICIENTS, 877 ((unsigned long)coef1 << SC1200_VIDEO_DOWNSCALER_COEF1_POS) | 878 ((unsigned long)coef2 << SC1200_VIDEO_DOWNSCALER_COEF2_POS) | 879 ((unsigned long)coef3 << SC1200_VIDEO_DOWNSCALER_COEF3_POS) | 880 ((unsigned long)coef4 << SC1200_VIDEO_DOWNSCALER_COEF4_POS)); 881 return (0); 882} 883 884/*--------------------------------------------------------------------------- 885 * gfx_set_video_downscale_enable 886 * 887 * This routine enables or disables downscaling for the video overlay window. 888 *--------------------------------------------------------------------------- 889 */ 890#if GFX_VIDEO_DYNAMIC 891int 892sc1200_set_video_downscale_enable(int enable) 893#else 894int 895gfx_set_video_downscale_enable(int enable) 896#endif 897{ 898 unsigned long downscale; 899 900 downscale = READ_VID32(SC1200_VIDEO_DOWNSCALER_CONTROL); 901 downscale &= ~SC1200_VIDEO_DOWNSCALE_ENABLE; 902 if (enable) 903 downscale |= SC1200_VIDEO_DOWNSCALE_ENABLE; 904 WRITE_VID32(SC1200_VIDEO_DOWNSCALER_CONTROL, downscale); 905 return (0); 906} 907 908/*--------------------------------------------------------------------------- 909 * gfx_set_video_window 910 * 911 * This routine sets the position and size of the video overlay window. The 912 * y position is specified in screen relative coordinates, and may be negative. 913 * The size of destination region is specified in pixels. The line size 914 * indicates the number of bytes of source data per scanline. 915 * For the effect of negative x values, call the function 916 * gfx_set_video_left_crop(). 917 *--------------------------------------------------------------------------- 918 */ 919#if GFX_VIDEO_DYNAMIC 920int 921sc1200_set_video_window(short x, short y, unsigned short w, unsigned short h) 922#else 923int 924gfx_set_video_window(short x, short y, unsigned short w, unsigned short h) 925#endif 926{ 927 unsigned long control; 928 unsigned long hadjust, vadjust; 929 unsigned long xstart, ystart, xend, yend; 930 931 /* For left cropping call the function gfx_set_video_left_crop() */ 932 933 if (x < 0) 934 return GFX_STATUS_BAD_PARAMETER; 935 936 /* SAVE PARAMETERS */ 937 /* These are needed to call this routine if the scale value changes. */ 938 /* In the case of SC1200 they are also needed for restoring when video is re-enabled */ 939 940 gfx_vid_xpos = x; 941 gfx_vid_ypos = y; 942 gfx_vid_width = w; 943 gfx_vid_height = h; 944 945 /* GET ADJUSTMENT VALUES */ 946 /* Use routines to abstract version of display controller. */ 947 948 hadjust = gfx_get_htotal() - gfx_get_hsync_end() - 14l; 949 vadjust = gfx_get_vtotal() - gfx_get_vsync_end() + 1l; 950 951 /* HORIZONTAL START */ 952 953 xstart = (unsigned long)x + hadjust; 954 955 /* HORIZONTAL END */ 956 /* End positions in register are non-inclusive (one more than the actual end) */ 957 958 if ((x + w) < gfx_get_hactive()) 959 xend = (unsigned long)x + (unsigned long)w + hadjust; 960 else /* right clipping needed */ 961 xend = (unsigned long)gfx_get_hactive() + hadjust; 962 963 /* VERTICAL START */ 964 965 ystart = (unsigned long)y + vadjust; 966 967 /* VERTICAL END */ 968 969 if ((y + h) < gfx_get_vactive()) 970 yend = (unsigned long)y + (unsigned long)h + vadjust; 971 else /* bottom clipping needed */ 972 yend = (unsigned long)gfx_get_vactive() + vadjust; 973 974 /* SET VIDEO LINE INVERT BIT */ 975 976 control = READ_VID32(SC1200_VID_ALPHA_CONTROL); 977 if (y & 0x1) 978 WRITE_VID32(SC1200_VID_ALPHA_CONTROL, 979 control | SC1200_VIDEO_LINE_OFFSET_ODD); 980 else 981 WRITE_VID32(SC1200_VID_ALPHA_CONTROL, 982 control & ~SC1200_VIDEO_LINE_OFFSET_ODD); 983 984 /* SET VIDEO POSITION */ 985 986 WRITE_VID32(SC1200_VIDEO_X_POS, (xend << 16) | xstart); 987 WRITE_VID32(SC1200_VIDEO_Y_POS, (yend << 16) | ystart); 988 989 return (0); 990} 991 992/*--------------------------------------------------------------------------- 993 * gfx_set_video_left_crop 994 * 995 * This routine sets the number of pixels which will be cropped from the 996 * beginning of each video line. The video window will begin to display only 997 * from the pixel following the cropped pixels, and the cropped pixels 998 * will be ignored. 999 *--------------------------------------------------------------------------- 1000 */ 1001#if GFX_VIDEO_DYNAMIC 1002int 1003sc1200_set_video_left_crop(unsigned short x) 1004#else 1005int 1006gfx_set_video_left_crop(unsigned short x) 1007#endif 1008{ 1009 unsigned long vcfg, initread; 1010 1011 /* CLIPPING ON LEFT */ 1012 /* Adjust initial read for scale, checking for divide by zero */ 1013 1014 if (gfx_vid_dstw) 1015 initread = (unsigned long)x *gfx_vid_srcw / gfx_vid_dstw; 1016 1017 else 1018 initread = 0l; 1019 1020 /* SET INITIAL READ ADDRESS */ 1021 1022 vcfg = READ_VID32(SC1200_VIDEO_CONFIG); 1023 vcfg &= ~SC1200_VCFG_INIT_READ_MASK; 1024 vcfg |= (initread << 15) & SC1200_VCFG_INIT_READ_MASK; 1025 WRITE_VID32(SC1200_VIDEO_CONFIG, vcfg); 1026 return (0); 1027} 1028 1029/*--------------------------------------------------------------------------- 1030 * gfx_set_video_color_key 1031 * 1032 * This routine specifies the color key value and mask for the video overlay 1033 * hardware. To disable color key, the color and mask should both be set to 1034 * zero. The hardware uses the color key in the following equation: 1035 * 1036 * ((source data) & (color key mask)) == ((color key) & (color key mask)) 1037 * 1038 * If "graphics" is set to TRUE, the source data is graphics, and color key 1039 * is an RGB value. If "graphics" is set to FALSE, the source data is the video, 1040 * and color key is a YUV value. 1041 *--------------------------------------------------------------------------- 1042 */ 1043#if GFX_VIDEO_DYNAMIC 1044int 1045sc1200_set_video_color_key(unsigned long key, unsigned long mask, 1046 int graphics) 1047#else 1048int 1049gfx_set_video_color_key(unsigned long key, unsigned long mask, int graphics) 1050#endif 1051{ 1052 unsigned long dcfg = 0; 1053 1054 /* SET SC1200 COLOR KEY VALUE */ 1055 1056 WRITE_VID32(SC1200_VIDEO_COLOR_KEY, key); 1057 WRITE_VID32(SC1200_VIDEO_COLOR_MASK, mask); 1058 1059 /* SELECT GRAPHICS OR VIDEO DATA TO COMPARE TO THE COLOR KEY */ 1060 1061 dcfg = READ_VID32(SC1200_DISPLAY_CONFIG); 1062 if (graphics & 0x01) 1063 dcfg &= ~SC1200_DCFG_VG_CK; 1064 else 1065 dcfg |= SC1200_DCFG_VG_CK; 1066 WRITE_VID32(SC1200_DISPLAY_CONFIG, dcfg); 1067 return (0); 1068} 1069 1070/*--------------------------------------------------------------------------- 1071 * gfx_set_video_filter 1072 * 1073 * This routine enables or disables the video overlay filters. 1074 *--------------------------------------------------------------------------- 1075 */ 1076#if GFX_VIDEO_DYNAMIC 1077int 1078sc1200_set_video_filter(int xfilter, int yfilter) 1079#else 1080int 1081gfx_set_video_filter(int xfilter, int yfilter) 1082#endif 1083{ 1084 unsigned long vcfg = 0; 1085 1086 /* ENABLE OR DISABLE SC1200 VIDEO OVERLAY FILTERS */ 1087 1088 vcfg = READ_VID32(SC1200_VIDEO_CONFIG); 1089 vcfg &= ~(SC1200_VCFG_X_FILTER_EN | SC1200_VCFG_Y_FILTER_EN); 1090 if (xfilter) 1091 vcfg |= SC1200_VCFG_X_FILTER_EN; 1092 if (yfilter) 1093 vcfg |= SC1200_VCFG_Y_FILTER_EN; 1094 WRITE_VID32(SC1200_VIDEO_CONFIG, vcfg); 1095 return (0); 1096} 1097 1098/*--------------------------------------------------------------------------- 1099 * gfx_set_video_palette 1100 * 1101 * This routine loads the video hardware palette. If a NULL pointer is 1102 * specified, the palette is bypassed (for SC1200, this means loading the 1103 * palette with identity values). 1104 *--------------------------------------------------------------------------- 1105 */ 1106#if GFX_VIDEO_DYNAMIC 1107int 1108sc1200_set_video_palette(unsigned long *palette) 1109#else 1110int 1111gfx_set_video_palette(unsigned long *palette) 1112#endif 1113{ 1114 unsigned long i, entry; 1115 1116 /* WAIT FOR VERTICAL BLANK TO END */ 1117 /* Otherwise palette will not be written properly. */ 1118 1119 if (gfx_test_timing_active()) { 1120 if (gfx_test_vertical_active()) { 1121 while (gfx_test_vertical_active()) ; 1122 } 1123 while (!gfx_test_vertical_active()) ; 1124 } 1125 1126 /* LOAD SC1200 VIDEO PALETTE */ 1127 1128 WRITE_VID32(SC1200_PALETTE_ADDRESS, 0); 1129 for (i = 0; i < 256; i++) { 1130 if (palette) 1131 entry = palette[i]; 1132 else 1133 entry = (i << 8) | (i << 16) | (i << 24); 1134 WRITE_VID32(SC1200_PALETTE_DATA, entry); 1135 } 1136 return (0); 1137} 1138 1139/*--------------------------------------------------------------------------- 1140 * gfx_set_video_palette_entry 1141 * 1142 * This routine loads a single entry of the video hardware palette. 1143 *--------------------------------------------------------------------------- 1144 */ 1145#if GFX_VIDEO_DYNAMIC 1146int 1147sc1200_set_video_palette_entry(unsigned long index, unsigned long palette) 1148#else 1149int 1150gfx_set_video_palette_entry(unsigned long index, unsigned long palette) 1151#endif 1152{ 1153 if (index > 0xFF) 1154 return GFX_STATUS_BAD_PARAMETER; 1155 1156 /* WAIT FOR VERTICAL BLANK TO END */ 1157 /* Otherwise palette will not be written properly. */ 1158 1159 if (gfx_test_timing_active()) { 1160 if (gfx_test_vertical_active()) { 1161 while (gfx_test_vertical_active()) ; 1162 } 1163 while (!gfx_test_vertical_active()) ; 1164 } 1165 1166 /* SET A SINGLE ENTRY */ 1167 1168 WRITE_VID32(SC1200_PALETTE_ADDRESS, index); 1169 WRITE_VID32(SC1200_PALETTE_DATA, palette); 1170 1171 return (0); 1172} 1173 1174/*--------------------------------------------------------------------------- 1175 * gfx_set_video_request() 1176 * 1177 * This routine sets the horizontal (pixel) and vertical (line) video request 1178 * values. 1179 *--------------------------------------------------------------------------- 1180 */ 1181#if GFX_VIDEO_DYNAMIC 1182int 1183sc1200_set_video_request(short x, short y) 1184#else 1185int 1186gfx_set_video_request(short x, short y) 1187#endif 1188{ 1189 /* SET SC1200 VIDEO REQUEST */ 1190 1191 x += gfx_get_htotal() - gfx_get_hsync_end() - 2; 1192 y += gfx_get_vtotal() - gfx_get_vsync_end() + 1; 1193 1194 if ((x < 0) || (x > SC1200_VIDEO_REQUEST_MASK) || 1195 (y < 0) || (y > SC1200_VIDEO_REQUEST_MASK)) 1196 return GFX_STATUS_BAD_PARAMETER; 1197 1198 WRITE_VID32(SC1200_VIDEO_REQUEST, 1199 ((unsigned long)x << SC1200_VIDEO_X_REQUEST_POS) | 1200 ((unsigned long)y << SC1200_VIDEO_Y_REQUEST_POS)); 1201 return (0); 1202} 1203 1204/*--------------------------------------------------------------------------- 1205 * gfx_set_video_source() 1206 * 1207 * This routine sets the video source to either memory or Direct VIP. 1208 *--------------------------------------------------------------------------- 1209 */ 1210#if GFX_VIDEO_DYNAMIC 1211int 1212sc1200_set_video_source(VideoSourceType source) 1213#else 1214int 1215gfx_set_video_source(VideoSourceType source) 1216#endif 1217{ 1218 unsigned long display_mode; 1219 1220 display_mode = READ_VID32(SC1200_VIDEO_DISPLAY_MODE); 1221 1222 /* SET SC1200 VIDEO SOURCE */ 1223 switch (source) { 1224 case VIDEO_SOURCE_MEMORY: 1225 WRITE_VID32(SC1200_VIDEO_DISPLAY_MODE, 1226 (display_mode & ~SC1200_VIDEO_SOURCE_MASK) | 1227 SC1200_VIDEO_SOURCE_GX1); 1228 break; 1229 case VIDEO_SOURCE_DVIP: 1230 WRITE_VID32(SC1200_VIDEO_DISPLAY_MODE, 1231 (display_mode & ~SC1200_VIDEO_SOURCE_MASK) | 1232 SC1200_VIDEO_SOURCE_DVIP); 1233 break; 1234 default: 1235 return GFX_STATUS_BAD_PARAMETER; 1236 } 1237 return (0); 1238} 1239 1240/*--------------------------------------------------------------------------- 1241 * gfx_set_vbi_source() 1242 * 1243 * This routine sets the vbi source to either memory or Direct VIP. 1244 *--------------------------------------------------------------------------- 1245 */ 1246#if GFX_VIDEO_DYNAMIC 1247int 1248sc1200_set_vbi_source(VbiSourceType source) 1249#else 1250int 1251gfx_set_vbi_source(VbiSourceType source) 1252#endif 1253{ 1254 unsigned long display_mode; 1255 1256 display_mode = READ_VID32(SC1200_VIDEO_DISPLAY_MODE); 1257 1258 /* SET SC1200 VBI SOURCE */ 1259 switch (source) { 1260 case VBI_SOURCE_MEMORY: 1261 WRITE_VID32(SC1200_VIDEO_DISPLAY_MODE, 1262 (display_mode & ~SC1200_VBI_SOURCE_MASK) | 1263 SC1200_VBI_SOURCE_GX1); 1264 break; 1265 case VBI_SOURCE_DVIP: 1266 WRITE_VID32(SC1200_VIDEO_DISPLAY_MODE, 1267 (display_mode & ~SC1200_VBI_SOURCE_MASK) | 1268 SC1200_VBI_SOURCE_DVIP); 1269 break; 1270 default: 1271 return GFX_STATUS_BAD_PARAMETER; 1272 } 1273 return (0); 1274} 1275 1276/*--------------------------------------------------------------------------- 1277 * gfx_set_vbi_lines() 1278 * 1279 * This routine sets the VBI lines to pass to the TV encoder. 1280 *--------------------------------------------------------------------------- 1281 */ 1282#if GFX_VIDEO_DYNAMIC 1283int 1284sc1200_set_vbi_lines(unsigned long even, unsigned long odd) 1285#else 1286int 1287gfx_set_vbi_lines(unsigned long even, unsigned long odd) 1288#endif 1289{ 1290 /* SET SC1200 VBI LINES */ 1291 WRITE_VID32(SC1200_VIDEO_EVEN_VBI_LINE_ENABLE, 1292 even & SC1200_VIDEO_VBI_LINE_ENABLE_MASK); 1293 WRITE_VID32(SC1200_VIDEO_ODD_VBI_LINE_ENABLE, 1294 odd & SC1200_VIDEO_VBI_LINE_ENABLE_MASK); 1295 return (0); 1296} 1297 1298/*--------------------------------------------------------------------------- 1299 * gfx_set_vbi_total() 1300 * 1301 * This routine sets the total number of VBI bytes for each field. 1302 * The total is needed when both VBI and active video are received from memory. 1303 *--------------------------------------------------------------------------- 1304 */ 1305#if GFX_VIDEO_DYNAMIC 1306int 1307sc1200_set_vbi_total(unsigned long even, unsigned long odd) 1308#else 1309int 1310gfx_set_vbi_total(unsigned long even, unsigned long odd) 1311#endif 1312{ 1313 /* SET SC1200 VBI TOTAL */ 1314 WRITE_VID32(SC1200_VIDEO_EVEN_VBI_TOTAL_COUNT, 1315 even & SC1200_VIDEO_VBI_TOTAL_COUNT_MASK); 1316 WRITE_VID32(SC1200_VIDEO_ODD_VBI_TOTAL_COUNT, 1317 odd & SC1200_VIDEO_VBI_TOTAL_COUNT_MASK); 1318 return (0); 1319} 1320 1321/*--------------------------------------------------------------------------- 1322 * gfx_set_video_interlaced() 1323 * 1324 * This routine configures the video processor video overlay mode to be 1325 * interlaced YUV. 1326 *--------------------------------------------------------------------------- 1327 */ 1328#if GFX_VIDEO_DYNAMIC 1329int 1330sc1200_set_video_interlaced(int enable) 1331#else 1332int 1333gfx_set_video_interlaced(int enable) 1334#endif 1335{ 1336 unsigned long control; 1337 1338 control = READ_VID32(SC1200_VID_ALPHA_CONTROL); 1339 /* SET INTERLACED VIDEO */ 1340 if (enable) 1341 WRITE_VID32(SC1200_VID_ALPHA_CONTROL, 1342 control | SC1200_VIDEO_IS_INTERLACED); 1343 else 1344 WRITE_VID32(SC1200_VID_ALPHA_CONTROL, 1345 control & ~SC1200_VIDEO_IS_INTERLACED); 1346 return (0); 1347} 1348 1349/*--------------------------------------------------------------------------- 1350 * gfx_set_color_space_YUV() 1351 * 1352 * This routine configures the video processor to process graphics and video 1353 * in either YUV or RGB color space. The mode should be set to tune image 1354 * quality. 1355 * Setting "enable" to TRUE improves image quality on TV, 1356 * but in this mode colors on CRT will not be correct. 1357 *--------------------------------------------------------------------------- 1358 */ 1359#if GFX_VIDEO_DYNAMIC 1360int 1361sc1200_set_color_space_YUV(int enable) 1362#else 1363int 1364gfx_set_color_space_YUV(int enable) 1365#endif 1366{ 1367 unsigned long control; 1368 1369 control = READ_VID32(SC1200_VID_ALPHA_CONTROL); 1370 1371 /* SET SC1200 VIDEO COLOR SPACE TO YUV OR RGB */ 1372 1373 if (enable) { 1374 /* ENABLE YUV BLENDING */ 1375 /* YUV blending cannot be enabled in RGB video formats */ 1376 1377 control |= SC1200_CSC_GFX_RGB_TO_YUV; /* Convert graphics to YUV */ 1378 control &= ~SC1200_CSC_VIDEO_YUV_TO_RGB; /* Leave video in YUV */ 1379 1380 if (control & SC1200_VIDEO_INPUT_IS_RGB) 1381 return (GFX_STATUS_UNSUPPORTED); /* Can't convert video from RGB to YUV */ 1382 } else { 1383 /* RGB BLENDING */ 1384 1385 control &= ~SC1200_CSC_GFX_RGB_TO_YUV; /* Leave graphics in RGB */ 1386 if (control & SC1200_VIDEO_INPUT_IS_RGB) 1387 control &= ~SC1200_CSC_VIDEO_YUV_TO_RGB; /* Leave video in RGB */ 1388 else 1389 control |= SC1200_CSC_VIDEO_YUV_TO_RGB; /* Convert video to RGB */ 1390 } 1391 WRITE_VID32(SC1200_VID_ALPHA_CONTROL, control); 1392 return (0); 1393} 1394 1395/*--------------------------------------------------------------------------- 1396 * gfx_set_vertical_scaler_offset() 1397 * 1398 * This routine sets the value by which the odd frame is shifted with respect 1399 * to the even frame. This is useful for de-interlacing in Bob method, by 1400 * setting the shift value to be one line. 1401 * If offset is 0, no shifting occurs. 1402 *--------------------------------------------------------------------------- 1403 */ 1404#if GFX_VIDEO_DYNAMIC 1405int 1406sc1200_set_vertical_scaler_offset(char offset) 1407#else 1408int 1409gfx_set_vertical_scaler_offset(char offset) 1410#endif 1411{ 1412 unsigned long control; 1413 1414 control = READ_VID32(SC1200_VID_ALPHA_CONTROL); 1415 if (offset == 1) { 1416 control &= ~SC1200_VERTICAL_SCALER_SHIFT_MASK; /* Clear shifting value */ 1417 control |= SC1200_VERTICAL_SCALER_SHIFT_INIT; /* Set shifting value */ 1418 control |= SC1200_VERTICAL_SCALER_SHIFT_EN; /* Enable odd frame shifting */ 1419 } else if (offset == 0) { 1420 control &= ~SC1200_VERTICAL_SCALER_SHIFT_EN; /* No shifting occurs */ 1421 control &= ~SC1200_VERTICAL_SCALER_SHIFT_MASK; /* Clear shifting value */ 1422 } else 1423 return (GFX_STATUS_BAD_PARAMETER); /* TODO: how to program other values ? */ 1424 WRITE_VID32(SC1200_VID_ALPHA_CONTROL, control); 1425 return (0); 1426} 1427 1428/*--------------------------------------------------------------------------- 1429 * gfx_set_top_line_in_odd() 1430 * 1431 * This routine sets the field in which the top line of input video resides. 1432 * If enable is "0", this is the even field (default). [not to be confused 1433 * with the odd field being the top field on TV]. 1434 * If enable is "1", this is the odd field. 1435 * Use enable "1" for input devices whose field indication is reversed from 1436 * normal, i.e. an indication of "odd" field is given for even field data, 1437 * and vice versa. 1438 * This setting affects the video processor only when it is in either interlaced 1439 * or Bob (scaler offset active) modes. 1440 *--------------------------------------------------------------------------- 1441 */ 1442#if GFX_VIDEO_DYNAMIC 1443int 1444sc1200_set_top_line_in_odd(int enable) 1445#else 1446int 1447gfx_set_top_line_in_odd(int enable) 1448#endif 1449{ 1450 unsigned long control; 1451 1452 control = READ_VID32(SC1200_VID_ALPHA_CONTROL); 1453 if (enable) 1454 control |= SC1200_TOP_LINE_IN_ODD; /* Set shifting value */ 1455 else 1456 control &= ~SC1200_TOP_LINE_IN_ODD; /* No shifting occurs */ 1457 WRITE_VID32(SC1200_VID_ALPHA_CONTROL, control); 1458 return (0); 1459} 1460 1461/*--------------------------------------------------------------------------- 1462 * gfx_set_genlock_delay() 1463 * 1464 * This routine sets the delay between VIP VSYNC and display controller VSYNC. 1465 * The delay is in 27 MHz clocks. 1466 *--------------------------------------------------------------------------- 1467 */ 1468#if GFX_VIDEO_DYNAMIC 1469int 1470sc1200_set_genlock_delay(unsigned long delay) 1471#else 1472int 1473gfx_set_genlock_delay(unsigned long delay) 1474#endif 1475{ 1476 /* SET SC1200 GENLOCK DELAY */ 1477 WRITE_VID32(SC1200_GENLOCK_DELAY, delay & SC1200_GENLOCK_DELAY_MASK); 1478 return (0); 1479} 1480 1481/*--------------------------------------------------------------------------- 1482 * gfx_set_genlock_enable() 1483 * 1484 * This routine sets and configures the genlock according to the flags parameter. 1485 * Flags value of 0 disables genlock and resets its configuration. 1486 *--------------------------------------------------------------------------- 1487 */ 1488#if GFX_VIDEO_DYNAMIC 1489int 1490sc1200_set_genlock_enable(int flags) 1491#else 1492int 1493gfx_set_genlock_enable(int flags) 1494#endif 1495{ 1496 unsigned long genlock = 0; 1497 1498 if (flags) { 1499 /* SET SC1200 GENLOCK CONFIGURATION */ 1500 if (flags & GENLOCK_SINGLE) 1501 genlock |= SC1200_GENLOCK_SINGLE_ENABLE; 1502 if (flags & GENLOCK_FIELD_SYNC) 1503 genlock |= SC1200_GENLOCK_FIELD_SYNC_ENABLE; 1504 if (flags & GENLOCK_CONTINUOUS) 1505 genlock |= SC1200_GENLOCK_CONTINUOUS_ENABLE; 1506 if (flags & GENLOCK_SYNCED_EDGE_FALLING) 1507 genlock |= SC1200_GENLOCK_GX_VSYNC_FALLING_EDGE; 1508 if (flags & GENLOCK_SYNCING_EDGE_FALLING) 1509 genlock |= SC1200_GENLOCK_VIP_VSYNC_FALLING_EDGE; 1510 if (flags & GENLOCK_TIMEOUT) 1511 genlock |= SC1200_GENLOCK_TIMEOUT_ENABLE; 1512 if (flags & GENLOCK_TVENC_RESET_EVEN_FIELD) 1513 genlock |= SC1200_GENLOCK_TVENC_RESET_EVEN_FIELD; 1514 if (flags & GENLOCK_TVENC_RESET_BEFORE_DELAY) 1515 genlock |= SC1200_GENLOCK_TVENC_RESET_BEFORE_DELAY; 1516 if (flags & GENLOCK_TVENC_RESET) 1517 genlock |= SC1200_GENLOCK_TVENC_RESET_ENABLE; 1518 if (flags & GENLOCK_SYNC_TO_TVENC) 1519 genlock |= SC1200_GENLOCK_SYNC_TO_TVENC; 1520 } 1521 WRITE_VID32(SC1200_GENLOCK, genlock); 1522 return (0); 1523} 1524 1525/*--------------------------------------------------------------------------- 1526 * gfx_set_video_cursor() 1527 * 1528 * This routine configures the video hardware cursor. 1529 * If the "mask"ed bits in the graphics pixel match "key", then either "color1" 1530 * or "color2" will be used for this pixel, according to the value of bit 1531 * number "select_color2" of the graphics pixel. 1532 * 1533 * key - 24 bit RGB value 1534 * mask - 24 bit mask 1535 * color1, color2 - RGB or YUV, depending on the current color space conversion 1536 * select_color2 - value between 0 to 23 1537 * 1538 * To disable match, a "mask" and "key" value of 0xffffff should be set, 1539 * because the graphics pixels incoming to the video processor have maximum 16 1540 * bits set (0xF8FCF8). 1541 * 1542 * This feature is useful for disabling alpha blending of the cursor. 1543 * Otherwise cursor image would be blurred (or completely invisible if video 1544 * alpha is maximum value). 1545 * Note: the cursor pixel replacements take place both inside and outside the 1546 * video overlay window. 1547 *--------------------------------------------------------------------------- 1548 */ 1549#if GFX_VIDEO_DYNAMIC 1550int 1551sc1200_set_video_cursor(unsigned long key, unsigned long mask, 1552 unsigned short select_color2, unsigned long color1, 1553 unsigned long color2) 1554#else 1555int 1556gfx_set_video_cursor(unsigned long key, unsigned long mask, 1557 unsigned short select_color2, unsigned long color1, 1558 unsigned long color2) 1559#endif 1560{ 1561 if (select_color2 > SC1200_CURSOR_COLOR_BITS) 1562 return GFX_STATUS_BAD_PARAMETER; 1563 key = (key & SC1200_COLOR_MASK) | ((unsigned long)select_color2 << 1564 SC1200_CURSOR_COLOR_KEY_OFFSET_POS); 1565 WRITE_VID32(SC1200_CURSOR_COLOR_KEY, key); 1566 WRITE_VID32(SC1200_CURSOR_COLOR_MASK, mask); 1567 WRITE_VID32(SC1200_CURSOR_COLOR_1, color1); 1568 WRITE_VID32(SC1200_CURSOR_COLOR_2, color2); 1569 return (0); 1570} 1571 1572/*--------------------------------------------------------------------------- 1573 * gfx_set_alpha_enable 1574 * 1575 * This routine enables or disables the currently selected alpha region. 1576 *--------------------------------------------------------------------------- 1577 */ 1578#if GFX_VIDEO_DYNAMIC 1579int 1580sc1200_set_alpha_enable(int enable) 1581#else 1582int 1583gfx_set_alpha_enable(int enable) 1584#endif 1585{ 1586 unsigned long address = 0, value = 0; 1587 1588 if (gfx_alpha_select > 2) 1589 return (GFX_STATUS_UNSUPPORTED); 1590 address = SC1200_ALPHA_CONTROL_1 + ((unsigned long)gfx_alpha_select << 4); 1591 value = READ_VID32(address); 1592 if (enable) 1593 value |= (SC1200_ACTRL_WIN_ENABLE | SC1200_ACTRL_LOAD_ALPHA); 1594 else 1595 value &= ~(SC1200_ACTRL_WIN_ENABLE); 1596 WRITE_VID32(address, value); 1597 return (GFX_STATUS_OK); 1598} 1599 1600/*--------------------------------------------------------------------------- 1601 * gfx_set_alpha_window 1602 * 1603 * This routine sets the size of the currently selected alpha region. 1604 * Note: "x" and "y" are signed to enable using negative values needed for 1605 * implementing workarounds of hardware issues. 1606 *--------------------------------------------------------------------------- 1607 */ 1608#if GFX_VIDEO_DYNAMIC 1609int 1610sc1200_set_alpha_window(short x, short y, 1611 unsigned short width, unsigned short height) 1612#else 1613int 1614gfx_set_alpha_window(short x, short y, 1615 unsigned short width, unsigned short height) 1616#endif 1617{ 1618 unsigned long address = 0; 1619 1620 /* CHECK FOR CLIPPING */ 1621 1622 if ((x + width) > gfx_get_hactive()) 1623 width = gfx_get_hactive() - x; 1624 if ((y + height) > gfx_get_vactive()) 1625 height = gfx_get_vactive() - y; 1626 1627 /* ADJUST POSITIONS */ 1628 1629 x += gfx_get_htotal() - gfx_get_hsync_end() - 2; 1630 y += gfx_get_vtotal() - gfx_get_vsync_end() + 1; 1631 1632 if (gfx_alpha_select > 2) 1633 return (GFX_STATUS_UNSUPPORTED); 1634 address = SC1200_ALPHA_XPOS_1 + ((unsigned long)gfx_alpha_select << 4); 1635 1636 /* End positions in register are non-inclusive (one more than the actual end) */ 1637 1638 WRITE_VID32(address, (unsigned long)x | 1639 ((unsigned long)(x + width) << 16)); 1640 WRITE_VID32(address + 4l, (unsigned long)y | 1641 ((unsigned long)(y + height) << 16)); 1642 return (GFX_STATUS_OK); 1643} 1644 1645/*--------------------------------------------------------------------------- 1646 * gfx_set_alpha_value 1647 * 1648 * This routine sets the alpha value for the currently selected alpha 1649 * region. It also specifies an increment/decrement value for fading. 1650 *--------------------------------------------------------------------------- 1651 */ 1652#if GFX_VIDEO_DYNAMIC 1653int 1654sc1200_set_alpha_value(unsigned char alpha, char delta) 1655#else 1656int 1657gfx_set_alpha_value(unsigned char alpha, char delta) 1658#endif 1659{ 1660 unsigned long address = 0, value = 0; 1661 unsigned char new_value = 0; 1662 int loop = 1; 1663 1664 if (gfx_alpha_select > 2) 1665 return (GFX_STATUS_UNSUPPORTED); 1666 address = SC1200_ALPHA_CONTROL_1 + ((unsigned long)gfx_alpha_select << 4); 1667 value = READ_VID32(address); 1668 value &= SC1200_ACTRL_WIN_ENABLE; /* keep only enable bit */ 1669 value |= (unsigned long)alpha; 1670 value |= (((unsigned long)delta) & 0xff) << 8; 1671 value |= SC1200_ACTRL_LOAD_ALPHA; 1672 WRITE_VID32(address, value); 1673 1674 /* WORKAROUND FOR ISSUE #1187 */ 1675 /* Need to verify that the alpha operation succeeded */ 1676 1677 while (1) { 1678 /* WAIT FOR VERTICAL BLANK TO END */ 1679 if (gfx_test_timing_active()) { 1680 if (gfx_test_vertical_active()) 1681 while (gfx_test_vertical_active()) ; 1682 while (!gfx_test_vertical_active()) ; 1683 } 1684 new_value = 1685 (unsigned 1686 char)((READ_VID32(SC1200_ALPHA_WATCH) >> (gfx_alpha_select << 3)) 1687 & 0xff); 1688 if (new_value == alpha) 1689 return GFX_STATUS_OK; 1690 if (++loop > 10) 1691 return GFX_STATUS_ERROR; 1692 WRITE_VID32(address, value); 1693 } 1694} 1695 1696/*--------------------------------------------------------------------------- 1697 * gfx_set_alpha_priority 1698 * 1699 * This routine sets the priority of the currently selected alpha region. 1700 * A higher value indicates a higher priority. 1701 * Note: Priority of enabled alpha windows must be different. 1702 *--------------------------------------------------------------------------- 1703 */ 1704#if GFX_VIDEO_DYNAMIC 1705int 1706sc1200_set_alpha_priority(int priority) 1707#else 1708int 1709gfx_set_alpha_priority(int priority) 1710#endif 1711{ 1712 unsigned long pos = 0, value = 0; 1713 1714 if (priority > 3) 1715 return (GFX_STATUS_BAD_PARAMETER); 1716 if (gfx_alpha_select > 2) 1717 return (GFX_STATUS_UNSUPPORTED); 1718 value = READ_VID32(SC1200_VID_ALPHA_CONTROL); 1719 pos = 16 + (gfx_alpha_select << 1); 1720 value &= ~(0x03l << pos); 1721 value |= (unsigned long)priority << pos; 1722 WRITE_VID32(SC1200_VID_ALPHA_CONTROL, value); 1723 return (GFX_STATUS_OK); 1724} 1725 1726/*--------------------------------------------------------------------------- 1727 * gfx_set_alpha_color 1728 * 1729 * This routine sets the color to be displayed inside the currently selected 1730 * alpha window when there is a color key match (when the alpha color 1731 * mechanism is enabled). 1732 * "color" is a 24 bit RGB value (for RGB blending) or YUV value (for YUV blending). 1733 * In Interlaced YUV blending mode, Y/2 value should be used. 1734 *--------------------------------------------------------------------------- 1735 */ 1736#if GFX_VIDEO_DYNAMIC 1737int 1738sc1200_set_alpha_color(unsigned long color) 1739#else 1740int 1741gfx_set_alpha_color(unsigned long color) 1742#endif 1743{ 1744 unsigned long address = 0; 1745 1746 if (gfx_alpha_select > 2) 1747 return (GFX_STATUS_UNSUPPORTED); 1748 address = SC1200_ALPHA_COLOR_1 + ((unsigned long)gfx_alpha_select << 4); 1749 1750 /* ONLY 24 VALID BITS */ 1751 color &= 0xffffffl; 1752 1753 /* KEEP UPPER BYTE UNCHANGED */ 1754 WRITE_VID32(address, (color | (READ_VID32(address) & ~0xffffffl))); 1755 return (GFX_STATUS_OK); 1756} 1757 1758/*--------------------------------------------------------------------------- 1759 * gfx_set_alpha_color_enable 1760 * 1761 * Enable or disable the color mechanism in the alpha window. 1762 *--------------------------------------------------------------------------- 1763 */ 1764#if GFX_VIDEO_DYNAMIC 1765int 1766sc1200_set_alpha_color_enable(int enable) 1767#else 1768int 1769gfx_set_alpha_color_enable(int enable) 1770#endif 1771{ 1772 unsigned long color; 1773 unsigned long address = 0; 1774 1775 if (gfx_alpha_select > 2) 1776 return (GFX_STATUS_UNSUPPORTED); 1777 address = SC1200_ALPHA_COLOR_1 + ((unsigned long)gfx_alpha_select << 4); 1778 color = READ_VID32(address); 1779 if (enable) 1780 color |= SC1200_ALPHA_COLOR_ENABLE; 1781 else 1782 color &= ~SC1200_ALPHA_COLOR_ENABLE; 1783 WRITE_VID32(address, color); 1784 return (GFX_STATUS_OK); 1785} 1786 1787/*--------------------------------------------------------------------------- 1788 * gfx_set_no_ck_outside_alpha 1789 * 1790 * This function affects where inside the video window color key or chroma 1791 * key comparison is done: 1792 * If enable is TRUE, color/chroma key comparison is performed only inside 1793 * the enabled alpha windows. Outside the (enabled) alpha windows, only video 1794 * is displayed if color key is used, and only graphics is displayed if chroma 1795 * key is used. 1796 * If enable is FALSE, color/chroma key comparison is performed in all the 1797 * video window area. 1798 *--------------------------------------------------------------------------- 1799 */ 1800#if GFX_VIDEO_DYNAMIC 1801int 1802sc1200_set_no_ck_outside_alpha(int enable) 1803#else 1804int 1805gfx_set_no_ck_outside_alpha(int enable) 1806#endif 1807{ 1808 unsigned long value; 1809 1810 value = READ_VID32(SC1200_VID_ALPHA_CONTROL); 1811 if (enable) 1812 WRITE_VID32(SC1200_VID_ALPHA_CONTROL, 1813 value | SC1200_NO_CK_OUTSIDE_ALPHA); 1814 else 1815 WRITE_VID32(SC1200_VID_ALPHA_CONTROL, 1816 value & ~SC1200_NO_CK_OUTSIDE_ALPHA); 1817 return (0); 1818} 1819 1820/*--------------------------------------------------------------------------- 1821 * gfx_set_macrovision_enable 1822 * 1823 * This routine enables or disables macrovision on the tv encoder output. 1824 *--------------------------------------------------------------------------- 1825 */ 1826#if GFX_VIDEO_DYNAMIC 1827int 1828sc1200_set_macrovision_enable(int enable) 1829#else 1830int 1831gfx_set_macrovision_enable(int enable) 1832#endif 1833{ 1834 if (enable) 1835 WRITE_VID32(SC1200_TVENC_MV_CONTROL, SC1200_TVENC_MV_ENABLE); 1836 else 1837 WRITE_VID32(SC1200_TVENC_MV_CONTROL, 0); 1838 return (GFX_STATUS_OK); 1839} 1840 1841#define SC1200_VIDEO_PCI_44 0x80009444 1842 1843/*--------------------------------------------------------------------------- 1844 * gfx_disable_softvga 1845 * 1846 * Disables SoftVga. This function is only valid with VSA2, Returns 1 if 1847 * SoftVga can be disabled; 0 if not. 1848 *--------------------------------------------------------------------------- 1849 */ 1850#if GFX_VIDEO_DYNAMIC 1851int 1852sc1200_disable_softvga(void) 1853#else 1854int 1855gfx_disable_softvga(void) 1856#endif 1857{ 1858 unsigned long reg_val; 1859 1860 /* get the current value */ 1861 reg_val = gfx_pci_config_read(SC1200_VIDEO_PCI_44); 1862 /* setting video PCI register 44 bit 0 to 1 disables SoftVga */ 1863 reg_val |= 0x1; 1864 gfx_pci_config_write(SC1200_VIDEO_PCI_44, reg_val); 1865 1866 /* see if we set the bit and return the appropriate value */ 1867 reg_val = gfx_pci_config_read(SC1200_VIDEO_PCI_44); 1868 if ((reg_val & 0x1) == 0x1) 1869 return (1); 1870 else 1871 return (0); 1872} 1873 1874/*--------------------------------------------------------------------------- 1875 * gfx_enable_softvga 1876 * 1877 * Enables SoftVga. This function is only valid with VSA2, Returns 1 if 1878 * SoftVga can be enbled; 0 if not. 1879 *--------------------------------------------------------------------------- 1880 */ 1881#if GFX_VIDEO_DYNAMIC 1882int 1883sc1200_enable_softvga(void) 1884#else 1885int 1886gfx_enable_softvga(void) 1887#endif 1888{ 1889 unsigned long reg_val; 1890 1891 /* get the current value */ 1892 reg_val = gfx_pci_config_read(SC1200_VIDEO_PCI_44); 1893 /* clearing video PCI register 44 bit 0 enables SoftVga */ 1894 gfx_pci_config_write(SC1200_VIDEO_PCI_44, reg_val & 0xfffffffel); 1895 1896 /* see if we cleared the bit and return the appropriate value */ 1897 reg_val = gfx_pci_config_read(SC1200_VIDEO_PCI_44); 1898 if ((reg_val & 0x1) == 0) 1899 return (1); 1900 else 1901 return (0); 1902} 1903 1904/*--------------------------------------------------------------------------- 1905 * gfx_get_clock_frequency 1906 * 1907 * This routine returns the current clock frequency in 16.16 format. 1908 * It reads the current register value and finds the match in the table. 1909 * If no match is found, this routine returns 0. 1910 *--------------------------------------------------------------------------- 1911 */ 1912#if GFX_VIDEO_DYNAMIC 1913unsigned long 1914sc1200_get_clock_frequency(void) 1915#else 1916unsigned long 1917gfx_get_clock_frequency(void) 1918#endif 1919{ 1920 unsigned int index; 1921 unsigned long value, mask; 1922 1923 mask = 0x007FFF0F; 1924 value = READ_VID32(SC1200_VID_CLOCK_SELECT) & mask; 1925 for (index = 0; index < NUM_SC1200_FREQUENCIES; index++) { 1926 if ((gfx_sc1200_clock_table[index].clock_select & mask) == value) 1927 return (gfx_sc1200_clock_table[index].frequency); 1928 } 1929 return (0); 1930} 1931 1932/*************************************************************/ 1933/* READ ROUTINES | INCLUDED FOR DIAGNOSTIC PURPOSES ONLY */ 1934/*************************************************************/ 1935 1936#if GFX_READ_ROUTINES 1937 1938/*--------------------------------------------------------------------------- 1939 * gfx_get_vsa2_softvga_enable 1940 * 1941 * This function returns the enable status of SoftVGA. It is valid 1942 * only if VSAII is present. 1943 *--------------------------------------------------------------------------- 1944 */ 1945#if GFX_VIDEO_DYNAMIC 1946int 1947sc1200_get_vsa2_softvga_enable(void) 1948#else 1949int 1950gfx_get_vsa2_softvga_enable(void) 1951#endif 1952{ 1953 unsigned long reg_val; 1954 1955 reg_val = gfx_pci_config_read(SC1200_VIDEO_PCI_44); 1956 if ((reg_val & 0x1) == 0) 1957 return (1); 1958 else 1959 return (0); 1960 1961} 1962 1963/*--------------------------------------------------------------------------- 1964 * gfx_get_sync_polarities 1965 * 1966 * This routine returns the polarities of the sync pulses: 1967 * Bit 0: Set if negative horizontal polarity. 1968 * Bit 1: Set if negative vertical polarity. 1969 *--------------------------------------------------------------------------- 1970 */ 1971#if GFX_VIDEO_DYNAMIC 1972int 1973sc1200_get_sync_polarities(void) 1974#else 1975int 1976gfx_get_sync_polarities(void) 1977#endif 1978{ 1979 int polarities = 0; 1980 1981 if (READ_VID32(SC1200_DISPLAY_CONFIG) & SC1200_DCFG_CRT_HSYNC_POL) 1982 polarities |= 1; 1983 if (READ_VID32(SC1200_DISPLAY_CONFIG) & SC1200_DCFG_CRT_VSYNC_POL) 1984 polarities |= 2; 1985 return (polarities); 1986} 1987 1988/*--------------------------------------------------------------------------- 1989 * gfx_get_video_palette_entry 1990 * 1991 * This routine returns a single palette entry. 1992 *--------------------------------------------------------------------------- 1993 */ 1994#if GFX_VIDEO_DYNAMIC 1995int 1996sc1200_get_video_palette_entry(unsigned long index, unsigned long *palette) 1997#else 1998int 1999gfx_get_video_palette_entry(unsigned long index, unsigned long *palette) 2000#endif 2001{ 2002 if (index > 0xFF) 2003 return GFX_STATUS_BAD_PARAMETER; 2004 2005 /* READ A SINGLE ENTRY */ 2006 2007 WRITE_VID32(SC1200_PALETTE_ADDRESS, index); 2008 *palette = READ_VID32(SC1200_PALETTE_DATA); 2009 2010 return (GFX_STATUS_OK); 2011} 2012 2013/*----------------------------------------------------------------------------- 2014 * gfx_get_video_enable 2015 * 2016 * This routine returns the value "one" if video overlay is currently enabled, 2017 * otherwise it returns the value "zero". 2018 *----------------------------------------------------------------------------- 2019 */ 2020#if GFX_VIDEO_DYNAMIC 2021int 2022sc1200_get_video_enable(void) 2023#else 2024int 2025gfx_get_video_enable(void) 2026#endif 2027{ 2028 if (READ_VID32(SC1200_VIDEO_CONFIG) & SC1200_VCFG_VID_EN) 2029 return (1); 2030 return (0); 2031} 2032 2033/*----------------------------------------------------------------------------- 2034 * gfx_get_video_format 2035 * 2036 * This routine returns the current video overlay format. 2037 *----------------------------------------------------------------------------- 2038 */ 2039#if GFX_VIDEO_DYNAMIC 2040int 2041sc1200_get_video_format(void) 2042#else 2043int 2044gfx_get_video_format(void) 2045#endif 2046{ 2047 unsigned long ctrl, vcfg; 2048 2049 ctrl = READ_VID32(SC1200_VID_ALPHA_CONTROL); 2050 vcfg = READ_VID32(SC1200_VIDEO_CONFIG); 2051 2052 if (ctrl & SC1200_VIDEO_INPUT_IS_RGB) { 2053 switch (vcfg & SC1200_VCFG_VID_INP_FORMAT) { 2054 case SC1200_VCFG_UYVY_FORMAT: 2055 return VIDEO_FORMAT_RGB; 2056 case SC1200_VCFG_Y2YU_FORMAT: 2057 return VIDEO_FORMAT_P2M_P2L_P1M_P1L; 2058 case SC1200_VCFG_YUYV_FORMAT: 2059 return VIDEO_FORMAT_P1M_P1L_P2M_P2L; 2060 case SC1200_VCFG_YVYU_FORMAT: 2061 return VIDEO_FORMAT_P1M_P2L_P2M_P1L; 2062 } 2063 } 2064 2065 if (vcfg & SC1200_VCFG_4_2_0_MODE) { 2066 switch (vcfg & SC1200_VCFG_VID_INP_FORMAT) { 2067 case SC1200_VCFG_UYVY_FORMAT: 2068 return VIDEO_FORMAT_Y0Y1Y2Y3; 2069 case SC1200_VCFG_Y2YU_FORMAT: 2070 return VIDEO_FORMAT_Y3Y2Y1Y0; 2071 case SC1200_VCFG_YUYV_FORMAT: 2072 return VIDEO_FORMAT_Y1Y0Y3Y2; 2073 case SC1200_VCFG_YVYU_FORMAT: 2074 return VIDEO_FORMAT_Y1Y2Y3Y0; 2075 } 2076 } else { 2077 switch (vcfg & SC1200_VCFG_VID_INP_FORMAT) { 2078 case SC1200_VCFG_UYVY_FORMAT: 2079 return VIDEO_FORMAT_UYVY; 2080 case SC1200_VCFG_Y2YU_FORMAT: 2081 return VIDEO_FORMAT_Y2YU; 2082 case SC1200_VCFG_YUYV_FORMAT: 2083 return VIDEO_FORMAT_YUYV; 2084 case SC1200_VCFG_YVYU_FORMAT: 2085 return VIDEO_FORMAT_YVYU; 2086 } 2087 } 2088 return (GFX_STATUS_ERROR); 2089} 2090 2091/*----------------------------------------------------------------------------- 2092 * gfx_get_video_src_size 2093 * 2094 * This routine returns the size of the source video overlay buffer. The 2095 * return value is (height << 16) | width. 2096 *----------------------------------------------------------------------------- 2097 */ 2098#if GFX_VIDEO_DYNAMIC 2099unsigned long 2100sc1200_get_video_src_size(void) 2101#else 2102unsigned long 2103gfx_get_video_src_size(void) 2104#endif 2105{ 2106 unsigned long width = 0, height = 0; 2107 2108 /* DETERMINE SOURCE WIDTH FROM THE SC1200 VIDEO LINE SIZE */ 2109 2110 width = (READ_VID32(SC1200_VIDEO_CONFIG) >> 7) & 0x000001FE; 2111 if (READ_VID32(SC1200_VIDEO_CONFIG) & SC1200_VCFG_LINE_SIZE_UPPER) 2112 width += 512l; 2113 2114 if (width) { 2115 /* DETERMINE HEIGHT BY DIVIDING TOTAL SIZE BY WIDTH */ 2116 /* Get total size from display controller - abtracted. */ 2117 2118 height = gfx_get_display_video_size() / (width << 1); 2119 } 2120 return ((height << 16) | width); 2121} 2122 2123/*----------------------------------------------------------------------------- 2124 * gfx_get_video_line_size 2125 * 2126 * This routine returns the line size of the source video overlay buffer, in 2127 * pixels. 2128 *----------------------------------------------------------------------------- 2129 */ 2130#if GFX_VIDEO_DYNAMIC 2131unsigned long 2132sc1200_get_video_line_size(void) 2133#else 2134unsigned long 2135gfx_get_video_line_size(void) 2136#endif 2137{ 2138 unsigned long width = 0; 2139 2140 /* DETERMINE SOURCE WIDTH FROM THE SC1200 VIDEO LINE SIZE */ 2141 2142 width = (READ_VID32(SC1200_VIDEO_CONFIG) >> 7) & 0x000001FE; 2143 if (READ_VID32(SC1200_VIDEO_CONFIG) & SC1200_VCFG_LINE_SIZE_UPPER) 2144 width += 512l; 2145 return (width); 2146} 2147 2148/*----------------------------------------------------------------------------- 2149 * gfx_get_video_xclip 2150 * 2151 * This routine returns the number of bytes clipped on the left side of a 2152 * video overlay line (skipped at beginning). 2153 *----------------------------------------------------------------------------- 2154 */ 2155#if GFX_VIDEO_DYNAMIC 2156unsigned long 2157sc1200_get_video_xclip(void) 2158#else 2159unsigned long 2160gfx_get_video_xclip(void) 2161#endif 2162{ 2163 unsigned long clip = 0; 2164 2165 /* DETERMINE SOURCE WIDTH FROM THE SC1200 VIDEO LINE SIZE */ 2166 2167 clip = (READ_VID32(SC1200_VIDEO_CONFIG) >> 14) & 0x000007FC; 2168 return (clip); 2169} 2170 2171/*----------------------------------------------------------------------------- 2172 * gfx_get_video_offset 2173 * 2174 * This routine returns the current offset for the video overlay buffer. 2175 *----------------------------------------------------------------------------- 2176 */ 2177#if GFX_VIDEO_DYNAMIC 2178unsigned long 2179sc1200_get_video_offset(void) 2180#else 2181unsigned long 2182gfx_get_video_offset(void) 2183#endif 2184{ 2185 return (gfx_get_display_video_offset()); 2186} 2187 2188/*--------------------------------------------------------------------------- 2189 * gfx_get_video_upscale 2190 * 2191 * This routine returns the scale factor for the video overlay window. 2192 *--------------------------------------------------------------------------- 2193 */ 2194#if GFX_VIDEO_DYNAMIC 2195unsigned long 2196sc1200_get_video_upscale(void) 2197#else 2198unsigned long 2199gfx_get_video_upscale(void) 2200#endif 2201{ 2202 return (READ_VID32(SC1200_VIDEO_UPSCALE)); 2203} 2204 2205/*--------------------------------------------------------------------------- 2206 * gfx_get_video_scale 2207 * 2208 * This routine returns the scale factor for the video overlay window. 2209 *--------------------------------------------------------------------------- 2210 */ 2211#if GFX_VIDEO_DYNAMIC 2212unsigned long 2213sc1200_get_video_scale(void) 2214#else 2215unsigned long 2216gfx_get_video_scale(void) 2217#endif 2218{ 2219 return gfx_get_video_upscale(); 2220} 2221 2222/*--------------------------------------------------------------------------- 2223 * gfx_get_video_downscale_config 2224 * 2225 * This routine returns the current type and value of video downscaling. 2226 *--------------------------------------------------------------------------- 2227 */ 2228#if GFX_VIDEO_DYNAMIC 2229int 2230sc1200_get_video_downscale_config(unsigned short *type, unsigned short *m) 2231#else 2232int 2233gfx_get_video_downscale_config(unsigned short *type, unsigned short *m) 2234#endif 2235{ 2236 unsigned long downscale; 2237 2238 downscale = READ_VID32(SC1200_VIDEO_DOWNSCALER_CONTROL); 2239 *m = (unsigned short)((downscale & SC1200_VIDEO_DOWNSCALE_FACTOR_MASK) >> 2240 SC1200_VIDEO_DOWNSCALE_FACTOR_POS) + 1; 2241 2242 switch (downscale & SC1200_VIDEO_DOWNSCALE_TYPE_MASK) { 2243 case SC1200_VIDEO_DOWNSCALE_TYPE_A: 2244 *type = VIDEO_DOWNSCALE_KEEP_1_OF; 2245 break; 2246 case SC1200_VIDEO_DOWNSCALE_TYPE_B: 2247 *type = VIDEO_DOWNSCALE_DROP_1_OF; 2248 break; 2249 default: 2250 return GFX_STATUS_ERROR; 2251 break; 2252 } 2253 return (0); 2254} 2255 2256/*--------------------------------------------------------------------------- 2257 * gfx_get_video_downscale_coefficients 2258 * 2259 * This routine returns the current video downscaling coefficients. 2260 *--------------------------------------------------------------------------- 2261 */ 2262#if GFX_VIDEO_DYNAMIC 2263void 2264sc1200_get_video_downscale_coefficients(unsigned short *coef1, 2265 unsigned short *coef2, 2266 unsigned short *coef3, 2267 unsigned short *coef4) 2268#else 2269void 2270gfx_get_video_downscale_coefficients(unsigned short *coef1, 2271 unsigned short *coef2, 2272 unsigned short *coef3, 2273 unsigned short *coef4) 2274#endif 2275{ 2276 unsigned long coef; 2277 2278 coef = READ_VID32(SC1200_VIDEO_DOWNSCALER_COEFFICIENTS); 2279 *coef1 = 2280 (unsigned short)((coef >> SC1200_VIDEO_DOWNSCALER_COEF1_POS) & 2281 SC1200_VIDEO_DOWNSCALER_COEF_MASK); 2282 *coef2 = 2283 (unsigned short)((coef >> SC1200_VIDEO_DOWNSCALER_COEF2_POS) & 2284 SC1200_VIDEO_DOWNSCALER_COEF_MASK); 2285 *coef3 = 2286 (unsigned short)((coef >> SC1200_VIDEO_DOWNSCALER_COEF3_POS) & 2287 SC1200_VIDEO_DOWNSCALER_COEF_MASK); 2288 *coef4 = 2289 (unsigned short)((coef >> SC1200_VIDEO_DOWNSCALER_COEF4_POS) & 2290 SC1200_VIDEO_DOWNSCALER_COEF_MASK); 2291 return; 2292} 2293 2294/*--------------------------------------------------------------------------- 2295 * gfx_get_video_downscale_enable 2296 * 2297 * This routine returns 1 if video downscaling is currently enabled, 2298 * or 0 if it is currently disabled. 2299 *--------------------------------------------------------------------------- 2300 */ 2301#if GFX_VIDEO_DYNAMIC 2302void 2303sc1200_get_video_downscale_enable(int *enable) 2304#else 2305void 2306gfx_get_video_downscale_enable(int *enable) 2307#endif 2308{ 2309 if (READ_VID32(SC1200_VIDEO_DOWNSCALER_CONTROL) & 2310 SC1200_VIDEO_DOWNSCALE_ENABLE) 2311 *enable = 1; 2312 else 2313 *enable = 0; 2314 return; 2315} 2316 2317/*--------------------------------------------------------------------------- 2318 * gfx_get_video_dst_size 2319 * 2320 * This routine returns the size of the displayed video overlay window. 2321 *--------------------------------------------------------------------------- 2322 */ 2323#if GFX_VIDEO_DYNAMIC 2324unsigned long 2325sc1200_get_video_dst_size(void) 2326#else 2327unsigned long 2328gfx_get_video_dst_size(void) 2329#endif 2330{ 2331 unsigned long xsize, ysize; 2332 2333 xsize = READ_VID32(SC1200_VIDEO_X_POS); 2334 xsize = ((xsize >> 16) & 0x7FF) - (xsize & 0x7FF); 2335 ysize = READ_VID32(SC1200_VIDEO_Y_POS); 2336 ysize = ((ysize >> 16) & 0x7FF) - (ysize & 0x7FF); 2337 return ((ysize << 16) | xsize); 2338} 2339 2340/*--------------------------------------------------------------------------- 2341 * gfx_get_video_position 2342 * 2343 * This routine returns the position of the video overlay window. The 2344 * return value is (ypos << 16) | xpos. 2345 *--------------------------------------------------------------------------- 2346 */ 2347#if GFX_VIDEO_DYNAMIC 2348unsigned long 2349sc1200_get_video_position(void) 2350#else 2351unsigned long 2352gfx_get_video_position(void) 2353#endif 2354{ 2355 unsigned long hadjust, vadjust; 2356 unsigned long xpos, ypos; 2357 2358 /* READ HARDWARE POSITION */ 2359 2360 xpos = READ_VID32(SC1200_VIDEO_X_POS) & 0x000007FF; 2361 ypos = READ_VID32(SC1200_VIDEO_Y_POS) & 0x000007FF; 2362 2363 /* GET ADJUSTMENT VALUES */ 2364 /* Use routines to abstract version of display controller. */ 2365 2366 hadjust = 2367 (unsigned long)gfx_get_htotal() - 2368 (unsigned long)gfx_get_hsync_end() - 14l; 2369 vadjust = 2370 (unsigned long)gfx_get_vtotal() - 2371 (unsigned long)gfx_get_vsync_end() + 1l; 2372 xpos -= hadjust; 2373 ypos -= vadjust; 2374 return ((ypos << 16) | (xpos & 0x0000FFFF)); 2375} 2376 2377/*--------------------------------------------------------------------------- 2378 * gfx_get_video_color_key 2379 * 2380 * This routine returns the current video color key value. 2381 *--------------------------------------------------------------------------- 2382 */ 2383#if GFX_VIDEO_DYNAMIC 2384unsigned long 2385sc1200_get_video_color_key(void) 2386#else 2387unsigned long 2388gfx_get_video_color_key(void) 2389#endif 2390{ 2391 return (READ_VID32(SC1200_VIDEO_COLOR_KEY)); 2392} 2393 2394/*--------------------------------------------------------------------------- 2395 * gfx_get_video_color_key_mask 2396 * 2397 * This routine returns the current video color mask value. 2398 *--------------------------------------------------------------------------- 2399 */ 2400#if GFX_VIDEO_DYNAMIC 2401unsigned long 2402sc1200_get_video_color_key_mask(void) 2403#else 2404unsigned long 2405gfx_get_video_color_key_mask(void) 2406#endif 2407{ 2408 return (READ_VID32(SC1200_VIDEO_COLOR_MASK)); 2409} 2410 2411/*--------------------------------------------------------------------------- 2412 * gfx_get_video_color_key_src 2413 * 2414 * This routine returns 0 for video data compare, 1 for graphics data. 2415 *--------------------------------------------------------------------------- 2416 */ 2417#if GFX_VIDEO_DYNAMIC 2418int 2419sc1200_get_video_color_key_src(void) 2420#else 2421int 2422gfx_get_video_color_key_src(void) 2423#endif 2424{ 2425 if (READ_VID32(SC1200_DISPLAY_CONFIG) & SC1200_DCFG_VG_CK) 2426 return (0); 2427 return (1); 2428} 2429 2430/*--------------------------------------------------------------------------- 2431 * gfx_get_video_filter 2432 * 2433 * This routine returns if the filters are currently enabled. 2434 *--------------------------------------------------------------------------- 2435 */ 2436#if GFX_VIDEO_DYNAMIC 2437int 2438sc1200_get_video_filter(void) 2439#else 2440int 2441gfx_get_video_filter(void) 2442#endif 2443{ 2444 int retval = 0; 2445 2446 if (READ_VID32(SC1200_VIDEO_CONFIG) & SC1200_VCFG_X_FILTER_EN) 2447 retval |= 1; 2448 if (READ_VID32(SC1200_VIDEO_CONFIG) & SC1200_VCFG_Y_FILTER_EN) 2449 retval |= 2; 2450 return (retval); 2451} 2452 2453/*--------------------------------------------------------------------------- 2454 * gfx_get_video_request 2455 * 2456 * This routine returns the horizontal (pixel) and vertical (lines) video 2457 * request values. 2458 *--------------------------------------------------------------------------- 2459 */ 2460#if GFX_VIDEO_DYNAMIC 2461int 2462sc1200_get_video_request(short *x, short *y) 2463#else 2464int 2465gfx_get_video_request(short *x, short *y) 2466#endif 2467{ 2468 int request = 0; 2469 2470 request = (int)(READ_VID32(SC1200_VIDEO_REQUEST)); 2471 *x = (request >> SC1200_VIDEO_X_REQUEST_POS) & SC1200_VIDEO_REQUEST_MASK; 2472 *y = (request >> SC1200_VIDEO_Y_REQUEST_POS) & SC1200_VIDEO_REQUEST_MASK; 2473 2474 *x -= gfx_get_htotal() - gfx_get_hsync_end() - 2; 2475 *y -= gfx_get_vtotal() - gfx_get_vsync_end() + 1; 2476 2477 return (0); 2478} 2479 2480/*--------------------------------------------------------------------------- 2481 * gfx_get_video_source 2482 * 2483 * This routine returns the current video source. 2484 *--------------------------------------------------------------------------- 2485 */ 2486#if GFX_VIDEO_DYNAMIC 2487int 2488sc1200_get_video_source(VideoSourceType * source) 2489#else 2490int 2491gfx_get_video_source(VideoSourceType * source) 2492#endif 2493{ 2494 switch (READ_VID32(SC1200_VIDEO_DISPLAY_MODE) & SC1200_VIDEO_SOURCE_MASK) { 2495 case SC1200_VIDEO_SOURCE_GX1: 2496 *source = VIDEO_SOURCE_MEMORY; 2497 break; 2498 case SC1200_VIDEO_SOURCE_DVIP: 2499 *source = VIDEO_SOURCE_DVIP; 2500 break; 2501 default: 2502 return GFX_STATUS_ERROR; 2503 } 2504 return (0); 2505} 2506 2507/*--------------------------------------------------------------------------- 2508 * gfx_get_vbi_source 2509 * 2510 * This routine returns the current vbi source. 2511 *--------------------------------------------------------------------------- 2512 */ 2513#if GFX_VIDEO_DYNAMIC 2514int 2515sc1200_get_vbi_source(VbiSourceType * source) 2516#else 2517int 2518gfx_get_vbi_source(VbiSourceType * source) 2519#endif 2520{ 2521 switch (READ_VID32(SC1200_VIDEO_DISPLAY_MODE) & SC1200_VBI_SOURCE_MASK) { 2522 case SC1200_VBI_SOURCE_GX1: 2523 *source = VBI_SOURCE_MEMORY; 2524 break; 2525 case SC1200_VBI_SOURCE_DVIP: 2526 *source = VBI_SOURCE_DVIP; 2527 break; 2528 default: 2529 return GFX_STATUS_ERROR; 2530 } 2531 return (0); 2532} 2533 2534/*--------------------------------------------------------------------------- 2535 * gfx_get_vbi_lines 2536 * 2537 * This routine returns the VBI lines which are sent to the TV encoder. 2538 *--------------------------------------------------------------------------- 2539 */ 2540#if GFX_VIDEO_DYNAMIC 2541unsigned long 2542sc1200_get_vbi_lines(int odd) 2543#else 2544unsigned long 2545gfx_get_vbi_lines(int odd) 2546#endif 2547{ 2548 if (odd) 2549 return (READ_VID32(SC1200_VIDEO_ODD_VBI_LINE_ENABLE) & 2550 SC1200_VIDEO_VBI_LINE_ENABLE_MASK); 2551 return (READ_VID32(SC1200_VIDEO_EVEN_VBI_LINE_ENABLE) & 2552 SC1200_VIDEO_VBI_LINE_ENABLE_MASK); 2553} 2554 2555/*--------------------------------------------------------------------------- 2556 * gfx_get_vbi_total 2557 * 2558 * This routine returns the total number of VBI bytes in the field. 2559 *--------------------------------------------------------------------------- 2560 */ 2561#if GFX_VIDEO_DYNAMIC 2562unsigned long 2563sc1200_get_vbi_total(int odd) 2564#else 2565unsigned long 2566gfx_get_vbi_total(int odd) 2567#endif 2568{ 2569 if (odd) 2570 return (READ_VID32(SC1200_VIDEO_ODD_VBI_TOTAL_COUNT) & 2571 SC1200_VIDEO_VBI_TOTAL_COUNT_MASK); 2572 return (READ_VID32(SC1200_VIDEO_EVEN_VBI_TOTAL_COUNT) & 2573 SC1200_VIDEO_VBI_TOTAL_COUNT_MASK); 2574} 2575 2576/*--------------------------------------------------------------------------- 2577 * gfx_get_video_interlaced() 2578 * 2579 * This routine returns "1" if input video is currently in interlaced mode. 2580 * "0" otherwise. 2581 *--------------------------------------------------------------------------- 2582 */ 2583#if GFX_VIDEO_DYNAMIC 2584int 2585sc1200_get_video_interlaced(void) 2586#else 2587int 2588gfx_get_video_interlaced(void) 2589#endif 2590{ 2591 if (READ_VID32(SC1200_VID_ALPHA_CONTROL) & SC1200_VIDEO_IS_INTERLACED) 2592 return (1); 2593 else 2594 return (0); 2595} 2596 2597/*--------------------------------------------------------------------------- 2598 * gfx_get_color_space_YUV() 2599 * 2600 * This routine returns "1" if video processor color space mode is currently 2601 * YUV. "0" otherwise. 2602 *--------------------------------------------------------------------------- 2603 */ 2604#if GFX_VIDEO_DYNAMIC 2605int 2606sc1200_get_color_space_YUV(void) 2607#else 2608int 2609gfx_get_color_space_YUV(void) 2610#endif 2611{ 2612 unsigned long control; 2613 2614 control = READ_VID32(SC1200_VID_ALPHA_CONTROL); 2615 2616 /* IS SC1200 VIDEO COLOR SPACE RGB OR CONVERTED TO RGB */ 2617 if ((control & SC1200_VIDEO_INPUT_IS_RGB) 2618 || (control & SC1200_CSC_VIDEO_YUV_TO_RGB)) 2619 return (0); 2620 else 2621 return (1); 2622} 2623 2624/*--------------------------------------------------------------------------- 2625 * gfx_get_vertical_scaler_offset() 2626 * 2627 * This routine sets "offset" to the value by which odd frames are shifted, 2628 * if insert is enabled, and to 0 if no shifting occurs. 2629 *--------------------------------------------------------------------------- 2630 */ 2631#if GFX_VIDEO_DYNAMIC 2632int 2633sc1200_get_vertical_scaler_offset(char *offset) 2634#else 2635int 2636gfx_get_vertical_scaler_offset(char *offset) 2637#endif 2638{ 2639 unsigned long control; 2640 2641 control = READ_VID32(SC1200_VID_ALPHA_CONTROL); 2642 if (control & SC1200_VERTICAL_SCALER_SHIFT_EN) { 2643 if ((control & SC1200_VERTICAL_SCALER_SHIFT_MASK) == 2644 SC1200_VERTICAL_SCALER_SHIFT_INIT) 2645 *offset = 1; 2646 else 2647 return GFX_STATUS_ERROR; /* TODO: find the interpretation of other values */ 2648 } else 2649 *offset = 0; 2650 return (0); 2651} 2652 2653/*--------------------------------------------------------------------------- 2654 * gfx_get_genlock_delay 2655 * 2656 * This routine returns the genlock delay in 27 MHz clocks. 2657 *--------------------------------------------------------------------------- 2658 */ 2659#if GFX_VIDEO_DYNAMIC 2660unsigned long 2661sc1200_get_genlock_delay(void) 2662#else 2663unsigned long 2664gfx_get_genlock_delay(void) 2665#endif 2666{ 2667 return (READ_VID32(SC1200_GENLOCK_DELAY) & SC1200_GENLOCK_DELAY_MASK); 2668} 2669 2670/*--------------------------------------------------------------------------- 2671 * gfx_get_genlock_enable 2672 * 2673 * This routine returns "1" if genlock is currently enabled, "0" otherwise. 2674 *--------------------------------------------------------------------------- 2675 */ 2676#if GFX_VIDEO_DYNAMIC 2677int 2678sc1200_get_genlock_enable(void) 2679#else 2680int 2681gfx_get_genlock_enable(void) 2682#endif 2683{ 2684 if (READ_VID32(SC1200_GENLOCK) & 2685 (SC1200_GENLOCK_SINGLE_ENABLE | SC1200_GENLOCK_CONTINUOUS_ENABLE)) 2686 return (1); 2687 else 2688 return (0); 2689} 2690 2691/*--------------------------------------------------------------------------- 2692 * gfx_get_video_cursor() 2693 * 2694 * This routine configures the video hardware cursor. 2695 * If the "mask"ed bits in the graphics pixel match "key", then either "color1" 2696 * or "color2" will be used for this pixel, according to the value of the bit 2697 * in offset "select_color2". 2698 *--------------------------------------------------------------------------- 2699 */ 2700#if GFX_VIDEO_DYNAMIC 2701int 2702sc1200_get_video_cursor(unsigned long *key, unsigned long *mask, 2703 unsigned short *select_color2, unsigned long *color1, 2704 unsigned short *color2) 2705#else 2706int 2707gfx_get_video_cursor(unsigned long *key, unsigned long *mask, 2708 unsigned short *select_color2, unsigned long *color1, 2709 unsigned short *color2) 2710#endif 2711{ 2712 *select_color2 = 2713 (unsigned short)(READ_VID32(SC1200_CURSOR_COLOR_KEY) >> 2714 SC1200_CURSOR_COLOR_KEY_OFFSET_POS); 2715 *key = READ_VID32(SC1200_CURSOR_COLOR_KEY) & SC1200_COLOR_MASK; 2716 *mask = READ_VID32(SC1200_CURSOR_COLOR_MASK) & SC1200_COLOR_MASK; 2717 *color1 = READ_VID32(SC1200_CURSOR_COLOR_1) & SC1200_COLOR_MASK; 2718 *color2 = 2719 (unsigned short)(READ_VID32(SC1200_CURSOR_COLOR_2) & 2720 SC1200_COLOR_MASK); 2721 return (0); 2722} 2723 2724/*--------------------------------------------------------------------------- 2725 * gfx_read_crc 2726 * 2727 * This routine returns the hardware CRC value, which is used for automated 2728 * testing. The value is like a checksum, but will change if pixels move 2729 * locations. 2730 *--------------------------------------------------------------------------- 2731 */ 2732#if GFX_VIDEO_DYNAMIC 2733unsigned long 2734sc1200_read_crc(void) 2735#else 2736unsigned long 2737gfx_read_crc(void) 2738#endif 2739{ 2740 unsigned long crc = 0xFFFFFFFF; 2741 2742 if (gfx_test_timing_active()) { 2743 /* WAIT UNTIL ACTIVE DISPLAY */ 2744 2745 while (!gfx_test_vertical_active()) ; 2746 2747 /* RESET CRC DURING ACTIVE DISPLAY */ 2748 2749 WRITE_VID32(SC1200_VID_CRC, 0); 2750 WRITE_VID32(SC1200_VID_CRC, 1); 2751 2752 /* WAIT UNTIL NOT ACTIVE, THEN ACTIVE, NOT ACTIVE, THEN ACTIVE */ 2753 2754 while (gfx_test_vertical_active()) ; 2755 while (!gfx_test_vertical_active()) ; 2756 while (gfx_test_vertical_active()) ; 2757 while (!gfx_test_vertical_active()) ; 2758 crc = READ_VID32(SC1200_VID_CRC) >> 8; 2759 } 2760 return (crc); 2761} 2762 2763/*----------------------------------------------------------------------------- 2764 * gfx_get_macrovision_enable 2765 * 2766 * This routine returns the value "one" if macrovision currently enabled in the 2767 * TV encoder, otherwise it returns the value "zero". 2768 *----------------------------------------------------------------------------- 2769 */ 2770#if GFX_VIDEO_DYNAMIC 2771int 2772sc1200_get_macrovision_enable(void) 2773#else 2774int 2775gfx_get_macrovision_enable(void) 2776#endif 2777{ 2778 if (READ_VID32(SC1200_TVENC_MV_CONTROL) == SC1200_TVENC_MV_ENABLE) 2779 return (1); 2780 return (0); 2781} 2782 2783/*--------------------------------------------------------------------------- 2784 * gfx_get_alpha_enable 2785 * 2786 * This routine returns 1 if the selected alpha window is currently 2787 * enabled, or 0 if it is currently disabled. 2788 *--------------------------------------------------------------------------- 2789 */ 2790#if GFX_VIDEO_DYNAMIC 2791void 2792sc1200_get_alpha_enable(int *enable) 2793#else 2794void 2795gfx_get_alpha_enable(int *enable) 2796#endif 2797{ 2798 unsigned long value = 0; 2799 2800 *enable = 0; 2801 if (gfx_alpha_select <= 2) { 2802 value = 2803 READ_VID32(SC1200_ALPHA_CONTROL_1 + 2804 ((unsigned long)gfx_alpha_select << 4)); 2805 if (value & SC1200_ACTRL_WIN_ENABLE) 2806 *enable = 1; 2807 } 2808 return; 2809} 2810 2811/*--------------------------------------------------------------------------- 2812 * gfx_get_alpha_size 2813 * 2814 * This routine returns the size of the currently selected alpha region. 2815 *--------------------------------------------------------------------------- 2816 */ 2817#if GFX_VIDEO_DYNAMIC 2818void 2819sc1200_get_alpha_size(unsigned short *x, unsigned short *y, 2820 unsigned short *width, unsigned short *height) 2821#else 2822void 2823gfx_get_alpha_size(unsigned short *x, unsigned short *y, 2824 unsigned short *width, unsigned short *height) 2825#endif 2826{ 2827 unsigned long value = 0; 2828 2829 *x = 0; 2830 *y = 0; 2831 *width = 0; 2832 *height = 0; 2833 if (gfx_alpha_select <= 2) { 2834 value = 2835 READ_VID32(SC1200_ALPHA_XPOS_1 + 2836 ((unsigned long)gfx_alpha_select << 4)); 2837 *x = (unsigned short)(value & 0x000007FF); 2838 *width = (unsigned short)((value >> 16) & 0x000007FF) - *x; 2839 value = 2840 READ_VID32(SC1200_ALPHA_YPOS_1 + 2841 ((unsigned long)gfx_alpha_select << 4)); 2842 *y = (unsigned short)(value & 0x000007FF); 2843 *height = (unsigned short)((value >> 16) & 0x000007FF) - *y; 2844 } 2845 *x -= gfx_get_htotal() - gfx_get_hsync_end() - 2; 2846 *y -= gfx_get_vtotal() - gfx_get_vsync_end() + 1; 2847 return; 2848} 2849 2850/*--------------------------------------------------------------------------- 2851 * gfx_get_alpha_value 2852 * 2853 * This routine returns the alpha value and increment/decrement value of 2854 * the currently selected alpha region. 2855 *--------------------------------------------------------------------------- 2856 */ 2857#if GFX_VIDEO_DYNAMIC 2858void 2859sc1200_get_alpha_value(unsigned char *alpha, char *delta) 2860#else 2861void 2862gfx_get_alpha_value(unsigned char *alpha, char *delta) 2863#endif 2864{ 2865 unsigned long value = 0; 2866 2867 *alpha = 0; 2868 *delta = 0; 2869 if (gfx_alpha_select <= 2) { 2870 value = 2871 READ_VID32(SC1200_ALPHA_CONTROL_1 + 2872 ((unsigned long)gfx_alpha_select << 4)); 2873 *alpha = (unsigned char)(value & 0x00FF); 2874 *delta = (char)((value >> 8) & 0x00FF); 2875 } 2876 return; 2877} 2878 2879/*--------------------------------------------------------------------------- 2880 * gfx_get_alpha_priority 2881 * 2882 * This routine returns the priority of the currently selected alpha region. 2883 *--------------------------------------------------------------------------- 2884 */ 2885#if GFX_VIDEO_DYNAMIC 2886void 2887sc1200_get_alpha_priority(int *priority) 2888#else 2889void 2890gfx_get_alpha_priority(int *priority) 2891#endif 2892{ 2893 unsigned long pos = 0, value = 0; 2894 2895 *priority = 0; 2896 if (gfx_alpha_select <= 2) { 2897 value = READ_VID32(SC1200_VID_ALPHA_CONTROL); 2898 pos = 16 + (gfx_alpha_select << 1); 2899 *priority = (int)((value >> pos) & 3); 2900 } 2901 return; 2902} 2903 2904/*--------------------------------------------------------------------------- 2905 * gfx_get_alpha_color 2906 * 2907 * This routine returns the color register value for the currently selected 2908 * alpha region. Bit 24 is set if the color register is enabled. 2909 *--------------------------------------------------------------------------- 2910 */ 2911#if GFX_VIDEO_DYNAMIC 2912void 2913sc1200_get_alpha_color(unsigned long *color) 2914#else 2915void 2916gfx_get_alpha_color(unsigned long *color) 2917#endif 2918{ 2919 *color = 0; 2920 if (gfx_alpha_select <= 2) { 2921 *color = 2922 READ_VID32(SC1200_ALPHA_COLOR_1 + 2923 ((unsigned long)gfx_alpha_select << 4)); 2924 } 2925 return; 2926} 2927 2928#endif /* GFX_READ_ROUTINES */ 2929 2930/* END OF FILE */ 2931