~ubuntu-branches/ubuntu/trusty/xserver-xorg-video-geode-lts-utopic/trusty-proposed

« back to all changes in this revision

Viewing changes to src/cim/cim_vip.c

  • Committer: Package Import Robot
  • Author(s): Maarten Lankhorst
  • Date: 2015-01-06 10:39:17 UTC
  • Revision ID: package-import@ubuntu.com-20150106103917-bumwel1243pseqs6
Tags: upstream-2.11.16
ImportĀ upstreamĀ versionĀ 2.11.16

Show diffs side-by-side

added added

removed removed

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