1f29dbc25Smrg/* Copyright (c) 2005 Advanced Micro Devices, Inc. 2f29dbc25Smrg * 3f29dbc25Smrg * Permission is hereby granted, free of charge, to any person obtaining a copy 4f29dbc25Smrg * of this software and associated documentation files (the "Software"), to 5f29dbc25Smrg * deal in the Software without restriction, including without limitation the 6f29dbc25Smrg * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7f29dbc25Smrg * sell copies of the Software, and to permit persons to whom the Software is 8f29dbc25Smrg * furnished to do so, subject to the following conditions: 9f29dbc25Smrg * 10f29dbc25Smrg * The above copyright notice and this permission notice shall be included in 11f29dbc25Smrg * all copies or substantial portions of the Software. 12f29dbc25Smrg * 13f29dbc25Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14f29dbc25Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15f29dbc25Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16f29dbc25Smrg * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17f29dbc25Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18f29dbc25Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19f29dbc25Smrg * IN THE SOFTWARE. 20f29dbc25Smrg * 21f29dbc25Smrg * Neither the name of the Advanced Micro Devices, Inc. nor the names of its 22f29dbc25Smrg * contributors may be used to endorse or promote products derived from this 23f29dbc25Smrg * software without specific prior written permission. 24f29dbc25Smrg * */ 25f29dbc25Smrg 26f29dbc25Smrg/* 27f29dbc25Smrg * This file contains routines to control the SC1200 TVOUT and TV encoder. 28f29dbc25Smrg * */ 29f29dbc25Smrg 30f29dbc25Smrg/*---------------------------------------------------------------------------- 31f29dbc25Smrg * gfx_set_tv_format 32f29dbc25Smrg * 33f29dbc25Smrg * This routine sets the TV encoder registers to the specified format 34f29dbc25Smrg * and resolution. 35f29dbc25Smrg *---------------------------------------------------------------------------- 36f29dbc25Smrg */ 37f29dbc25Smrg#if GFX_TV_DYNAMIC 38f29dbc25Smrgint 39f29dbc25Smrgsc1200_set_tv_format(TVStandardType format, GfxOnTVType resolution) 40f29dbc25Smrg#else 41f29dbc25Smrgint 42f29dbc25Smrggfx_set_tv_format(TVStandardType format, GfxOnTVType resolution) 43f29dbc25Smrg#endif 44f29dbc25Smrg{ 45f29dbc25Smrg unsigned long ctrl2, mode; 46f29dbc25Smrg 47f29dbc25Smrg /* Save TV output mode */ 48f29dbc25Smrg ctrl2 = 49f29dbc25Smrg READ_VID32(SC1200_TVENC_TIM_CTRL_2) & (SC1200_TVENC_OUTPUT_YCBCR | 5004007ebaSmrg SC1200_TVENC_CFS_MASK); 51f29dbc25Smrg /* Save flicker filter setting */ 52f29dbc25Smrg mode = 53f29dbc25Smrg READ_VID32(SC1200_TVOUT_HORZ_SCALING) & 54f29dbc25Smrg SC1200_TVOUT_FLICKER_FILTER_MASK; 55f29dbc25Smrg 56f29dbc25Smrg switch (format) { 57f29dbc25Smrg case TV_STANDARD_NTSC: 58f29dbc25Smrg /* Horizontal Sync Start is 848 */ 59f29dbc25Smrg /* Horizontal Sync End is 856 */ 60f29dbc25Smrg WRITE_VID32(SC1200_TVOUT_HORZ_SYNC, 0x03580350); 61f29dbc25Smrg /* Vertical Sync Start is 0 */ 62f29dbc25Smrg /* Vertical Sync End is 1 */ 63f29dbc25Smrg /* Vertical Display Start Skew is 1 */ 64f29dbc25Smrg /* Vertical Display End Skew is 1 */ 65f29dbc25Smrg WRITE_VID32(SC1200_TVOUT_VERT_SYNC, 0x05001000); 66f29dbc25Smrg /* Disable vertical down scaling, take all lines */ 67f29dbc25Smrg if (gfx_chip_revision <= SC1200_REV_B3) 68f29dbc25Smrg WRITE_VID32(SC1200_TVOUT_VERT_DOWNSCALE, 0xffffffff); 69f29dbc25Smrg /* Enable video timing */ 70f29dbc25Smrg /* Reset sub carrier every two frames */ 71f29dbc25Smrg /* Disable BLANK */ 72f29dbc25Smrg /* Enable color burst */ 73f29dbc25Smrg /* Add the IRE offset */ 74f29dbc25Smrg /* NTSC color encoding */ 75f29dbc25Smrg /* Video generator timing is 525 lines / 60Hz */ 76f29dbc25Smrg /* Horizontal and Vertical counters are initialized to HPHASE & 77f29dbc25Smrg * VPHASE */ 78f29dbc25Smrg /* VPHASE is 2, HPHASE is 0x50 */ 79f29dbc25Smrg WRITE_VID32(SC1200_TVENC_TIM_CTRL_1, 0xa2a01050); 80f29dbc25Smrg /* Increase horizontal blanking interval */ 81f29dbc25Smrg /* Low Water Mark for Y is 0x1F */ 82f29dbc25Smrg /* Low Water Mark for Cb is 0xF */ 83f29dbc25Smrg /* HUE is 0 */ 84f29dbc25Smrg /* SCPHASE is 0xF9 */ 85f29dbc25Smrg WRITE_VID32(SC1200_TVENC_TIM_CTRL_2, 0x9ff000f9 | ctrl2); 86f29dbc25Smrg /* Subcarrier Frequency is 3.579545 MHz */ 87f29dbc25Smrg WRITE_VID32(SC1200_TVENC_SUB_FREQ, 0x21f07c1f); 88f29dbc25Smrg /* VSTART is 18, HSTART is 113 */ 89f29dbc25Smrg WRITE_VID32(SC1200_TVENC_DISP_POS, 0x00120071); 90f29dbc25Smrg /* Display size: HEIGHT is 239, WIDTH is 719 */ 91f29dbc25Smrg WRITE_VID32(SC1200_TVENC_DISP_SIZE, 0x00ef02cf); 92f29dbc25Smrg switch (resolution) { 93f29dbc25Smrg case GFX_ON_TV_SQUARE_PIXELS: 94f29dbc25Smrg if (gfx_chip_revision <= SC1200_REV_B3) { 95f29dbc25Smrg /* Horizontal Display start is 116 */ 96f29dbc25Smrg /* Total number of pixels per line is 857 */ 97f29dbc25Smrg WRITE_VID32(SC1200_TVOUT_HORZ_TIM, 0x00740359); 98f29dbc25Smrg /* HSYNC generated in the TV Encoder module */ 99f29dbc25Smrg /* Interval between resets of TV Encoder is once every odd 100f29dbc25Smrg * field */ 101f29dbc25Smrg /* Enable Horizontal interpolation */ 102f29dbc25Smrg /* Enable Horizontal up scaling 9/8 */ 103f29dbc25Smrg /* Disable Horizontal downscale */ 104f29dbc25Smrg WRITE_VID32(SC1200_TVOUT_HORZ_SCALING, 0x10020700 | mode); 105f29dbc25Smrg /* Horizontal display end is 919, i.e. 720 active pixels */ 106f29dbc25Smrg /* Total number of display lines per field is 240 */ 107f29dbc25Smrg WRITE_VID32(SC1200_TVOUT_LINE_END, 0x039700f0); 10804007ebaSmrg } 10904007ebaSmrg else { /* Use new scaler available in Rev. C */ 110f29dbc25Smrg /* Horizontal Display start is 111 */ 111f29dbc25Smrg /* Total number of pixels per line is 857 */ 112f29dbc25Smrg WRITE_VID32(SC1200_TVOUT_HORZ_TIM, 0x006f0359); 113f29dbc25Smrg /* HSYNC generated in the TV Encoder module */ 114f29dbc25Smrg /* Interval between resets of TV Encoder is once every odd 115f29dbc25Smrg * field */ 116f29dbc25Smrg /* Enable Horizontal interpolation */ 117f29dbc25Smrg /* Disable Horizontal up scaling 9/8 */ 118f29dbc25Smrg /* Disable Horizontal downscale */ 119f29dbc25Smrg WRITE_VID32(SC1200_TVOUT_HORZ_SCALING, 0x10020500 | mode); 120f29dbc25Smrg /* Set Horizontal upscaling to 64/58 (~ 11/10) */ 121f29dbc25Smrg WRITE_VID32(SC1200_TVOUT_HORZ_PRE_ENCODER_SCALE, 0x3A000000); 122f29dbc25Smrg /* Horizontal display end is 900, i.e. 706 active pixels */ 123f29dbc25Smrg /* Total number of display lines per field is 240 */ 124f29dbc25Smrg WRITE_VID32(SC1200_TVOUT_LINE_END, 0x038400f0); 125f29dbc25Smrg } 126f29dbc25Smrg break; 127f29dbc25Smrg case GFX_ON_TV_NO_SCALING: 128f29dbc25Smrg /* Horizontal Display start is 116 */ 129f29dbc25Smrg /* Total number of pixels per line is 857 */ 130f29dbc25Smrg WRITE_VID32(SC1200_TVOUT_HORZ_TIM, 0x00740359); 131f29dbc25Smrg /* HSYNC generated in the TV Encoder module */ 132f29dbc25Smrg /* Interval between resets of TV Encoder is once every odd field */ 133f29dbc25Smrg /* Enable Horizontal interpolation */ 134f29dbc25Smrg /* Disable Horizontal up scaling 9/8 */ 135f29dbc25Smrg /* Disable Horizontal downscale */ 136f29dbc25Smrg WRITE_VID32(SC1200_TVOUT_HORZ_SCALING, 0x10020500 | mode); 137f29dbc25Smrg /* Disable Horizontal scaling (set to 64/64) */ 138f29dbc25Smrg if (gfx_chip_revision >= SC1200_REV_C1) 139f29dbc25Smrg WRITE_VID32(SC1200_TVOUT_HORZ_PRE_ENCODER_SCALE, 0x40000000); 140f29dbc25Smrg /* Horizontal display end is 919, i.e. 720 active pixels */ 141f29dbc25Smrg /* Total number of display lines per field is 240 */ 142f29dbc25Smrg WRITE_VID32(SC1200_TVOUT_LINE_END, 0x039700f0); 143f29dbc25Smrg break; 144f29dbc25Smrg default: 145f29dbc25Smrg return (GFX_STATUS_BAD_PARAMETER); 146f29dbc25Smrg } 147f29dbc25Smrg break; 148f29dbc25Smrg case TV_STANDARD_PAL: 149f29dbc25Smrg /* Horizontal Sync Start is 854 */ 150f29dbc25Smrg /* Horizontal Sync End is 862 */ 151f29dbc25Smrg WRITE_VID32(SC1200_TVOUT_HORZ_SYNC, 0x035e0356); 152f29dbc25Smrg /* Vertical Sync Start is 0 */ 153f29dbc25Smrg /* Vertical Sync End is 1 */ 154f29dbc25Smrg /* Vertical Display Start Skew is 1 */ 155f29dbc25Smrg /* Vertical Display End Skew is 1 */ 156f29dbc25Smrg WRITE_VID32(SC1200_TVOUT_VERT_SYNC, 0x05001000); 157f29dbc25Smrg /* Disable vertical down scaling, take all lines */ 158f29dbc25Smrg if (gfx_chip_revision <= SC1200_REV_B3) 159f29dbc25Smrg WRITE_VID32(SC1200_TVOUT_VERT_DOWNSCALE, 0xffffffff); 160f29dbc25Smrg /* Enable video timing */ 161f29dbc25Smrg /* Never reset sub carrier (should be every 4 frames but doesn't work 162f29dbc25Smrg * with genlock) */ 163f29dbc25Smrg /* Disable BLANK */ 164f29dbc25Smrg /* Enable color burst */ 165f29dbc25Smrg /* Do not add the IRE offset */ 166f29dbc25Smrg /* NTSC color encoding */ 167f29dbc25Smrg /* Video generator timing is 625 lines / 50Hz */ 168f29dbc25Smrg /* Horizontal and Vertical counters are initialized to HPHASE & VPHASE 169f29dbc25Smrg * */ 170f29dbc25Smrg /* VPHASE is 2, HPHASE is 50 */ 171f29dbc25Smrg WRITE_VID32(SC1200_TVENC_TIM_CTRL_1, 0xB1201050); 172f29dbc25Smrg /* Increase horizontal blanking interval */ 173f29dbc25Smrg /* Low Water Mark for Y is 0x1F */ 174f29dbc25Smrg /* Low Water Mark for Cb is 0xF */ 175f29dbc25Smrg /* HUE is 0 */ 176f29dbc25Smrg /* SCPHASE is 0xD9 */ 177f29dbc25Smrg WRITE_VID32(SC1200_TVENC_TIM_CTRL_2, 0x9ff000d9 | ctrl2); 178f29dbc25Smrg /* Subcarrier Frequency is 4.43361875 MHz */ 179f29dbc25Smrg WRITE_VID32(SC1200_TVENC_SUB_FREQ, 0x2a098acb); 180f29dbc25Smrg /* VSTART is 22, HSTART is 123 */ 181f29dbc25Smrg WRITE_VID32(SC1200_TVENC_DISP_POS, 0x0016007b); 182f29dbc25Smrg /* Display size: HEIGHT is 287, WIDTH is 719 */ 183f29dbc25Smrg WRITE_VID32(SC1200_TVENC_DISP_SIZE, 0x011f02cf); 184f29dbc25Smrg switch (resolution) { 185f29dbc25Smrg case GFX_ON_TV_NO_SCALING: 186f29dbc25Smrg /* Horizontal Display start is 124 */ 187f29dbc25Smrg /* Total number of pixels per line is 863 */ 188f29dbc25Smrg WRITE_VID32(SC1200_TVOUT_HORZ_TIM, 0x007c035f); 189f29dbc25Smrg /* HSYNC generated in the TV Encoder module */ 190f29dbc25Smrg /* Interval between resets of TV Encoder is once every odd field */ 191f29dbc25Smrg /* Enable Horizontal interpolation */ 192f29dbc25Smrg /* Disable Horizontal up scaling 9/8 */ 193f29dbc25Smrg /* Disable Horizontal downscale */ 194f29dbc25Smrg WRITE_VID32(SC1200_TVOUT_HORZ_SCALING, 0x10020500 | mode); 195f29dbc25Smrg /* Disable Horizontal scaling (set to 64/64) */ 196f29dbc25Smrg if (gfx_chip_revision >= SC1200_REV_C1) 197f29dbc25Smrg WRITE_VID32(SC1200_TVOUT_HORZ_PRE_ENCODER_SCALE, 0x40000000); 198f29dbc25Smrg /* Horizontal display end is 924, i.e. 720 active pixels */ 199f29dbc25Smrg /* Total number of display lines per field is 288 */ 200f29dbc25Smrg WRITE_VID32(SC1200_TVOUT_LINE_END, 0x039c0120); 201f29dbc25Smrg break; 202f29dbc25Smrg case GFX_ON_TV_SQUARE_PIXELS: 203f29dbc25Smrg /* Horizontal Display start is 122 */ 204f29dbc25Smrg /* Total number of pixels per line is 863 */ 205f29dbc25Smrg WRITE_VID32(SC1200_TVOUT_HORZ_TIM, 0x007a035f); 206f29dbc25Smrg if (gfx_chip_revision <= SC1200_REV_B3) { 207f29dbc25Smrg /* HSYNC generated in the TV Encoder module */ 208f29dbc25Smrg /* Interval between resets of TV Encoder is once every odd 209f29dbc25Smrg * field */ 210f29dbc25Smrg /* Enable Horizontal interpolation */ 211f29dbc25Smrg /* Disable Horizontal up scaling 9/8 */ 212f29dbc25Smrg /* Horizontal downscale m/(m+1), m = 11, (i.e. 11/12 - closest 213f29dbc25Smrg * possible to 54/59) */ 214f29dbc25Smrg WRITE_VID32(SC1200_TVOUT_HORZ_SCALING, 0x1002040b | mode); 215f29dbc25Smrg /* Horizontal display end is 906, i.e. 704 active pixels */ 216f29dbc25Smrg /* Total number of display lines per field is 288 */ 217f29dbc25Smrg WRITE_VID32(SC1200_TVOUT_LINE_END, 0x038a0120); 21804007ebaSmrg } 21904007ebaSmrg else { 220f29dbc25Smrg /* HSYNC generated in the TV Encoder module */ 221f29dbc25Smrg /* Interval between resets of TV Encoder is once every odd 222f29dbc25Smrg * field */ 223f29dbc25Smrg /* Enable Horizontal interpolation */ 224f29dbc25Smrg /* Disable Horizontal up scaling 9/8 */ 225f29dbc25Smrg /* Disable Horizontal downscale */ 226f29dbc25Smrg WRITE_VID32(SC1200_TVOUT_HORZ_SCALING, 0x10020500 | mode); 227f29dbc25Smrg /* Set Horizontal down scaling to 64/70 (closest possible to 228f29dbc25Smrg * 54/59) */ 229f29dbc25Smrg WRITE_VID32(SC1200_TVOUT_HORZ_PRE_ENCODER_SCALE, 0x46000000); 230f29dbc25Smrg /* Horizontal display end is 904, i.e. 702 active pixels */ 231f29dbc25Smrg /* Total number of display lines per field is 288 */ 232f29dbc25Smrg WRITE_VID32(SC1200_TVOUT_LINE_END, 0x03880120); 233f29dbc25Smrg } 234f29dbc25Smrg break; 235f29dbc25Smrg default: 236f29dbc25Smrg return (GFX_STATUS_BAD_PARAMETER); 237f29dbc25Smrg } 238f29dbc25Smrg break; 239f29dbc25Smrg default: 240f29dbc25Smrg return (GFX_STATUS_BAD_PARAMETER); 241f29dbc25Smrg } 242f29dbc25Smrg return (GFX_STATUS_OK); 243f29dbc25Smrg} 244f29dbc25Smrg 245f29dbc25Smrg/*---------------------------------------------------------------------------- 246f29dbc25Smrg * gfx_set_tv_output 247f29dbc25Smrg * 248f29dbc25Smrg * This routine sets the TV encoder registers to the specified output type. 249f29dbc25Smrg * Supported output types are : S-VIDEO, Composite, YUV and SCART. 250f29dbc25Smrg *---------------------------------------------------------------------------- 251f29dbc25Smrg */ 252f29dbc25Smrg#if GFX_TV_DYNAMIC 253f29dbc25Smrgint 254f29dbc25Smrgsc1200_set_tv_output(int output) 255f29dbc25Smrg#else 256f29dbc25Smrgint 257f29dbc25Smrggfx_set_tv_output(int output) 258f29dbc25Smrg#endif 259f29dbc25Smrg{ 260f29dbc25Smrg unsigned long ctrl2, ctrl3; 261f29dbc25Smrg 262f29dbc25Smrg ctrl2 = READ_VID32(SC1200_TVENC_TIM_CTRL_2); 263f29dbc25Smrg ctrl3 = READ_VID32(SC1200_TVENC_TIM_CTRL_3); 264f29dbc25Smrg ctrl2 &= ~(SC1200_TVENC_OUTPUT_YCBCR | SC1200_TVENC_CFS_MASK); 26504007ebaSmrg ctrl3 &= ~(SC1200_TVENC_CM | SC1200_TVENC_SYNCMODE_MASK | SC1200_TVENC_CS); 266f29dbc25Smrg switch (output) { 267f29dbc25Smrg case TV_OUTPUT_COMPOSITE: 268f29dbc25Smrg /* Analog outputs provide Y, C and CVBS */ 269f29dbc25Smrg /* Chrominance Lowpass filter is 1.3MHz (for composite video output) */ 270f29dbc25Smrg WRITE_VID32(SC1200_TVENC_TIM_CTRL_2, ctrl2 | SC1200_TVENC_CFS_CVBS); 271f29dbc25Smrg WRITE_VID32(SC1200_TVENC_TIM_CTRL_3, ctrl3); 272f29dbc25Smrg break; 273f29dbc25Smrg case TV_OUTPUT_S_VIDEO: 274f29dbc25Smrg /* Analog outputs provide Y, C and CVBS */ 275f29dbc25Smrg /* Chrominance Lowpass filter is 1.8MHz (for S-video output) */ 276f29dbc25Smrg WRITE_VID32(SC1200_TVENC_TIM_CTRL_2, ctrl2 | SC1200_TVENC_CFS_SVIDEO); 277f29dbc25Smrg WRITE_VID32(SC1200_TVENC_TIM_CTRL_3, ctrl3); 278f29dbc25Smrg break; 279f29dbc25Smrg case TV_OUTPUT_YUV: 280f29dbc25Smrg /* Analog outputs provide Y, Cb and Cr */ 281f29dbc25Smrg /* A 7.5 IRE setup is applied to the output */ 282f29dbc25Smrg WRITE_VID32(SC1200_TVENC_TIM_CTRL_2, 28304007ebaSmrg ctrl2 | SC1200_TVENC_OUTPUT_YCBCR | 28404007ebaSmrg SC1200_TVENC_CFS_BYPASS); 285f29dbc25Smrg WRITE_VID32(SC1200_TVENC_TIM_CTRL_3, 28604007ebaSmrg ctrl3 | SC1200_TVENC_CM | SC1200_TVENC_CS); 287f29dbc25Smrg break; 288f29dbc25Smrg case TV_OUTPUT_SCART: 289f29dbc25Smrg /* Analog outputs provide SCART (RGB and CVBS) */ 290f29dbc25Smrg /* Sync is added to green signal */ 291f29dbc25Smrg WRITE_VID32(SC1200_TVENC_TIM_CTRL_2, ctrl2 | SC1200_TVENC_CFS_CVBS); 292f29dbc25Smrg WRITE_VID32(SC1200_TVENC_TIM_CTRL_3, 29304007ebaSmrg ctrl3 | SC1200_TVENC_CM | SC1200_TVENC_SYNC_ON_GREEN); 294f29dbc25Smrg break; 295f29dbc25Smrg default: 296f29dbc25Smrg return (GFX_STATUS_BAD_PARAMETER); 297f29dbc25Smrg } 298f29dbc25Smrg 299f29dbc25Smrg /* Adjusts the internal voltage reference */ 300f29dbc25Smrg ctrl2 = READ_VID32(SC1200_TVENC_DAC_CONTROL); 301f29dbc25Smrg ctrl2 &= ~SC1200_TVENC_TRIM_MASK; 302f29dbc25Smrg 303f29dbc25Smrg /* Bypass for issue #926 : Inadequate chroma level of S-Video output */ 304f29dbc25Smrg if ((gfx_chip_revision == SC1200_REV_B3) && (output == TV_OUTPUT_S_VIDEO)) 305f29dbc25Smrg ctrl2 |= 0x7; 306f29dbc25Smrg else 307f29dbc25Smrg ctrl2 |= 0x5; 308f29dbc25Smrg 309f29dbc25Smrg WRITE_VID32(SC1200_TVENC_DAC_CONTROL, ctrl2); 310f29dbc25Smrg 311f29dbc25Smrg /* Disable 4:2:2 to 4:4:4 converter interpolation */ 312f29dbc25Smrg WRITE_VID32(SC1200_TVOUT_DEBUG, SC1200_TVOUT_CONVERTER_INTERPOLATION); 313f29dbc25Smrg 314f29dbc25Smrg return (GFX_STATUS_OK); 315f29dbc25Smrg} 316f29dbc25Smrg 317f29dbc25Smrg/*---------------------------------------------------------------------------- 318f29dbc25Smrg * gfx_set_tv_enable 319f29dbc25Smrg * 320f29dbc25Smrg * This routine enables or disables the TV output. 321f29dbc25Smrg *---------------------------------------------------------------------------- 322f29dbc25Smrg */ 323f29dbc25Smrg#if GFX_TV_DYNAMIC 324f29dbc25Smrgint 325f29dbc25Smrgsc1200_set_tv_enable(int enable) 326f29dbc25Smrg#else 327f29dbc25Smrgint 328f29dbc25Smrggfx_set_tv_enable(int enable) 329f29dbc25Smrg#endif 330f29dbc25Smrg{ 331f29dbc25Smrg unsigned long value_tim, value_dac; 332f29dbc25Smrg 333f29dbc25Smrg value_tim = READ_VID32(SC1200_TVENC_TIM_CTRL_1); 334f29dbc25Smrg value_dac = READ_VID32(SC1200_TVENC_DAC_CONTROL); 335f29dbc25Smrg 336f29dbc25Smrg if (enable) { 337f29dbc25Smrg value_tim |= SC1200_TVENC_VIDEO_TIMING_ENABLE; 338f29dbc25Smrg value_dac &= ~SC1200_TVENC_POWER_DOWN; 339f29dbc25Smrg /* ENABLE GRAPHICS DISPLAY LOGIC IN VIDEO PROCESSOR */ 340f29dbc25Smrg gfx_set_screen_enable(1); 34104007ebaSmrg } 34204007ebaSmrg else { 343f29dbc25Smrg value_tim &= ~SC1200_TVENC_VIDEO_TIMING_ENABLE; 344f29dbc25Smrg value_dac |= SC1200_TVENC_POWER_DOWN; 345f29dbc25Smrg /* Do not disable the graphics display logic because it might be 346f29dbc25Smrg * needed for CRT */ 347f29dbc25Smrg } 348f29dbc25Smrg 349f29dbc25Smrg WRITE_VID32(SC1200_TVENC_TIM_CTRL_1, value_tim); 350f29dbc25Smrg WRITE_VID32(SC1200_TVENC_DAC_CONTROL, value_dac); 351f29dbc25Smrg 352f29dbc25Smrg return (GFX_STATUS_OK); 353f29dbc25Smrg} 354f29dbc25Smrg 355f29dbc25Smrg/*---------------------------------------------------------------------------- 356f29dbc25Smrg * gfx_set_tv_flicker_filter 357f29dbc25Smrg * 358f29dbc25Smrg * This routine configures the TV out flicker filter. 359f29dbc25Smrg *---------------------------------------------------------------------------- 360f29dbc25Smrg */ 361f29dbc25Smrg#if GFX_TV_DYNAMIC 362f29dbc25Smrgint 363f29dbc25Smrgsc1200_set_tv_flicker_filter(int ff) 364f29dbc25Smrg#else 365f29dbc25Smrgint 366f29dbc25Smrggfx_set_tv_flicker_filter(int ff) 367f29dbc25Smrg#endif 368f29dbc25Smrg{ 369f29dbc25Smrg unsigned long mode; 370f29dbc25Smrg 371f29dbc25Smrg mode = READ_VID32(SC1200_TVOUT_HORZ_SCALING); 372f29dbc25Smrg mode &= ~SC1200_TVOUT_FLICKER_FILTER_MASK; 373f29dbc25Smrg switch (ff) { 374f29dbc25Smrg case TV_FLICKER_FILTER_NONE: 375f29dbc25Smrg WRITE_VID32(SC1200_TVOUT_HORZ_SCALING, 37604007ebaSmrg mode | SC1200_TVOUT_FLICKER_FILTER_DISABLED); 377f29dbc25Smrg break; 378f29dbc25Smrg case TV_FLICKER_FILTER_NORMAL: 379f29dbc25Smrg WRITE_VID32(SC1200_TVOUT_HORZ_SCALING, 38004007ebaSmrg mode | SC1200_TVOUT_FLICKER_FILTER_FOURTH_HALF_FOURTH); 381f29dbc25Smrg break; 382f29dbc25Smrg case TV_FLICKER_FILTER_INTERLACED: 383f29dbc25Smrg WRITE_VID32(SC1200_TVOUT_HORZ_SCALING, 38404007ebaSmrg mode | SC1200_TVOUT_FLICKER_FILTER_HALF_ONE_HALF); 385f29dbc25Smrg break; 386f29dbc25Smrg default: 387f29dbc25Smrg return GFX_STATUS_BAD_PARAMETER; 388f29dbc25Smrg } 389f29dbc25Smrg return (GFX_STATUS_OK); 390f29dbc25Smrg} 391f29dbc25Smrg 392f29dbc25Smrg/*---------------------------------------------------------------------------- 393f29dbc25Smrg * gfx_set_tv_sub_carrier_reset 394f29dbc25Smrg * 395f29dbc25Smrg * This routine configures the TV encoder sub carrier reset interval. 396f29dbc25Smrg *---------------------------------------------------------------------------- 397f29dbc25Smrg */ 398f29dbc25Smrg#if GFX_TV_DYNAMIC 399f29dbc25Smrgint 400f29dbc25Smrgsc1200_set_tv_sub_carrier_reset(int screset) 401f29dbc25Smrg#else 402f29dbc25Smrgint 403f29dbc25Smrggfx_set_tv_sub_carrier_reset(int screset) 404f29dbc25Smrg#endif 405f29dbc25Smrg{ 406f29dbc25Smrg unsigned long mode; 407f29dbc25Smrg 408f29dbc25Smrg mode = READ_VID32(SC1200_TVENC_TIM_CTRL_1); 409f29dbc25Smrg mode &= ~SC1200_TVENC_SUB_CARRIER_RESET_MASK; 410f29dbc25Smrg switch (screset) { 411f29dbc25Smrg case TV_SUB_CARRIER_RESET_NEVER: 412f29dbc25Smrg WRITE_VID32(SC1200_TVENC_TIM_CTRL_1, 41304007ebaSmrg mode | SC1200_TVENC_SUB_CARRIER_RESET_NEVER); 414f29dbc25Smrg break; 415f29dbc25Smrg case TV_SUB_CARRIER_RESET_EVERY_TWO_LINES: 416f29dbc25Smrg WRITE_VID32(SC1200_TVENC_TIM_CTRL_1, 41704007ebaSmrg mode | SC1200_TVENC_SUB_CARRIER_RESET_EVERY_TWO_LINES); 418f29dbc25Smrg break; 419f29dbc25Smrg case TV_SUB_CARRIER_RESET_EVERY_TWO_FRAMES: 420f29dbc25Smrg WRITE_VID32(SC1200_TVENC_TIM_CTRL_1, 42104007ebaSmrg mode | SC1200_TVENC_SUB_CARRIER_RESET_EVERY_TWO_FRAMES); 422f29dbc25Smrg break; 423f29dbc25Smrg case TV_SUB_CARRIER_RESET_EVERY_FOUR_FRAMES: 424f29dbc25Smrg WRITE_VID32(SC1200_TVENC_TIM_CTRL_1, 42504007ebaSmrg mode | SC1200_TVENC_SUB_CARRIER_RESET_EVERY_FOUR_FRAMES); 426f29dbc25Smrg break; 427f29dbc25Smrg default: 428f29dbc25Smrg return GFX_STATUS_BAD_PARAMETER; 429f29dbc25Smrg } 430f29dbc25Smrg return (GFX_STATUS_OK); 431f29dbc25Smrg} 432f29dbc25Smrg 433f29dbc25Smrg/*---------------------------------------------------------------------------- 434f29dbc25Smrg * gfx_set_tv_vphase 435f29dbc25Smrg * 436f29dbc25Smrg * This routine sets the tv encoder VPHASE value. 437f29dbc25Smrg *---------------------------------------------------------------------------- 438f29dbc25Smrg */ 439f29dbc25Smrg#if GFX_TV_DYNAMIC 440f29dbc25Smrgint 441f29dbc25Smrgsc1200_set_tv_vphase(int vphase) 442f29dbc25Smrg#else 443f29dbc25Smrgint 444f29dbc25Smrggfx_set_tv_vphase(int vphase) 445f29dbc25Smrg#endif 446f29dbc25Smrg{ 447f29dbc25Smrg unsigned long mode = READ_VID32(SC1200_TVENC_TIM_CTRL_1); 448f29dbc25Smrg 449f29dbc25Smrg mode &= ~SC1200_TVENC_VPHASE_MASK; 450f29dbc25Smrg mode |= (vphase << SC1200_TVENC_VPHASE_POS) & SC1200_TVENC_VPHASE_MASK; 451f29dbc25Smrg WRITE_VID32(SC1200_TVENC_TIM_CTRL_1, mode); 452f29dbc25Smrg return (GFX_STATUS_OK); 453f29dbc25Smrg} 454f29dbc25Smrg 455f29dbc25Smrg/*---------------------------------------------------------------------------- 456f29dbc25Smrg * gfx_set_tv_YC_delay 457f29dbc25Smrg * 458f29dbc25Smrg * This routine configures the TV out Y/C delay. 459f29dbc25Smrg *---------------------------------------------------------------------------- 460f29dbc25Smrg */ 461f29dbc25Smrg#if GFX_TV_DYNAMIC 462f29dbc25Smrgint 463f29dbc25Smrgsc1200_set_tv_YC_delay(int delay) 464f29dbc25Smrg#else 465f29dbc25Smrgint 466f29dbc25Smrggfx_set_tv_YC_delay(int delay) 467f29dbc25Smrg#endif 468f29dbc25Smrg{ 469f29dbc25Smrg unsigned long mode; 470f29dbc25Smrg 471f29dbc25Smrg /* This feature is implemented in Rev C1 */ 472f29dbc25Smrg if (gfx_chip_revision < SC1200_REV_C1) 473f29dbc25Smrg return (GFX_STATUS_OK); 474f29dbc25Smrg 475f29dbc25Smrg mode = READ_VID32(SC1200_TVOUT_HORZ_PRE_ENCODER_SCALE); 476f29dbc25Smrg mode &= ~SC1200_TVOUT_YC_DELAY_MASK; 477f29dbc25Smrg switch (delay) { 478f29dbc25Smrg case TV_YC_DELAY_NONE: 479f29dbc25Smrg WRITE_VID32(SC1200_TVOUT_HORZ_PRE_ENCODER_SCALE, 48004007ebaSmrg mode | SC1200_TVOUT_YC_DELAY_NONE); 481f29dbc25Smrg break; 482f29dbc25Smrg case TV_Y_DELAY_ONE_PIXEL: 483f29dbc25Smrg WRITE_VID32(SC1200_TVOUT_HORZ_PRE_ENCODER_SCALE, 48404007ebaSmrg mode | SC1200_TVOUT_Y_DELAY_ONE_PIXEL); 485f29dbc25Smrg break; 486f29dbc25Smrg case TV_C_DELAY_ONE_PIXEL: 487f29dbc25Smrg WRITE_VID32(SC1200_TVOUT_HORZ_PRE_ENCODER_SCALE, 48804007ebaSmrg mode | SC1200_TVOUT_C_DELAY_ONE_PIXEL); 489f29dbc25Smrg break; 490f29dbc25Smrg case TV_C_DELAY_TWO_PIXELS: 491f29dbc25Smrg WRITE_VID32(SC1200_TVOUT_HORZ_PRE_ENCODER_SCALE, 49204007ebaSmrg mode | SC1200_TVOUT_C_DELAY_TWO_PIXELS); 493f29dbc25Smrg break; 494f29dbc25Smrg default: 495f29dbc25Smrg return GFX_STATUS_BAD_PARAMETER; 496f29dbc25Smrg } 497f29dbc25Smrg return (GFX_STATUS_OK); 498f29dbc25Smrg} 499f29dbc25Smrg 500f29dbc25Smrg/*---------------------------------------------------------------------------- 501f29dbc25Smrg * gfx_set_tvenc_reset_interval 502f29dbc25Smrg * 503f29dbc25Smrg * This routine sets the interval between external resets of the TV encoder 504f29dbc25Smrg * timing generator by the TV out. 505f29dbc25Smrg *---------------------------------------------------------------------------- 506f29dbc25Smrg */ 507f29dbc25Smrg#if GFX_TV_DYNAMIC 508f29dbc25Smrgint 509f29dbc25Smrgsc1200_set_tvenc_reset_interval(int interval) 510f29dbc25Smrg#else 511f29dbc25Smrgint 512f29dbc25Smrggfx_set_tvenc_reset_interval(int interval) 513f29dbc25Smrg#endif 514f29dbc25Smrg{ 515f29dbc25Smrg unsigned long value; 516f29dbc25Smrg 517f29dbc25Smrg value = READ_VID32(SC1200_TVOUT_HORZ_SCALING); 518f29dbc25Smrg value &= ~SC1200_TVENC_EXTERNAL_RESET_INTERVAL_MASK; 519f29dbc25Smrg switch (interval) { 520f29dbc25Smrg case TVENC_RESET_EVERY_ODD_FIELD: 521f29dbc25Smrg WRITE_VID32(SC1200_TVOUT_HORZ_SCALING, 52204007ebaSmrg value | SC1200_TVENC_EXTERNAL_RESET_EVERY_ODD_FIELD); 523f29dbc25Smrg break; 524f29dbc25Smrg case TVENC_RESET_EVERY_EVEN_FIELD: 525f29dbc25Smrg WRITE_VID32(SC1200_TVOUT_HORZ_SCALING, 52604007ebaSmrg value | SC1200_TVENC_EXTERNAL_RESET_EVERY_EVEN_FIELD); 527f29dbc25Smrg break; 528f29dbc25Smrg case TVENC_RESET_NEXT_ODD_FIELD: 529f29dbc25Smrg WRITE_VID32(SC1200_TVOUT_HORZ_SCALING, 53004007ebaSmrg value | SC1200_TVENC_EXTERNAL_RESET_NEXT_ODD_FIELD); 531f29dbc25Smrg break; 532f29dbc25Smrg case TVENC_RESET_NEXT_EVEN_FIELD: 533f29dbc25Smrg WRITE_VID32(SC1200_TVOUT_HORZ_SCALING, 53404007ebaSmrg value | SC1200_TVENC_EXTERNAL_RESET_NEXT_EVEN_FIELD); 535f29dbc25Smrg break; 536f29dbc25Smrg case TVENC_RESET_EVERY_FIELD: 537f29dbc25Smrg WRITE_VID32(SC1200_TVOUT_HORZ_SCALING, 53804007ebaSmrg value | SC1200_TVENC_EXTERNAL_RESET_EVERY_FIELD); 539f29dbc25Smrg break; 540f29dbc25Smrg case TVENC_RESET_EVERY_X_ODD_FIELDS: 541f29dbc25Smrg case TVENC_RESET_EVERY_X_EVEN_FIELDS: 542f29dbc25Smrg return GFX_STATUS_UNSUPPORTED; 543f29dbc25Smrg default: 544f29dbc25Smrg return GFX_STATUS_BAD_PARAMETER; 545f29dbc25Smrg } 546f29dbc25Smrg return (GFX_STATUS_OK); 547f29dbc25Smrg} 548f29dbc25Smrg 549f29dbc25Smrg/*---------------------------------------------------------------------------- 550f29dbc25Smrg * gfx_set_tv_cc_enable 551f29dbc25Smrg * 552f29dbc25Smrg * This routine enables or disables the use of the hardware CC registers 553f29dbc25Smrg * in the TV encoder. 554f29dbc25Smrg *---------------------------------------------------------------------------- 555f29dbc25Smrg */ 556f29dbc25Smrg#if GFX_TV_DYNAMIC 557f29dbc25Smrgint 558f29dbc25Smrgsc1200_set_tv_cc_enable(int enable) 559f29dbc25Smrg#else 560f29dbc25Smrgint 561f29dbc25Smrggfx_set_tv_cc_enable(int enable) 562f29dbc25Smrg#endif 563f29dbc25Smrg{ 564f29dbc25Smrg unsigned long value; 565f29dbc25Smrg 566f29dbc25Smrg value = READ_VID32(SC1200_TVENC_CC_CONTROL); 567f29dbc25Smrg value &= ~(0x0005F); 568f29dbc25Smrg if (enable) 569f29dbc25Smrg value |= 0x51; 570f29dbc25Smrg WRITE_VID32(SC1200_TVENC_CC_CONTROL, value); 571f29dbc25Smrg return (0); 572f29dbc25Smrg} 573f29dbc25Smrg 574f29dbc25Smrg/*--------------------------------------------------------------------------- 575f29dbc25Smrg * gfx_set_tv_display 576f29dbc25Smrg * 577f29dbc25Smrg * This routine sets the timings in the display controller to support a 578f29dbc25Smrg * TV resolution. 579f29dbc25Smrg *--------------------------------------------------------------------------- 580f29dbc25Smrg */ 581f29dbc25Smrg#if GFX_TV_DYNAMIC 582f29dbc25Smrgint 583f29dbc25Smrgsc1200_set_tv_display(int width, int height) 584f29dbc25Smrg#else 585f29dbc25Smrgint 586f29dbc25Smrggfx_set_tv_display(int width, int height) 587f29dbc25Smrg#endif 588f29dbc25Smrg{ 589f29dbc25Smrg DISPLAYMODE *pMode; 590f29dbc25Smrg unsigned int i; 591f29dbc25Smrg 592f29dbc25Smrg for (i = 0; i < NUM_TV_MODES; i++) { 593f29dbc25Smrg pMode = &TVTimings[i]; 59404007ebaSmrg if ((unsigned) width == pMode->hactive 59504007ebaSmrg && (unsigned) height == pMode->vactive) 596f29dbc25Smrg break; 597f29dbc25Smrg } 598f29dbc25Smrg 599f29dbc25Smrg if (i == NUM_TV_MODES) 600f29dbc25Smrg return 0; 601f29dbc25Smrg 602f29dbc25Smrg gfx_set_display_timings(gfx_get_display_bpp(), 60304007ebaSmrg (unsigned short) pMode->flags, pMode->hactive, 60404007ebaSmrg pMode->hblankstart, pMode->hsyncstart, 60504007ebaSmrg pMode->hsyncend, pMode->hblankend, pMode->htotal, 60604007ebaSmrg pMode->vactive, pMode->vblankstart, 60704007ebaSmrg pMode->vsyncstart, pMode->vsyncend, 60804007ebaSmrg pMode->vblankend, pMode->vtotal, pMode->frequency); 609f29dbc25Smrg 610f29dbc25Smrg return 1; 611f29dbc25Smrg} 612f29dbc25Smrg 613f29dbc25Smrg/*---------------------------------------------------------------------------- 614f29dbc25Smrg * cc_add_parity_bit 615f29dbc25Smrg * 616f29dbc25Smrg * This routine adds the (odd) parity bit to the data character. 617f29dbc25Smrg *---------------------------------------------------------------------------- 618f29dbc25Smrg */ 619f29dbc25Smrgunsigned char 620f29dbc25Smrgcc_add_parity_bit(unsigned char data) 621f29dbc25Smrg{ 622f29dbc25Smrg int i, num = 0; 623f29dbc25Smrg unsigned char d = data; 624f29dbc25Smrg 625f29dbc25Smrg for (i = 0; i < 7; i++) { 626f29dbc25Smrg if (d & 0x1) 627f29dbc25Smrg num++; 628f29dbc25Smrg d >>= 1; 629f29dbc25Smrg } 630f29dbc25Smrg if (num & 0x1) 631f29dbc25Smrg return (data & ~0x80); 632f29dbc25Smrg else 633f29dbc25Smrg return (data | 0x80); 634f29dbc25Smrg} 635f29dbc25Smrg 636f29dbc25Smrg/*---------------------------------------------------------------------------- 637f29dbc25Smrg * gfx_set_tv_cc_data 638f29dbc25Smrg * 639f29dbc25Smrg * This routine writes the two specified characters to the CC data register 640f29dbc25Smrg * of the TV encoder. 641f29dbc25Smrg *---------------------------------------------------------------------------- 642f29dbc25Smrg */ 643f29dbc25Smrg#if GFX_TV_DYNAMIC 644f29dbc25Smrgint 645f29dbc25Smrgsc1200_set_tv_cc_data(unsigned char data1, unsigned char data2) 646f29dbc25Smrg#else 647f29dbc25Smrgint 648f29dbc25Smrggfx_set_tv_cc_data(unsigned char data1, unsigned char data2) 649f29dbc25Smrg#endif 650f29dbc25Smrg{ 651f29dbc25Smrg unsigned long value; 652f29dbc25Smrg 653f29dbc25Smrg value = cc_add_parity_bit(data1) | (cc_add_parity_bit(data2) << 8); 654f29dbc25Smrg WRITE_VID32(SC1200_TVENC_CC_DATA, value); 655f29dbc25Smrg return (0); 656f29dbc25Smrg} 657f29dbc25Smrg 658f29dbc25Smrg/*--------------------------------------------------------------------------- 659f29dbc25Smrg * gfx_test_tvout_odd_field 660f29dbc25Smrg * 661f29dbc25Smrg * This routine returns 1 if the current TVout field is odd. Otherwise returns 662f29dbc25Smrg * 0. 663f29dbc25Smrg *--------------------------------------------------------------------------- 664f29dbc25Smrg */ 665f29dbc25Smrg#if GFX_TV_DYNAMIC 666f29dbc25Smrgint 667f29dbc25Smrgsc1200_test_tvout_odd_field(void) 668f29dbc25Smrg#else 669f29dbc25Smrgint 670f29dbc25Smrggfx_test_tvout_odd_field(void) 671f29dbc25Smrg#endif 672f29dbc25Smrg{ 673f29dbc25Smrg unsigned long debug = READ_VID32(SC1200_TVOUT_DEBUG); 674f29dbc25Smrg 675f29dbc25Smrg WRITE_VID32(SC1200_TVOUT_DEBUG, debug | SC1200_TVOUT_FIELD_STATUS_TV); 676f29dbc25Smrg if (READ_VID32(SC1200_TVOUT_DEBUG) & SC1200_TVOUT_FIELD_STATUS_EVEN) 677f29dbc25Smrg return (0); 678f29dbc25Smrg else 679f29dbc25Smrg return (1); 680f29dbc25Smrg} 681f29dbc25Smrg 682f29dbc25Smrg/*--------------------------------------------------------------------------- 683f29dbc25Smrg * gfx_test_tvenc_odd_field 684f29dbc25Smrg * 685f29dbc25Smrg * This routine returns 1 if the current TV encoder field is odd. Otherwise 686f29dbc25Smrg * returns 0. 687f29dbc25Smrg *--------------------------------------------------------------------------- 688f29dbc25Smrg */ 689f29dbc25Smrg#if GFX_TV_DYNAMIC 690f29dbc25Smrgint 691f29dbc25Smrgsc1200_test_tvenc_odd_field(void) 692f29dbc25Smrg#else 693f29dbc25Smrgint 694f29dbc25Smrggfx_test_tvenc_odd_field(void) 695f29dbc25Smrg#endif 696f29dbc25Smrg{ 697f29dbc25Smrg unsigned long debug = READ_VID32(SC1200_TVOUT_DEBUG); 698f29dbc25Smrg 699f29dbc25Smrg WRITE_VID32(SC1200_TVOUT_DEBUG, debug & ~SC1200_TVOUT_FIELD_STATUS_TV); 700f29dbc25Smrg if (READ_VID32(SC1200_TVOUT_DEBUG) & SC1200_TVOUT_FIELD_STATUS_EVEN) 701f29dbc25Smrg return (0); 702f29dbc25Smrg else 703f29dbc25Smrg return (1); 704f29dbc25Smrg} 705f29dbc25Smrg 706f29dbc25Smrg/*---------------------------------------------------------------------------- 707f29dbc25Smrg * gfx_set_tv_field_status_invert 708f29dbc25Smrg * 709f29dbc25Smrg * This routines determines whether the tvout/tvencoder field status bit is 710f29dbc25Smrg * inverted (enable = 1) or not (enable = 0). 711f29dbc25Smrg *---------------------------------------------------------------------------- 712f29dbc25Smrg */ 713f29dbc25Smrg#if GFX_TV_DYNAMIC 714f29dbc25Smrgint 715f29dbc25Smrgsc1200_set_tv_field_status_invert(int enable) 716f29dbc25Smrg#else 717f29dbc25Smrgint 718f29dbc25Smrggfx_set_tv_field_status_invert(int enable) 719f29dbc25Smrg#endif 720f29dbc25Smrg{ 721f29dbc25Smrg unsigned long value; 722f29dbc25Smrg 723f29dbc25Smrg value = READ_VID32(SC1200_TVOUT_DEBUG); 724f29dbc25Smrg 725f29dbc25Smrg if (enable) { 726f29dbc25Smrg value |= SC1200_TVOUT_FIELD_STATUS_INVERT; 72704007ebaSmrg } 72804007ebaSmrg else { 729f29dbc25Smrg value &= ~(SC1200_TVOUT_FIELD_STATUS_INVERT); 730f29dbc25Smrg } 731f29dbc25Smrg 732f29dbc25Smrg WRITE_VID32(SC1200_TVOUT_DEBUG, value); 733f29dbc25Smrg 734f29dbc25Smrg return (GFX_STATUS_OK); 735f29dbc25Smrg} 736f29dbc25Smrg 737f29dbc25Smrg/*--------------------------------------------------------------------------- 738f29dbc25Smrg * gfx_get_tv_vphase 739f29dbc25Smrg * 740f29dbc25Smrg * This routine returns the tv encoder vertical phase. 741f29dbc25Smrg *--------------------------------------------------------------------------- 742f29dbc25Smrg */ 743f29dbc25Smrg#if GFX_TV_DYNAMIC 744f29dbc25Smrgint 745f29dbc25Smrgsc1200_get_tv_vphase(void) 746f29dbc25Smrg#else 747f29dbc25Smrgint 748f29dbc25Smrggfx_get_tv_vphase(void) 749f29dbc25Smrg#endif 750f29dbc25Smrg{ 751f29dbc25Smrg unsigned long mode = READ_VID32(SC1200_TVENC_TIM_CTRL_1); 752f29dbc25Smrg 75304007ebaSmrg return (int) ((mode & SC1200_TVENC_VPHASE_MASK) >> SC1200_TVENC_VPHASE_POS); 754f29dbc25Smrg} 755f29dbc25Smrg 756f29dbc25Smrg/*--------------------------------------------------------------------------- 757f29dbc25Smrg * gfx_get_tv_enable 758f29dbc25Smrg * 759f29dbc25Smrg * This routine returns the current tv enable status 760f29dbc25Smrg *--------------------------------------------------------------------------- 761f29dbc25Smrg */ 762f29dbc25Smrg#if GFX_TV_DYNAMIC 763f29dbc25Smrgint 764f29dbc25Smrgsc1200_get_tv_enable(unsigned int *p_on) 765f29dbc25Smrg#else 766f29dbc25Smrgint 767f29dbc25Smrggfx_get_tv_enable(unsigned int *p_on) 768f29dbc25Smrg#endif 769f29dbc25Smrg{ 770f29dbc25Smrg unsigned long control = READ_VID32(SC1200_TVENC_DAC_CONTROL); 771f29dbc25Smrg 77204007ebaSmrg *p_on = (unsigned int) (!(control & SC1200_TVENC_POWER_DOWN)); 773f29dbc25Smrg 774f29dbc25Smrg return GFX_STATUS_OK; 775f29dbc25Smrg} 776f29dbc25Smrg 777f29dbc25Smrg/*--------------------------------------------------------------------------- 778f29dbc25Smrg * gfx_get_tv_output 779f29dbc25Smrg * 780f29dbc25Smrg * This routine returns the current programmed TV output type. It does not 781f29dbc25Smrg * detect invalid configurations. 782f29dbc25Smrg *--------------------------------------------------------------------------- 783f29dbc25Smrg */ 784f29dbc25Smrg#if GFX_TV_DYNAMIC 785f29dbc25Smrgint 786f29dbc25Smrgsc1200_get_tv_output(void) 787f29dbc25Smrg#else 788f29dbc25Smrgint 789f29dbc25Smrggfx_get_tv_output(void) 790f29dbc25Smrg#endif 791f29dbc25Smrg{ 792f29dbc25Smrg unsigned long ctrl2, ctrl3; 793f29dbc25Smrg int format = 0; 794f29dbc25Smrg 795f29dbc25Smrg ctrl2 = READ_VID32(SC1200_TVENC_TIM_CTRL_2); 796f29dbc25Smrg ctrl3 = READ_VID32(SC1200_TVENC_TIM_CTRL_3); 797f29dbc25Smrg 798f29dbc25Smrg if ((ctrl2 & SC1200_TVENC_CFS_MASK) == SC1200_TVENC_CFS_SVIDEO) 799f29dbc25Smrg format = TV_OUTPUT_S_VIDEO; 800f29dbc25Smrg else if (ctrl2 & SC1200_TVENC_OUTPUT_YCBCR) 801f29dbc25Smrg format = TV_OUTPUT_YUV; 802f29dbc25Smrg else if ((ctrl2 & SC1200_TVENC_CFS_MASK) == SC1200_TVENC_CFS_CVBS) { 803f29dbc25Smrg if (ctrl3 & SC1200_TVENC_CM) 804f29dbc25Smrg format = TV_OUTPUT_SCART; 805f29dbc25Smrg else 806f29dbc25Smrg format = TV_OUTPUT_COMPOSITE; 807f29dbc25Smrg } 808f29dbc25Smrg 809f29dbc25Smrg return format; 810f29dbc25Smrg} 811f29dbc25Smrg 812f29dbc25Smrg/*--------------------------------------------------------------------------- 813f29dbc25Smrg * gfx_get_tv_mode_count 814f29dbc25Smrg * 815f29dbc25Smrg * This routine returns the number of valid TV out resolutions. 816f29dbc25Smrg *--------------------------------------------------------------------------- 817f29dbc25Smrg */ 818f29dbc25Smrg#if GFX_TV_DYNAMIC 819f29dbc25Smrgint 820f29dbc25Smrgsc1200_get_tv_mode_count(TVStandardType format) 821f29dbc25Smrg#else 822f29dbc25Smrgint 823f29dbc25Smrggfx_get_tv_mode_count(TVStandardType format) 824f29dbc25Smrg#endif 825f29dbc25Smrg{ 826f29dbc25Smrg unsigned int mode, count = 0; 827f29dbc25Smrg unsigned long flag; 828f29dbc25Smrg 829f29dbc25Smrg switch (format) { 830f29dbc25Smrg case TV_STANDARD_NTSC: 831f29dbc25Smrg flag = GFX_MODE_TV_NTSC; 832f29dbc25Smrg break; 833f29dbc25Smrg case TV_STANDARD_PAL: 834f29dbc25Smrg flag = GFX_MODE_TV_PAL; 835f29dbc25Smrg break; 836f29dbc25Smrg default: 837f29dbc25Smrg return 0; 838f29dbc25Smrg } 839f29dbc25Smrg 840f29dbc25Smrg for (mode = 0; mode < NUM_TV_MODES; mode++) { 841f29dbc25Smrg if (TVTimings[mode].flags & flag) 842f29dbc25Smrg count++; 843f29dbc25Smrg } 844f29dbc25Smrg 845f29dbc25Smrg return count; 846f29dbc25Smrg} 847f29dbc25Smrg 848f29dbc25Smrg/*--------------------------------------------------------------------------- 849f29dbc25Smrg * gfx_get_tv_display_mode 850f29dbc25Smrg * 851f29dbc25Smrg * This routine returns the current TV display parameters. 852f29dbc25Smrg *--------------------------------------------------------------------------- 853f29dbc25Smrg */ 854f29dbc25Smrg#if GFX_TV_DYNAMIC 855f29dbc25Smrgint 856f29dbc25Smrgsc1200_get_tv_display_mode(int *width, int *height, int *bpp, int *hz) 857f29dbc25Smrg#else 858f29dbc25Smrgint 859f29dbc25Smrggfx_get_tv_display_mode(int *width, int *height, int *bpp, int *hz) 860f29dbc25Smrg#endif 861f29dbc25Smrg{ 862f29dbc25Smrg unsigned long frequency; 863f29dbc25Smrg unsigned long mode, flags; 864f29dbc25Smrg 865f29dbc25Smrg *width = gfx_get_hactive(); 866f29dbc25Smrg *height = gfx_get_vactive(); 867f29dbc25Smrg *bpp = gfx_get_display_bpp(); 868f29dbc25Smrg frequency = gfx_get_clock_frequency(); 869f29dbc25Smrg 870f29dbc25Smrg for (mode = 0; mode < NUM_TV_MODES; mode++) { 87104007ebaSmrg if (TVTimings[mode].hactive == (unsigned short) (*width) && 87204007ebaSmrg TVTimings[mode].vactive == (unsigned short) (*height) && 873f29dbc25Smrg TVTimings[mode].frequency == frequency) { 874f29dbc25Smrg flags = TVTimings[mode].flags; 875f29dbc25Smrg 876f29dbc25Smrg if (flags & GFX_MODE_TV_NTSC) 877f29dbc25Smrg *hz = 60; 878f29dbc25Smrg else if (flags & GFX_MODE_TV_PAL) 879f29dbc25Smrg *hz = 50; 880f29dbc25Smrg else 881f29dbc25Smrg *hz = 0; 882f29dbc25Smrg return (1); 883f29dbc25Smrg } 884f29dbc25Smrg } 885f29dbc25Smrg 886f29dbc25Smrg return -1; 887f29dbc25Smrg} 888f29dbc25Smrg 889f29dbc25Smrg/*--------------------------------------------------------------------------- 890f29dbc25Smrg * gfx_get_tv_display_mode_frequency 891f29dbc25Smrg * 892f29dbc25Smrg * This routine returns the PLL frequency of a given TV mode. 893f29dbc25Smrg *--------------------------------------------------------------------------- 894f29dbc25Smrg */ 895f29dbc25Smrg#if GFX_TV_DYNAMIC 896f29dbc25Smrgint 897f29dbc25Smrgsc1200_get_tv_display_mode_frequency(unsigned short width, 89804007ebaSmrg unsigned short height, 89904007ebaSmrg TVStandardType format, int *frequency) 900f29dbc25Smrg#else 901f29dbc25Smrgint 902f29dbc25Smrggfx_get_tv_display_mode_frequency(unsigned short width, unsigned short height, 90304007ebaSmrg TVStandardType format, int *frequency) 904f29dbc25Smrg#endif 905f29dbc25Smrg{ 906f29dbc25Smrg unsigned long mode, flag; 907f29dbc25Smrg int retval = -1; 908f29dbc25Smrg 909f29dbc25Smrg *frequency = 0; 910f29dbc25Smrg 911f29dbc25Smrg switch (format) { 912f29dbc25Smrg case TV_STANDARD_NTSC: 913f29dbc25Smrg flag = GFX_MODE_TV_NTSC; 914f29dbc25Smrg break; 915f29dbc25Smrg case TV_STANDARD_PAL: 916f29dbc25Smrg flag = GFX_MODE_TV_PAL; 917f29dbc25Smrg break; 918f29dbc25Smrg default: 919f29dbc25Smrg return -1; 920f29dbc25Smrg } 921f29dbc25Smrg 922f29dbc25Smrg for (mode = 0; mode < NUM_TV_MODES; mode++) { 923f29dbc25Smrg if ((TVTimings[mode].hactive == width) && 924f29dbc25Smrg (TVTimings[mode].vactive == height) && 925f29dbc25Smrg (TVTimings[mode].flags & flag)) { 926f29dbc25Smrg *frequency = TVTimings[mode].frequency; 927f29dbc25Smrg retval = 1; 928f29dbc25Smrg } 929f29dbc25Smrg } 930f29dbc25Smrg return retval; 931f29dbc25Smrg} 932f29dbc25Smrg 933f29dbc25Smrg/*--------------------------------------------------------------------------- 934f29dbc25Smrg * gfx_is_tv_display_mode_supported 935f29dbc25Smrg * 936f29dbc25Smrg * Returns >= 0 if the mode is available, -1 if the mode could not be found 937f29dbc25Smrg *--------------------------------------------------------------------------- 938f29dbc25Smrg */ 939f29dbc25Smrg#if GFX_TV_DYNAMIC 940f29dbc25Smrgint 941f29dbc25Smrgsc1200_is_tv_display_mode_supported(unsigned short width, 94204007ebaSmrg unsigned short height, 94304007ebaSmrg TVStandardType format) 944f29dbc25Smrg#else 945f29dbc25Smrgint 946f29dbc25Smrggfx_is_tv_display_mode_supported(unsigned short width, unsigned short height, 94704007ebaSmrg TVStandardType format) 948f29dbc25Smrg#endif 949f29dbc25Smrg{ 950f29dbc25Smrg unsigned long mode, flag; 951f29dbc25Smrg 952f29dbc25Smrg switch (format) { 953f29dbc25Smrg case TV_STANDARD_NTSC: 954f29dbc25Smrg flag = GFX_MODE_TV_NTSC; 955f29dbc25Smrg break; 956f29dbc25Smrg case TV_STANDARD_PAL: 957f29dbc25Smrg flag = GFX_MODE_TV_PAL; 958f29dbc25Smrg break; 959f29dbc25Smrg default: 960f29dbc25Smrg return -1; 961f29dbc25Smrg } 962f29dbc25Smrg 963f29dbc25Smrg for (mode = 0; mode < NUM_TV_MODES; mode++) { 964f29dbc25Smrg if (TVTimings[mode].hactive == width && 965f29dbc25Smrg TVTimings[mode].vactive == height && 966f29dbc25Smrg (TVTimings[mode].flags & flag)) { 96704007ebaSmrg return ((int) mode); 968f29dbc25Smrg } 969f29dbc25Smrg } 970f29dbc25Smrg 971f29dbc25Smrg return -1; 972f29dbc25Smrg} 973f29dbc25Smrg 974f29dbc25Smrg/* END OF FILE */ 975