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