cim_vip.c revision f29dbc25
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 VIP configuration routines. 29f29dbc25Smrg */ 30f29dbc25Smrg 31f29dbc25Smrg/*--------------------------------------------------------------------------- 32f29dbc25Smrg * vip_initialize 33f29dbc25Smrg * 34f29dbc25Smrg * This routine initializes the internal module state and prepares the 35f29dbc25Smrg * module for subsequent VIP orientated activities. 36f29dbc25Smrg *--------------------------------------------------------------------------*/ 37f29dbc25Smrg 38f29dbc25Smrgint 39f29dbc25Smrgvip_initialize(VIPSETMODEBUFFER * buffer) 40f29dbc25Smrg{ 41f29dbc25Smrg unsigned long vip_control1, vip_control2, vip_control3; 42f29dbc25Smrg 43f29dbc25Smrg if (!buffer) 44f29dbc25Smrg return CIM_STATUS_INVALIDPARAMS; 45f29dbc25Smrg 46f29dbc25Smrg vip_control1 = 0; 47f29dbc25Smrg vip_control2 = 0; 48f29dbc25Smrg vip_control3 = 0; 49f29dbc25Smrg 50f29dbc25Smrg /* CONFIGURE CONTROL WORDS BASED ON MODE STRUCTURE */ 51f29dbc25Smrg /* Note that some of the input parameters match the register fields */ 52f29dbc25Smrg /* they represent. */ 53f29dbc25Smrg 54f29dbc25Smrg /* STREAM ENABLES */ 55f29dbc25Smrg 56f29dbc25Smrg vip_control1 |= buffer->stream_enables; 57f29dbc25Smrg 58f29dbc25Smrg /* VIP CAPTURE MODE */ 59f29dbc25Smrg 60f29dbc25Smrg vip_control1 |= buffer->operating_mode; 61f29dbc25Smrg 62f29dbc25Smrg /* HANDLE PLANAR CAPTURE */ 63f29dbc25Smrg 64f29dbc25Smrg if (buffer->flags & VIP_MODEFLAG_PLANARCAPTURE) { 65f29dbc25Smrg vip_control1 |= VIP_CONTROL1_PLANAR; 66f29dbc25Smrg 67f29dbc25Smrg if (buffer->planar_capture == VIP_420CAPTURE_EVERYLINE) { 68f29dbc25Smrg vip_control1 |= VIP_CONTROL1_DISABLE_DECIMATION; 69f29dbc25Smrg } else if (buffer->planar_capture == VIP_420CAPTURE_ALTERNATINGFIELDS) { 70f29dbc25Smrg if (buffer->flags & VIP_MODEFLAG_PROGRESSIVE) 71f29dbc25Smrg return CIM_STATUS_INVALIDPARAMS; 72f29dbc25Smrg 73f29dbc25Smrg vip_control1 |= VIP_CONTROL1_DISABLE_DECIMATION; 74f29dbc25Smrg vip_control3 |= VIP_CONTROL3_DECIMATE_EVEN; 75f29dbc25Smrg } else if (buffer->planar_capture != VIP_420CAPTURE_ALTERNATINGLINES) 76f29dbc25Smrg return CIM_STATUS_INVALIDPARAMS; 77f29dbc25Smrg 78f29dbc25Smrg /* CONFIGURE THE VIDEO FIFO THRESHOLD BASED ON THE FIFO DEPTH */ 79f29dbc25Smrg 80f29dbc25Smrg vip_control2 |= VIP_CONTROL2_DEFAULT_VIDTH_420 << 81f29dbc25Smrg VIP_CONTROL2_VIDTH_SHIFT; 82f29dbc25Smrg 83f29dbc25Smrg } else { 84f29dbc25Smrg vip_control2 |= VIP_CONTROL2_DEFAULT_VIDTH_422 << 85f29dbc25Smrg VIP_CONTROL2_VIDTH_SHIFT; 86f29dbc25Smrg } 87f29dbc25Smrg 88f29dbc25Smrg /* CONFIGURE DEFAULT ANCILARRY THRESHOLD AND VIDEO FLUSH VALUES */ 89f29dbc25Smrg 90f29dbc25Smrg vip_control2 |= VIP_CONTROL2_DEFAULT_ANCTH << VIP_CONTROL2_ANCTH_SHIFT; 91f29dbc25Smrg vip_control1 |= VIP_CONTROL1_DEFAULT_ANC_FF << VIP_CONTROL1_ANC_FF_SHIFT; 92f29dbc25Smrg vip_control1 |= VIP_CONTROL1_DEFAULT_VID_FF << VIP_CONTROL1_VID_FF_SHIFT; 93f29dbc25Smrg 94f29dbc25Smrg /* PROGRAM VIP OPTIONS */ 95f29dbc25Smrg /* The options are sanitized based on the current configuration. */ 96f29dbc25Smrg 97f29dbc25Smrg if (buffer->flags & VIP_MODEFLAG_PROGRESSIVE) 98f29dbc25Smrg vip_control1 |= VIP_CONTROL1_NON_INTERLACED; 99f29dbc25Smrg else { 100f29dbc25Smrg if (buffer->flags & VIP_MODEFLAG_TOGGLEEACHFIELD) 101f29dbc25Smrg vip_control3 |= VIP_CONTROL3_BASE_UPDATE; 102f29dbc25Smrg if (buffer->flags & VIP_MODEFLAG_INVERTPOLARITY) 103f29dbc25Smrg vip_control2 |= VIP_CONTROL2_INVERT_POLARITY; 104f29dbc25Smrg } 105f29dbc25Smrg 106f29dbc25Smrg if ((buffer->operating_mode == VIP_MODE_MSG || 107f29dbc25Smrg buffer->operating_mode == VIP_MODE_DATA) && 108f29dbc25Smrg (buffer->flags & VIP_MODEFLAG_FLIPMESSAGEWHENFULL)) { 109f29dbc25Smrg vip_control1 |= VIP_CONTROL1_MSG_STRM_CTRL; 110f29dbc25Smrg } 111f29dbc25Smrg 112f29dbc25Smrg else if (buffer->operating_mode == VIP_MODE_VIP2_8BIT || 113f29dbc25Smrg buffer->operating_mode == VIP_MODE_VIP2_16BIT) { 114f29dbc25Smrg if (buffer->flags & VIP_MODEFLAG_ENABLEREPEATFLAG) 115f29dbc25Smrg vip_control2 |= VIP_CONTROL2_REPEAT_ENABLE; 116f29dbc25Smrg if (buffer->flags & VIP_MODEFLAG_INVERTTASKPOLARITY) 117f29dbc25Smrg vip_control3 |= VIP_CONTROL3_TASK_POLARITY; 118f29dbc25Smrg } 119f29dbc25Smrg 120f29dbc25Smrg if (buffer->flags & VIP_MODEFLAG_DISABLEZERODETECT) 121f29dbc25Smrg vip_control1 |= VIP_CONTROL1_DISABLE_ZERO_DETECT; 122f29dbc25Smrg if (buffer->flags & VIP_MODEFLAG_10BITANCILLARY) 123f29dbc25Smrg vip_control2 |= VIP_CONTROL2_ANC10; 124f29dbc25Smrg 125f29dbc25Smrg /* WRITE THE CONTROL REGISTERS */ 126f29dbc25Smrg /* The control registers are kept 'live' to allow separate instances of */ 127f29dbc25Smrg /* Cimarron to control the VIP hardware. */ 128f29dbc25Smrg 129f29dbc25Smrg WRITE_VIP32(VIP_CONTROL1, vip_control1); 130f29dbc25Smrg WRITE_VIP32(VIP_CONTROL2, vip_control2); 131f29dbc25Smrg WRITE_VIP32(VIP_CONTROL3, vip_control3); 132f29dbc25Smrg 133f29dbc25Smrg /* CONFIGURE 601 PARAMETERS */ 134f29dbc25Smrg 135f29dbc25Smrg if (buffer->operating_mode == VIP_MODE_8BIT601 || 136f29dbc25Smrg buffer->operating_mode == VIP_MODE_16BIT601) { 137f29dbc25Smrg vip_update_601_params(&buffer->vip601_settings); 138f29dbc25Smrg } 139f29dbc25Smrg 140f29dbc25Smrg return CIM_STATUS_OK; 141f29dbc25Smrg} 142f29dbc25Smrg 143f29dbc25Smrg/*--------------------------------------------------------------------------- 144f29dbc25Smrg * vip_update_601_params 145f29dbc25Smrg * 146f29dbc25Smrg * This routine configures all aspects of 601 VIP data capture, including 147f29dbc25Smrg * start and stop timings and input polarities. 148f29dbc25Smrg *--------------------------------------------------------------------------*/ 149f29dbc25Smrg 150f29dbc25Smrgint 151f29dbc25Smrgvip_update_601_params(VIP_601PARAMS * buffer) 152f29dbc25Smrg{ 153f29dbc25Smrg unsigned long vip_control3, vip_control1; 154f29dbc25Smrg 155f29dbc25Smrg if (!buffer) 156f29dbc25Smrg return CIM_STATUS_INVALIDPARAMS; 157f29dbc25Smrg 158f29dbc25Smrg vip_control1 = READ_VIP32(VIP_CONTROL3); 159f29dbc25Smrg vip_control3 = READ_VIP32(VIP_CONTROL3); 160f29dbc25Smrg 161f29dbc25Smrg if (buffer->flags & VIP_MODEFLAG_VSYNCACTIVEHIGH) 162f29dbc25Smrg vip_control3 |= VIP_CONTROL3_VSYNC_POLARITY; 163f29dbc25Smrg else 164f29dbc25Smrg vip_control3 &= ~VIP_CONTROL3_VSYNC_POLARITY; 165f29dbc25Smrg if (buffer->flags & VIP_MODEFLAG_HSYNCACTIVEHIGH) 166f29dbc25Smrg vip_control3 |= VIP_CONTROL3_HSYNC_POLARITY; 167f29dbc25Smrg else 168f29dbc25Smrg vip_control3 &= ~VIP_CONTROL3_HSYNC_POLARITY; 169f29dbc25Smrg 170f29dbc25Smrg WRITE_VIP32(VIP_CONTROL3, vip_control3); 171f29dbc25Smrg WRITE_VIP32(VIP_601_HORZ_START, buffer->horz_start); 172f29dbc25Smrg WRITE_VIP32(VIP_601_VBI_START, buffer->vbi_start); 173f29dbc25Smrg WRITE_VIP32(VIP_601_VBI_END, buffer->vbi_start + buffer->vbi_height - 1); 174f29dbc25Smrg WRITE_VIP32(VIP_601_EVEN_START_STOP, 175f29dbc25Smrg buffer->vert_start_even | ((buffer->vert_start_even + 176f29dbc25Smrg buffer->even_height - 1) << 16)); 177f29dbc25Smrg WRITE_VIP32(VIP_601_ODD_START_STOP, 178f29dbc25Smrg buffer->vert_start_odd | ((buffer->vert_start_odd + 179f29dbc25Smrg buffer->odd_height - 1) << 16)); 180f29dbc25Smrg WRITE_VIP32(VIP_ODD_FIELD_DETECT, 181f29dbc25Smrg buffer->odd_detect_start | (buffer->odd_detect_end << 16)); 182f29dbc25Smrg 183f29dbc25Smrg /* SPECIAL CASE FOR HORIZONTAL DATA 184f29dbc25Smrg * 601 horizontal parameters are based on the number of clocks and not 185f29dbc25Smrg * the number of pixels. 186f29dbc25Smrg */ 187f29dbc25Smrg 188f29dbc25Smrg if ((vip_control1 & VIP_CONTROL1_MODE_MASK) == VIP_MODE_16BIT601) 189f29dbc25Smrg WRITE_VIP32(VIP_601_HORZ_END, 190f29dbc25Smrg buffer->horz_start + (buffer->width << 1) + 3); 191f29dbc25Smrg else 192f29dbc25Smrg WRITE_VIP32(VIP_601_HORZ_END, buffer->horz_start + buffer->width + 3); 193f29dbc25Smrg 194f29dbc25Smrg return CIM_STATUS_OK; 195f29dbc25Smrg} 196f29dbc25Smrg 197f29dbc25Smrg/*--------------------------------------------------------------------------- 198f29dbc25Smrg * vip_configure_capture_buffers 199f29dbc25Smrg * 200f29dbc25Smrg * This routine configures the base offsets for video, ancillary or message 201f29dbc25Smrg * mode capture. The input structure can also contain multiple offsets, such 202f29dbc25Smrg * that the calling application can avoid updating the structure for each 203f29dbc25Smrg * flip. 204f29dbc25Smrg * 205f29dbc25Smrg * The new buffer addresses are written to the hardware registers although 206f29dbc25Smrg * they may not be latched immediately. Calling vip_is_buffer_update_latched 207f29dbc25Smrg * allows the determination of whether the update has occured. 208f29dbc25Smrg * 209f29dbc25Smrg * Review the Cimarron VIP API documentation to determine which buffer 210f29dbc25Smrg * addresses are latched immediately. 211f29dbc25Smrg *--------------------------------------------------------------------------*/ 212f29dbc25Smrg 213f29dbc25Smrgint 214f29dbc25Smrgvip_configure_capture_buffers(int buffer_type, VIPINPUTBUFFER * buffer) 215f29dbc25Smrg{ 216f29dbc25Smrg VIPINPUTBUFFER_ADDR *offsets; 217f29dbc25Smrg unsigned long cur_buffer = buffer->current_buffer; 218f29dbc25Smrg 219f29dbc25Smrg if (!buffer) 220f29dbc25Smrg return CIM_STATUS_INVALIDPARAMS; 221f29dbc25Smrg 222f29dbc25Smrg if (buffer_type == VIP_BUFFER_A || buffer_type == VIP_BUFFER_601) { 223f29dbc25Smrg offsets = &buffer->offsets[VIP_BUFFER_TASK_A]; 224f29dbc25Smrg 225f29dbc25Smrg /* SET VIDEO PITCH */ 226f29dbc25Smrg 227f29dbc25Smrg WRITE_VIP32(VIP_TASKA_VID_PITCH, 228f29dbc25Smrg offsets->y_pitch | (offsets->uv_pitch << 16)); 229f29dbc25Smrg 230f29dbc25Smrg /* SET BASE OFFSETS */ 231f29dbc25Smrg 232f29dbc25Smrg if (buffer->flags & VIP_INPUTFLAG_INVERTPOLARITY) { 233f29dbc25Smrg WRITE_VIP32(VIP_TASKA_VID_ODD_BASE, 234f29dbc25Smrg offsets->even_base[cur_buffer]); 235f29dbc25Smrg WRITE_VIP32(VIP_TASKA_VID_EVEN_BASE, 236f29dbc25Smrg offsets->odd_base[cur_buffer]); 237f29dbc25Smrg if (buffer->flags & VIP_INPUTFLAG_VBI) { 238f29dbc25Smrg WRITE_VIP32(VIP_TASKA_VBI_ODD_BASE, offsets->vbi_even_base); 239f29dbc25Smrg WRITE_VIP32(VIP_TASKA_VBI_EVEN_BASE, offsets->vbi_odd_base); 240f29dbc25Smrg } 241f29dbc25Smrg } else { 242f29dbc25Smrg WRITE_VIP32(VIP_TASKA_VID_ODD_BASE, 243f29dbc25Smrg offsets->odd_base[cur_buffer]); 244f29dbc25Smrg WRITE_VIP32(VIP_TASKA_VID_EVEN_BASE, 245f29dbc25Smrg offsets->even_base[cur_buffer]); 246f29dbc25Smrg if (buffer->flags & VIP_INPUTFLAG_VBI) { 247f29dbc25Smrg WRITE_VIP32(VIP_TASKA_VBI_ODD_BASE, offsets->vbi_odd_base); 248f29dbc25Smrg WRITE_VIP32(VIP_TASKA_VBI_EVEN_BASE, offsets->vbi_even_base); 249f29dbc25Smrg } 250f29dbc25Smrg } 251f29dbc25Smrg 252f29dbc25Smrg /* SET 4:2:0 OFFSETS */ 253f29dbc25Smrg 254f29dbc25Smrg if (buffer->flags & VIP_INPUTFLAG_PLANAR) { 255f29dbc25Smrg WRITE_VIP32(VIP_TASKA_U_OFFSET, offsets->odd_uoffset); 256f29dbc25Smrg WRITE_VIP32(VIP_TASKA_V_OFFSET, offsets->odd_voffset); 257f29dbc25Smrg WRITE_VIP32(VIP_TASKA_U_EVEN_OFFSET, offsets->even_uoffset); 258f29dbc25Smrg WRITE_VIP32(VIP_TASKA_V_EVEN_OFFSET, offsets->even_voffset); 259f29dbc25Smrg } 260f29dbc25Smrg } else if (buffer_type == VIP_BUFFER_B) { 261f29dbc25Smrg offsets = &buffer->offsets[VIP_BUFFER_TASK_B]; 262f29dbc25Smrg 263f29dbc25Smrg /* SET VIDEO PITCH */ 264f29dbc25Smrg 265f29dbc25Smrg WRITE_VIP32(VIP_TASKB_VID_PITCH, 266f29dbc25Smrg offsets->y_pitch | (offsets->uv_pitch << 16)); 267f29dbc25Smrg 268f29dbc25Smrg /* SET BASE OFFSETS */ 269f29dbc25Smrg 270f29dbc25Smrg if (buffer->flags & VIP_INPUTFLAG_INVERTPOLARITY) { 271f29dbc25Smrg WRITE_VIP32(VIP_TASKB_VID_ODD_BASE, 272f29dbc25Smrg offsets->even_base[cur_buffer]); 273f29dbc25Smrg WRITE_VIP32(VIP_TASKB_VID_EVEN_BASE, 274f29dbc25Smrg offsets->odd_base[cur_buffer]); 275f29dbc25Smrg if (buffer->flags & VIP_INPUTFLAG_VBI) { 276f29dbc25Smrg WRITE_VIP32(VIP_TASKB_VBI_ODD_BASE, offsets->vbi_even_base); 277f29dbc25Smrg WRITE_VIP32(VIP_TASKB_VBI_EVEN_BASE, offsets->vbi_odd_base); 278f29dbc25Smrg } 279f29dbc25Smrg } else { 280f29dbc25Smrg WRITE_VIP32(VIP_TASKB_VID_ODD_BASE, 281f29dbc25Smrg offsets->odd_base[cur_buffer]); 282f29dbc25Smrg WRITE_VIP32(VIP_TASKB_VID_EVEN_BASE, 283f29dbc25Smrg offsets->even_base[cur_buffer]); 284f29dbc25Smrg if (buffer->flags & VIP_INPUTFLAG_VBI) { 285f29dbc25Smrg WRITE_VIP32(VIP_TASKB_VBI_ODD_BASE, offsets->vbi_odd_base); 286f29dbc25Smrg WRITE_VIP32(VIP_TASKB_VBI_EVEN_BASE, offsets->vbi_even_base); 287f29dbc25Smrg } 288f29dbc25Smrg } 289f29dbc25Smrg 290f29dbc25Smrg /* SET 4:2:0 OFFSETS */ 291f29dbc25Smrg 292f29dbc25Smrg if (buffer->flags & VIP_INPUTFLAG_PLANAR) { 293f29dbc25Smrg WRITE_VIP32(VIP_TASKB_U_OFFSET, offsets->odd_uoffset); 294f29dbc25Smrg WRITE_VIP32(VIP_TASKB_V_OFFSET, offsets->odd_voffset); 295f29dbc25Smrg } 296f29dbc25Smrg } else if (buffer_type == VIP_BUFFER_ANC || buffer_type == VIP_BUFFER_MSG) { 297f29dbc25Smrg WRITE_VIP32(VIP_ANC_MSG1_BASE, buffer->ancillaryData.msg1_base); 298f29dbc25Smrg WRITE_VIP32(VIP_ANC_MSG2_BASE, buffer->ancillaryData.msg2_base); 299f29dbc25Smrg WRITE_VIP32(VIP_ANC_MSG_SIZE, buffer->ancillaryData.msg_size); 300f29dbc25Smrg } else { 301f29dbc25Smrg return CIM_STATUS_INVALIDPARAMS; 302f29dbc25Smrg } 303f29dbc25Smrg 304f29dbc25Smrg return CIM_STATUS_OK; 305f29dbc25Smrg} 306f29dbc25Smrg 307f29dbc25Smrg/*--------------------------------------------------------------------------- 308f29dbc25Smrg * vip_toggle_vip_video_offsets 309f29dbc25Smrg * 310f29dbc25Smrg * This routine updates the offsets for video capture. It is a simplified 311f29dbc25Smrg * version of vip_configure_capture_buffers that is designed to be called from 312f29dbc25Smrg * interrupt service routines or other buffer flipping applications that 313f29dbc25Smrg * require low latency. 314f29dbc25Smrg *--------------------------------------------------------------------------*/ 315f29dbc25Smrg 316f29dbc25Smrgint 317f29dbc25Smrgvip_toggle_video_offsets(int buffer_type, VIPINPUTBUFFER * buffer) 318f29dbc25Smrg{ 319f29dbc25Smrg unsigned long cur_buffer = buffer->current_buffer; 320f29dbc25Smrg VIPINPUTBUFFER_ADDR *offsets; 321f29dbc25Smrg 322f29dbc25Smrg if (buffer_type == VIP_BUFFER_A) { 323f29dbc25Smrg offsets = &buffer->offsets[VIP_BUFFER_TASK_A]; 324f29dbc25Smrg 325f29dbc25Smrg /* SET BASE OFFSETS */ 326f29dbc25Smrg 327f29dbc25Smrg if (buffer->flags & VIP_INPUTFLAG_INVERTPOLARITY) { 328f29dbc25Smrg WRITE_VIP32(VIP_TASKA_VID_ODD_BASE, 329f29dbc25Smrg offsets->even_base[cur_buffer]); 330f29dbc25Smrg WRITE_VIP32(VIP_TASKA_VID_EVEN_BASE, 331f29dbc25Smrg offsets->odd_base[cur_buffer]); 332f29dbc25Smrg } else { 333f29dbc25Smrg WRITE_VIP32(VIP_TASKA_VID_ODD_BASE, 334f29dbc25Smrg offsets->odd_base[cur_buffer]); 335f29dbc25Smrg WRITE_VIP32(VIP_TASKA_VID_EVEN_BASE, 336f29dbc25Smrg offsets->even_base[cur_buffer]); 337f29dbc25Smrg } 338f29dbc25Smrg } else if (buffer_type == VIP_BUFFER_B) { 339f29dbc25Smrg offsets = &buffer->offsets[VIP_BUFFER_TASK_B]; 340f29dbc25Smrg 341f29dbc25Smrg /* SET BASE OFFSETS */ 342f29dbc25Smrg 343f29dbc25Smrg if (buffer->flags & VIP_INPUTFLAG_INVERTPOLARITY) { 344f29dbc25Smrg WRITE_VIP32(VIP_TASKB_VID_ODD_BASE, 345f29dbc25Smrg offsets->even_base[cur_buffer]); 346f29dbc25Smrg WRITE_VIP32(VIP_TASKB_VID_EVEN_BASE, 347f29dbc25Smrg offsets->odd_base[cur_buffer]); 348f29dbc25Smrg } else { 349f29dbc25Smrg WRITE_VIP32(VIP_TASKB_VID_ODD_BASE, 350f29dbc25Smrg offsets->odd_base[cur_buffer]); 351f29dbc25Smrg WRITE_VIP32(VIP_TASKB_VID_EVEN_BASE, 352f29dbc25Smrg offsets->even_base[cur_buffer]); 353f29dbc25Smrg } 354f29dbc25Smrg } else if (buffer_type == VIP_BUFFER_A_ODD) { 355f29dbc25Smrg offsets = &buffer->offsets[VIP_BUFFER_TASK_A]; 356f29dbc25Smrg 357f29dbc25Smrg /* SET BASE OFFSETS */ 358f29dbc25Smrg 359f29dbc25Smrg if (buffer->flags & VIP_INPUTFLAG_INVERTPOLARITY) 360f29dbc25Smrg WRITE_VIP32(VIP_TASKA_VID_ODD_BASE, 361f29dbc25Smrg offsets->even_base[cur_buffer]); 362f29dbc25Smrg else 363f29dbc25Smrg WRITE_VIP32(VIP_TASKA_VID_ODD_BASE, 364f29dbc25Smrg offsets->odd_base[cur_buffer]); 365f29dbc25Smrg } else if (buffer_type == VIP_BUFFER_A_EVEN) { 366f29dbc25Smrg offsets = &buffer->offsets[VIP_BUFFER_TASK_A]; 367f29dbc25Smrg 368f29dbc25Smrg /* SET BASE OFFSETS */ 369f29dbc25Smrg 370f29dbc25Smrg if (buffer->flags & VIP_INPUTFLAG_INVERTPOLARITY) 371f29dbc25Smrg WRITE_VIP32(VIP_TASKA_VID_EVEN_BASE, 372f29dbc25Smrg offsets->odd_base[cur_buffer]); 373f29dbc25Smrg else 374f29dbc25Smrg WRITE_VIP32(VIP_TASKA_VID_EVEN_BASE, 375f29dbc25Smrg offsets->even_base[cur_buffer]); 376f29dbc25Smrg } else if (buffer_type == VIP_BUFFER_B_ODD) { 377f29dbc25Smrg offsets = &buffer->offsets[VIP_BUFFER_TASK_B]; 378f29dbc25Smrg 379f29dbc25Smrg /* SET BASE OFFSETS */ 380f29dbc25Smrg 381f29dbc25Smrg if (buffer->flags & VIP_INPUTFLAG_INVERTPOLARITY) 382f29dbc25Smrg WRITE_VIP32(VIP_TASKB_VID_ODD_BASE, 383f29dbc25Smrg offsets->even_base[cur_buffer]); 384f29dbc25Smrg else 385f29dbc25Smrg WRITE_VIP32(VIP_TASKB_VID_ODD_BASE, 386f29dbc25Smrg offsets->odd_base[cur_buffer]); 387f29dbc25Smrg } else if (buffer_type == VIP_BUFFER_B_EVEN) { 388f29dbc25Smrg offsets = &buffer->offsets[VIP_BUFFER_TASK_B]; 389f29dbc25Smrg 390f29dbc25Smrg /* SET BASE OFFSETS */ 391f29dbc25Smrg 392f29dbc25Smrg if (buffer->flags & VIP_INPUTFLAG_INVERTPOLARITY) 393f29dbc25Smrg WRITE_VIP32(VIP_TASKB_VID_EVEN_BASE, 394f29dbc25Smrg offsets->odd_base[cur_buffer]); 395f29dbc25Smrg else 396f29dbc25Smrg WRITE_VIP32(VIP_TASKB_VID_EVEN_BASE, 397f29dbc25Smrg offsets->even_base[cur_buffer]); 398f29dbc25Smrg } else 399f29dbc25Smrg return CIM_STATUS_INVALIDPARAMS; 400f29dbc25Smrg 401f29dbc25Smrg return CIM_STATUS_OK; 402f29dbc25Smrg} 403f29dbc25Smrg 404f29dbc25Smrg/*--------------------------------------------------------------------------- 405f29dbc25Smrg * vip_set_capture_state 406f29dbc25Smrg * 407f29dbc25Smrg * This routine takes the current control word definition ( stored in locals ) 408f29dbc25Smrg * adds in the specified state, and writes the control word. 409f29dbc25Smrg *--------------------------------------------------------------------------*/ 410f29dbc25Smrg 411f29dbc25Smrgint 412f29dbc25Smrgvip_set_capture_state(unsigned long state) 413f29dbc25Smrg{ 414f29dbc25Smrg unsigned long vip_control1, vip_control3; 415f29dbc25Smrg 416f29dbc25Smrg /* UPDATE THE CURRENT CAPTURE MODE */ 417f29dbc25Smrg 418f29dbc25Smrg vip_control1 = READ_VIP32(VIP_CONTROL1); 419f29dbc25Smrg vip_control3 = READ_VIP32(VIP_CONTROL3); 420f29dbc25Smrg vip_control1 &= ~VIP_CONTROL1_RUNMODE_MASK; 421f29dbc25Smrg vip_control1 |= (state << VIP_CONTROL1_RUNMODE_SHIFT); 422f29dbc25Smrg 423f29dbc25Smrg WRITE_VIP32(VIP_CONTROL1, vip_control1); 424f29dbc25Smrg 425f29dbc25Smrg if (state >= VIP_STARTCAPTUREATNEXTLINE) { 426f29dbc25Smrg /* WHACK VIP RESET 427f29dbc25Smrg * The VIP can get confused when switching between capture settings, 428f29dbc25Smrg * such as between linear and planar. We will thus whack VIP reset 429f29dbc25Smrg * when enabling capture to ensure a pristine VIP state. 430f29dbc25Smrg */ 431f29dbc25Smrg 432f29dbc25Smrg WRITE_VIP32(VIP_CONTROL1, vip_control1 | VIP_CONTROL1_RESET); 433f29dbc25Smrg WRITE_VIP32(VIP_CONTROL1, vip_control1 & ~VIP_CONTROL1_RESET); 434f29dbc25Smrg WRITE_VIP32(VIP_CONTROL3, vip_control3 | VIP_CONTROL3_FIFO_RESET); 435f29dbc25Smrg } 436f29dbc25Smrg 437f29dbc25Smrg return CIM_STATUS_OK; 438f29dbc25Smrg} 439f29dbc25Smrg 440f29dbc25Smrg/*--------------------------------------------------------------------------- 441f29dbc25Smrg * vip_terminate 442f29dbc25Smrg * 443f29dbc25Smrg * This routine stops VIP capture and resets the VIP internal state. 444f29dbc25Smrg *--------------------------------------------------------------------------*/ 445f29dbc25Smrg 446f29dbc25Smrgint 447f29dbc25Smrgvip_terminate(void) 448f29dbc25Smrg{ 449f29dbc25Smrg unsigned long timeout = 50000; 450f29dbc25Smrg 451f29dbc25Smrg /* DISABLE AND CLEAR ALL VIP INTERRUPTS */ 452f29dbc25Smrg 453f29dbc25Smrg WRITE_VIP32(VIP_INTERRUPT, VIP_ALL_INTERRUPTS | 454f29dbc25Smrg (VIP_ALL_INTERRUPTS >> 16)); 455f29dbc25Smrg 456f29dbc25Smrg /* DISABLE VIP CAPTURE */ 457f29dbc25Smrg /* We will try to let the VIP FIFO flush before shutting it down. */ 458f29dbc25Smrg 459f29dbc25Smrg WRITE_VIP32(VIP_CONTROL1, 0); 460f29dbc25Smrg while (timeout) { 461f29dbc25Smrg timeout--; 462f29dbc25Smrg if (READ_VIP32(VIP_STATUS) & VIP_STATUS_WRITES_COMPLETE) 463f29dbc25Smrg break; 464f29dbc25Smrg } 465f29dbc25Smrg 466f29dbc25Smrg /* RESET THE HARDWARE REGISTERS */ 467f29dbc25Smrg /* Note that we enable VIP reset to allow clock gating to lower VIP */ 468f29dbc25Smrg /* power consumption. */ 469f29dbc25Smrg 470f29dbc25Smrg WRITE_VIP32(VIP_CONTROL1, VIP_CONTROL1_RESET); 471f29dbc25Smrg WRITE_VIP32(VIP_CONTROL3, VIP_CONTROL3_FIFO_RESET); 472f29dbc25Smrg WRITE_VIP32(VIP_CONTROL2, 0); 473f29dbc25Smrg 474f29dbc25Smrg return CIM_STATUS_OK; 475f29dbc25Smrg} 476f29dbc25Smrg 477f29dbc25Smrg/*--------------------------------------------------------------------------- 478f29dbc25Smrg * vip_configure_fifo 479f29dbc25Smrg * 480f29dbc25Smrg * This routine sets the desired threshold or flush for the specified fifo. 481f29dbc25Smrg *--------------------------------------------------------------------------*/ 482f29dbc25Smrg 483f29dbc25Smrgint 484f29dbc25Smrgvip_configure_fifo(unsigned long fifo_type, unsigned long fifo_size) 485f29dbc25Smrg{ 486f29dbc25Smrg unsigned long vip_control1, vip_control2; 487f29dbc25Smrg 488f29dbc25Smrg vip_control1 = READ_VIP32(VIP_CONTROL1); 489f29dbc25Smrg vip_control2 = READ_VIP32(VIP_CONTROL2); 490f29dbc25Smrg 491f29dbc25Smrg switch (fifo_type) { 492f29dbc25Smrg case VIP_VIDEOTHRESHOLD: 493f29dbc25Smrg vip_control2 &= ~VIP_CONTROL2_VIDTH_MASK; 494f29dbc25Smrg vip_control2 |= 495f29dbc25Smrg (fifo_size << VIP_CONTROL2_VIDTH_SHIFT) & VIP_CONTROL2_VIDTH_MASK; 496f29dbc25Smrg break; 497f29dbc25Smrg 498f29dbc25Smrg case VIP_ANCILLARYTHRESHOLD: 499f29dbc25Smrg vip_control2 &= ~VIP_CONTROL2_ANCTH_MASK; 500f29dbc25Smrg vip_control2 |= 501f29dbc25Smrg (fifo_size << VIP_CONTROL2_ANCTH_SHIFT) & VIP_CONTROL2_ANCTH_MASK; 502f29dbc25Smrg break; 503f29dbc25Smrg 504f29dbc25Smrg case VIP_VIDEOFLUSH: 505f29dbc25Smrg vip_control1 &= ~VIP_CONTROL1_VID_FF_MASK; 506f29dbc25Smrg vip_control1 |= 507f29dbc25Smrg ((fifo_size >> 2) << VIP_CONTROL1_VID_FF_SHIFT) & 508f29dbc25Smrg VIP_CONTROL1_VID_FF_MASK; 509f29dbc25Smrg break; 510f29dbc25Smrg 511f29dbc25Smrg case VIP_ANCILLARYFLUSH: 512f29dbc25Smrg vip_control1 &= ~VIP_CONTROL1_ANC_FF_MASK; 513f29dbc25Smrg vip_control1 |= 514f29dbc25Smrg ((fifo_size >> 2) << VIP_CONTROL1_ANC_FF_SHIFT) & 515f29dbc25Smrg VIP_CONTROL1_ANC_FF_MASK; 516f29dbc25Smrg break; 517f29dbc25Smrg 518f29dbc25Smrg default: 519f29dbc25Smrg return CIM_STATUS_INVALIDPARAMS; 520f29dbc25Smrg } 521f29dbc25Smrg 522f29dbc25Smrg WRITE_VIP32(VIP_CONTROL1, vip_control1); 523f29dbc25Smrg WRITE_VIP32(VIP_CONTROL2, vip_control2); 524f29dbc25Smrg 525f29dbc25Smrg return CIM_STATUS_OK; 526f29dbc25Smrg} 527f29dbc25Smrg 528f29dbc25Smrg/*--------------------------------------------------------------------------- 529f29dbc25Smrg * vip_set_interrupt_enable 530f29dbc25Smrg * 531f29dbc25Smrg * This routine accepts a mask of interrupts to be enabled/disabled and 532f29dbc25Smrg * an enable flag. 533f29dbc25Smrg * 534f29dbc25Smrg * For each mask match, the interrupt will be enabled or disabled based on 535f29dbc25Smrg * enable 536f29dbc25Smrg *--------------------------------------------------------------------------*/ 537f29dbc25Smrg 538f29dbc25Smrgint 539f29dbc25Smrgvip_set_interrupt_enable(unsigned long mask, int enable) 540f29dbc25Smrg{ 541f29dbc25Smrg /* CHECK IF ANY VALID INTERRUPTS ARE BEING CHANGED */ 542f29dbc25Smrg 543f29dbc25Smrg if (mask & VIP_ALL_INTERRUPTS) { 544f29dbc25Smrg unsigned long int_enable = READ_VIP32(VIP_INTERRUPT) & 0xFFFF; 545f29dbc25Smrg 546f29dbc25Smrg /* SET OR CLEAR THE MASK BITS */ 547f29dbc25Smrg /* Note that the upper 16-bits of the register are 0 after this */ 548f29dbc25Smrg /* operation. This prevents us from indadvertently clearing a */ 549f29dbc25Smrg /* pending interrupt by enabling/disabling another one. */ 550f29dbc25Smrg 551f29dbc25Smrg if (enable) 552f29dbc25Smrg int_enable &= ~(mask >> 16); 553f29dbc25Smrg else 554f29dbc25Smrg int_enable |= (mask >> 16); 555f29dbc25Smrg 556f29dbc25Smrg WRITE_VIP32(VIP_INTERRUPT, int_enable); 557f29dbc25Smrg } 558f29dbc25Smrg 559f29dbc25Smrg return CIM_STATUS_OK; 560f29dbc25Smrg} 561f29dbc25Smrg 562f29dbc25Smrg/*--------------------------------------------------------------------------- 563f29dbc25Smrg * vip_set_vsync_error 564f29dbc25Smrg * 565f29dbc25Smrg * This routine defines a region that is used to determine if the vsync is 566f29dbc25Smrg * within an acceptable range. This definition is accomplished using 567f29dbc25Smrg * a count and a vertical window. The count specifies the exact number 568f29dbc25Smrg * of clocks expected for one field. The window parameters specify the number 569f29dbc25Smrg * of clocks variation allowed before and after the expected vsync. For 570f29dbc25Smrg * example, if vertical_count is 1000, window_before is 5 and window_after 571f29dbc25Smrg * is 12, VSync will be considered valid if it occurs between 995 and 1012 572f29dbc25Smrg * clocks after the last VSync. The total window size (window_before + 573f29dbc25Smrg * window_after) cannot exceed 255. 574f29dbc25Smrg *--------------------------------------------------------------------------*/ 575f29dbc25Smrg 576f29dbc25Smrgint 577f29dbc25Smrgvip_set_vsync_error(unsigned long vertical_count, unsigned long window_before, 578f29dbc25Smrg unsigned long window_after, int enable) 579f29dbc25Smrg{ 580f29dbc25Smrg unsigned long vip_control2 = READ_VIP32(VIP_CONTROL2); 581f29dbc25Smrg unsigned long temp; 582f29dbc25Smrg 583f29dbc25Smrg if (enable) { 584f29dbc25Smrg /* CREATE THE VERTICAL WINDOW 585f29dbc25Smrg * The VIP uses two counters. The first counter defines the minimum 586f29dbc25Smrg * clock count before a valid VSync can occur. The second counter 587f29dbc25Smrg * starts after the first completes and defines the acceptable 588f29dbc25Smrg * region of variation. 589f29dbc25Smrg */ 590f29dbc25Smrg 591f29dbc25Smrg temp = ((window_before + 592f29dbc25Smrg window_after) << VIP_VSYNC_ERR_WINDOW_SHIFT) & 593f29dbc25Smrg VIP_VSYNC_ERR_WINDOW_MASK; 594f29dbc25Smrg temp |= (vertical_count - window_before) & VIP_VSYNC_ERR_COUNT_MASK; 595f29dbc25Smrg 596f29dbc25Smrg vip_control2 |= VIP_CONTROL2_VERTERROR_ENABLE; 597f29dbc25Smrg 598f29dbc25Smrg WRITE_VIP32(VIP_VSYNC_ERR_COUNT, temp); 599f29dbc25Smrg } else { 600f29dbc25Smrg vip_control2 &= ~VIP_CONTROL2_VERTERROR_ENABLE; 601f29dbc25Smrg } 602f29dbc25Smrg WRITE_VIP32(VIP_CONTROL2, vip_control2); 603f29dbc25Smrg 604f29dbc25Smrg return CIM_STATUS_OK; 605f29dbc25Smrg} 606f29dbc25Smrg 607f29dbc25Smrg/*--------------------------------------------------------------------------- 608f29dbc25Smrg * vip_max_address_enable 609f29dbc25Smrg * 610f29dbc25Smrg * This routine specifies the maximum address to which the the hardware should 611f29dbc25Smrg * write during data storage. If this value is exceeded an error is generated, 612f29dbc25Smrg * (this may be monitored using the appropriate interrupt flags - see 613f29dbc25Smrg * vip_set_interrupt_enable) 614f29dbc25Smrg *--------------------------------------------------------------------------*/ 615f29dbc25Smrg 616f29dbc25Smrgint 617f29dbc25Smrgvip_max_address_enable(unsigned long max_address, int enable) 618f29dbc25Smrg{ 619f29dbc25Smrg unsigned long vip_control2 = READ_VIP32(VIP_CONTROL2); 620f29dbc25Smrg 621f29dbc25Smrg if (enable) { 622f29dbc25Smrg /* ENABLE THE CONTROL BIT */ 623f29dbc25Smrg 624f29dbc25Smrg vip_control2 |= VIP_CONTROL2_ADD_ERROR_ENABLE; 625f29dbc25Smrg 626f29dbc25Smrg WRITE_VIP32(VIP_MAX_ADDRESS, max_address & VIP_MAXADDR_MASK); 627f29dbc25Smrg } else { 628f29dbc25Smrg /* DISABLE DETECTION */ 629f29dbc25Smrg 630f29dbc25Smrg vip_control2 &= ~VIP_CONTROL2_ADD_ERROR_ENABLE; 631f29dbc25Smrg } 632f29dbc25Smrg WRITE_VIP32(VIP_CONTROL2, vip_control2); 633f29dbc25Smrg 634f29dbc25Smrg return CIM_STATUS_OK; 635f29dbc25Smrg} 636f29dbc25Smrg 637f29dbc25Smrg/*--------------------------------------------------------------------------- 638f29dbc25Smrg * vip_set_loopback_enable 639f29dbc25Smrg * 640f29dbc25Smrg * This routine enables/disables internal loopback functionality. When 641f29dbc25Smrg * loopback is enabled, the VOP outputs are rerouted to the VIP inputs 642f29dbc25Smrg * internal to the chip. No loopback connector is required. 643f29dbc25Smrg *--------------------------------------------------------------------------*/ 644f29dbc25Smrg 645f29dbc25Smrgint 646f29dbc25Smrgvip_set_loopback_enable(int enable) 647f29dbc25Smrg{ 648f29dbc25Smrg unsigned long vip_control2 = READ_VIP32(VIP_CONTROL2); 649f29dbc25Smrg 650f29dbc25Smrg if (enable) 651f29dbc25Smrg vip_control2 |= VIP_CONTROL2_LOOPBACK_ENABLE; 652f29dbc25Smrg else 653f29dbc25Smrg vip_control2 &= ~VIP_CONTROL2_LOOPBACK_ENABLE; 654f29dbc25Smrg 655f29dbc25Smrg WRITE_VIP32(VIP_CONTROL2, vip_control2); 656f29dbc25Smrg 657f29dbc25Smrg return CIM_STATUS_OK; 658f29dbc25Smrg} 659f29dbc25Smrg 660f29dbc25Smrg/*--------------------------------------------------------------------------- 661f29dbc25Smrg * vip_configure_genlock 662f29dbc25Smrg * 663f29dbc25Smrg * This routine configures genlock functionality. 664f29dbc25Smrg *---------------------------------------------------------------------------*/ 665f29dbc25Smrg 666f29dbc25Smrgint 667f29dbc25Smrgvip_configure_genlock(VIPGENLOCKBUFFER * buffer) 668f29dbc25Smrg{ 669f29dbc25Smrg unsigned long vip_control1, vip_control2; 670f29dbc25Smrg unsigned long unlock, genlk_ctl; 671f29dbc25Smrg 672f29dbc25Smrg if (!buffer) 673f29dbc25Smrg return CIM_STATUS_INVALIDPARAMS; 674f29dbc25Smrg 675f29dbc25Smrg unlock = READ_REG32(DC3_UNLOCK); 676f29dbc25Smrg genlk_ctl = READ_REG32(DC3_GENLK_CTL); 677f29dbc25Smrg vip_control1 = READ_VIP32(VIP_CONTROL1); 678f29dbc25Smrg vip_control2 = READ_VIP32(VIP_CONTROL2); 679f29dbc25Smrg 680f29dbc25Smrg /* UPDATE VIDEO DETECTION */ 681f29dbc25Smrg /* These flags are used to indicate the ways in which the VIP signal */ 682f29dbc25Smrg /* can be considered 'lost'. */ 683f29dbc25Smrg 684f29dbc25Smrg vip_control1 &= ~VIP_CONTROL1_VDE_FF_MASK; 685f29dbc25Smrg vip_control2 &= ~(VIP_CONTROL2_FIELD2VG_MASK | VIP_CONTROL2_SYNC2VG_MASK); 686f29dbc25Smrg vip_control1 |= buffer->vip_signal_loss; 687f29dbc25Smrg 688f29dbc25Smrg /* UPDATE FIELD AND VSYNC INFORMATION */ 689f29dbc25Smrg /* These flags control how and when the even/odd field and Vsync */ 690f29dbc25Smrg /* information is communicated to the VG. */ 691f29dbc25Smrg 692f29dbc25Smrg vip_control2 |= buffer->field_to_vg; 693f29dbc25Smrg vip_control2 |= buffer->vsync_to_vg; 694f29dbc25Smrg 695f29dbc25Smrg /* ENABLE OR DISABLE GENLOCK TIMEOUT */ 696f29dbc25Smrg /* Enabling genlock timeout allows the VG to revert to its own sync */ 697f29dbc25Smrg /* timings when the VIP input is lost. Note that the VIP will not */ 698f29dbc25Smrg /* know the signal is lost unless the appropriate error detection */ 699f29dbc25Smrg /* flags have been enabled inside vip_initialize. */ 700f29dbc25Smrg 701f29dbc25Smrg if (buffer->enable_timeout) 702f29dbc25Smrg genlk_ctl |= DC3_GC_GENLOCK_TO_ENABLE; 703f29dbc25Smrg else 704f29dbc25Smrg genlk_ctl &= ~DC3_GC_GENLOCK_TO_ENABLE; 705f29dbc25Smrg 706f29dbc25Smrg genlk_ctl &= ~DC3_GC_GENLOCK_SKEW_MASK; 707f29dbc25Smrg genlk_ctl |= buffer->genlock_skew & DC3_GC_GENLOCK_SKEW_MASK; 708f29dbc25Smrg 709f29dbc25Smrg WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE); 710f29dbc25Smrg WRITE_REG32(DC3_GENLK_CTL, genlk_ctl); 711f29dbc25Smrg WRITE_VIP32(VIP_CONTROL1, vip_control1); 712f29dbc25Smrg WRITE_VIP32(VIP_CONTROL2, vip_control2); 713f29dbc25Smrg WRITE_REG32(DC3_UNLOCK, unlock); 714f29dbc25Smrg 715f29dbc25Smrg return CIM_STATUS_OK; 716f29dbc25Smrg} 717f29dbc25Smrg 718f29dbc25Smrg/*--------------------------------------------------------------------------- 719f29dbc25Smrg * vip_set_genlock_enable 720f29dbc25Smrg * 721f29dbc25Smrg * This routine enables/disables genlock inside the VG. 722f29dbc25Smrg *--------------------------------------------------------------------------*/ 723f29dbc25Smrg 724f29dbc25Smrgint 725f29dbc25Smrgvip_set_genlock_enable(int enable) 726f29dbc25Smrg{ 727f29dbc25Smrg unsigned long unlock, temp; 728f29dbc25Smrg 729f29dbc25Smrg unlock = READ_REG32(DC3_UNLOCK); 730f29dbc25Smrg temp = READ_REG32(DC3_GENLK_CTL); 731f29dbc25Smrg 732f29dbc25Smrg if (enable) 733f29dbc25Smrg temp |= DC3_GC_GENLOCK_ENABLE; 734f29dbc25Smrg else 735f29dbc25Smrg temp &= ~DC3_GC_GENLOCK_ENABLE; 736f29dbc25Smrg 737f29dbc25Smrg WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE); 738f29dbc25Smrg WRITE_REG32(DC3_GENLK_CTL, temp); 739f29dbc25Smrg WRITE_REG32(DC3_UNLOCK, unlock); 740f29dbc25Smrg 741f29dbc25Smrg return CIM_STATUS_OK; 742f29dbc25Smrg} 743f29dbc25Smrg 744f29dbc25Smrg/*--------------------------------------------------------------------------- 745f29dbc25Smrg * vip_set_power_characteristics 746f29dbc25Smrg * 747f29dbc25Smrg * This routine takes a VIPPOWERBUFFER structure, and selectively sets the 748f29dbc25Smrg * GeodeLink power and/or Vip clock power states. 749f29dbc25Smrg *--------------------------------------------------------------------------*/ 750f29dbc25Smrg 751f29dbc25Smrgint 752f29dbc25Smrgvip_set_power_characteristics(VIPPOWERBUFFER * buffer) 753f29dbc25Smrg{ 754f29dbc25Smrg Q_WORD q_word; 755f29dbc25Smrg 756f29dbc25Smrg if (!buffer) 757f29dbc25Smrg return CIM_STATUS_INVALIDPARAMS; 758f29dbc25Smrg 759f29dbc25Smrg q_word.low = q_word.high = 0; 760f29dbc25Smrg 761f29dbc25Smrg /* ENABLE GEODELINK CLOCK GATING */ 762f29dbc25Smrg 763f29dbc25Smrg if (buffer->glink_clock_mode) 764f29dbc25Smrg q_word.low |= VIP_MSR_POWER_GLINK; 765f29dbc25Smrg 766f29dbc25Smrg /* ENABLE VIP CLOCK GATING */ 767f29dbc25Smrg 768f29dbc25Smrg if (buffer->vip_clock_mode) 769f29dbc25Smrg q_word.low |= VIP_MSR_POWER_CLOCK; 770f29dbc25Smrg 771f29dbc25Smrg /* WRITE THE NEW VALUE */ 772f29dbc25Smrg 773f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_PM, &q_word); 774f29dbc25Smrg 775f29dbc25Smrg return CIM_STATUS_OK; 776f29dbc25Smrg} 777f29dbc25Smrg 778f29dbc25Smrg/*--------------------------------------------------------------------------- 779f29dbc25Smrg * vip_set_priority_characteristics 780f29dbc25Smrg * 781f29dbc25Smrg * This routine programs the VIP GeodeLink priority characteristics 782f29dbc25Smrg *--------------------------------------------------------------------------*/ 783f29dbc25Smrg 784f29dbc25Smrgint 785f29dbc25Smrgvip_set_priority_characteristics(VIPPRIORITYBUFFER * buffer) 786f29dbc25Smrg{ 787f29dbc25Smrg Q_WORD q_word; 788f29dbc25Smrg 789f29dbc25Smrg if (!buffer) 790f29dbc25Smrg return CIM_STATUS_INVALIDPARAMS; 791f29dbc25Smrg 792f29dbc25Smrg q_word.low = q_word.high = 0; 793f29dbc25Smrg 794f29dbc25Smrg q_word.low |= (buffer->secondary << 795f29dbc25Smrg VIP_MSR_MCR_SECOND_PRIORITY_SHIFT) & VIP_MSR_MCR_SECOND_PRIORITY_MASK; 796f29dbc25Smrg q_word.low |= (buffer->primary << 797f29dbc25Smrg VIP_MSR_MCR_PRIMARY_PRIORITY_SHIFT) & 798f29dbc25Smrg VIP_MSR_MCR_PRIMARY_PRIORITY_MASK; 799f29dbc25Smrg q_word.low |= (buffer->pid << VIP_MSR_MCR_PID_SHIFT) & 800f29dbc25Smrg VIP_MSR_MCR_PID_MASK; 801f29dbc25Smrg 802f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_CONFIG, &q_word); 803f29dbc25Smrg 804f29dbc25Smrg return CIM_STATUS_OK; 805f29dbc25Smrg} 806f29dbc25Smrg 807f29dbc25Smrg/*--------------------------------------------------------------------------- 808f29dbc25Smrg * vip_set_debug_characteristics 809f29dbc25Smrg * 810f29dbc25Smrg * This routine configures the debug data that is exposed over the diag bus. 811f29dbc25Smrg *--------------------------------------------------------------------------*/ 812f29dbc25Smrg 813f29dbc25Smrgint 814f29dbc25Smrgvip_set_debug_characteristics(VIPDEBUGBUFFER * buffer) 815f29dbc25Smrg{ 816f29dbc25Smrg Q_WORD q_word; 817f29dbc25Smrg 818f29dbc25Smrg if (!buffer) 819f29dbc25Smrg return CIM_STATUS_INVALIDPARAMS; 820f29dbc25Smrg 821f29dbc25Smrg q_word.low = q_word.high = 0; 822f29dbc25Smrg 823f29dbc25Smrg q_word.high |= (buffer->bist << VIP_MSR_DIAG_BIST_SHIFT) & 824f29dbc25Smrg VIP_MSR_DIAG_BIST_WMASK; 825f29dbc25Smrg q_word.low |= (buffer->enable_upper ? 826f29dbc25Smrg VIP_MSR_DIAG_MSB_ENABLE : 0x00000000); 827f29dbc25Smrg q_word.low |= (buffer->select_upper << VIP_MSR_DIAG_SEL_UPPER_SHIFT) & 828f29dbc25Smrg VIP_MSR_DIAG_SEL_UPPER_MASK; 829f29dbc25Smrg q_word.low |= (buffer->enable_lower ? 830f29dbc25Smrg VIP_MSR_DIAG_LSB_ENABLE : 0x00000000); 831f29dbc25Smrg q_word.low |= (buffer->select_lower << VIP_MSR_DIAG_SEL_LOWER_SHIFT) & 832f29dbc25Smrg VIP_MSR_DIAG_SEL_LOWER_MASK; 833f29dbc25Smrg 834f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_DIAG, &q_word); 835f29dbc25Smrg 836f29dbc25Smrg return CIM_STATUS_OK; 837f29dbc25Smrg} 838f29dbc25Smrg 839f29dbc25Smrg/*--------------------------------------------------------------------------- 840f29dbc25Smrg * vip_configure_pages 841f29dbc25Smrg * 842f29dbc25Smrg * This routine sets the number of pages, and their offset from each other. 843f29dbc25Smrg *--------------------------------------------------------------------------*/ 844f29dbc25Smrg 845f29dbc25Smrgint 846f29dbc25Smrgvip_configure_pages(int page_count, unsigned long page_offset) 847f29dbc25Smrg{ 848f29dbc25Smrg unsigned long vip_control2 = READ_VIP32(VIP_CONTROL2); 849f29dbc25Smrg 850f29dbc25Smrg /* SET THE NEW PAGE COUNT */ 851f29dbc25Smrg 852f29dbc25Smrg vip_control2 &= ~VIP_CONTROL2_PAGECNT_MASK; 853f29dbc25Smrg vip_control2 |= (page_count << VIP_CONTROL2_PAGECNT_SHIFT) & 854f29dbc25Smrg VIP_CONTROL2_PAGECNT_MASK; 855f29dbc25Smrg 856f29dbc25Smrg /* WRITE THE PAGE OFFSET */ 857f29dbc25Smrg 858f29dbc25Smrg WRITE_VIP32(VIP_CONTROL2, vip_control2); 859f29dbc25Smrg WRITE_VIP32(VIP_PAGE_OFFSET, page_offset); 860f29dbc25Smrg 861f29dbc25Smrg return CIM_STATUS_OK; 862f29dbc25Smrg} 863f29dbc25Smrg 864f29dbc25Smrg/*--------------------------------------------------------------------------- 865f29dbc25Smrg * vip_set_interrupt_line 866f29dbc25Smrg * 867f29dbc25Smrg * This routine sets the line at which a line interrupt should be generated. 868f29dbc25Smrg *--------------------------------------------------------------------------*/ 869f29dbc25Smrg 870f29dbc25Smrgint 871f29dbc25Smrgvip_set_interrupt_line(int line) 872f29dbc25Smrg{ 873f29dbc25Smrg WRITE_VIP32(VIP_CURRENT_TARGET, 874f29dbc25Smrg (line << VIP_CTARGET_TLINE_SHIFT) & VIP_CTARGET_TLINE_MASK); 875f29dbc25Smrg 876f29dbc25Smrg return CIM_STATUS_OK; 877f29dbc25Smrg} 878f29dbc25Smrg 879f29dbc25Smrg/*--------------------------------------------------------------------------- 880f29dbc25Smrg * vip_reset 881f29dbc25Smrg * 882f29dbc25Smrg * This routine does a one-shot enable of the VIP hardware. It is useful 883f29dbc25Smrg * for handling unrecoverable VIP errors. 884f29dbc25Smrg *--------------------------------------------------------------------------*/ 885f29dbc25Smrg 886f29dbc25Smrgint 887f29dbc25Smrgvip_reset(void) 888f29dbc25Smrg{ 889f29dbc25Smrg unsigned long vip_control1, vip_control3; 890f29dbc25Smrg 891f29dbc25Smrg /* INVERT THE PAUSE BIT */ 892f29dbc25Smrg 893f29dbc25Smrg vip_control1 = READ_VIP32(VIP_CONTROL1); 894f29dbc25Smrg vip_control3 = READ_VIP32(VIP_CONTROL3); 895f29dbc25Smrg 896f29dbc25Smrg WRITE_VIP32(VIP_CONTROL1, vip_control1 | VIP_CONTROL1_RESET); 897f29dbc25Smrg WRITE_VIP32(VIP_CONTROL1, vip_control1 & ~VIP_CONTROL1_RESET); 898f29dbc25Smrg WRITE_VIP32(VIP_CONTROL3, vip_control3 | VIP_CONTROL3_FIFO_RESET); 899f29dbc25Smrg 900f29dbc25Smrg return CIM_STATUS_OK; 901f29dbc25Smrg} 902f29dbc25Smrg 903f29dbc25Smrg/*--------------------------------------------------------------------------- 904f29dbc25Smrg * vip_set_subwindow_enable 905f29dbc25Smrg * 906f29dbc25Smrg * This routine turns on SubWindow capture, that is a portion of the incoming 907f29dbc25Smrg * signal is captured rather than the entire frame. The window always has 908f29dbc25Smrg * the same width as the frame, only the vertical component can be 909f29dbc25Smrg * modified. 910f29dbc25Smrg *--------------------------------------------------------------------------*/ 911f29dbc25Smrg 912f29dbc25Smrgint 913f29dbc25Smrgvip_set_subwindow_enable(VIPSUBWINDOWBUFFER * buffer) 914f29dbc25Smrg{ 915f29dbc25Smrg unsigned long vip_control2; 916f29dbc25Smrg 917f29dbc25Smrg if (!buffer) 918f29dbc25Smrg return CIM_STATUS_INVALIDPARAMS; 919f29dbc25Smrg 920f29dbc25Smrg vip_control2 = READ_VIP32(VIP_CONTROL2); 921f29dbc25Smrg if (buffer->enable) { 922f29dbc25Smrg /* WRITE THE WINDOW VALUE */ 923f29dbc25Smrg 924f29dbc25Smrg WRITE_VIP32(VIP_VERTICAL_START_STOP, ((buffer->stop << 925f29dbc25Smrg VIP_VSTART_VERTEND_SHIFT) & 926f29dbc25Smrg VIP_VSTART_VERTEND_MASK) | ((buffer->start << 927f29dbc25Smrg VIP_VSTART_VERTSTART_SHIFT) & VIP_VSTART_VERTSTART_MASK)); 928f29dbc25Smrg 929f29dbc25Smrg /* ENABLE IN THE CONTROL REGISTER */ 930f29dbc25Smrg 931f29dbc25Smrg vip_control2 |= VIP_CONTROL2_SWC_ENABLE; 932f29dbc25Smrg } else { 933f29dbc25Smrg /* DISABLE SUBWINDOW CAPTURE IN THE CONTROL REGISTER */ 934f29dbc25Smrg 935f29dbc25Smrg vip_control2 &= ~VIP_CONTROL2_SWC_ENABLE; 936f29dbc25Smrg } 937f29dbc25Smrg WRITE_VIP32(VIP_CONTROL2, vip_control2); 938f29dbc25Smrg 939f29dbc25Smrg return CIM_STATUS_OK; 940f29dbc25Smrg} 941f29dbc25Smrg 942f29dbc25Smrg/*--------------------------------------------------------------------------- 943f29dbc25Smrg * vip_reset_interrupt_state 944f29dbc25Smrg * 945f29dbc25Smrg * This routine resets the state of one or more interrupts. 946f29dbc25Smrg *--------------------------------------------------------------------------*/ 947f29dbc25Smrg 948f29dbc25Smrgint 949f29dbc25Smrgvip_reset_interrupt_state(unsigned long interrupt_mask) 950f29dbc25Smrg{ 951f29dbc25Smrg unsigned long temp; 952f29dbc25Smrg 953f29dbc25Smrg temp = READ_VIP32(VIP_INTERRUPT); 954f29dbc25Smrg WRITE_VIP32(VIP_INTERRUPT, temp | (interrupt_mask & VIP_ALL_INTERRUPTS)); 955f29dbc25Smrg 956f29dbc25Smrg return CIM_STATUS_OK; 957f29dbc25Smrg} 958f29dbc25Smrg 959f29dbc25Smrg/*--------------------------------------------------------------------------- 960f29dbc25Smrg * vip_save_state 961f29dbc25Smrg * 962f29dbc25Smrg * This routine saves the necessary register contents in order to restore 963f29dbc25Smrg * at a later point to the same state. 964f29dbc25Smrg * 965f29dbc25Smrg * NOTE: Capture state is forced to OFF in this routine 966f29dbc25Smrg *--------------------------------------------------------------------------*/ 967f29dbc25Smrg 968f29dbc25Smrgint 969f29dbc25Smrgvip_save_state(VIPSTATEBUFFER * save_buffer) 970f29dbc25Smrg{ 971f29dbc25Smrg if (!save_buffer) 972f29dbc25Smrg return CIM_STATUS_INVALIDPARAMS; 973f29dbc25Smrg 974f29dbc25Smrg /* FORCE CAPTURE TO BE DISABLED */ 975f29dbc25Smrg 976f29dbc25Smrg vip_set_capture_state(VIP_STOPCAPTURE); 977f29dbc25Smrg 978f29dbc25Smrg /* READ AND SAVE THE REGISTER CONTENTS */ 979f29dbc25Smrg 980f29dbc25Smrg save_buffer->control1 = READ_VIP32(VIP_CONTROL1); 981f29dbc25Smrg save_buffer->control2 = READ_VIP32(VIP_CONTROL2); 982f29dbc25Smrg save_buffer->vip_int = READ_VIP32(VIP_INTERRUPT); 983f29dbc25Smrg save_buffer->current_target = READ_VIP32(VIP_CURRENT_TARGET); 984f29dbc25Smrg save_buffer->max_address = READ_VIP32(VIP_MAX_ADDRESS); 985f29dbc25Smrg save_buffer->taska_evenbase = READ_VIP32(VIP_TASKA_VID_EVEN_BASE); 986f29dbc25Smrg save_buffer->taska_oddbase = READ_VIP32(VIP_TASKA_VID_ODD_BASE); 987f29dbc25Smrg save_buffer->taska_vbi_evenbase = READ_VIP32(VIP_TASKA_VBI_EVEN_BASE); 988f29dbc25Smrg save_buffer->taska_vbi_oddbase = READ_VIP32(VIP_TASKA_VBI_ODD_BASE); 989f29dbc25Smrg save_buffer->taska_data_pitch = READ_VIP32(VIP_TASKA_VID_PITCH); 990f29dbc25Smrg save_buffer->control3 = READ_VIP32(VIP_CONTROL3); 991f29dbc25Smrg save_buffer->taska_v_oddoffset = READ_VIP32(VIP_TASKA_U_OFFSET); 992f29dbc25Smrg save_buffer->taska_u_oddoffset = READ_VIP32(VIP_TASKA_V_OFFSET); 993f29dbc25Smrg save_buffer->taskb_evenbase = READ_VIP32(VIP_TASKB_VID_EVEN_BASE); 994f29dbc25Smrg save_buffer->taskb_oddbase = READ_VIP32(VIP_TASKB_VID_ODD_BASE); 995f29dbc25Smrg save_buffer->taskb_vbi_evenbase = READ_VIP32(VIP_TASKB_VBI_EVEN_BASE); 996f29dbc25Smrg save_buffer->taskb_vbi_oddbase = READ_VIP32(VIP_TASKB_VBI_ODD_BASE); 997f29dbc25Smrg save_buffer->taskb_pitch = READ_VIP32(VIP_TASKB_VID_PITCH); 998f29dbc25Smrg save_buffer->taskb_voffset = READ_VIP32(VIP_TASKB_U_OFFSET); 999f29dbc25Smrg save_buffer->taskb_uoffset = READ_VIP32(VIP_TASKB_V_OFFSET); 1000f29dbc25Smrg save_buffer->msg1_base = READ_VIP32(VIP_ANC_MSG1_BASE); 1001f29dbc25Smrg save_buffer->msg2_base = READ_VIP32(VIP_ANC_MSG2_BASE); 1002f29dbc25Smrg save_buffer->msg_size = READ_VIP32(VIP_ANC_MSG_SIZE); 1003f29dbc25Smrg save_buffer->page_offset = READ_VIP32(VIP_PAGE_OFFSET); 1004f29dbc25Smrg save_buffer->vert_start_stop = READ_VIP32(VIP_VERTICAL_START_STOP); 1005f29dbc25Smrg save_buffer->vsync_err_count = READ_VIP32(VIP_VSYNC_ERR_COUNT); 1006f29dbc25Smrg save_buffer->taska_u_evenoffset = READ_VIP32(VIP_TASKA_U_EVEN_OFFSET); 1007f29dbc25Smrg save_buffer->taska_v_evenoffset = READ_VIP32(VIP_TASKA_V_EVEN_OFFSET); 1008f29dbc25Smrg 1009f29dbc25Smrg /* READ ALL VIP MSRS */ 1010f29dbc25Smrg 1011f29dbc25Smrg msr_read64(MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_CONFIG, 1012f29dbc25Smrg &(save_buffer->msr_config)); 1013f29dbc25Smrg msr_read64(MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_SMI, 1014f29dbc25Smrg &(save_buffer->msr_smi)); 1015f29dbc25Smrg msr_read64(MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_PM, 1016f29dbc25Smrg &(save_buffer->msr_pm)); 1017f29dbc25Smrg msr_read64(MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_DIAG, 1018f29dbc25Smrg &(save_buffer->msr_diag)); 1019f29dbc25Smrg 1020f29dbc25Smrg return CIM_STATUS_OK; 1021f29dbc25Smrg} 1022f29dbc25Smrg 1023f29dbc25Smrg/*--------------------------------------------------------------------------- 1024f29dbc25Smrg * vip_restore_state 1025f29dbc25Smrg * 1026f29dbc25Smrg * This routine restores the state of the vip registers - which were 1027f29dbc25Smrg * previously saved using vip_save_state. 1028f29dbc25Smrg *--------------------------------------------------------------------------*/ 1029f29dbc25Smrg 1030f29dbc25Smrgint 1031f29dbc25Smrgvip_restore_state(VIPSTATEBUFFER * restore_buffer) 1032f29dbc25Smrg{ 1033f29dbc25Smrg if (!restore_buffer) 1034f29dbc25Smrg return CIM_STATUS_OK; 1035f29dbc25Smrg 1036f29dbc25Smrg /* RESTORE THE REGISTERS */ 1037f29dbc25Smrg 1038f29dbc25Smrg WRITE_VIP32(VIP_CURRENT_TARGET, restore_buffer->current_target); 1039f29dbc25Smrg WRITE_VIP32(VIP_MAX_ADDRESS, restore_buffer->max_address); 1040f29dbc25Smrg WRITE_VIP32(VIP_TASKA_VID_EVEN_BASE, restore_buffer->taska_evenbase); 1041f29dbc25Smrg WRITE_VIP32(VIP_TASKA_VID_ODD_BASE, restore_buffer->taska_oddbase); 1042f29dbc25Smrg WRITE_VIP32(VIP_TASKA_VBI_EVEN_BASE, restore_buffer->taska_vbi_evenbase); 1043f29dbc25Smrg WRITE_VIP32(VIP_TASKA_VBI_ODD_BASE, restore_buffer->taska_vbi_oddbase); 1044f29dbc25Smrg WRITE_VIP32(VIP_TASKA_VID_PITCH, restore_buffer->taska_data_pitch); 1045f29dbc25Smrg WRITE_VIP32(VIP_CONTROL3, restore_buffer->control3); 1046f29dbc25Smrg WRITE_VIP32(VIP_TASKA_U_OFFSET, restore_buffer->taska_v_oddoffset); 1047f29dbc25Smrg WRITE_VIP32(VIP_TASKA_V_OFFSET, restore_buffer->taska_u_oddoffset); 1048f29dbc25Smrg WRITE_VIP32(VIP_TASKB_VID_EVEN_BASE, restore_buffer->taskb_evenbase); 1049f29dbc25Smrg WRITE_VIP32(VIP_TASKB_VID_ODD_BASE, restore_buffer->taskb_oddbase); 1050f29dbc25Smrg WRITE_VIP32(VIP_TASKB_VBI_EVEN_BASE, restore_buffer->taskb_vbi_evenbase); 1051f29dbc25Smrg WRITE_VIP32(VIP_TASKB_VBI_ODD_BASE, restore_buffer->taskb_vbi_oddbase); 1052f29dbc25Smrg WRITE_VIP32(VIP_TASKB_VID_PITCH, restore_buffer->taskb_pitch); 1053f29dbc25Smrg WRITE_VIP32(VIP_TASKB_U_OFFSET, restore_buffer->taskb_voffset); 1054f29dbc25Smrg WRITE_VIP32(VIP_TASKB_V_OFFSET, restore_buffer->taskb_uoffset); 1055f29dbc25Smrg WRITE_VIP32(VIP_ANC_MSG1_BASE, restore_buffer->msg1_base); 1056f29dbc25Smrg WRITE_VIP32(VIP_ANC_MSG2_BASE, restore_buffer->msg2_base); 1057f29dbc25Smrg WRITE_VIP32(VIP_ANC_MSG_SIZE, restore_buffer->msg_size); 1058f29dbc25Smrg WRITE_VIP32(VIP_PAGE_OFFSET, restore_buffer->page_offset); 1059f29dbc25Smrg WRITE_VIP32(VIP_VERTICAL_START_STOP, restore_buffer->vert_start_stop); 1060f29dbc25Smrg WRITE_VIP32(VIP_VSYNC_ERR_COUNT, restore_buffer->vsync_err_count); 1061f29dbc25Smrg WRITE_VIP32(VIP_TASKA_U_EVEN_OFFSET, restore_buffer->taska_u_evenoffset); 1062f29dbc25Smrg WRITE_VIP32(VIP_TASKA_V_EVEN_OFFSET, restore_buffer->taska_v_evenoffset); 1063f29dbc25Smrg 1064f29dbc25Smrg /* RESTORE THE VIP MSRS */ 1065f29dbc25Smrg 1066f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_CONFIG, 1067f29dbc25Smrg &(restore_buffer->msr_config)); 1068f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_SMI, 1069f29dbc25Smrg &(restore_buffer->msr_smi)); 1070f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_PM, 1071f29dbc25Smrg &(restore_buffer->msr_pm)); 1072f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_DIAG, 1073f29dbc25Smrg &(restore_buffer->msr_diag)); 1074f29dbc25Smrg 1075f29dbc25Smrg /* RESTORE THE CONTROL WORDS LAST */ 1076f29dbc25Smrg 1077f29dbc25Smrg WRITE_VIP32(VIP_CONTROL1, restore_buffer->control1); 1078f29dbc25Smrg WRITE_VIP32(VIP_CONTROL2, restore_buffer->control2); 1079f29dbc25Smrg WRITE_VIP32(VIP_CONTROL3, restore_buffer->control3); 1080f29dbc25Smrg 1081f29dbc25Smrg return CIM_STATUS_OK; 1082f29dbc25Smrg} 1083f29dbc25Smrg 1084f29dbc25Smrg/*--------------------------------------------------------------------------- 1085f29dbc25Smrg * vip_get_interrupt_state 1086f29dbc25Smrg * 1087f29dbc25Smrg * This routine returns the current interrupt state of the system. The 1088f29dbc25Smrg * rv can be tested with the following flags to determine if the appropriate 1089f29dbc25Smrg * event has occured. 1090f29dbc25Smrg *--------------------------------------------------------------------------*/ 1091f29dbc25Smrg 1092f29dbc25Smrgunsigned long 1093f29dbc25Smrgvip_get_interrupt_state(void) 1094f29dbc25Smrg{ 1095f29dbc25Smrg unsigned long interrupt_mask = READ_VIP32(VIP_INTERRUPT); 1096f29dbc25Smrg 1097f29dbc25Smrg return (~(interrupt_mask << 16) & interrupt_mask & VIP_ALL_INTERRUPTS); 1098f29dbc25Smrg} 1099f29dbc25Smrg 1100f29dbc25Smrg/*--------------------------------------------------------------------------- 1101f29dbc25Smrg * vip_test_genlock_active 1102f29dbc25Smrg * 1103f29dbc25Smrg * This routine reads the live status of the genlock connection between the 1104f29dbc25Smrg * VIP and VG blocks. 1105f29dbc25Smrg *--------------------------------------------------------------------------*/ 1106f29dbc25Smrg 1107f29dbc25Smrgint 1108f29dbc25Smrgvip_test_genlock_active(void) 1109f29dbc25Smrg{ 1110f29dbc25Smrg if (READ_REG32(DC3_GENLK_CTL) & DC3_GC_GENLK_ACTIVE) 1111f29dbc25Smrg return 1; 1112f29dbc25Smrg 1113f29dbc25Smrg return 0; 1114f29dbc25Smrg} 1115f29dbc25Smrg 1116f29dbc25Smrg/*--------------------------------------------------------------------------- 1117f29dbc25Smrg * vip_test_signal_status 1118f29dbc25Smrg * 1119f29dbc25Smrg * This routine reads the live signal status coming into the VIP block. 1120f29dbc25Smrg *--------------------------------------------------------------------------*/ 1121f29dbc25Smrg 1122f29dbc25Smrgint 1123f29dbc25Smrgvip_test_signal_status(void) 1124f29dbc25Smrg{ 1125f29dbc25Smrg if (READ_REG32(DC3_GENLK_CTL) & DC3_GC_VIP_VID_OK) 1126f29dbc25Smrg return 1; 1127f29dbc25Smrg 1128f29dbc25Smrg return 0; 1129f29dbc25Smrg} 1130f29dbc25Smrg 1131f29dbc25Smrg/*--------------------------------------------------------------------------- 1132f29dbc25Smrg * vip_get_current_field 1133f29dbc25Smrg * 1134f29dbc25Smrg * This routine returns the current field being received. 1135f29dbc25Smrg *--------------------------------------------------------------------------*/ 1136f29dbc25Smrg 1137f29dbc25Smrgunsigned long 1138f29dbc25Smrgvip_get_current_field(void) 1139f29dbc25Smrg{ 1140f29dbc25Smrg if (READ_VIP32(VIP_STATUS) & VIP_STATUS_FIELD) 1141f29dbc25Smrg return VIP_EVEN_FIELD; 1142f29dbc25Smrg 1143f29dbc25Smrg return VIP_ODD_FIELD; 1144f29dbc25Smrg} 1145f29dbc25Smrg 1146f29dbc25Smrg/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1147f29dbc25Smrg * CIMARRON VIP READ ROUTINES 1148f29dbc25Smrg * These routines are included for use in diagnostics or when debugging. They 1149f29dbc25Smrg * can be optionally excluded from a project. 1150f29dbc25Smrg *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ 1151f29dbc25Smrg 1152f29dbc25Smrg#if CIMARRON_INCLUDE_VIP_READ_ROUTINES 1153f29dbc25Smrg 1154f29dbc25Smrg/*--------------------------------------------------------------------------- 1155f29dbc25Smrg * vip_get_current_mode 1156f29dbc25Smrg * 1157f29dbc25Smrg * This routine reads the current VIP operating mode. 1158f29dbc25Smrg *--------------------------------------------------------------------------*/ 1159f29dbc25Smrg 1160f29dbc25Smrgint 1161f29dbc25Smrgvip_get_current_mode(VIPSETMODEBUFFER * buffer) 1162f29dbc25Smrg{ 1163f29dbc25Smrg unsigned long vip_control1, vip_control2, vip_control3; 1164f29dbc25Smrg 1165f29dbc25Smrg if (!buffer) 1166f29dbc25Smrg return CIM_STATUS_INVALIDPARAMS; 1167f29dbc25Smrg 1168f29dbc25Smrg vip_control1 = READ_VIP32(VIP_CONTROL1); 1169f29dbc25Smrg vip_control2 = READ_VIP32(VIP_CONTROL2); 1170f29dbc25Smrg vip_control3 = READ_VIP32(VIP_CONTROL3); 1171f29dbc25Smrg 1172f29dbc25Smrg /* READ CURRENT OPERATING MODE AND ENABLES */ 1173f29dbc25Smrg 1174f29dbc25Smrg buffer->stream_enables = vip_control1 & VIP_ENABLE_ALL; 1175f29dbc25Smrg buffer->operating_mode = vip_control1 & VIP_CONTROL1_MODE_MASK; 1176f29dbc25Smrg 1177f29dbc25Smrg /* READ CURRENT PLANAR CAPTURE SETTINGS */ 1178f29dbc25Smrg 1179f29dbc25Smrg buffer->flags = 0; 1180f29dbc25Smrg buffer->planar_capture = 0; 1181f29dbc25Smrg if (vip_control1 & VIP_CONTROL1_PLANAR) { 1182f29dbc25Smrg buffer->flags |= VIP_MODEFLAG_PLANARCAPTURE; 1183f29dbc25Smrg if (vip_control1 & VIP_CONTROL1_DISABLE_DECIMATION) { 1184f29dbc25Smrg if (vip_control3 & VIP_CONTROL3_DECIMATE_EVEN) 1185f29dbc25Smrg buffer->planar_capture = VIP_420CAPTURE_ALTERNATINGFIELDS; 1186f29dbc25Smrg else 1187f29dbc25Smrg buffer->planar_capture = VIP_420CAPTURE_EVERYLINE; 1188f29dbc25Smrg } else 1189f29dbc25Smrg buffer->planar_capture = VIP_420CAPTURE_ALTERNATINGLINES; 1190f29dbc25Smrg } 1191f29dbc25Smrg 1192f29dbc25Smrg /* READ MISCELLANEOUS FLAGS */ 1193f29dbc25Smrg 1194f29dbc25Smrg if (vip_control1 & VIP_CONTROL1_NON_INTERLACED) 1195f29dbc25Smrg buffer->flags |= VIP_MODEFLAG_PROGRESSIVE; 1196f29dbc25Smrg if (vip_control3 & VIP_CONTROL3_BASE_UPDATE) 1197f29dbc25Smrg buffer->flags |= VIP_MODEFLAG_TOGGLEEACHFIELD; 1198f29dbc25Smrg if (vip_control2 & VIP_CONTROL2_INVERT_POLARITY) 1199f29dbc25Smrg buffer->flags |= VIP_MODEFLAG_INVERTPOLARITY; 1200f29dbc25Smrg if (vip_control1 & VIP_CONTROL1_MSG_STRM_CTRL) 1201f29dbc25Smrg buffer->flags |= VIP_MODEFLAG_FLIPMESSAGEWHENFULL; 1202f29dbc25Smrg if (vip_control2 & VIP_CONTROL2_REPEAT_ENABLE) 1203f29dbc25Smrg buffer->flags |= VIP_MODEFLAG_ENABLEREPEATFLAG; 1204f29dbc25Smrg if (vip_control3 & VIP_CONTROL3_TASK_POLARITY) 1205f29dbc25Smrg buffer->flags |= VIP_MODEFLAG_INVERTTASKPOLARITY; 1206f29dbc25Smrg if (vip_control1 & VIP_CONTROL1_DISABLE_ZERO_DETECT) 1207f29dbc25Smrg buffer->flags |= VIP_MODEFLAG_DISABLEZERODETECT; 1208f29dbc25Smrg if (vip_control2 & VIP_CONTROL2_ANC10) 1209f29dbc25Smrg buffer->flags |= VIP_MODEFLAG_10BITANCILLARY; 1210f29dbc25Smrg 1211f29dbc25Smrg /* READ THE CURRENT VIP 601 SETTINGS */ 1212f29dbc25Smrg 1213f29dbc25Smrg vip_get_601_configuration(&buffer->vip601_settings); 1214f29dbc25Smrg 1215f29dbc25Smrg return CIM_STATUS_OK; 1216f29dbc25Smrg} 1217f29dbc25Smrg 1218f29dbc25Smrg/*--------------------------------------------------------------------------- 1219f29dbc25Smrg * vip_get_601_configuration 1220f29dbc25Smrg * 1221f29dbc25Smrg * This routine returns the current 601 configuration information. 1222f29dbc25Smrg *--------------------------------------------------------------------------*/ 1223f29dbc25Smrg 1224f29dbc25Smrgint 1225f29dbc25Smrgvip_get_601_configuration(VIP_601PARAMS * buffer) 1226f29dbc25Smrg{ 1227f29dbc25Smrg unsigned long vip_control3, vip_control1; 1228f29dbc25Smrg 1229f29dbc25Smrg if (!buffer) 1230f29dbc25Smrg return CIM_STATUS_INVALIDPARAMS; 1231f29dbc25Smrg 1232f29dbc25Smrg vip_control1 = READ_VIP32(VIP_CONTROL3); 1233f29dbc25Smrg vip_control3 = READ_VIP32(VIP_CONTROL3); 1234f29dbc25Smrg 1235f29dbc25Smrg buffer->flags = 0; 1236f29dbc25Smrg if (vip_control3 & VIP_CONTROL3_VSYNC_POLARITY) 1237f29dbc25Smrg buffer->flags |= VIP_MODEFLAG_VSYNCACTIVEHIGH; 1238f29dbc25Smrg if (vip_control3 & VIP_CONTROL3_HSYNC_POLARITY) 1239f29dbc25Smrg buffer->flags |= VIP_MODEFLAG_HSYNCACTIVEHIGH; 1240f29dbc25Smrg 1241f29dbc25Smrg buffer->horz_start = READ_VIP32(VIP_601_HORZ_START); 1242f29dbc25Smrg buffer->vbi_start = READ_VIP32(VIP_601_VBI_START); 1243f29dbc25Smrg buffer->vbi_height = READ_VIP32(VIP_601_VBI_END) - buffer->vbi_start + 1; 1244f29dbc25Smrg buffer->vert_start_even = READ_VIP32(VIP_601_EVEN_START_STOP) & 0xFFFF; 1245f29dbc25Smrg buffer->even_height = (READ_VIP32(VIP_601_EVEN_START_STOP) >> 16) - 1246f29dbc25Smrg buffer->vert_start_even + 1; 1247f29dbc25Smrg buffer->vert_start_odd = READ_VIP32(VIP_601_ODD_START_STOP) & 0xFFFF; 1248f29dbc25Smrg buffer->odd_height = (READ_VIP32(VIP_601_ODD_START_STOP) >> 16) - 1249f29dbc25Smrg buffer->vert_start_odd + 1; 1250f29dbc25Smrg buffer->odd_detect_start = READ_VIP32(VIP_ODD_FIELD_DETECT) & 0xFFFF; 1251f29dbc25Smrg buffer->odd_detect_end = READ_VIP32(VIP_ODD_FIELD_DETECT) >> 16; 1252f29dbc25Smrg 1253f29dbc25Smrg /* SPECIAL CASE FOR HORIZONTAL DATA 1254f29dbc25Smrg * 601 horizontal parameters are based on the number of clocks and not 1255f29dbc25Smrg * the number of pixels. 1256f29dbc25Smrg */ 1257f29dbc25Smrg 1258f29dbc25Smrg if ((vip_control1 & VIP_CONTROL1_MODE_MASK) == VIP_MODE_16BIT601) 1259f29dbc25Smrg buffer->width = (READ_VIP32(VIP_601_HORZ_END) - 1260f29dbc25Smrg buffer->horz_start - 3) >> 1; 1261f29dbc25Smrg else 1262f29dbc25Smrg buffer->width = (READ_VIP32(VIP_601_HORZ_END) - 1263f29dbc25Smrg buffer->horz_start - 3); 1264f29dbc25Smrg 1265f29dbc25Smrg return CIM_STATUS_OK; 1266f29dbc25Smrg} 1267f29dbc25Smrg 1268f29dbc25Smrg/*--------------------------------------------------------------------------- 1269f29dbc25Smrg * vip_get_buffer_configuration 1270f29dbc25Smrg * 1271f29dbc25Smrg * This routine reads the current buffer configuration for Task A, Task B, 1272f29dbc25Smrg * ancillary or message data. The current_buffer member indicates which 1273f29dbc25Smrg * array index should hold the new values for Task A or Task B data. 1274f29dbc25Smrg *--------------------------------------------------------------------------*/ 1275f29dbc25Smrg 1276f29dbc25Smrgint 1277f29dbc25Smrgvip_get_buffer_configuration(int buffer_type, VIPINPUTBUFFER * buffer) 1278f29dbc25Smrg{ 1279f29dbc25Smrg unsigned long cur_buffer = buffer->current_buffer; 1280f29dbc25Smrg VIPINPUTBUFFER_ADDR *offsets; 1281f29dbc25Smrg 1282f29dbc25Smrg if (!buffer) 1283f29dbc25Smrg return CIM_STATUS_INVALIDPARAMS; 1284f29dbc25Smrg 1285f29dbc25Smrg if (buffer_type == VIP_BUFFER_A) { 1286f29dbc25Smrg offsets = &buffer->offsets[VIP_BUFFER_TASK_A]; 1287f29dbc25Smrg 1288f29dbc25Smrg /* READ VIDEO PITCH */ 1289f29dbc25Smrg 1290f29dbc25Smrg offsets->y_pitch = READ_VIP32(VIP_TASKA_VID_PITCH) & 0xFFFF; 1291f29dbc25Smrg offsets->uv_pitch = READ_VIP32(VIP_TASKA_VID_PITCH) >> 16; 1292f29dbc25Smrg 1293f29dbc25Smrg /* READ BASE OFFSETS */ 1294f29dbc25Smrg 1295f29dbc25Smrg if (buffer->flags & VIP_INPUTFLAG_INVERTPOLARITY) { 1296f29dbc25Smrg offsets->even_base[cur_buffer] = 1297f29dbc25Smrg READ_VIP32(VIP_TASKA_VID_ODD_BASE); 1298f29dbc25Smrg offsets->odd_base[cur_buffer] = 1299f29dbc25Smrg READ_VIP32(VIP_TASKA_VID_EVEN_BASE); 1300f29dbc25Smrg 1301f29dbc25Smrg if (buffer->flags & VIP_INPUTFLAG_VBI) { 1302f29dbc25Smrg offsets->vbi_even_base = READ_VIP32(VIP_TASKA_VBI_ODD_BASE); 1303f29dbc25Smrg offsets->vbi_odd_base = READ_VIP32(VIP_TASKA_VBI_EVEN_BASE); 1304f29dbc25Smrg } 1305f29dbc25Smrg } else { 1306f29dbc25Smrg offsets->even_base[cur_buffer] = 1307f29dbc25Smrg READ_VIP32(VIP_TASKA_VID_EVEN_BASE); 1308f29dbc25Smrg offsets->odd_base[cur_buffer] = 1309f29dbc25Smrg READ_VIP32(VIP_TASKA_VID_ODD_BASE); 1310f29dbc25Smrg 1311f29dbc25Smrg if (buffer->flags & VIP_INPUTFLAG_VBI) { 1312f29dbc25Smrg offsets->vbi_even_base = READ_VIP32(VIP_TASKA_VBI_EVEN_BASE); 1313f29dbc25Smrg offsets->vbi_odd_base = READ_VIP32(VIP_TASKA_VBI_ODD_BASE); 1314f29dbc25Smrg } 1315f29dbc25Smrg } 1316f29dbc25Smrg 1317f29dbc25Smrg /* READ 4:2:0 OFFSETS */ 1318f29dbc25Smrg 1319f29dbc25Smrg if (buffer->flags & VIP_INPUTFLAG_PLANAR) { 1320f29dbc25Smrg offsets->odd_uoffset = READ_VIP32(VIP_TASKA_U_OFFSET); 1321f29dbc25Smrg offsets->odd_voffset = READ_VIP32(VIP_TASKA_V_OFFSET); 1322f29dbc25Smrg offsets->even_uoffset = READ_VIP32(VIP_TASKA_U_EVEN_OFFSET); 1323f29dbc25Smrg offsets->even_voffset = READ_VIP32(VIP_TASKA_V_EVEN_OFFSET); 1324f29dbc25Smrg } 1325f29dbc25Smrg } else if (buffer_type == VIP_BUFFER_B) { 1326f29dbc25Smrg offsets = &buffer->offsets[VIP_BUFFER_TASK_B]; 1327f29dbc25Smrg 1328f29dbc25Smrg /* READ VIDEO PITCH */ 1329f29dbc25Smrg 1330f29dbc25Smrg offsets->y_pitch = READ_VIP32(VIP_TASKB_VID_PITCH) & 0xFFFF; 1331f29dbc25Smrg offsets->uv_pitch = READ_VIP32(VIP_TASKB_VID_PITCH) >> 16; 1332f29dbc25Smrg 1333f29dbc25Smrg /* READ BASE OFFSETS */ 1334f29dbc25Smrg 1335f29dbc25Smrg if (buffer->flags & VIP_INPUTFLAG_INVERTPOLARITY) { 1336f29dbc25Smrg offsets->even_base[cur_buffer] = 1337f29dbc25Smrg READ_VIP32(VIP_TASKB_VID_ODD_BASE); 1338f29dbc25Smrg offsets->odd_base[cur_buffer] = 1339f29dbc25Smrg READ_VIP32(VIP_TASKB_VID_EVEN_BASE); 1340f29dbc25Smrg 1341f29dbc25Smrg if (buffer->flags & VIP_INPUTFLAG_VBI) { 1342f29dbc25Smrg offsets->vbi_even_base = READ_VIP32(VIP_TASKB_VBI_ODD_BASE); 1343f29dbc25Smrg offsets->vbi_odd_base = READ_VIP32(VIP_TASKB_VBI_EVEN_BASE); 1344f29dbc25Smrg } 1345f29dbc25Smrg } else { 1346f29dbc25Smrg offsets->even_base[cur_buffer] = 1347f29dbc25Smrg READ_VIP32(VIP_TASKB_VID_EVEN_BASE); 1348f29dbc25Smrg offsets->odd_base[cur_buffer] = 1349f29dbc25Smrg READ_VIP32(VIP_TASKB_VID_ODD_BASE); 1350f29dbc25Smrg 1351f29dbc25Smrg if (buffer->flags & VIP_INPUTFLAG_VBI) { 1352f29dbc25Smrg offsets->vbi_even_base = READ_VIP32(VIP_TASKB_VBI_EVEN_BASE); 1353f29dbc25Smrg offsets->vbi_odd_base = READ_VIP32(VIP_TASKB_VBI_ODD_BASE); 1354f29dbc25Smrg } 1355f29dbc25Smrg } 1356f29dbc25Smrg 1357f29dbc25Smrg /* READ 4:2:0 OFFSETS */ 1358f29dbc25Smrg 1359f29dbc25Smrg if (buffer->flags & VIP_INPUTFLAG_PLANAR) { 1360f29dbc25Smrg offsets->odd_uoffset = READ_VIP32(VIP_TASKB_U_OFFSET); 1361f29dbc25Smrg offsets->odd_voffset = READ_VIP32(VIP_TASKB_V_OFFSET); 1362f29dbc25Smrg } 1363f29dbc25Smrg } else if (buffer_type == VIP_BUFFER_ANC || buffer_type == VIP_BUFFER_MSG) { 1364f29dbc25Smrg buffer->ancillaryData.msg1_base = READ_VIP32(VIP_ANC_MSG1_BASE); 1365f29dbc25Smrg buffer->ancillaryData.msg2_base = READ_VIP32(VIP_ANC_MSG2_BASE); 1366f29dbc25Smrg buffer->ancillaryData.msg_size = READ_VIP32(VIP_ANC_MSG_SIZE); 1367f29dbc25Smrg } else { 1368f29dbc25Smrg return CIM_STATUS_INVALIDPARAMS; 1369f29dbc25Smrg } 1370f29dbc25Smrg 1371f29dbc25Smrg return CIM_STATUS_OK; 1372f29dbc25Smrg} 1373f29dbc25Smrg 1374f29dbc25Smrg/*--------------------------------------------------------------------------- 1375f29dbc25Smrg * vip_get_genlock_configuration 1376f29dbc25Smrg * 1377f29dbc25Smrg * This routine reads the current genlock configuration. 1378f29dbc25Smrg *--------------------------------------------------------------------------*/ 1379f29dbc25Smrg 1380f29dbc25Smrgint 1381f29dbc25Smrgvip_get_genlock_configuration(VIPGENLOCKBUFFER * buffer) 1382f29dbc25Smrg{ 1383f29dbc25Smrg unsigned long vip_control1, vip_control2; 1384f29dbc25Smrg unsigned long genlk_ctl; 1385f29dbc25Smrg 1386f29dbc25Smrg if (!buffer) 1387f29dbc25Smrg return CIM_STATUS_INVALIDPARAMS; 1388f29dbc25Smrg 1389f29dbc25Smrg genlk_ctl = READ_REG32(DC3_GENLK_CTL); 1390f29dbc25Smrg vip_control1 = READ_VIP32(VIP_CONTROL1); 1391f29dbc25Smrg vip_control2 = READ_VIP32(VIP_CONTROL2); 1392f29dbc25Smrg 1393f29dbc25Smrg /* READ ERROR DETECTION, CURRENT FIELD AND CURRENT VSYNC 1394f29dbc25Smrg * These flags are used to indicate the ways in which the VIP signal can 1395f29dbc25Smrg * be considered 'lost'. 1396f29dbc25Smrg */ 1397f29dbc25Smrg 1398f29dbc25Smrg buffer->vip_signal_loss = vip_control1 & VIP_CONTROL1_VDE_FF_MASK; 1399f29dbc25Smrg buffer->field_to_vg = vip_control2 & VIP_CONTROL2_FIELD2VG_MASK; 1400f29dbc25Smrg buffer->vsync_to_vg = vip_control2 & VIP_CONTROL2_SYNC2VG_MASK; 1401f29dbc25Smrg 1402f29dbc25Smrg /* GENLOCK TIMEOUT ENABLE */ 1403f29dbc25Smrg 1404f29dbc25Smrg buffer->enable_timeout = 0; 1405f29dbc25Smrg if (genlk_ctl & DC3_GC_GENLOCK_TO_ENABLE) 1406f29dbc25Smrg buffer->enable_timeout = 1; 1407f29dbc25Smrg 1408f29dbc25Smrg /* GENLOCK SKEW */ 1409f29dbc25Smrg 1410f29dbc25Smrg buffer->genlock_skew = genlk_ctl & DC3_GC_GENLOCK_SKEW_MASK; 1411f29dbc25Smrg 1412f29dbc25Smrg return CIM_STATUS_OK; 1413f29dbc25Smrg} 1414f29dbc25Smrg 1415f29dbc25Smrg/*--------------------------------------------------------------------------- 1416f29dbc25Smrg * vip_get_genlock_enable 1417f29dbc25Smrg * 1418f29dbc25Smrg * This routine returns the current enable status of genlock in the VG. 1419f29dbc25Smrg *--------------------------------------------------------------------------*/ 1420f29dbc25Smrg 1421f29dbc25Smrgint 1422f29dbc25Smrgvip_get_genlock_enable(void) 1423f29dbc25Smrg{ 1424f29dbc25Smrg if (READ_REG32(DC3_GENLK_CTL) & DC3_GC_GENLOCK_ENABLE) 1425f29dbc25Smrg return 1; 1426f29dbc25Smrg 1427f29dbc25Smrg return 0; 1428f29dbc25Smrg} 1429f29dbc25Smrg 1430f29dbc25Smrg/*--------------------------------------------------------------------------- 1431f29dbc25Smrg * vip_is_buffer_update_latched 1432f29dbc25Smrg * 1433f29dbc25Smrg * This routine indicates whether changes to the VIP offsets have been 1434f29dbc25Smrg * latched by the hardware. 1435f29dbc25Smrg *--------------------------------------------------------------------------*/ 1436f29dbc25Smrg 1437f29dbc25Smrgint 1438f29dbc25Smrgvip_is_buffer_update_latched(void) 1439f29dbc25Smrg{ 1440f29dbc25Smrg return (!(READ_VIP32(VIP_STATUS) & VIP_STATUS_BASEREG_NOTUPDT)); 1441f29dbc25Smrg} 1442f29dbc25Smrg 1443f29dbc25Smrg/*--------------------------------------------------------------------------- 1444f29dbc25Smrg * vip_get_capture_state 1445f29dbc25Smrg * 1446f29dbc25Smrg * This routine reads the current capture status of the VIP hardware. 1447f29dbc25Smrg *--------------------------------------------------------------------------*/ 1448f29dbc25Smrg 1449f29dbc25Smrgunsigned long 1450f29dbc25Smrgvip_get_capture_state(void) 1451f29dbc25Smrg{ 1452f29dbc25Smrg return ((READ_VIP32(VIP_CONTROL1) & VIP_CONTROL1_RUNMODE_MASK) >> 1453f29dbc25Smrg VIP_CONTROL1_RUNMODE_SHIFT); 1454f29dbc25Smrg} 1455f29dbc25Smrg 1456f29dbc25Smrg/*--------------------------------------------------------------------------- 1457f29dbc25Smrg * vip_get_current_line 1458f29dbc25Smrg * 1459f29dbc25Smrg * This routine returns the current line that is being processed. 1460f29dbc25Smrg *--------------------------------------------------------------------------*/ 1461f29dbc25Smrg 1462f29dbc25Smrgunsigned long 1463f29dbc25Smrgvip_get_current_line(void) 1464f29dbc25Smrg{ 1465f29dbc25Smrg return (READ_VIP32(VIP_CURRENT_TARGET) & VIP_CTARGET_CLINE_MASK); 1466f29dbc25Smrg} 1467f29dbc25Smrg 1468f29dbc25Smrg/*--------------------------------------------------------------------------- 1469f29dbc25Smrg * vip_read_fifo 1470f29dbc25Smrg * 1471f29dbc25Smrg * This routine reads from the specified fifo address. As the fifo access 1472f29dbc25Smrg * enable should be disabled when running in normal vip mode, this routine 1473f29dbc25Smrg * enables and disables access around the read. 1474f29dbc25Smrg * DIAGNOSTIC USE ONLY 1475f29dbc25Smrg *--------------------------------------------------------------------------*/ 1476f29dbc25Smrg 1477f29dbc25Smrgunsigned long 1478f29dbc25Smrgvip_read_fifo(unsigned long dwFifoAddress) 1479f29dbc25Smrg{ 1480f29dbc25Smrg unsigned long fifo_data; 1481f29dbc25Smrg 1482f29dbc25Smrg /* ENABLE FIFO ACCESS */ 1483f29dbc25Smrg 1484f29dbc25Smrg vip_enable_fifo_access(1); 1485f29dbc25Smrg 1486f29dbc25Smrg /* NOW READ THE DATA */ 1487f29dbc25Smrg 1488f29dbc25Smrg WRITE_VIP32(VIP_FIFO_ADDRESS, dwFifoAddress); 1489f29dbc25Smrg fifo_data = READ_VIP32(VIP_FIFO_DATA); 1490f29dbc25Smrg 1491f29dbc25Smrg /* DISABLE FIFO ACCESS */ 1492f29dbc25Smrg 1493f29dbc25Smrg vip_enable_fifo_access(0); 1494f29dbc25Smrg 1495f29dbc25Smrg return fifo_data; 1496f29dbc25Smrg} 1497f29dbc25Smrg 1498f29dbc25Smrg/*--------------------------------------------------------------------------- 1499f29dbc25Smrg * vip_write_fifo 1500f29dbc25Smrg * 1501f29dbc25Smrg * SYNOPSIS: 1502f29dbc25Smrg * This routine writes to the specified fifo address. As the fifo access 1503f29dbc25Smrg * enable should be disabled when running in normal vip mode, this routine 1504f29dbc25Smrg * enables and disables access around the write. 1505f29dbc25Smrg * DIAGNOSTIC USE ONLY 1506f29dbc25Smrg *--------------------------------------------------------------------------*/ 1507f29dbc25Smrg 1508f29dbc25Smrgint 1509f29dbc25Smrgvip_write_fifo(unsigned long dwFifoAddress, unsigned long dwFifoData) 1510f29dbc25Smrg{ 1511f29dbc25Smrg /* ENABLE FIFO ACCESS */ 1512f29dbc25Smrg 1513f29dbc25Smrg vip_enable_fifo_access(1); 1514f29dbc25Smrg 1515f29dbc25Smrg /* WRITE THE FIFO DATA */ 1516f29dbc25Smrg 1517f29dbc25Smrg WRITE_VIP32(VIP_FIFO_ADDRESS, dwFifoAddress); 1518f29dbc25Smrg WRITE_VIP32(VIP_FIFO_DATA, dwFifoData); 1519f29dbc25Smrg 1520f29dbc25Smrg /* DISABLE FIFO ACCESS */ 1521f29dbc25Smrg 1522f29dbc25Smrg vip_enable_fifo_access(0); 1523f29dbc25Smrg 1524f29dbc25Smrg return CIM_STATUS_OK; 1525f29dbc25Smrg} 1526f29dbc25Smrg 1527f29dbc25Smrg/*--------------------------------------------------------------------------- 1528f29dbc25Smrg * vip_enable_fifo_access 1529f29dbc25Smrg * 1530f29dbc25Smrg * This routine enables/disables access to the vip fifo. 1531f29dbc25Smrg * DIAGNOSTIC USE ONLY 1532f29dbc25Smrg *--------------------------------------------------------------------------*/ 1533f29dbc25Smrg 1534f29dbc25Smrgint 1535f29dbc25Smrgvip_enable_fifo_access(int enable) 1536f29dbc25Smrg{ 1537f29dbc25Smrg unsigned long cw2; 1538f29dbc25Smrg 1539f29dbc25Smrg cw2 = READ_VIP32(VIP_CONTROL2); 1540f29dbc25Smrg 1541f29dbc25Smrg if (enable) 1542f29dbc25Smrg cw2 |= VIP_CONTROL2_FIFO_ACCESS; 1543f29dbc25Smrg else 1544f29dbc25Smrg cw2 &= ~VIP_CONTROL2_FIFO_ACCESS; 1545f29dbc25Smrg 1546f29dbc25Smrg WRITE_VIP32(VIP_CONTROL2, cw2); 1547f29dbc25Smrg 1548f29dbc25Smrg return CIM_STATUS_OK; 1549f29dbc25Smrg} 1550f29dbc25Smrg 1551f29dbc25Smrg/*--------------------------------------------------------------------------- 1552f29dbc25Smrg * vip_get_power_characteristics 1553f29dbc25Smrg * 1554f29dbc25Smrg * This routine returns the current VIP clock gating state in a 1555f29dbc25Smrg * VIPPOWERBUFFER. 1556f29dbc25Smrg *--------------------------------------------------------------------------*/ 1557f29dbc25Smrg 1558f29dbc25Smrgint 1559f29dbc25Smrgvip_get_power_characteristics(VIPPOWERBUFFER * buffer) 1560f29dbc25Smrg{ 1561f29dbc25Smrg Q_WORD q_word; 1562f29dbc25Smrg 1563f29dbc25Smrg if (!buffer) 1564f29dbc25Smrg return CIM_STATUS_INVALIDPARAMS; 1565f29dbc25Smrg 1566f29dbc25Smrg /* READ THE EXISTING STATE */ 1567f29dbc25Smrg 1568f29dbc25Smrg msr_read64(MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_PM, &q_word); 1569f29dbc25Smrg 1570f29dbc25Smrg /* DECODE THE CLOCK GATING BITS */ 1571f29dbc25Smrg 1572f29dbc25Smrg buffer->glink_clock_mode = (int)(q_word.low & VIP_MSR_POWER_GLINK); 1573f29dbc25Smrg buffer->vip_clock_mode = (int)(q_word.low & VIP_MSR_POWER_CLOCK); 1574f29dbc25Smrg 1575f29dbc25Smrg return CIM_STATUS_OK; 1576f29dbc25Smrg} 1577f29dbc25Smrg 1578f29dbc25Smrg/*--------------------------------------------------------------------------- 1579f29dbc25Smrg * vip_get_priority_characteristics 1580f29dbc25Smrg * 1581f29dbc25Smrg * This routine returns the priority characteristics in the supplied 1582f29dbc25Smrg * VIPPRIORITYBUFFER. 1583f29dbc25Smrg *--------------------------------------------------------------------------*/ 1584f29dbc25Smrg 1585f29dbc25Smrgint 1586f29dbc25Smrgvip_get_priority_characteristics(VIPPRIORITYBUFFER * buffer) 1587f29dbc25Smrg{ 1588f29dbc25Smrg Q_WORD q_word; 1589f29dbc25Smrg 1590f29dbc25Smrg if (!buffer) 1591f29dbc25Smrg return CIM_STATUS_INVALIDPARAMS; 1592f29dbc25Smrg 1593f29dbc25Smrg /* READ THE CURRENT STATE */ 1594f29dbc25Smrg 1595f29dbc25Smrg msr_read64(MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_CONFIG, &q_word); 1596f29dbc25Smrg 1597f29dbc25Smrg /* DECODE THE PRIORITIES */ 1598f29dbc25Smrg 1599f29dbc25Smrg buffer->secondary = (q_word.low & VIP_MSR_MCR_SECOND_PRIORITY_MASK) >> 1600f29dbc25Smrg VIP_MSR_MCR_SECOND_PRIORITY_SHIFT; 1601f29dbc25Smrg buffer->primary = (q_word.low & VIP_MSR_MCR_PRIMARY_PRIORITY_MASK) >> 1602f29dbc25Smrg VIP_MSR_MCR_PRIMARY_PRIORITY_SHIFT; 1603f29dbc25Smrg buffer->pid = q_word.low & VIP_MSR_MCR_PID_MASK; 1604f29dbc25Smrg 1605f29dbc25Smrg return CIM_STATUS_OK; 1606f29dbc25Smrg} 1607f29dbc25Smrg 1608f29dbc25Smrg/*--------------------------------------------------------------------------- 1609f29dbc25Smrg * vip_get_capability_characteristics 1610f29dbc25Smrg * 1611f29dbc25Smrg * This routine returns revision information for the device. 1612f29dbc25Smrg *--------------------------------------------------------------------------*/ 1613f29dbc25Smrg 1614f29dbc25Smrgint 1615f29dbc25Smrgvip_get_capability_characteristics(VIPCAPABILITIESBUFFER * buffer) 1616f29dbc25Smrg{ 1617f29dbc25Smrg Q_WORD q_word; 1618f29dbc25Smrg 1619f29dbc25Smrg if (!buffer) 1620f29dbc25Smrg return CIM_STATUS_INVALIDPARAMS; 1621f29dbc25Smrg 1622f29dbc25Smrg /* READ THE CURRENT MSR CONTENTS */ 1623f29dbc25Smrg 1624f29dbc25Smrg msr_read64(MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_CAP, &q_word); 1625f29dbc25Smrg 1626f29dbc25Smrg /* DECODE THE REVISIONS */ 1627f29dbc25Smrg 1628f29dbc25Smrg buffer->revision_id = (q_word.low & VIP_MSR_CAP_REVID_MASK) >> 1629f29dbc25Smrg VIP_MSR_CAP_REVID_SHIFT; 1630f29dbc25Smrg buffer->device_id = (q_word.low & VIP_MSR_CAP_DEVID_MASK) >> 1631f29dbc25Smrg VIP_MSR_CAP_DEVID_SHIFT; 1632f29dbc25Smrg buffer->n_clock_domains = (q_word.low & VIP_MSR_CAP_NCLK_MASK) >> 1633f29dbc25Smrg VIP_MSR_CAP_NCLK_SHIFT; 1634f29dbc25Smrg buffer->n_smi_registers = (q_word.low & VIP_MSR_CAP_NSMI_MASK) >> 1635f29dbc25Smrg VIP_MSR_CAP_NSMI_SHIFT; 1636f29dbc25Smrg 1637f29dbc25Smrg return CIM_STATUS_OK; 1638f29dbc25Smrg} 1639f29dbc25Smrg 1640f29dbc25Smrg#endif 1641