1f29dbc25Smrg/* 2f29dbc25Smrg * Copyright (c) 2006 Advanced Micro Devices, Inc. 3f29dbc25Smrg * 4f29dbc25Smrg * Permission is hereby granted, free of charge, to any person obtaining a 5f29dbc25Smrg * copy of this software and associated documentation files (the "Software"), 6f29dbc25Smrg * to deal in the Software without restriction, including without limitation 7f29dbc25Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8f29dbc25Smrg * and/or sell copies of the Software, and to permit persons to whom the 9f29dbc25Smrg * Software is furnished to do so, subject to the following conditions: 10f29dbc25Smrg * 11f29dbc25Smrg * The above copyright notice and this permission notice shall be included in 12f29dbc25Smrg * all copies or substantial portions of the Software. 13f29dbc25Smrg * 14f29dbc25Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15f29dbc25Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16f29dbc25Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17f29dbc25Smrg * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18f29dbc25Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19f29dbc25Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20f29dbc25Smrg * DEALINGS IN THE SOFTWARE. 21f29dbc25Smrg * 22f29dbc25Smrg * Neither the name of the Advanced Micro Devices, Inc. nor the names of its 23f29dbc25Smrg * contributors may be used to endorse or promote products derived from this 24f29dbc25Smrg * software without specific prior written permission. 25f29dbc25Smrg */ 26f29dbc25Smrg 27f29dbc25Smrg /* 28f29dbc25Smrg * Cimarron VOP configuration routines. 29f29dbc25Smrg */ 30f29dbc25Smrg 31f29dbc25Smrg/*--------------------------------------------------------------------------- 32f29dbc25Smrg * vop_set_vbi_window 33f29dbc25Smrg * 34f29dbc25Smrg * This routine configures the output position and location in memory of 35f29dbc25Smrg * VBI data. 36f29dbc25Smrg *--------------------------------------------------------------------------*/ 37f29dbc25Smrg 38f29dbc25Smrgint 39f29dbc25Smrgvop_set_vbi_window(VOPVBIWINDOWBUFFER * buffer) 40f29dbc25Smrg{ 41f29dbc25Smrg unsigned long unlock, temp; 42f29dbc25Smrg unsigned long hstart, hstop; 43f29dbc25Smrg unsigned long htotal, hsyncstart; 44f29dbc25Smrg 45f29dbc25Smrg if (!buffer) 46f29dbc25Smrg return CIM_STATUS_INVALIDPARAMS; 47f29dbc25Smrg 48f29dbc25Smrg unlock = READ_REG32(DC3_UNLOCK); 49f29dbc25Smrg WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE); 50f29dbc25Smrg 51f29dbc25Smrg /* PROGRAM HORIZONTAL POSITION 52f29dbc25Smrg * The horizontal position is a little tricky. The counter for the 53f29dbc25Smrg * horizontal timings is reused for the VBI counter. Consequently, the 54f29dbc25Smrg * horizontal start and stop values are based off the beginning of active 55f29dbc25Smrg * data. However, the VG has a quirk. If the counter start position is 56f29dbc25Smrg * before the beginning of HSync, it applies to the previous line. If 57f29dbc25Smrg * the counter is after the beginning of HSync it applies to the current 58f29dbc25Smrg * line. So, for one line the real range can be thought of as 59f29dbc25Smrg * HSync_start to (HSync_start + htotal - 1). However, the counters 60f29dbc25Smrg * must be between 0 and htotal - 1. When placing VBI data before the 61f29dbc25Smrg * start of active data, the horizontal end position will thus be *less* 62f29dbc25Smrg * than the horizontal start. 63f29dbc25Smrg */ 64f29dbc25Smrg 65f29dbc25Smrg htotal = ((READ_REG32(DC3_H_ACTIVE_TIMING) >> 16) & 0xFFF) + 1; 66f29dbc25Smrg hsyncstart = (READ_REG32(DC3_H_SYNC_TIMING) & 0xFFF) + 1; 67f29dbc25Smrg 68f29dbc25Smrg if (buffer->horz_from_hsync) { 69f29dbc25Smrg /* VERIFY THAT THE INPUT IS VALID */ 70f29dbc25Smrg 71f29dbc25Smrg if (buffer->horz_start < 0 72f29dbc25Smrg || (buffer->horz_start + buffer->vbi_width) > htotal) 73f29dbc25Smrg return CIM_STATUS_INVALIDPARAMS; 74f29dbc25Smrg 75f29dbc25Smrg hstart = buffer->horz_start + hsyncstart; 7604007ebaSmrg } 7704007ebaSmrg else { 78f29dbc25Smrg /* VERIFY THAT THE INPUT IS VALID */ 79f29dbc25Smrg 8004007ebaSmrg if (buffer->horz_start < ((long) hsyncstart - (long) htotal) || 8104007ebaSmrg buffer->horz_start > (long) hsyncstart || 82f29dbc25Smrg buffer->vbi_width > htotal) { 83f29dbc25Smrg return CIM_STATUS_INVALIDPARAMS; 84f29dbc25Smrg } 85f29dbc25Smrg 86f29dbc25Smrg hstart = buffer->horz_start + htotal; 87f29dbc25Smrg } 88f29dbc25Smrg 89f29dbc25Smrg hstop = hstart + buffer->vbi_width; 90f29dbc25Smrg if (hstart > htotal) 91f29dbc25Smrg hstart -= htotal; 92f29dbc25Smrg if (hstop > htotal) 93f29dbc25Smrg hstop -= htotal; 94f29dbc25Smrg hstart--; 95f29dbc25Smrg hstop--; 96f29dbc25Smrg WRITE_REG32(DC3_VBI_HOR, ((hstop << DC3_VBI_HOR_END_SHIFT) & 9704007ebaSmrg DC3_VBI_HOR_END_MASK) | (hstart & 9804007ebaSmrg DC3_VBI_HOR_START_MASK)); 99f29dbc25Smrg 100f29dbc25Smrg /* WRITE LINE CAPTURE MASKS */ 101f29dbc25Smrg 102f29dbc25Smrg WRITE_REG32(DC3_VBI_LN_ODD, ((buffer->odd_line_offset << 10304007ebaSmrg DC3_VBI_ODD_LINE_SHIFT) & 10404007ebaSmrg DC3_VBI_ODD_LINE_MASK) | 10504007ebaSmrg (buffer->odd_line_capture_mask & DC3_VBI_ODD_ENABLE_MASK)); 106f29dbc25Smrg 107f29dbc25Smrg WRITE_REG32(DC3_VBI_LN_EVEN, ((buffer->even_line_offset << 10804007ebaSmrg DC3_VBI_EVEN_LINE_SHIFT) & 10904007ebaSmrg DC3_VBI_EVEN_LINE_MASK) | 11004007ebaSmrg (buffer->even_line_capture_mask & DC3_VBI_EVEN_ENABLE_MASK)); 111f29dbc25Smrg 112f29dbc25Smrg /* PROGRAM SOURCE OFFSETS 113f29dbc25Smrg * Start with the even offsets. Note that we always enable 16-bit VBI, 114f29dbc25Smrg * as this is the only way to get VBI data on each VOP clock. 115f29dbc25Smrg */ 116f29dbc25Smrg 117f29dbc25Smrg temp = READ_REG32(DC3_VBI_EVEN_CTL) & ~DC3_VBI_EVEN_CTL_OFFSET_MASK; 118f29dbc25Smrg temp |= DC3_VBI_EVEN_CTL_ENABLE_16; 119f29dbc25Smrg if (buffer->enable_upscale) 120f29dbc25Smrg temp |= DC3_VBI_EVEN_CTL_UPSCALE; 121f29dbc25Smrg WRITE_REG32(DC3_VBI_EVEN_CTL, temp | 12204007ebaSmrg (buffer->even_address_offset & DC3_VBI_EVEN_CTL_OFFSET_MASK)); 123f29dbc25Smrg 124f29dbc25Smrg /* ODD OFFSET */ 125f29dbc25Smrg 126f29dbc25Smrg temp = READ_REG32(DC3_VBI_ODD_CTL) & ~DC3_VBI_ODD_CTL_OFFSET_MASK; 127f29dbc25Smrg WRITE_REG32(DC3_VBI_ODD_CTL, temp | 12804007ebaSmrg (buffer->odd_address_offset & DC3_VBI_ODD_CTL_OFFSET_MASK)); 129f29dbc25Smrg 130f29dbc25Smrg /* PITCH */ 131f29dbc25Smrg 132f29dbc25Smrg temp = ((buffer->data_size >> 3) << 16) | ((buffer->data_pitch >> 3) & 13304007ebaSmrg 0x0000FFFF); 134f29dbc25Smrg WRITE_REG32(DC3_VBI_PITCH, temp); 135f29dbc25Smrg 136f29dbc25Smrg WRITE_REG32(DC3_UNLOCK, unlock); 137f29dbc25Smrg 138f29dbc25Smrg return CIM_STATUS_OK; 139f29dbc25Smrg} 140f29dbc25Smrg 141f29dbc25Smrg/*--------------------------------------------------------------------------- 142f29dbc25Smrg * vop_enable_vbi_output 143f29dbc25Smrg * 144f29dbc25Smrg * This routine enables/disables VBI fetching inside the video generator. 145f29dbc25Smrg *--------------------------------------------------------------------------*/ 146f29dbc25Smrg 147f29dbc25Smrgint 148f29dbc25Smrgvop_enable_vbi_output(int enable) 149f29dbc25Smrg{ 150f29dbc25Smrg unsigned long unlock, temp; 151f29dbc25Smrg 152f29dbc25Smrg unlock = READ_REG32(DC3_UNLOCK); 153f29dbc25Smrg temp = READ_REG32(DC3_VBI_EVEN_CTL); 154f29dbc25Smrg 155f29dbc25Smrg if (enable) 156f29dbc25Smrg temp |= DC3_VBI_ENABLE; 157f29dbc25Smrg else 158f29dbc25Smrg temp &= ~DC3_VBI_ENABLE; 159f29dbc25Smrg 160f29dbc25Smrg WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE); 161f29dbc25Smrg WRITE_REG32(DC3_VBI_EVEN_CTL, temp); 162f29dbc25Smrg WRITE_REG32(DC3_UNLOCK, unlock); 163f29dbc25Smrg 164f29dbc25Smrg return CIM_STATUS_OK; 165f29dbc25Smrg} 166f29dbc25Smrg 167f29dbc25Smrg/*--------------------------------------------------------------------------- 168f29dbc25Smrg * vop_set_configuration 169f29dbc25Smrg * 170f29dbc25Smrg * This routine is passed a VOP_CONFIGURATION structure that contains all 171f29dbc25Smrg * the necessary information to configure VOP output. 172f29dbc25Smrg *--------------------------------------------------------------------------*/ 173f29dbc25Smrg 174f29dbc25Smrgint 175f29dbc25Smrgvop_set_configuration(VOPCONFIGURATIONBUFFER * config) 176f29dbc25Smrg{ 177f29dbc25Smrg unsigned long vop_config = 0; 178f29dbc25Smrg unsigned long alpha, control2; 179f29dbc25Smrg unsigned long unlock; 180f29dbc25Smrg unsigned long delta; 181f29dbc25Smrg Q_WORD msr_value; 182f29dbc25Smrg int rgb = 0; 183f29dbc25Smrg 184f29dbc25Smrg if (!config) 185f29dbc25Smrg return CIM_STATUS_INVALIDPARAMS; 186f29dbc25Smrg 187f29dbc25Smrg unlock = READ_REG32(DC3_UNLOCK); 188f29dbc25Smrg delta = READ_REG32(DC3_VID_DS_DELTA) & DC3_DS_DELTA_MASK; 189f29dbc25Smrg 190f29dbc25Smrg /* OVERRIDE THE OUTPUT SETTINGS TO ENABLE VOP OUTPUT */ 191f29dbc25Smrg 192f29dbc25Smrg if (config->mode != VOP_MODE_DISABLED) { 193f29dbc25Smrg msr_read64(MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_CONFIG, &msr_value); 194f29dbc25Smrg msr_value.low &= ~DF_CONFIG_OUTPUT_MASK; 195f29dbc25Smrg msr_value.low |= DF_OUTPUT_VOP; 196f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_CONFIG, &msr_value); 197f29dbc25Smrg } 198f29dbc25Smrg 199f29dbc25Smrg /* SET THE UNIVERSAL VOP OPTIONS */ 200f29dbc25Smrg 201f29dbc25Smrg if (config->flags & VOP_FLAG_SWAP_UV) 202f29dbc25Smrg vop_config |= VOP_CONFIG_SWAPUV; 203f29dbc25Smrg if (config->flags & VOP_FLAG_SWAP_VBI) 204f29dbc25Smrg vop_config |= VOP_CONFIG_SWAPVBI; 205f29dbc25Smrg 206f29dbc25Smrg /* SET THE MODE SPECIFIC PARAMETERS */ 207f29dbc25Smrg 208f29dbc25Smrg if (config->mode == VOP_MODE_601) { 209f29dbc25Smrg vop_config |= config->vop601.flags; 210f29dbc25Smrg vop_config |= config->vop601.vsync_shift; 211f29dbc25Smrg vop_config |= VOP_CONFIG_ENABLE_601 | VOP_CONFIG_VIP2_0; 212f29dbc25Smrg 213f29dbc25Smrg switch (config->vop601.output_mode) { 214f29dbc25Smrg case VOP_601_YUV_16BIT: 215f29dbc25Smrg vop_config |= VOP_CONFIG_VIP2_16BIT; 216f29dbc25Smrg break; 217f29dbc25Smrg case VOP_601_YUV_4_4_4: 218f29dbc25Smrg vop_config |= VOP_CONFIG_DISABLE_DECIMATE; 219f29dbc25Smrg break; 220f29dbc25Smrg case VOP_601_RGB_8_8_8: 221f29dbc25Smrg vop_config |= VOP_CONFIG_DISABLE_DECIMATE | VOP_CONFIG_RGBMODE; 222f29dbc25Smrg rgb = 1; 223f29dbc25Smrg break; 224f29dbc25Smrg } 225f29dbc25Smrg 226f29dbc25Smrg if (config->vop601.vsync_shift == VOP_VSYNC_LATER_BY_X) { 227f29dbc25Smrg delta |= (config->vop601.vsync_shift_count & 22804007ebaSmrg DC3_601_VSYNC_SHIFT_MASK); 229f29dbc25Smrg delta |= DC3_601_VSYNC_SHIFT_ENABLE; 230f29dbc25Smrg } 23104007ebaSmrg } 23204007ebaSmrg else { 233f29dbc25Smrg if (config->flags & VOP_FLAG_VBI) 234f29dbc25Smrg vop_config |= VOP_CONFIG_VBI; 235f29dbc25Smrg if (config->flags & VOP_FLAG_TASK) 236f29dbc25Smrg vop_config |= VOP_CONFIG_TASK; 237f29dbc25Smrg if (config->flags & VOP_FLAG_SINGLECHIPCOMPAT) 238f29dbc25Smrg vop_config |= VOP_CONFIG_SC_COMPATIBLE; 239f29dbc25Smrg if (config->flags & VOP_FLAG_EXTENDEDSAV) 240f29dbc25Smrg vop_config |= VOP_CONFIG_EXTENDED_SAV; 241f29dbc25Smrg 242f29dbc25Smrg switch (config->mode) { 243f29dbc25Smrg case VOP_MODE_DISABLED: 244f29dbc25Smrg vop_config |= VOP_CONFIG_DISABLED; 245f29dbc25Smrg break; 246f29dbc25Smrg case VOP_MODE_VIP11: 247f29dbc25Smrg vop_config |= VOP_CONFIG_VIP1_1; 248f29dbc25Smrg break; 249f29dbc25Smrg case VOP_MODE_CCIR656: 250f29dbc25Smrg vop_config |= VOP_CONFIG_CCIR656; 251f29dbc25Smrg break; 252f29dbc25Smrg case VOP_MODE_VIP20_8BIT: 253f29dbc25Smrg vop_config |= VOP_CONFIG_VIP2_0; 254f29dbc25Smrg break; 255f29dbc25Smrg case VOP_MODE_VIP20_16BIT: 256f29dbc25Smrg vop_config |= VOP_CONFIG_VIP2_0 | VOP_CONFIG_VIP2_16BIT; 257f29dbc25Smrg break; 258f29dbc25Smrg } 259f29dbc25Smrg } 260f29dbc25Smrg 261f29dbc25Smrg /* SET THE 4:4:4 TO 4:2:2 DECIMATION ALGORITHM */ 262f29dbc25Smrg 263f29dbc25Smrg vop_config |= (config->conversion_mode); 264f29dbc25Smrg 265f29dbc25Smrg /* SET THE VSYNC OUT OPTIONS */ 266f29dbc25Smrg 267f29dbc25Smrg control2 = READ_VIP32(VIP_CONTROL2) & ~VIP_CONTROL2_SYNC2PIN_MASK; 268f29dbc25Smrg control2 |= config->vsync_out; 269f29dbc25Smrg WRITE_VIP32(VIP_CONTROL2, control2); 270f29dbc25Smrg 271f29dbc25Smrg /* FORCE THE CORRECT VOP COLOR SPACE */ 272f29dbc25Smrg /* The output of the mixer will be either RGB or YUV. We must enable */ 273f29dbc25Smrg /* or disable the VOP CSC based on the desired output format. */ 274f29dbc25Smrg 275f29dbc25Smrg alpha = READ_VID32(DF_VID_ALPHA_CONTROL); 276f29dbc25Smrg if (!(alpha & DF_CSC_GRAPHICS_RGB_TO_YUV)) { 277f29dbc25Smrg /* RGB OUTPUT FROM THE MIXER */ 278f29dbc25Smrg 279f29dbc25Smrg if (!rgb) 280f29dbc25Smrg alpha |= DF_CSC_VOP_RGB_TO_YUV; 281f29dbc25Smrg else 282f29dbc25Smrg alpha &= ~DF_CSC_VOP_RGB_TO_YUV; 28304007ebaSmrg } 28404007ebaSmrg else { 285f29dbc25Smrg /* YUV OUTPUT FROM THE MIXER */ 286f29dbc25Smrg /* As there is no YUV->RGB VOP conversion, we simply disable the */ 287f29dbc25Smrg /* VOP CSC and trust that the user is competent. */ 288f29dbc25Smrg 289f29dbc25Smrg alpha &= ~DF_CSC_VOP_RGB_TO_YUV; 290f29dbc25Smrg } 291f29dbc25Smrg 292f29dbc25Smrg /* AND WRITE THE CONFIGURATION */ 293f29dbc25Smrg 294f29dbc25Smrg WRITE_VID32(DF_VID_ALPHA_CONTROL, alpha); 295f29dbc25Smrg WRITE_VOP32(VOP_CONFIGURATION, vop_config); 296f29dbc25Smrg WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE); 297f29dbc25Smrg WRITE_REG32(DC3_VID_DS_DELTA, delta); 298f29dbc25Smrg WRITE_REG32(DC3_UNLOCK, unlock); 299f29dbc25Smrg 300f29dbc25Smrg return CIM_STATUS_OK; 301f29dbc25Smrg} 302f29dbc25Smrg 303f29dbc25Smrg/*--------------------------------------------------------------------------- 304f29dbc25Smrg * vop_save_state 305f29dbc25Smrg * 306f29dbc25Smrg * This routine saves the necessary register contents in order to restore 307f29dbc25Smrg * at a later point to the same state. Note that the capture state is 308f29dbc25Smrg * forced to OFF in this routine. 309f29dbc25Smrg *--------------------------------------------------------------------------*/ 310f29dbc25Smrg 311f29dbc25Smrgint 312f29dbc25Smrgvop_save_state(VOPSTATEBUFFER * save_buffer) 313f29dbc25Smrg{ 314f29dbc25Smrg if (!save_buffer) 315f29dbc25Smrg return CIM_STATUS_INVALIDPARAMS; 316f29dbc25Smrg 317f29dbc25Smrg save_buffer->config = READ_VOP32(VOP_CONFIGURATION); 318f29dbc25Smrg 319f29dbc25Smrg return CIM_STATUS_OK; 320f29dbc25Smrg} 321f29dbc25Smrg 322f29dbc25Smrg/*--------------------------------------------------------------------------- 323f29dbc25Smrg * vop_restore_state 324f29dbc25Smrg * 325f29dbc25Smrg * This routine restores the state of the vop registers - which were 326f29dbc25Smrg * previously saved using vop_save_state. 327f29dbc25Smrg *--------------------------------------------------------------------------*/ 328f29dbc25Smrg 329f29dbc25Smrgint 330f29dbc25Smrgvop_restore_state(VOPSTATEBUFFER * restore_buffer) 331f29dbc25Smrg{ 332f29dbc25Smrg if (!restore_buffer) 333f29dbc25Smrg return CIM_STATUS_INVALIDPARAMS; 334f29dbc25Smrg 335f29dbc25Smrg WRITE_VOP32(VOP_CONFIGURATION, restore_buffer->config); 336f29dbc25Smrg 337f29dbc25Smrg return CIM_STATUS_OK; 338f29dbc25Smrg} 339f29dbc25Smrg 340f29dbc25Smrg/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 341f29dbc25Smrg * CIMARRON VOP READ ROUTINES 342f29dbc25Smrg * These routines are included for use in diagnostics or when debugging. They 343f29dbc25Smrg * can be optionally excluded from a project. 344f29dbc25Smrg *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ 345f29dbc25Smrg 346f29dbc25Smrg#if CIMARRON_INCLUDE_VOP_READ_ROUTINES 347f29dbc25Smrg 348f29dbc25Smrg/*--------------------------------------------------------------------------- 349f29dbc25Smrg * vop_get_current_mode 350f29dbc25Smrg * 351f29dbc25Smrg * This routine reads the current VIP operating mode and stores it in the 352f29dbc25Smrg * passed VOP_CONFIGURATION structure. 353f29dbc25Smrg *--------------------------------------------------------------------------*/ 354f29dbc25Smrg 355f29dbc25Smrgint 356f29dbc25Smrgvop_get_current_mode(VOPCONFIGURATIONBUFFER * config) 357f29dbc25Smrg{ 358f29dbc25Smrg unsigned long vop_config = 0; 359f29dbc25Smrg unsigned long alpha; 360f29dbc25Smrg 361f29dbc25Smrg if (!config) 362f29dbc25Smrg return CIM_STATUS_INVALIDPARAMS; 363f29dbc25Smrg 364f29dbc25Smrg vop_config = READ_VOP32(VOP_CONFIGURATION); 365f29dbc25Smrg alpha = READ_VID32(DF_VID_ALPHA_CONTROL); 366f29dbc25Smrg 367f29dbc25Smrg /* READ THE CURRENT MODE */ 368f29dbc25Smrg 369f29dbc25Smrg switch (vop_config & VOP_CONFIG_MODE_MASK) { 370f29dbc25Smrg case VOP_CONFIG_DISABLED: 371f29dbc25Smrg config->mode = VOP_MODE_DISABLED; 372f29dbc25Smrg break; 373f29dbc25Smrg case VOP_CONFIG_VIP1_1: 374f29dbc25Smrg config->mode = VOP_MODE_VIP11; 375f29dbc25Smrg break; 376f29dbc25Smrg case VOP_CONFIG_CCIR656: 377f29dbc25Smrg config->mode = VOP_MODE_CCIR656; 378f29dbc25Smrg break; 379f29dbc25Smrg case VOP_CONFIG_VIP2_0: 380f29dbc25Smrg 381f29dbc25Smrg if (vop_config & VOP_CONFIG_ENABLE_601) 382f29dbc25Smrg config->mode = VOP_MODE_601; 383f29dbc25Smrg else if (vop_config & VOP_CONFIG_VIP2_16BIT) 384f29dbc25Smrg config->mode = VOP_MODE_VIP20_16BIT; 385f29dbc25Smrg else 386f29dbc25Smrg config->mode = VOP_MODE_VIP20_8BIT; 387f29dbc25Smrg break; 388f29dbc25Smrg } 389f29dbc25Smrg 390f29dbc25Smrg /* READ 601 SETTINGS */ 391f29dbc25Smrg 392f29dbc25Smrg config->vop601.flags = vop_config & (VOP_CONFIG_INVERT_DISPE | 39304007ebaSmrg VOP_CONFIG_INVERT_HSYNC | 39404007ebaSmrg VOP_CONFIG_INVERT_VSYNC); 395f29dbc25Smrg 396f29dbc25Smrg config->vop601.vsync_shift = vop_config & VOP_CONFIG_VSYNC_MASK; 397f29dbc25Smrg config->vop601.vsync_shift_count = 398f29dbc25Smrg READ_REG32(DC3_VID_DS_DELTA) & DC3_601_VSYNC_SHIFT_MASK; 399f29dbc25Smrg 40004007ebaSmrg if ((alpha & DF_CSC_GRAPHICS_RGB_TO_YUV) || (alpha & DF_CSC_VOP_RGB_TO_YUV)) { 401f29dbc25Smrg /* YUV OUTPUT */ 402f29dbc25Smrg 403f29dbc25Smrg if (vop_config & VOP_CONFIG_DISABLE_DECIMATE) 404f29dbc25Smrg config->vop601.output_mode = VOP_601_YUV_4_4_4; 405f29dbc25Smrg else if (vop_config & VOP_CONFIG_VIP2_16BIT) 406f29dbc25Smrg config->vop601.output_mode = VOP_601_YUV_16BIT; 407f29dbc25Smrg else 408f29dbc25Smrg config->vop601.output_mode = VOP_601_YUV_8BIT; 40904007ebaSmrg } 41004007ebaSmrg else { 411f29dbc25Smrg config->vop601.output_mode = VOP_601_RGB_8_8_8; 412f29dbc25Smrg } 413f29dbc25Smrg 414f29dbc25Smrg config->flags = 0; 415f29dbc25Smrg 416f29dbc25Smrg /* READ THE UNIVERSAL VOP OPTIONS */ 417f29dbc25Smrg 418f29dbc25Smrg if (vop_config & VOP_CONFIG_SWAPUV) 419f29dbc25Smrg config->flags |= VOP_FLAG_SWAP_UV; 420f29dbc25Smrg if (vop_config & VOP_CONFIG_SWAPVBI) 421f29dbc25Smrg config->flags |= VOP_FLAG_SWAP_VBI; 422f29dbc25Smrg if (vop_config & VOP_CONFIG_VBI) 423f29dbc25Smrg config->flags |= VOP_FLAG_VBI; 424f29dbc25Smrg if (vop_config & VOP_CONFIG_TASK) 425f29dbc25Smrg config->flags |= VOP_FLAG_TASK; 426f29dbc25Smrg if (vop_config & VOP_CONFIG_SC_COMPATIBLE) 427f29dbc25Smrg config->flags |= VOP_FLAG_SINGLECHIPCOMPAT; 428f29dbc25Smrg if (vop_config & VOP_CONFIG_EXTENDED_SAV) 429f29dbc25Smrg config->flags |= VOP_FLAG_EXTENDEDSAV; 430f29dbc25Smrg 431f29dbc25Smrg config->conversion_mode = vop_config & VOP_CONFIG_422_MASK; 432f29dbc25Smrg 433f29dbc25Smrg config->vsync_out = READ_VIP32(VIP_CONTROL2) & VIP_CONTROL2_SYNC2PIN_MASK; 434f29dbc25Smrg 435f29dbc25Smrg return CIM_STATUS_OK; 436f29dbc25Smrg} 437f29dbc25Smrg 438f29dbc25Smrg/*--------------------------------------------------------------------------- 439f29dbc25Smrg * vop_get_vbi_window 440f29dbc25Smrg * 441f29dbc25Smrg * This routine reads the current VBI configuration for VOP output. 442f29dbc25Smrg *--------------------------------------------------------------------------*/ 443f29dbc25Smrg 444f29dbc25Smrgint 445f29dbc25Smrgvop_get_vbi_configuration(VOPVBIWINDOWBUFFER * buffer) 446f29dbc25Smrg{ 447f29dbc25Smrg unsigned long temp; 448f29dbc25Smrg unsigned long hstart, hstop; 449f29dbc25Smrg unsigned long htotal, hsyncstart; 450f29dbc25Smrg 451f29dbc25Smrg if (!buffer) 452f29dbc25Smrg return CIM_STATUS_INVALIDPARAMS; 453f29dbc25Smrg 454f29dbc25Smrg htotal = ((READ_REG32(DC3_H_ACTIVE_TIMING) >> 16) & 0xFFF) + 1; 455f29dbc25Smrg hsyncstart = (READ_REG32(DC3_H_SYNC_TIMING) & 0xFFF) + 1; 456f29dbc25Smrg 457f29dbc25Smrg /* DECODE HORIZONTAL POSITION */ 458f29dbc25Smrg /* This is done according to the requested horizontal origin */ 459f29dbc25Smrg 460f29dbc25Smrg temp = READ_REG32(DC3_VBI_HOR); 461f29dbc25Smrg hstart = (temp & DC3_VBI_HOR_START_MASK) + 1; 462f29dbc25Smrg hstop = ((temp & DC3_VBI_HOR_END_MASK) >> DC3_VBI_HOR_END_SHIFT) + 1; 463f29dbc25Smrg if (buffer->horz_from_hsync) { 464f29dbc25Smrg buffer->horz_start = hstart + htotal - hsyncstart; 46504007ebaSmrg if (buffer->horz_start >= (long) htotal) 466f29dbc25Smrg buffer->horz_start -= htotal; 46704007ebaSmrg } 46804007ebaSmrg else { 469f29dbc25Smrg if (hstart > hsyncstart) 47004007ebaSmrg buffer->horz_start = (long) hstart - (long) htotal; 471f29dbc25Smrg else 472f29dbc25Smrg buffer->horz_start = hstart; 473f29dbc25Smrg } 474f29dbc25Smrg 475f29dbc25Smrg if (hstop > hstart) 476f29dbc25Smrg buffer->vbi_width = hstop - hstart; 477f29dbc25Smrg else 478f29dbc25Smrg buffer->vbi_width = (htotal - hstart) + hstop; 479f29dbc25Smrg 480f29dbc25Smrg /* READ LINE MASKS */ 481f29dbc25Smrg 482f29dbc25Smrg temp = READ_REG32(DC3_VBI_LN_ODD); 483f29dbc25Smrg buffer->odd_line_offset = (temp & DC3_VBI_ODD_LINE_MASK) >> 484f29dbc25Smrg DC3_VBI_ODD_LINE_SHIFT; 485f29dbc25Smrg buffer->odd_line_capture_mask = (temp & DC3_VBI_ODD_ENABLE_MASK); 486f29dbc25Smrg 487f29dbc25Smrg temp = READ_REG32(DC3_VBI_LN_EVEN); 488f29dbc25Smrg buffer->even_line_offset = (temp & DC3_VBI_EVEN_LINE_MASK) >> 489f29dbc25Smrg DC3_VBI_EVEN_LINE_SHIFT; 490f29dbc25Smrg buffer->even_line_capture_mask = (temp & DC3_VBI_EVEN_ENABLE_MASK); 491f29dbc25Smrg 492f29dbc25Smrg /* READ VBI UPSCALE SETTINGS */ 493f29dbc25Smrg 494f29dbc25Smrg buffer->enable_upscale = 0; 495f29dbc25Smrg temp = READ_REG32(DC3_VBI_EVEN_CTL); 496f29dbc25Smrg if (temp & DC3_VBI_EVEN_CTL_UPSCALE) 497f29dbc25Smrg buffer->enable_upscale = 1; 498f29dbc25Smrg 499f29dbc25Smrg /* READ SOURCE OFFSETS */ 500f29dbc25Smrg 501f29dbc25Smrg buffer->even_address_offset = temp & DC3_VBI_EVEN_CTL_OFFSET_MASK; 502f29dbc25Smrg buffer->odd_address_offset = 503f29dbc25Smrg READ_REG32(DC3_VBI_ODD_CTL) & DC3_VBI_ODD_CTL_OFFSET_MASK; 504f29dbc25Smrg 505f29dbc25Smrg /* PITCH AND SIZE */ 506f29dbc25Smrg 507f29dbc25Smrg temp = READ_REG32(DC3_VBI_PITCH); 508f29dbc25Smrg buffer->data_size = (temp >> 16) << 3; 509f29dbc25Smrg buffer->data_pitch = (temp & 0xFFFF); 510f29dbc25Smrg 511f29dbc25Smrg return CIM_STATUS_OK; 512f29dbc25Smrg} 513f29dbc25Smrg 514f29dbc25Smrg/*--------------------------------------------------------------------------- 515f29dbc25Smrg * vop_get_vbi_enable 516f29dbc25Smrg * 517f29dbc25Smrg * This routine reads the current enable status of VBI output. 518f29dbc25Smrg *--------------------------------------------------------------------------*/ 519f29dbc25Smrg 520f29dbc25Smrgint 521f29dbc25Smrgvop_get_vbi_enable(void) 522f29dbc25Smrg{ 523f29dbc25Smrg if (READ_REG32(DC3_VBI_EVEN_CTL) & DC3_VBI_ENABLE) 524f29dbc25Smrg return 1; 525f29dbc25Smrg 526f29dbc25Smrg return 0; 527f29dbc25Smrg} 528f29dbc25Smrg 529f29dbc25Smrg/*--------------------------------------------------------------------------- 530f29dbc25Smrg * vop_get_crc 531f29dbc25Smrg * 532f29dbc25Smrg * This routine returns a CRC of the current VOP data 533f29dbc25Smrg --------------------------------------------------------------------------*/ 534f29dbc25Smrg 535f29dbc25Smrgunsigned long 536f29dbc25Smrgvop_get_crc(void) 537f29dbc25Smrg{ 538f29dbc25Smrg unsigned long crc; 539f29dbc25Smrg unsigned long config = READ_VOP32(VOP_CONFIGURATION); 540f29dbc25Smrg unsigned long timeout = 1000; 541f29dbc25Smrg 542f29dbc25Smrg if (!(READ_REG32(DC3_DISPLAY_CFG) & DC3_DCFG_TGEN)) 543f29dbc25Smrg return 0xFFFFFFFF; 544f29dbc25Smrg 545f29dbc25Smrg /* RESET CRC */ 546f29dbc25Smrg 547f29dbc25Smrg WRITE_VOP32(VOP_CONFIGURATION, config & ~VOP_CONFIG_ENABLE_SIGNATURE); 548f29dbc25Smrg 549f29dbc25Smrg /* WAIT FOR THE RESET TO BE LATCHED */ 550f29dbc25Smrg 551f29dbc25Smrg while ((READ_VOP32(VOP_SIGNATURE) != 0x00000001) && timeout) 552f29dbc25Smrg timeout--; 553f29dbc25Smrg 554f29dbc25Smrg WRITE_VOP32(VOP_CONFIGURATION, config | VOP_CONFIG_ENABLE_SIGNATURE); 555f29dbc25Smrg 556f29dbc25Smrg /* WAIT UNTIL NOT ACTIVE, THEN ACTIVE, NOT ACTIVE, THEN ACTIVE */ 557f29dbc25Smrg 55804007ebaSmrg while (!(READ_VOP32(VOP_CONFIGURATION) & VOP_CONFIG_SIGVAL)); 559f29dbc25Smrg 560f29dbc25Smrg crc = READ_VOP32(VOP_SIGNATURE); 561f29dbc25Smrg 562f29dbc25Smrg return crc; 563f29dbc25Smrg} 564f29dbc25Smrg 565f29dbc25Smrg/*--------------------------------------------------------------------------- 566f29dbc25Smrg * vop_read_vbi_crc 567f29dbc25Smrg * 568f29dbc25Smrg * This routine returns a CRC of the current VBI data 569f29dbc25Smrg ---------------------------------------------------------------------------*/ 570f29dbc25Smrg 571f29dbc25Smrgunsigned long 572f29dbc25Smrgvop_read_vbi_crc(void) 573f29dbc25Smrg{ 574f29dbc25Smrg unsigned long gcfg, unlock, vbi_even; 575f29dbc25Smrg unsigned long crc; 576f29dbc25Smrg 577f29dbc25Smrg if (!(READ_REG32(DC3_DISPLAY_CFG) & DC3_DCFG_TGEN) || 578f29dbc25Smrg !(READ_REG32(DC3_VBI_EVEN_CTL) & DC3_VBI_ENABLE)) { 579f29dbc25Smrg return 0xFFFFFFFF; 580f29dbc25Smrg } 581f29dbc25Smrg 582f29dbc25Smrg unlock = READ_REG32(DC3_UNLOCK); 583f29dbc25Smrg gcfg = READ_REG32(DC3_GENERAL_CFG); 584f29dbc25Smrg vbi_even = READ_REG32(DC3_VBI_EVEN_CTL); 585f29dbc25Smrg 586f29dbc25Smrg gcfg |= DC3_GCFG_SGRE | DC3_GCFG_CRC_MODE; 587f29dbc25Smrg gcfg &= ~(DC3_GCFG_SGFR | DC3_GCFG_SIG_SEL); 588f29dbc25Smrg vbi_even |= DC3_VBI_EVEN_ENABLE_CRC; 589f29dbc25Smrg 590f29dbc25Smrg WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE); 591f29dbc25Smrg WRITE_REG32(DC3_VBI_EVEN_CTL, vbi_even); 592f29dbc25Smrg WRITE_REG32(DC3_GENERAL_CFG, gcfg & ~DC3_GCFG_SIGE); 593f29dbc25Smrg WRITE_REG32(DC3_GENERAL_CFG, gcfg | DC3_GCFG_SIGE); 594f29dbc25Smrg 595f29dbc25Smrg /* WAIT FOR THE CRC TO BE COMPLETED */ 596f29dbc25Smrg 59704007ebaSmrg while (!(READ_REG32(DC3_LINE_CNT_STATUS) & DC3_LNCNT_SIGC)); 598f29dbc25Smrg 599f29dbc25Smrg /* READ THE COMPLETED CRC */ 600f29dbc25Smrg 601f29dbc25Smrg crc = READ_REG32(DC3_PAL_DATA); 602f29dbc25Smrg 603f29dbc25Smrg /* RESTORE THE PALETTE SETTINGS */ 604f29dbc25Smrg 605f29dbc25Smrg gcfg &= ~DC3_GCFG_SGRE; 606f29dbc25Smrg WRITE_REG32(DC3_GENERAL_CFG, gcfg); 607f29dbc25Smrg WRITE_REG32(DC3_UNLOCK, unlock); 608f29dbc25Smrg 609f29dbc25Smrg return crc; 610f29dbc25Smrg} 611f29dbc25Smrg 612f29dbc25Smrg#endif 613