2
* Copyright (c) 2006 Advanced Micro Devices, Inc.
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:
11
* The above copyright notice and this permission notice shall be included in
12
* all copies or substantial portions of the Software.
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.
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.
28
* Cimarron VIP configuration routines.
31
/*---------------------------------------------------------------------------
34
* This routine initializes the internal module state and prepares the
35
* module for subsequent VIP orientated activities.
36
*--------------------------------------------------------------------------*/
39
vip_initialize(VIPSETMODEBUFFER * buffer)
41
unsigned long vip_control1, vip_control2, vip_control3;
44
return CIM_STATUS_INVALIDPARAMS;
50
/* CONFIGURE CONTROL WORDS BASED ON MODE STRUCTURE */
51
/* Note that some of the input parameters match the register fields */
56
vip_control1 |= buffer->stream_enables;
58
/* VIP CAPTURE MODE */
60
vip_control1 |= buffer->operating_mode;
62
/* HANDLE PLANAR CAPTURE */
64
if (buffer->flags & VIP_MODEFLAG_PLANARCAPTURE) {
65
vip_control1 |= VIP_CONTROL1_PLANAR;
67
if (buffer->planar_capture == VIP_420CAPTURE_EVERYLINE) {
68
vip_control1 |= VIP_CONTROL1_DISABLE_DECIMATION;
70
else if (buffer->planar_capture == VIP_420CAPTURE_ALTERNATINGFIELDS) {
71
if (buffer->flags & VIP_MODEFLAG_PROGRESSIVE)
72
return CIM_STATUS_INVALIDPARAMS;
74
vip_control1 |= VIP_CONTROL1_DISABLE_DECIMATION;
75
vip_control3 |= VIP_CONTROL3_DECIMATE_EVEN;
77
else if (buffer->planar_capture != VIP_420CAPTURE_ALTERNATINGLINES)
78
return CIM_STATUS_INVALIDPARAMS;
80
/* CONFIGURE THE VIDEO FIFO THRESHOLD BASED ON THE FIFO DEPTH */
82
vip_control2 |= VIP_CONTROL2_DEFAULT_VIDTH_420 <<
83
VIP_CONTROL2_VIDTH_SHIFT;
87
vip_control2 |= VIP_CONTROL2_DEFAULT_VIDTH_422 <<
88
VIP_CONTROL2_VIDTH_SHIFT;
91
/* CONFIGURE DEFAULT ANCILARRY THRESHOLD AND VIDEO FLUSH VALUES */
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;
97
/* PROGRAM VIP OPTIONS */
98
/* The options are sanitized based on the current configuration. */
100
if (buffer->flags & VIP_MODEFLAG_PROGRESSIVE)
101
vip_control1 |= VIP_CONTROL1_NON_INTERLACED;
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;
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;
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;
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;
128
/* WRITE THE CONTROL REGISTERS */
129
/* The control registers are kept 'live' to allow separate instances of */
130
/* Cimarron to control the VIP hardware. */
132
WRITE_VIP32(VIP_CONTROL1, vip_control1);
133
WRITE_VIP32(VIP_CONTROL2, vip_control2);
134
WRITE_VIP32(VIP_CONTROL3, vip_control3);
136
/* CONFIGURE 601 PARAMETERS */
138
if (buffer->operating_mode == VIP_MODE_8BIT601 ||
139
buffer->operating_mode == VIP_MODE_16BIT601) {
140
vip_update_601_params(&buffer->vip601_settings);
143
return CIM_STATUS_OK;
146
/*---------------------------------------------------------------------------
147
* vip_update_601_params
149
* This routine configures all aspects of 601 VIP data capture, including
150
* start and stop timings and input polarities.
151
*--------------------------------------------------------------------------*/
154
vip_update_601_params(VIP_601PARAMS * buffer)
156
unsigned long vip_control3, vip_control1;
159
return CIM_STATUS_INVALIDPARAMS;
161
vip_control1 = READ_VIP32(VIP_CONTROL3);
162
vip_control3 = READ_VIP32(VIP_CONTROL3);
164
if (buffer->flags & VIP_MODEFLAG_VSYNCACTIVEHIGH)
165
vip_control3 |= VIP_CONTROL3_VSYNC_POLARITY;
167
vip_control3 &= ~VIP_CONTROL3_VSYNC_POLARITY;
168
if (buffer->flags & VIP_MODEFLAG_HSYNCACTIVEHIGH)
169
vip_control3 |= VIP_CONTROL3_HSYNC_POLARITY;
171
vip_control3 &= ~VIP_CONTROL3_HSYNC_POLARITY;
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));
186
/* SPECIAL CASE FOR HORIZONTAL DATA
187
* 601 horizontal parameters are based on the number of clocks and not
188
* the number of pixels.
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);
195
WRITE_VIP32(VIP_601_HORZ_END, buffer->horz_start + buffer->width + 3);
197
return CIM_STATUS_OK;
200
/*---------------------------------------------------------------------------
201
* vip_configure_capture_buffers
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
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.
212
* Review the Cimarron VIP API documentation to determine which buffer
213
* addresses are latched immediately.
214
*--------------------------------------------------------------------------*/
217
vip_configure_capture_buffers(int buffer_type, VIPINPUTBUFFER * buffer)
219
VIPINPUTBUFFER_ADDR *offsets;
220
unsigned long cur_buffer = buffer->current_buffer;
223
return CIM_STATUS_INVALIDPARAMS;
225
if (buffer_type == VIP_BUFFER_A || buffer_type == VIP_BUFFER_601) {
226
offsets = &buffer->offsets[VIP_BUFFER_TASK_A];
228
/* SET VIDEO PITCH */
230
WRITE_VIP32(VIP_TASKA_VID_PITCH,
231
offsets->y_pitch | (offsets->uv_pitch << 16));
233
/* SET BASE OFFSETS */
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);
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);
253
/* SET 4:2:0 OFFSETS */
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);
262
else if (buffer_type == VIP_BUFFER_B) {
263
offsets = &buffer->offsets[VIP_BUFFER_TASK_B];
265
/* SET VIDEO PITCH */
267
WRITE_VIP32(VIP_TASKB_VID_PITCH,
268
offsets->y_pitch | (offsets->uv_pitch << 16));
270
/* SET BASE OFFSETS */
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);
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);
290
/* SET 4:2:0 OFFSETS */
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);
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);
303
return CIM_STATUS_INVALIDPARAMS;
306
return CIM_STATUS_OK;
309
/*---------------------------------------------------------------------------
310
* vip_toggle_vip_video_offsets
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
*--------------------------------------------------------------------------*/
319
vip_toggle_video_offsets(int buffer_type, VIPINPUTBUFFER * buffer)
321
unsigned long cur_buffer = buffer->current_buffer;
322
VIPINPUTBUFFER_ADDR *offsets;
324
if (buffer_type == VIP_BUFFER_A) {
325
offsets = &buffer->offsets[VIP_BUFFER_TASK_A];
327
/* SET BASE OFFSETS */
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]);
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]);
339
else if (buffer_type == VIP_BUFFER_B) {
340
offsets = &buffer->offsets[VIP_BUFFER_TASK_B];
342
/* SET BASE OFFSETS */
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]);
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]);
354
else if (buffer_type == VIP_BUFFER_A_ODD) {
355
offsets = &buffer->offsets[VIP_BUFFER_TASK_A];
357
/* SET BASE OFFSETS */
359
if (buffer->flags & VIP_INPUTFLAG_INVERTPOLARITY)
360
WRITE_VIP32(VIP_TASKA_VID_ODD_BASE, offsets->even_base[cur_buffer]);
362
WRITE_VIP32(VIP_TASKA_VID_ODD_BASE, offsets->odd_base[cur_buffer]);
364
else if (buffer_type == VIP_BUFFER_A_EVEN) {
365
offsets = &buffer->offsets[VIP_BUFFER_TASK_A];
367
/* SET BASE OFFSETS */
369
if (buffer->flags & VIP_INPUTFLAG_INVERTPOLARITY)
370
WRITE_VIP32(VIP_TASKA_VID_EVEN_BASE, offsets->odd_base[cur_buffer]);
372
WRITE_VIP32(VIP_TASKA_VID_EVEN_BASE,
373
offsets->even_base[cur_buffer]);
375
else if (buffer_type == VIP_BUFFER_B_ODD) {
376
offsets = &buffer->offsets[VIP_BUFFER_TASK_B];
378
/* SET BASE OFFSETS */
380
if (buffer->flags & VIP_INPUTFLAG_INVERTPOLARITY)
381
WRITE_VIP32(VIP_TASKB_VID_ODD_BASE, offsets->even_base[cur_buffer]);
383
WRITE_VIP32(VIP_TASKB_VID_ODD_BASE, offsets->odd_base[cur_buffer]);
385
else if (buffer_type == VIP_BUFFER_B_EVEN) {
386
offsets = &buffer->offsets[VIP_BUFFER_TASK_B];
388
/* SET BASE OFFSETS */
390
if (buffer->flags & VIP_INPUTFLAG_INVERTPOLARITY)
391
WRITE_VIP32(VIP_TASKB_VID_EVEN_BASE, offsets->odd_base[cur_buffer]);
393
WRITE_VIP32(VIP_TASKB_VID_EVEN_BASE,
394
offsets->even_base[cur_buffer]);
397
return CIM_STATUS_INVALIDPARAMS;
399
return CIM_STATUS_OK;
402
/*---------------------------------------------------------------------------
403
* vip_set_capture_state
405
* This routine takes the current control word definition ( stored in locals )
406
* adds in the specified state, and writes the control word.
407
*--------------------------------------------------------------------------*/
410
vip_set_capture_state(unsigned long state)
412
unsigned long vip_control1, vip_control3;
414
/* UPDATE THE CURRENT CAPTURE MODE */
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);
421
WRITE_VIP32(VIP_CONTROL1, vip_control1);
423
if (state >= VIP_STARTCAPTUREATNEXTLINE) {
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.
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);
435
return CIM_STATUS_OK;
438
/*---------------------------------------------------------------------------
441
* This routine stops VIP capture and resets the VIP internal state.
442
*--------------------------------------------------------------------------*/
447
unsigned long timeout = 50000;
449
/* DISABLE AND CLEAR ALL VIP INTERRUPTS */
451
WRITE_VIP32(VIP_INTERRUPT, VIP_ALL_INTERRUPTS | (VIP_ALL_INTERRUPTS >> 16));
453
/* DISABLE VIP CAPTURE */
454
/* We will try to let the VIP FIFO flush before shutting it down. */
456
WRITE_VIP32(VIP_CONTROL1, 0);
459
if (READ_VIP32(VIP_STATUS) & VIP_STATUS_WRITES_COMPLETE)
463
/* RESET THE HARDWARE REGISTERS */
464
/* Note that we enable VIP reset to allow clock gating to lower VIP */
465
/* power consumption. */
467
WRITE_VIP32(VIP_CONTROL1, VIP_CONTROL1_RESET);
468
WRITE_VIP32(VIP_CONTROL3, VIP_CONTROL3_FIFO_RESET);
469
WRITE_VIP32(VIP_CONTROL2, 0);
471
return CIM_STATUS_OK;
474
/*---------------------------------------------------------------------------
477
* This routine sets the desired threshold or flush for the specified fifo.
478
*--------------------------------------------------------------------------*/
481
vip_configure_fifo(unsigned long fifo_type, unsigned long fifo_size)
483
unsigned long vip_control1, vip_control2;
485
vip_control1 = READ_VIP32(VIP_CONTROL1);
486
vip_control2 = READ_VIP32(VIP_CONTROL2);
489
case VIP_VIDEOTHRESHOLD:
490
vip_control2 &= ~VIP_CONTROL2_VIDTH_MASK;
492
(fifo_size << VIP_CONTROL2_VIDTH_SHIFT) & VIP_CONTROL2_VIDTH_MASK;
495
case VIP_ANCILLARYTHRESHOLD:
496
vip_control2 &= ~VIP_CONTROL2_ANCTH_MASK;
498
(fifo_size << VIP_CONTROL2_ANCTH_SHIFT) & VIP_CONTROL2_ANCTH_MASK;
502
vip_control1 &= ~VIP_CONTROL1_VID_FF_MASK;
504
((fifo_size >> 2) << VIP_CONTROL1_VID_FF_SHIFT) &
505
VIP_CONTROL1_VID_FF_MASK;
508
case VIP_ANCILLARYFLUSH:
509
vip_control1 &= ~VIP_CONTROL1_ANC_FF_MASK;
511
((fifo_size >> 2) << VIP_CONTROL1_ANC_FF_SHIFT) &
512
VIP_CONTROL1_ANC_FF_MASK;
516
return CIM_STATUS_INVALIDPARAMS;
519
WRITE_VIP32(VIP_CONTROL1, vip_control1);
520
WRITE_VIP32(VIP_CONTROL2, vip_control2);
522
return CIM_STATUS_OK;
525
/*---------------------------------------------------------------------------
526
* vip_set_interrupt_enable
528
* This routine accepts a mask of interrupts to be enabled/disabled and
531
* For each mask match, the interrupt will be enabled or disabled based on
533
*--------------------------------------------------------------------------*/
536
vip_set_interrupt_enable(unsigned long mask, int enable)
538
/* CHECK IF ANY VALID INTERRUPTS ARE BEING CHANGED */
540
if (mask & VIP_ALL_INTERRUPTS) {
541
unsigned long int_enable = READ_VIP32(VIP_INTERRUPT) & 0xFFFF;
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. */
549
int_enable &= ~(mask >> 16);
551
int_enable |= (mask >> 16);
553
WRITE_VIP32(VIP_INTERRUPT, int_enable);
556
return CIM_STATUS_OK;
559
/*---------------------------------------------------------------------------
560
* vip_set_vsync_error
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
*--------------------------------------------------------------------------*/
574
vip_set_vsync_error(unsigned long vertical_count, unsigned long window_before,
575
unsigned long window_after, int enable)
577
unsigned long vip_control2 = READ_VIP32(VIP_CONTROL2);
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.
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;
593
vip_control2 |= VIP_CONTROL2_VERTERROR_ENABLE;
595
WRITE_VIP32(VIP_VSYNC_ERR_COUNT, temp);
598
vip_control2 &= ~VIP_CONTROL2_VERTERROR_ENABLE;
600
WRITE_VIP32(VIP_CONTROL2, vip_control2);
602
return CIM_STATUS_OK;
605
/*---------------------------------------------------------------------------
606
* vip_max_address_enable
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
*--------------------------------------------------------------------------*/
615
vip_max_address_enable(unsigned long max_address, int enable)
617
unsigned long vip_control2 = READ_VIP32(VIP_CONTROL2);
620
/* ENABLE THE CONTROL BIT */
622
vip_control2 |= VIP_CONTROL2_ADD_ERROR_ENABLE;
624
WRITE_VIP32(VIP_MAX_ADDRESS, max_address & VIP_MAXADDR_MASK);
627
/* DISABLE DETECTION */
629
vip_control2 &= ~VIP_CONTROL2_ADD_ERROR_ENABLE;
631
WRITE_VIP32(VIP_CONTROL2, vip_control2);
633
return CIM_STATUS_OK;
636
/*---------------------------------------------------------------------------
637
* vip_set_loopback_enable
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
*--------------------------------------------------------------------------*/
645
vip_set_loopback_enable(int enable)
647
unsigned long vip_control2 = READ_VIP32(VIP_CONTROL2);
650
vip_control2 |= VIP_CONTROL2_LOOPBACK_ENABLE;
652
vip_control2 &= ~VIP_CONTROL2_LOOPBACK_ENABLE;
654
WRITE_VIP32(VIP_CONTROL2, vip_control2);
656
return CIM_STATUS_OK;
659
/*---------------------------------------------------------------------------
660
* vip_configure_genlock
662
* This routine configures genlock functionality.
663
*---------------------------------------------------------------------------*/
666
vip_configure_genlock(VIPGENLOCKBUFFER * buffer)
668
unsigned long vip_control1, vip_control2;
669
unsigned long unlock, genlk_ctl;
672
return CIM_STATUS_INVALIDPARAMS;
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);
679
/* UPDATE VIDEO DETECTION */
680
/* These flags are used to indicate the ways in which the VIP signal */
681
/* can be considered 'lost'. */
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;
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. */
691
vip_control2 |= buffer->field_to_vg;
692
vip_control2 |= buffer->vsync_to_vg;
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. */
700
if (buffer->enable_timeout)
701
genlk_ctl |= DC3_GC_GENLOCK_TO_ENABLE;
703
genlk_ctl &= ~DC3_GC_GENLOCK_TO_ENABLE;
705
genlk_ctl &= ~DC3_GC_GENLOCK_SKEW_MASK;
706
genlk_ctl |= buffer->genlock_skew & DC3_GC_GENLOCK_SKEW_MASK;
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);
714
return CIM_STATUS_OK;
717
/*---------------------------------------------------------------------------
718
* vip_set_genlock_enable
720
* This routine enables/disables genlock inside the VG.
721
*--------------------------------------------------------------------------*/
724
vip_set_genlock_enable(int enable)
726
unsigned long unlock, temp;
728
unlock = READ_REG32(DC3_UNLOCK);
729
temp = READ_REG32(DC3_GENLK_CTL);
732
temp |= DC3_GC_GENLOCK_ENABLE;
734
temp &= ~DC3_GC_GENLOCK_ENABLE;
736
WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE);
737
WRITE_REG32(DC3_GENLK_CTL, temp);
738
WRITE_REG32(DC3_UNLOCK, unlock);
740
return CIM_STATUS_OK;
743
/*---------------------------------------------------------------------------
744
* vip_set_power_characteristics
746
* This routine takes a VIPPOWERBUFFER structure, and selectively sets the
747
* GeodeLink power and/or Vip clock power states.
748
*--------------------------------------------------------------------------*/
751
vip_set_power_characteristics(VIPPOWERBUFFER * buffer)
756
return CIM_STATUS_INVALIDPARAMS;
758
q_word.low = q_word.high = 0;
760
/* ENABLE GEODELINK CLOCK GATING */
762
if (buffer->glink_clock_mode)
763
q_word.low |= VIP_MSR_POWER_GLINK;
765
/* ENABLE VIP CLOCK GATING */
767
if (buffer->vip_clock_mode)
768
q_word.low |= VIP_MSR_POWER_CLOCK;
770
/* WRITE THE NEW VALUE */
772
msr_write64(MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_PM, &q_word);
774
return CIM_STATUS_OK;
777
/*---------------------------------------------------------------------------
778
* vip_set_priority_characteristics
780
* This routine programs the VIP GeodeLink priority characteristics
781
*--------------------------------------------------------------------------*/
784
vip_set_priority_characteristics(VIPPRIORITYBUFFER * buffer)
789
return CIM_STATUS_INVALIDPARAMS;
791
q_word.low = q_word.high = 0;
793
q_word.low |= (buffer->secondary <<
794
VIP_MSR_MCR_SECOND_PRIORITY_SHIFT) &
795
VIP_MSR_MCR_SECOND_PRIORITY_MASK;
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;
801
msr_write64(MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_CONFIG, &q_word);
803
return CIM_STATUS_OK;
806
/*---------------------------------------------------------------------------
807
* vip_set_debug_characteristics
809
* This routine configures the debug data that is exposed over the diag bus.
810
*--------------------------------------------------------------------------*/
813
vip_set_debug_characteristics(VIPDEBUGBUFFER * buffer)
818
return CIM_STATUS_INVALIDPARAMS;
820
q_word.low = q_word.high = 0;
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;
831
msr_write64(MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_DIAG, &q_word);
833
return CIM_STATUS_OK;
836
/*---------------------------------------------------------------------------
837
* vip_configure_pages
839
* This routine sets the number of pages, and their offset from each other.
840
*--------------------------------------------------------------------------*/
843
vip_configure_pages(int page_count, unsigned long page_offset)
845
unsigned long vip_control2 = READ_VIP32(VIP_CONTROL2);
847
/* SET THE NEW PAGE COUNT */
849
vip_control2 &= ~VIP_CONTROL2_PAGECNT_MASK;
850
vip_control2 |= (page_count << VIP_CONTROL2_PAGECNT_SHIFT) &
851
VIP_CONTROL2_PAGECNT_MASK;
853
/* WRITE THE PAGE OFFSET */
855
WRITE_VIP32(VIP_CONTROL2, vip_control2);
856
WRITE_VIP32(VIP_PAGE_OFFSET, page_offset);
858
return CIM_STATUS_OK;
861
/*---------------------------------------------------------------------------
862
* vip_set_interrupt_line
864
* This routine sets the line at which a line interrupt should be generated.
865
*--------------------------------------------------------------------------*/
868
vip_set_interrupt_line(int line)
870
WRITE_VIP32(VIP_CURRENT_TARGET,
871
(line << VIP_CTARGET_TLINE_SHIFT) & VIP_CTARGET_TLINE_MASK);
873
return CIM_STATUS_OK;
876
/*---------------------------------------------------------------------------
879
* This routine does a one-shot enable of the VIP hardware. It is useful
880
* for handling unrecoverable VIP errors.
881
*--------------------------------------------------------------------------*/
886
unsigned long vip_control1, vip_control3;
888
/* INVERT THE PAUSE BIT */
890
vip_control1 = READ_VIP32(VIP_CONTROL1);
891
vip_control3 = READ_VIP32(VIP_CONTROL3);
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);
897
return CIM_STATUS_OK;
900
/*---------------------------------------------------------------------------
901
* vip_set_subwindow_enable
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
907
*--------------------------------------------------------------------------*/
910
vip_set_subwindow_enable(VIPSUBWINDOWBUFFER * buffer)
912
unsigned long vip_control2;
915
return CIM_STATUS_INVALIDPARAMS;
917
vip_control2 = READ_VIP32(VIP_CONTROL2);
918
if (buffer->enable) {
919
/* WRITE THE WINDOW VALUE */
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));
927
/* ENABLE IN THE CONTROL REGISTER */
929
vip_control2 |= VIP_CONTROL2_SWC_ENABLE;
932
/* DISABLE SUBWINDOW CAPTURE IN THE CONTROL REGISTER */
934
vip_control2 &= ~VIP_CONTROL2_SWC_ENABLE;
936
WRITE_VIP32(VIP_CONTROL2, vip_control2);
938
return CIM_STATUS_OK;
941
/*---------------------------------------------------------------------------
942
* vip_reset_interrupt_state
944
* This routine resets the state of one or more interrupts.
945
*--------------------------------------------------------------------------*/
948
vip_reset_interrupt_state(unsigned long interrupt_mask)
952
temp = READ_VIP32(VIP_INTERRUPT);
953
WRITE_VIP32(VIP_INTERRUPT, temp | (interrupt_mask & VIP_ALL_INTERRUPTS));
955
return CIM_STATUS_OK;
958
/*---------------------------------------------------------------------------
961
* This routine saves the necessary register contents in order to restore
962
* at a later point to the same state.
964
* NOTE: Capture state is forced to OFF in this routine
965
*--------------------------------------------------------------------------*/
968
vip_save_state(VIPSTATEBUFFER * save_buffer)
971
return CIM_STATUS_INVALIDPARAMS;
973
/* FORCE CAPTURE TO BE DISABLED */
975
vip_set_capture_state(VIP_STOPCAPTURE);
977
/* READ AND SAVE THE REGISTER CONTENTS */
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);
1008
/* READ ALL VIP MSRS */
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));
1019
return CIM_STATUS_OK;
1022
/*---------------------------------------------------------------------------
1025
* This routine restores the state of the vip registers - which were
1026
* previously saved using vip_save_state.
1027
*--------------------------------------------------------------------------*/
1030
vip_restore_state(VIPSTATEBUFFER * restore_buffer)
1032
if (!restore_buffer)
1033
return CIM_STATUS_OK;
1035
/* RESTORE THE REGISTERS */
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);
1063
/* RESTORE THE VIP MSRS */
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));
1074
/* RESTORE THE CONTROL WORDS LAST */
1076
WRITE_VIP32(VIP_CONTROL1, restore_buffer->control1);
1077
WRITE_VIP32(VIP_CONTROL2, restore_buffer->control2);
1078
WRITE_VIP32(VIP_CONTROL3, restore_buffer->control3);
1080
return CIM_STATUS_OK;
1083
/*---------------------------------------------------------------------------
1084
* vip_get_interrupt_state
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
*--------------------------------------------------------------------------*/
1092
vip_get_interrupt_state(void)
1094
unsigned long interrupt_mask = READ_VIP32(VIP_INTERRUPT);
1096
return (~(interrupt_mask << 16) & interrupt_mask & VIP_ALL_INTERRUPTS);
1099
/*---------------------------------------------------------------------------
1100
* vip_test_genlock_active
1102
* This routine reads the live status of the genlock connection between the
1103
* VIP and VG blocks.
1104
*--------------------------------------------------------------------------*/
1107
vip_test_genlock_active(void)
1109
if (READ_REG32(DC3_GENLK_CTL) & DC3_GC_GENLK_ACTIVE)
1115
/*---------------------------------------------------------------------------
1116
* vip_test_signal_status
1118
* This routine reads the live signal status coming into the VIP block.
1119
*--------------------------------------------------------------------------*/
1122
vip_test_signal_status(void)
1124
if (READ_REG32(DC3_GENLK_CTL) & DC3_GC_VIP_VID_OK)
1130
/*---------------------------------------------------------------------------
1131
* vip_get_current_field
1133
* This routine returns the current field being received.
1134
*--------------------------------------------------------------------------*/
1137
vip_get_current_field(void)
1139
if (READ_VIP32(VIP_STATUS) & VIP_STATUS_FIELD)
1140
return VIP_EVEN_FIELD;
1142
return VIP_ODD_FIELD;
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
*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
1151
#if CIMARRON_INCLUDE_VIP_READ_ROUTINES
1153
/*---------------------------------------------------------------------------
1154
* vip_get_current_mode
1156
* This routine reads the current VIP operating mode.
1157
*--------------------------------------------------------------------------*/
1160
vip_get_current_mode(VIPSETMODEBUFFER * buffer)
1162
unsigned long vip_control1, vip_control2, vip_control3;
1165
return CIM_STATUS_INVALIDPARAMS;
1167
vip_control1 = READ_VIP32(VIP_CONTROL1);
1168
vip_control2 = READ_VIP32(VIP_CONTROL2);
1169
vip_control3 = READ_VIP32(VIP_CONTROL3);
1171
/* READ CURRENT OPERATING MODE AND ENABLES */
1173
buffer->stream_enables = vip_control1 & VIP_ENABLE_ALL;
1174
buffer->operating_mode = vip_control1 & VIP_CONTROL1_MODE_MASK;
1176
/* READ CURRENT PLANAR CAPTURE SETTINGS */
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;
1186
buffer->planar_capture = VIP_420CAPTURE_EVERYLINE;
1189
buffer->planar_capture = VIP_420CAPTURE_ALTERNATINGLINES;
1192
/* READ MISCELLANEOUS FLAGS */
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;
1211
/* READ THE CURRENT VIP 601 SETTINGS */
1213
vip_get_601_configuration(&buffer->vip601_settings);
1215
return CIM_STATUS_OK;
1218
/*---------------------------------------------------------------------------
1219
* vip_get_601_configuration
1221
* This routine returns the current 601 configuration information.
1222
*--------------------------------------------------------------------------*/
1225
vip_get_601_configuration(VIP_601PARAMS * buffer)
1227
unsigned long vip_control3, vip_control1;
1230
return CIM_STATUS_INVALIDPARAMS;
1232
vip_control1 = READ_VIP32(VIP_CONTROL3);
1233
vip_control3 = READ_VIP32(VIP_CONTROL3);
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;
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;
1253
/* SPECIAL CASE FOR HORIZONTAL DATA
1254
* 601 horizontal parameters are based on the number of clocks and not
1255
* the number of pixels.
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;
1262
buffer->width = (READ_VIP32(VIP_601_HORZ_END) - buffer->horz_start - 3);
1264
return CIM_STATUS_OK;
1267
/*---------------------------------------------------------------------------
1268
* vip_get_buffer_configuration
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
*--------------------------------------------------------------------------*/
1276
vip_get_buffer_configuration(int buffer_type, VIPINPUTBUFFER * buffer)
1278
unsigned long cur_buffer = buffer->current_buffer;
1279
VIPINPUTBUFFER_ADDR *offsets;
1282
return CIM_STATUS_INVALIDPARAMS;
1284
if (buffer_type == VIP_BUFFER_A) {
1285
offsets = &buffer->offsets[VIP_BUFFER_TASK_A];
1287
/* READ VIDEO PITCH */
1289
offsets->y_pitch = READ_VIP32(VIP_TASKA_VID_PITCH) & 0xFFFF;
1290
offsets->uv_pitch = READ_VIP32(VIP_TASKA_VID_PITCH) >> 16;
1292
/* READ BASE OFFSETS */
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);
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);
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);
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);
1314
/* READ 4:2:0 OFFSETS */
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);
1323
else if (buffer_type == VIP_BUFFER_B) {
1324
offsets = &buffer->offsets[VIP_BUFFER_TASK_B];
1326
/* READ VIDEO PITCH */
1328
offsets->y_pitch = READ_VIP32(VIP_TASKB_VID_PITCH) & 0xFFFF;
1329
offsets->uv_pitch = READ_VIP32(VIP_TASKB_VID_PITCH) >> 16;
1331
/* READ BASE OFFSETS */
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);
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);
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);
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);
1353
/* READ 4:2:0 OFFSETS */
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);
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);
1366
return CIM_STATUS_INVALIDPARAMS;
1369
return CIM_STATUS_OK;
1372
/*---------------------------------------------------------------------------
1373
* vip_get_genlock_configuration
1375
* This routine reads the current genlock configuration.
1376
*--------------------------------------------------------------------------*/
1379
vip_get_genlock_configuration(VIPGENLOCKBUFFER * buffer)
1381
unsigned long vip_control1, vip_control2;
1382
unsigned long genlk_ctl;
1385
return CIM_STATUS_INVALIDPARAMS;
1387
genlk_ctl = READ_REG32(DC3_GENLK_CTL);
1388
vip_control1 = READ_VIP32(VIP_CONTROL1);
1389
vip_control2 = READ_VIP32(VIP_CONTROL2);
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'.
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;
1400
/* GENLOCK TIMEOUT ENABLE */
1402
buffer->enable_timeout = 0;
1403
if (genlk_ctl & DC3_GC_GENLOCK_TO_ENABLE)
1404
buffer->enable_timeout = 1;
1408
buffer->genlock_skew = genlk_ctl & DC3_GC_GENLOCK_SKEW_MASK;
1410
return CIM_STATUS_OK;
1413
/*---------------------------------------------------------------------------
1414
* vip_get_genlock_enable
1416
* This routine returns the current enable status of genlock in the VG.
1417
*--------------------------------------------------------------------------*/
1420
vip_get_genlock_enable(void)
1422
if (READ_REG32(DC3_GENLK_CTL) & DC3_GC_GENLOCK_ENABLE)
1428
/*---------------------------------------------------------------------------
1429
* vip_is_buffer_update_latched
1431
* This routine indicates whether changes to the VIP offsets have been
1432
* latched by the hardware.
1433
*--------------------------------------------------------------------------*/
1436
vip_is_buffer_update_latched(void)
1438
return (!(READ_VIP32(VIP_STATUS) & VIP_STATUS_BASEREG_NOTUPDT));
1441
/*---------------------------------------------------------------------------
1442
* vip_get_capture_state
1444
* This routine reads the current capture status of the VIP hardware.
1445
*--------------------------------------------------------------------------*/
1448
vip_get_capture_state(void)
1450
return ((READ_VIP32(VIP_CONTROL1) & VIP_CONTROL1_RUNMODE_MASK) >>
1451
VIP_CONTROL1_RUNMODE_SHIFT);
1454
/*---------------------------------------------------------------------------
1455
* vip_get_current_line
1457
* This routine returns the current line that is being processed.
1458
*--------------------------------------------------------------------------*/
1461
vip_get_current_line(void)
1463
return (READ_VIP32(VIP_CURRENT_TARGET) & VIP_CTARGET_CLINE_MASK);
1466
/*---------------------------------------------------------------------------
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
*--------------------------------------------------------------------------*/
1476
vip_read_fifo(unsigned long dwFifoAddress)
1478
unsigned long fifo_data;
1480
/* ENABLE FIFO ACCESS */
1482
vip_enable_fifo_access(1);
1484
/* NOW READ THE DATA */
1486
WRITE_VIP32(VIP_FIFO_ADDRESS, dwFifoAddress);
1487
fifo_data = READ_VIP32(VIP_FIFO_DATA);
1489
/* DISABLE FIFO ACCESS */
1491
vip_enable_fifo_access(0);
1496
/*---------------------------------------------------------------------------
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
*--------------------------------------------------------------------------*/
1507
vip_write_fifo(unsigned long dwFifoAddress, unsigned long dwFifoData)
1509
/* ENABLE FIFO ACCESS */
1511
vip_enable_fifo_access(1);
1513
/* WRITE THE FIFO DATA */
1515
WRITE_VIP32(VIP_FIFO_ADDRESS, dwFifoAddress);
1516
WRITE_VIP32(VIP_FIFO_DATA, dwFifoData);
1518
/* DISABLE FIFO ACCESS */
1520
vip_enable_fifo_access(0);
1522
return CIM_STATUS_OK;
1525
/*---------------------------------------------------------------------------
1526
* vip_enable_fifo_access
1528
* This routine enables/disables access to the vip fifo.
1529
* DIAGNOSTIC USE ONLY
1530
*--------------------------------------------------------------------------*/
1533
vip_enable_fifo_access(int enable)
1537
cw2 = READ_VIP32(VIP_CONTROL2);
1540
cw2 |= VIP_CONTROL2_FIFO_ACCESS;
1542
cw2 &= ~VIP_CONTROL2_FIFO_ACCESS;
1544
WRITE_VIP32(VIP_CONTROL2, cw2);
1546
return CIM_STATUS_OK;
1549
/*---------------------------------------------------------------------------
1550
* vip_get_power_characteristics
1552
* This routine returns the current VIP clock gating state in a
1554
*--------------------------------------------------------------------------*/
1557
vip_get_power_characteristics(VIPPOWERBUFFER * buffer)
1562
return CIM_STATUS_INVALIDPARAMS;
1564
/* READ THE EXISTING STATE */
1566
msr_read64(MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_PM, &q_word);
1568
/* DECODE THE CLOCK GATING BITS */
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);
1573
return CIM_STATUS_OK;
1576
/*---------------------------------------------------------------------------
1577
* vip_get_priority_characteristics
1579
* This routine returns the priority characteristics in the supplied
1580
* VIPPRIORITYBUFFER.
1581
*--------------------------------------------------------------------------*/
1584
vip_get_priority_characteristics(VIPPRIORITYBUFFER * buffer)
1589
return CIM_STATUS_INVALIDPARAMS;
1591
/* READ THE CURRENT STATE */
1593
msr_read64(MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_CONFIG, &q_word);
1595
/* DECODE THE PRIORITIES */
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;
1603
return CIM_STATUS_OK;
1606
/*---------------------------------------------------------------------------
1607
* vip_get_capability_characteristics
1609
* This routine returns revision information for the device.
1610
*--------------------------------------------------------------------------*/
1613
vip_get_capability_characteristics(VIPCAPABILITIESBUFFER * buffer)
1618
return CIM_STATUS_INVALIDPARAMS;
1620
/* READ THE CURRENT MSR CONTENTS */
1622
msr_read64(MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_CAP, &q_word);
1624
/* DECODE THE REVISIONS */
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;
1635
return CIM_STATUS_OK;