3 * Copyright (C) 2005 Advanced Micro Devices, Inc. All Rights Reserved.
10 * Cimarron VIP configuration routines.
15 /*---------------------------------------------------------------------------
18 * This routine initializes the internal module state and prepares the
19 * module for subsequent VIP orientated activities.
20 *---------------------------------------------------------------------------*/
22 int vip_initialize(VIPSETMODEBUFFER
*buffer
)
24 unsigned long vip_control1
, vip_control2
, vip_control3
;
27 return CIM_STATUS_INVALIDPARAMS
;
33 /* CONFIGURE CONTROL WORDS BASED ON MODE STRUCTURE */
34 /* Note that some of the input parameters match the register fields */
39 vip_control1
|= buffer
->stream_enables
;
41 /* VIP CAPTURE MODE */
43 vip_control1
|= buffer
->operating_mode
;
45 /* HANDLE PLANAR CAPTURE */
47 if (buffer
->flags
& VIP_MODEFLAG_PLANARCAPTURE
)
49 vip_control1
|= VIP_CONTROL1_PLANAR
;
51 if (buffer
->planar_capture
== VIP_420CAPTURE_EVERYLINE
)
53 vip_control1
|= VIP_CONTROL1_DISABLE_DECIMATION
;
55 else if (buffer
->planar_capture
== VIP_420CAPTURE_ALTERNATINGFIELDS
)
57 if (buffer
->flags
& VIP_MODEFLAG_PROGRESSIVE
)
58 return CIM_STATUS_INVALIDPARAMS
;
60 vip_control1
|= VIP_CONTROL1_DISABLE_DECIMATION
;
61 vip_control3
|= VIP_CONTROL3_DECIMATE_EVEN
;
63 else if (buffer
->planar_capture
!= VIP_420CAPTURE_ALTERNATINGLINES
)
64 return CIM_STATUS_INVALIDPARAMS
;
66 /* CONFIGURE THE VIDEO FIFO THRESHOLD BASED ON THE FIFO DEPTH */
68 vip_control2
|= VIP_CONTROL2_DEFAULT_VIDTH_420
<< VIP_CONTROL2_VIDTH_SHIFT
;
73 vip_control2
|= VIP_CONTROL2_DEFAULT_VIDTH_422
<< VIP_CONTROL2_VIDTH_SHIFT
;
76 /* CONFIGURE DEFAULT ANCILARRY THRESHOLD AND VIDEO FLUSH VALUES */
78 vip_control2
|= VIP_CONTROL2_DEFAULT_ANCTH
<< VIP_CONTROL2_ANCTH_SHIFT
;
79 vip_control1
|= VIP_CONTROL1_DEFAULT_ANC_FF
<< VIP_CONTROL1_ANC_FF_SHIFT
;
80 vip_control1
|= VIP_CONTROL1_DEFAULT_VID_FF
<< VIP_CONTROL1_VID_FF_SHIFT
;
82 /* PROGRAM VIP OPTIONS */
83 /* The options are sanitized based on the current configuration. */
85 if (buffer
->flags
& VIP_MODEFLAG_PROGRESSIVE
)
86 vip_control1
|= VIP_CONTROL1_NON_INTERLACED
;
89 if (buffer
->flags
& VIP_MODEFLAG_TOGGLEEACHFIELD
)
90 vip_control3
|= VIP_CONTROL3_BASE_UPDATE
;
91 if (buffer
->flags
& VIP_MODEFLAG_INVERTPOLARITY
)
92 vip_control2
|= VIP_CONTROL2_INVERT_POLARITY
;
95 if ((buffer
->operating_mode
== VIP_MODE_MSG
||
96 buffer
->operating_mode
== VIP_MODE_DATA
) &&
97 (buffer
->flags
& VIP_MODEFLAG_FLIPMESSAGEWHENFULL
))
99 vip_control1
|= VIP_CONTROL1_MSG_STRM_CTRL
;
102 else if (buffer
->operating_mode
== VIP_MODE_VIP2_8BIT
||
103 buffer
->operating_mode
== VIP_MODE_VIP2_16BIT
)
105 if (buffer
->flags
& VIP_MODEFLAG_ENABLEREPEATFLAG
)
106 vip_control2
|= VIP_CONTROL2_REPEAT_ENABLE
;
107 if (buffer
->flags
& VIP_MODEFLAG_INVERTTASKPOLARITY
)
108 vip_control3
|= VIP_CONTROL3_TASK_POLARITY
;
111 if (buffer
->flags
& VIP_MODEFLAG_DISABLEZERODETECT
)
112 vip_control1
|= VIP_CONTROL1_DISABLE_ZERO_DETECT
;
113 if (buffer
->flags
& VIP_MODEFLAG_10BITANCILLARY
)
114 vip_control2
|= VIP_CONTROL2_ANC10
;
116 /* WRITE THE CONTROL REGISTERS */
117 /* The control registers are kept 'live' to allow separate instances of */
118 /* Cimarron to control the VIP hardware. */
120 WRITE_VIP32 (VIP_CONTROL1
, vip_control1
);
121 WRITE_VIP32 (VIP_CONTROL2
, vip_control2
);
122 WRITE_VIP32 (VIP_CONTROL3
, vip_control3
);
124 /* CONFIGURE 601 PARAMETERS */
126 if (buffer
->operating_mode
== VIP_MODE_8BIT601
||
127 buffer
->operating_mode
== VIP_MODE_16BIT601
)
129 vip_update_601_params (&buffer
->vip601_settings
);
132 return CIM_STATUS_OK
;
135 /*---------------------------------------------------------------------------
136 * vip_update_601_params
138 * This routine configures all aspects of 601 VIP data capture, including
139 * start and stop timings and input polarities.
140 *---------------------------------------------------------------------------*/
142 int vip_update_601_params (VIP_601PARAMS
*buffer
)
144 unsigned long vip_control3
, vip_control1
;
147 return CIM_STATUS_INVALIDPARAMS
;
149 vip_control1
= READ_VIP32 (VIP_CONTROL3
);
150 vip_control3
= READ_VIP32 (VIP_CONTROL3
);
152 if (buffer
->flags
& VIP_MODEFLAG_VSYNCACTIVEHIGH
) vip_control3
|= VIP_CONTROL3_VSYNC_POLARITY
;
153 else vip_control3
&= ~VIP_CONTROL3_VSYNC_POLARITY
;
154 if (buffer
->flags
& VIP_MODEFLAG_HSYNCACTIVEHIGH
) vip_control3
|= VIP_CONTROL3_HSYNC_POLARITY
;
155 else vip_control3
&= ~VIP_CONTROL3_HSYNC_POLARITY
;
157 WRITE_VIP32 (VIP_CONTROL3
, vip_control3
);
158 WRITE_VIP32 (VIP_601_HORZ_START
, buffer
->horz_start
);
159 WRITE_VIP32 (VIP_601_VBI_START
, buffer
->vbi_start
);
160 WRITE_VIP32 (VIP_601_VBI_END
, buffer
->vbi_start
+ buffer
->vbi_height
- 1);
161 WRITE_VIP32 (VIP_601_EVEN_START_STOP
,
162 buffer
->vert_start_even
| ((buffer
->vert_start_even
+ buffer
->even_height
- 1) << 16));
163 WRITE_VIP32 (VIP_601_ODD_START_STOP
,
164 buffer
->vert_start_odd
| ((buffer
->vert_start_odd
+ buffer
->odd_height
- 1) << 16));
165 WRITE_VIP32 (VIP_ODD_FIELD_DETECT
,
166 buffer
->odd_detect_start
| (buffer
->odd_detect_end
<< 16));
168 /* SPECIAL CASE FOR HORIZONTAL DATA */
169 /* 601 horizontal parameters are based on the number of clocks and not the */
170 /* number of pixels. */
172 if ((vip_control1
& VIP_CONTROL1_MODE_MASK
) == VIP_MODE_16BIT601
)
173 WRITE_VIP32 (VIP_601_HORZ_END
, buffer
->horz_start
+ (buffer
->width
<< 1) + 3);
175 WRITE_VIP32 (VIP_601_HORZ_END
, buffer
->horz_start
+ buffer
->width
+ 3);
177 return CIM_STATUS_OK
;
180 /*---------------------------------------------------------------------------
181 * vip_configure_capture_buffers
183 * This routine configures the base offsets for video, ancillary or message
184 * mode capture. The input structure can also contain multiple offsets, such
185 * that the calling application can avoid updating the structure for each flip.
187 * The new buffer addresses are written to the hardware registers although
188 * they may not be latched immediately. Calling vip_is_buffer_update_latched
189 * allows the determination of whether the update has occured.
191 * Review the Cimarron VIP API documentation to determine which buffer addresses are
192 * latched immediately.
193 *---------------------------------------------------------------------------*/
195 int vip_configure_capture_buffers (int buffer_type
, VIPINPUTBUFFER
*buffer
)
197 VIPINPUTBUFFER_ADDR
*offsets
;
198 unsigned long cur_buffer
= buffer
->current_buffer
;
201 return CIM_STATUS_INVALIDPARAMS
;
203 if (buffer_type
== VIP_BUFFER_A
|| buffer_type
== VIP_BUFFER_601
)
205 offsets
= &buffer
->offsets
[VIP_BUFFER_TASK_A
];
207 /* SET VIDEO PITCH */
209 WRITE_VIP32 (VIP_TASKA_VID_PITCH
, offsets
->y_pitch
| (offsets
->uv_pitch
<< 16));
211 /* SET BASE OFFSETS */
213 if (buffer
->flags
& VIP_INPUTFLAG_INVERTPOLARITY
)
215 WRITE_VIP32 (VIP_TASKA_VID_ODD_BASE
, offsets
->even_base
[cur_buffer
]);
216 WRITE_VIP32 (VIP_TASKA_VID_EVEN_BASE
, offsets
->odd_base
[cur_buffer
]);
217 if (buffer
->flags
& VIP_INPUTFLAG_VBI
)
219 WRITE_VIP32 (VIP_TASKA_VBI_ODD_BASE
, offsets
->vbi_even_base
);
220 WRITE_VIP32 (VIP_TASKA_VBI_EVEN_BASE
, offsets
->vbi_odd_base
);
225 WRITE_VIP32 (VIP_TASKA_VID_ODD_BASE
, offsets
->odd_base
[cur_buffer
]);
226 WRITE_VIP32 (VIP_TASKA_VID_EVEN_BASE
, offsets
->even_base
[cur_buffer
]);
227 if (buffer
->flags
& VIP_INPUTFLAG_VBI
)
229 WRITE_VIP32 (VIP_TASKA_VBI_ODD_BASE
, offsets
->vbi_odd_base
);
230 WRITE_VIP32 (VIP_TASKA_VBI_EVEN_BASE
, offsets
->vbi_even_base
);
234 /* SET 4:2:0 OFFSETS */
236 if (buffer
->flags
& VIP_INPUTFLAG_PLANAR
)
238 WRITE_VIP32 (VIP_TASKA_U_OFFSET
, offsets
->odd_uoffset
);
239 WRITE_VIP32 (VIP_TASKA_V_OFFSET
, offsets
->odd_voffset
);
240 WRITE_VIP32 (VIP_TASKA_U_EVEN_OFFSET
, offsets
->even_uoffset
);
241 WRITE_VIP32 (VIP_TASKA_V_EVEN_OFFSET
, offsets
->even_voffset
);
244 else if (buffer_type
== VIP_BUFFER_B
)
246 offsets
= &buffer
->offsets
[VIP_BUFFER_TASK_B
];
248 /* SET VIDEO PITCH */
250 WRITE_VIP32 (VIP_TASKB_VID_PITCH
, offsets
->y_pitch
| (offsets
->uv_pitch
<< 16));
252 /* SET BASE OFFSETS */
254 if (buffer
->flags
& VIP_INPUTFLAG_INVERTPOLARITY
)
256 WRITE_VIP32 (VIP_TASKB_VID_ODD_BASE
, offsets
->even_base
[cur_buffer
]);
257 WRITE_VIP32 (VIP_TASKB_VID_EVEN_BASE
, offsets
->odd_base
[cur_buffer
]);
258 if (buffer
->flags
& VIP_INPUTFLAG_VBI
)
260 WRITE_VIP32 (VIP_TASKB_VBI_ODD_BASE
, offsets
->vbi_even_base
);
261 WRITE_VIP32 (VIP_TASKB_VBI_EVEN_BASE
, offsets
->vbi_odd_base
);
266 WRITE_VIP32 (VIP_TASKB_VID_ODD_BASE
, offsets
->odd_base
[cur_buffer
]);
267 WRITE_VIP32 (VIP_TASKB_VID_EVEN_BASE
, offsets
->even_base
[cur_buffer
]);
268 if (buffer
->flags
& VIP_INPUTFLAG_VBI
)
270 WRITE_VIP32 (VIP_TASKB_VBI_ODD_BASE
, offsets
->vbi_odd_base
);
271 WRITE_VIP32 (VIP_TASKB_VBI_EVEN_BASE
, offsets
->vbi_even_base
);
275 /* SET 4:2:0 OFFSETS */
277 if (buffer
->flags
& VIP_INPUTFLAG_PLANAR
)
279 WRITE_VIP32 (VIP_TASKB_U_OFFSET
, offsets
->odd_uoffset
);
280 WRITE_VIP32 (VIP_TASKB_V_OFFSET
, offsets
->odd_voffset
);
283 else if (buffer_type
== VIP_BUFFER_ANC
|| buffer_type
== VIP_BUFFER_MSG
)
285 WRITE_VIP32(VIP_ANC_MSG1_BASE
, buffer
->ancillaryData
.msg1_base
);
286 WRITE_VIP32(VIP_ANC_MSG2_BASE
, buffer
->ancillaryData
.msg2_base
);
287 WRITE_VIP32(VIP_ANC_MSG_SIZE
, buffer
->ancillaryData
.msg_size
);
291 return CIM_STATUS_INVALIDPARAMS
;
294 return CIM_STATUS_OK
;
297 /*---------------------------------------------------------------------------
298 * vip_toggle_vip_video_offsets
300 * This routine updates the offsets for video capture. It is a simplified
301 * version of vip_configure_capture_buffers that is designed to be called from
302 * interrupt service routines or other buffer flipping applications that
303 * require low latency.
304 *---------------------------------------------------------------------------*/
306 int vip_toggle_video_offsets (int buffer_type
, VIPINPUTBUFFER
*buffer
)
308 unsigned long cur_buffer
= buffer
->current_buffer
;
309 VIPINPUTBUFFER_ADDR
*offsets
;
311 if (buffer_type
== VIP_BUFFER_A
)
313 offsets
= &buffer
->offsets
[VIP_BUFFER_TASK_A
];
315 /* SET BASE OFFSETS */
317 if (buffer
->flags
& VIP_INPUTFLAG_INVERTPOLARITY
)
319 WRITE_VIP32 (VIP_TASKA_VID_ODD_BASE
, offsets
->even_base
[cur_buffer
]);
320 WRITE_VIP32 (VIP_TASKA_VID_EVEN_BASE
, offsets
->odd_base
[cur_buffer
]);
324 WRITE_VIP32 (VIP_TASKA_VID_ODD_BASE
, offsets
->odd_base
[cur_buffer
]);
325 WRITE_VIP32 (VIP_TASKA_VID_EVEN_BASE
, offsets
->even_base
[cur_buffer
]);
328 else if (buffer_type
== VIP_BUFFER_B
)
330 offsets
= &buffer
->offsets
[VIP_BUFFER_TASK_B
];
332 /* SET BASE OFFSETS */
334 if (buffer
->flags
& VIP_INPUTFLAG_INVERTPOLARITY
)
336 WRITE_VIP32 (VIP_TASKB_VID_ODD_BASE
, offsets
->even_base
[cur_buffer
]);
337 WRITE_VIP32 (VIP_TASKB_VID_EVEN_BASE
, offsets
->odd_base
[cur_buffer
]);
341 WRITE_VIP32 (VIP_TASKB_VID_ODD_BASE
, offsets
->odd_base
[cur_buffer
]);
342 WRITE_VIP32 (VIP_TASKB_VID_EVEN_BASE
, offsets
->even_base
[cur_buffer
]);
345 else if (buffer_type
== VIP_BUFFER_A_ODD
)
347 offsets
= &buffer
->offsets
[VIP_BUFFER_TASK_A
];
349 /* SET BASE OFFSETS */
351 if (buffer
->flags
& VIP_INPUTFLAG_INVERTPOLARITY
)
352 WRITE_VIP32 (VIP_TASKA_VID_ODD_BASE
, offsets
->even_base
[cur_buffer
]);
354 WRITE_VIP32 (VIP_TASKA_VID_ODD_BASE
, offsets
->odd_base
[cur_buffer
]);
356 else if (buffer_type
== VIP_BUFFER_A_EVEN
)
358 offsets
= &buffer
->offsets
[VIP_BUFFER_TASK_A
];
360 /* SET BASE OFFSETS */
362 if (buffer
->flags
& VIP_INPUTFLAG_INVERTPOLARITY
)
363 WRITE_VIP32 (VIP_TASKA_VID_EVEN_BASE
, offsets
->odd_base
[cur_buffer
]);
365 WRITE_VIP32 (VIP_TASKA_VID_EVEN_BASE
, offsets
->even_base
[cur_buffer
]);
367 else if (buffer_type
== VIP_BUFFER_B_ODD
)
369 offsets
= &buffer
->offsets
[VIP_BUFFER_TASK_B
];
371 /* SET BASE OFFSETS */
373 if (buffer
->flags
& VIP_INPUTFLAG_INVERTPOLARITY
)
374 WRITE_VIP32 (VIP_TASKB_VID_ODD_BASE
, offsets
->even_base
[cur_buffer
]);
376 WRITE_VIP32 (VIP_TASKB_VID_ODD_BASE
, offsets
->odd_base
[cur_buffer
]);
378 else if (buffer_type
== VIP_BUFFER_B_EVEN
)
380 offsets
= &buffer
->offsets
[VIP_BUFFER_TASK_B
];
382 /* SET BASE OFFSETS */
384 if (buffer
->flags
& VIP_INPUTFLAG_INVERTPOLARITY
)
385 WRITE_VIP32 (VIP_TASKB_VID_EVEN_BASE
, offsets
->odd_base
[cur_buffer
]);
387 WRITE_VIP32 (VIP_TASKB_VID_EVEN_BASE
, offsets
->even_base
[cur_buffer
]);
390 return CIM_STATUS_INVALIDPARAMS
;
392 return CIM_STATUS_OK
;
395 /*---------------------------------------------------------------------------
396 * vip_set_capture_state
398 * This routine takes the current control word definition ( stored in locals )
399 * adds in the specified state, and writes the control word.
400 *---------------------------------------------------------------------------*/
402 int vip_set_capture_state (unsigned long state
)
404 unsigned long vip_control1
, vip_control3
;
406 /* UPDATE THE CURRENT CAPTURE MODE */
408 vip_control1
= READ_VIP32 (VIP_CONTROL1
);
409 vip_control3
= READ_VIP32 (VIP_CONTROL3
);
410 vip_control1
&= ~VIP_CONTROL1_RUNMODE_MASK
;
411 vip_control1
|= (state
<< VIP_CONTROL1_RUNMODE_SHIFT
);
413 WRITE_VIP32 (VIP_CONTROL1
, vip_control1
);
415 if (state
>= VIP_STARTCAPTUREATNEXTLINE
)
417 /* WHACK VIP RESET */
418 /* The VIP can get confused when switching between capture settings, such as */
419 /* between linear and planar. We will thus whack VIP reset when enabling */
420 /* capture to ensure a pristine VIP state. */
422 WRITE_VIP32 (VIP_CONTROL1
, vip_control1
| VIP_CONTROL1_RESET
);
423 WRITE_VIP32 (VIP_CONTROL1
, vip_control1
& ~VIP_CONTROL1_RESET
);
424 WRITE_VIP32 (VIP_CONTROL3
, vip_control3
| VIP_CONTROL3_FIFO_RESET
);
427 return CIM_STATUS_OK
;
430 /*---------------------------------------------------------------------------
433 * This routine stops VIP capture and resets the VIP internal state.
434 *---------------------------------------------------------------------------*/
436 int vip_terminate (void)
438 unsigned long timeout
= 50000;
440 /* DISABLE AND CLEAR ALL VIP INTERRUPTS */
442 WRITE_VIP32 (VIP_INTERRUPT
, VIP_ALL_INTERRUPTS
| (VIP_ALL_INTERRUPTS
>> 16));
444 /* DISABLE VIP CAPTURE */
445 /* We will try to let the VIP FIFO flush before shutting it down. */
447 WRITE_VIP32 (VIP_CONTROL1
, 0);
451 if (READ_VIP32 (VIP_STATUS
) & VIP_STATUS_WRITES_COMPLETE
)
455 /* RESET THE HARDWARE REGISTERS */
456 /* Note that we enable VIP reset to allow clock gating to lower VIP */
457 /* power consumption. */
459 WRITE_VIP32 (VIP_CONTROL1
, VIP_CONTROL1_RESET
);
460 WRITE_VIP32 (VIP_CONTROL3
, VIP_CONTROL3_FIFO_RESET
);
461 WRITE_VIP32 (VIP_CONTROL2
, 0);
463 return CIM_STATUS_OK
;
466 /*---------------------------------------------------------------------------
469 * This routine sets the desired threshold or flush for the specified fifo.
470 *---------------------------------------------------------------------------*/
472 int vip_configure_fifo (unsigned long fifo_type
, unsigned long fifo_size
)
474 unsigned long vip_control1
, vip_control2
;
476 vip_control1
= READ_VIP32 (VIP_CONTROL1
);
477 vip_control2
= READ_VIP32 (VIP_CONTROL2
);
481 case VIP_VIDEOTHRESHOLD
:
482 vip_control2
&= ~VIP_CONTROL2_VIDTH_MASK
;
483 vip_control2
|= (fifo_size
<< VIP_CONTROL2_VIDTH_SHIFT
) & VIP_CONTROL2_VIDTH_MASK
;
486 case VIP_ANCILLARYTHRESHOLD
:
487 vip_control2
&= ~VIP_CONTROL2_ANCTH_MASK
;
488 vip_control2
|= (fifo_size
<< VIP_CONTROL2_ANCTH_SHIFT
) & VIP_CONTROL2_ANCTH_MASK
;
492 vip_control1
&= ~VIP_CONTROL1_VID_FF_MASK
;
493 vip_control1
|= ((fifo_size
>> 2) << VIP_CONTROL1_VID_FF_SHIFT
) & VIP_CONTROL1_VID_FF_MASK
;
496 case VIP_ANCILLARYFLUSH
:
497 vip_control1
&= ~VIP_CONTROL1_ANC_FF_MASK
;
498 vip_control1
|= ((fifo_size
>> 2) << VIP_CONTROL1_ANC_FF_SHIFT
) & VIP_CONTROL1_ANC_FF_MASK
;
502 return CIM_STATUS_INVALIDPARAMS
;
505 WRITE_VIP32 (VIP_CONTROL1
, vip_control1
);
506 WRITE_VIP32 (VIP_CONTROL2
, vip_control2
);
508 return CIM_STATUS_OK
;
511 /*---------------------------------------------------------------------------
512 * vip_set_interrupt_enable
514 * This routine accepts a mask of interrupts to be enabled/disabled and
517 * For each mask match, the interrupt will be enabled or disabled based on
519 *---------------------------------------------------------------------------*/
521 int vip_set_interrupt_enable (unsigned long mask
, int enable
)
523 /* CHECK IF ANY VALID INTERRUPTS ARE BEING CHANGED */
525 if (mask
& VIP_ALL_INTERRUPTS
)
527 unsigned long int_enable
= READ_VIP32(VIP_INTERRUPT
) & 0xFFFF;
529 /* SET OR CLEAR THE MASK BITS */
530 /* Note that the upper 16-bits of the register are 0 after this */
531 /* operation. This prevents us from indadvertently clearing a */
532 /* pending interrupt by enabling/disabling another one. */
534 if (enable
) int_enable
&= ~(mask
>> 16);
535 else int_enable
|= (mask
>> 16);
537 WRITE_VIP32 (VIP_INTERRUPT
, int_enable
);
540 return CIM_STATUS_OK
;
543 /*---------------------------------------------------------------------------
544 * vip_set_vsync_error
546 * This routine defines a region that is used to determine if the vsync is
547 * within an acceptable range. This definition is accomplished using
548 * a count and a vertical window. The count specifies the exact number
549 * of clocks expected for one field. The window parameters specify the number
550 * of clocks variation allowed before and after the expected vsync. For
551 * example, if vertical_count is 1000, window_before is 5 and window_after
552 * is 12, VSync will be considered valid if it occurs between 995 and 1012
553 * clocks after the last VSync. The total window size (window_before + window_after)
555 *---------------------------------------------------------------------------*/
557 int vip_set_vsync_error (unsigned long vertical_count
, unsigned long window_before
,
558 unsigned long window_after
, int enable
)
560 unsigned long vip_control2
= READ_VIP32 (VIP_CONTROL2
);
565 /* CREATE THE VERTICAL WINDOW */
566 /* The VIP uses two counters. The first counter defines the minimum clock count */
567 /* before a valid VSync can occur. The second counter starts after the first */
568 /* completes and defines the acceptable region of variation. */
570 temp
= ((window_before
+ window_after
) << VIP_VSYNC_ERR_WINDOW_SHIFT
) & VIP_VSYNC_ERR_WINDOW_MASK
;
571 temp
|= (vertical_count
- window_before
) & VIP_VSYNC_ERR_COUNT_MASK
;
573 vip_control2
|= VIP_CONTROL2_VERTERROR_ENABLE
;
575 WRITE_VIP32(VIP_VSYNC_ERR_COUNT
, temp
);
579 vip_control2
&= ~VIP_CONTROL2_VERTERROR_ENABLE
;
581 WRITE_VIP32 (VIP_CONTROL2
, vip_control2
);
583 return CIM_STATUS_OK
;
586 /*---------------------------------------------------------------------------
587 * vip_max_address_enable
589 * This routine specifies the maximum address to which the the hardware should
590 * write during data storage. If this value is exceeded an error is generated,
591 * (this may be monitored using the appropriate interrupt flags - see
592 * vip_set_interrupt_enable)
593 *---------------------------------------------------------------------------*/
595 int vip_max_address_enable (unsigned long max_address
, int enable
)
597 unsigned long vip_control2
= READ_VIP32 (VIP_CONTROL2
);
601 /* ENABLE THE CONTROL BIT */
603 vip_control2
|= VIP_CONTROL2_ADD_ERROR_ENABLE
;
605 WRITE_VIP32(VIP_MAX_ADDRESS
, max_address
& VIP_MAXADDR_MASK
);
609 /* DISABLE DETECTION */
611 vip_control2
&= ~VIP_CONTROL2_ADD_ERROR_ENABLE
;
613 WRITE_VIP32 (VIP_CONTROL2
, vip_control2
);
615 return CIM_STATUS_OK
;
618 /*---------------------------------------------------------------------------
619 * vip_set_loopback_enable
621 * This routine enables/disables internal loopback functionality. When
622 * loopback is enabled, the VOP outputs are rerouted to the VIP inputs
623 * internal to the chip. No loopback connector is required.
624 *---------------------------------------------------------------------------*/
626 int vip_set_loopback_enable(int enable
)
628 unsigned long vip_control2
= READ_VIP32 (VIP_CONTROL2
);
630 if (enable
) vip_control2
|= VIP_CONTROL2_LOOPBACK_ENABLE
;
631 else vip_control2
&= ~VIP_CONTROL2_LOOPBACK_ENABLE
;
633 WRITE_VIP32 (VIP_CONTROL2
, vip_control2
);
635 return CIM_STATUS_OK
;
638 /*---------------------------------------------------------------------------
639 * vip_configure_genlock
641 * This routine configures genlock functionality.
642 *---------------------------------------------------------------------------*/
644 int vip_configure_genlock (VIPGENLOCKBUFFER
*buffer
)
646 unsigned long vip_control1
, vip_control2
;
647 unsigned long unlock
, genlk_ctl
;
650 return CIM_STATUS_INVALIDPARAMS
;
652 unlock
= READ_REG32 (DC3_UNLOCK
);
653 genlk_ctl
= READ_REG32 (DC3_GENLK_CTL
);
654 vip_control1
= READ_VIP32 (VIP_CONTROL1
);
655 vip_control2
= READ_VIP32 (VIP_CONTROL2
);
657 /* UPDATE VIDEO DETECTION */
658 /* These flags are used to indicate the ways in which the VIP signal can */
659 /* be considered 'lost'. */
661 vip_control1
&= ~VIP_CONTROL1_VDE_FF_MASK
;
662 vip_control2
&= ~(VIP_CONTROL2_FIELD2VG_MASK
| VIP_CONTROL2_SYNC2VG_MASK
);
663 vip_control1
|= buffer
->vip_signal_loss
;
665 /* UPDATE FIELD AND VSYNC INFORMATION */
666 /* These flags control how and when the even/odd field and Vsync */
667 /* information is communicated to the VG. */
669 vip_control2
|= buffer
->field_to_vg
;
670 vip_control2
|= buffer
->vsync_to_vg
;
672 /* ENABLE OR DISABLE GENLOCK TIMEOUT */
673 /* Enabling genlock timeout allows the VG to revert to its own sync */
674 /* timings when the VIP input is lost. Note that the VIP will not */
675 /* know the signal is lost unless the appropriate error detection */
676 /* flags have been enabled inside vip_initialize. */
678 if (buffer
->enable_timeout
) genlk_ctl
|= DC3_GC_GENLOCK_TO_ENABLE
;
679 else genlk_ctl
&= ~DC3_GC_GENLOCK_TO_ENABLE
;
681 genlk_ctl
&= ~DC3_GC_GENLOCK_SKEW_MASK
;
682 genlk_ctl
|= buffer
->genlock_skew
& DC3_GC_GENLOCK_SKEW_MASK
;
684 WRITE_REG32 (DC3_UNLOCK
, DC3_UNLOCK_VALUE
);
685 WRITE_REG32 (DC3_GENLK_CTL
, genlk_ctl
);
686 WRITE_VIP32 (VIP_CONTROL1
, vip_control1
);
687 WRITE_VIP32 (VIP_CONTROL2
, vip_control2
);
688 WRITE_REG32 (DC3_UNLOCK
, unlock
);
690 return CIM_STATUS_OK
;
693 /*---------------------------------------------------------------------------
694 * vip_set_genlock_enable
696 * This routine enables/disables genlock inside the VG.
697 *---------------------------------------------------------------------------*/
699 int vip_set_genlock_enable (int enable
)
701 unsigned long unlock
, temp
;
703 unlock
= READ_REG32 (DC3_UNLOCK
);
704 temp
= READ_REG32 (DC3_GENLK_CTL
);
706 if (enable
) temp
|= DC3_GC_GENLOCK_ENABLE
;
707 else temp
&= ~DC3_GC_GENLOCK_ENABLE
;
709 WRITE_REG32 (DC3_UNLOCK
, DC3_UNLOCK_VALUE
);
710 WRITE_REG32 (DC3_GENLK_CTL
, temp
);
711 WRITE_REG32 (DC3_UNLOCK
, unlock
);
713 return CIM_STATUS_OK
;
716 /*---------------------------------------------------------------------------
717 * vip_set_power_characteristics
719 * This routine takes a VIPPOWERBUFFER structure, and selectively sets the
720 * GeodeLink power and/or Vip clock power states.
721 *---------------------------------------------------------------------------*/
723 int vip_set_power_characteristics (VIPPOWERBUFFER
*buffer
)
728 return CIM_STATUS_INVALIDPARAMS
;
730 q_word
.low
= q_word
.high
= 0;
732 /* ENABLE GEODELINK CLOCK GATING */
734 if (buffer
->glink_clock_mode
)
735 q_word
.low
|= VIP_MSR_POWER_GLINK
;
737 /* ENABLE VIP CLOCK GATING */
739 if (buffer
->vip_clock_mode
)
740 q_word
.low
|= VIP_MSR_POWER_CLOCK
;
742 /* WRITE THE NEW VALUE */
744 msr_write64 (MSR_DEVICE_GEODELX_VIP
, MSR_GEODELINK_PM
, &q_word
);
746 return CIM_STATUS_OK
;
749 /*---------------------------------------------------------------------------
750 * vip_set_priority_characteristics
752 * This routine programs the VIP GeodeLink priority characteristics
753 *---------------------------------------------------------------------------*/
755 int vip_set_priority_characteristics (VIPPRIORITYBUFFER
*buffer
)
760 return CIM_STATUS_INVALIDPARAMS
;
762 q_word
.low
= q_word
.high
= 0;
764 q_word
.low
|= (buffer
->secondary
<< VIP_MSR_MCR_SECOND_PRIORITY_SHIFT
) & VIP_MSR_MCR_SECOND_PRIORITY_MASK
;
765 q_word
.low
|= (buffer
->primary
<< VIP_MSR_MCR_PRIMARY_PRIORITY_SHIFT
) & VIP_MSR_MCR_PRIMARY_PRIORITY_MASK
;
766 q_word
.low
|= (buffer
->pid
<< VIP_MSR_MCR_PID_SHIFT
) & VIP_MSR_MCR_PID_MASK
;
768 msr_write64 (MSR_DEVICE_GEODELX_VIP
, MSR_GEODELINK_CONFIG
, &q_word
);
770 return CIM_STATUS_OK
;
773 /*---------------------------------------------------------------------------
774 * vip_set_debug_characteristics
776 * This routine configures the debug data that is exposed over the diag bus.
777 *---------------------------------------------------------------------------*/
779 int vip_set_debug_characteristics (VIPDEBUGBUFFER
*buffer
)
784 return CIM_STATUS_INVALIDPARAMS
;
786 q_word
.low
= q_word
.high
= 0;
788 q_word
.high
|= (buffer
->bist
<< VIP_MSR_DIAG_BIST_SHIFT
) & VIP_MSR_DIAG_BIST_WMASK
;
789 q_word
.low
|= (buffer
->enable_upper
? VIP_MSR_DIAG_MSB_ENABLE
: 0x00000000);
790 q_word
.low
|= (buffer
->select_upper
<< VIP_MSR_DIAG_SEL_UPPER_SHIFT
) & VIP_MSR_DIAG_SEL_UPPER_MASK
;
791 q_word
.low
|= (buffer
->enable_lower
? VIP_MSR_DIAG_LSB_ENABLE
: 0x00000000 );
792 q_word
.low
|= (buffer
->select_lower
<< VIP_MSR_DIAG_SEL_LOWER_SHIFT
) & VIP_MSR_DIAG_SEL_LOWER_MASK
;
794 msr_write64 (MSR_DEVICE_GEODELX_VIP
, MSR_GEODELINK_DIAG
, &q_word
);
796 return CIM_STATUS_OK
;
799 /*---------------------------------------------------------------------------
800 * vip_configure_pages
802 * This routine sets the number of pages, and their offset from each other.
803 *---------------------------------------------------------------------------*/
805 int vip_configure_pages (int page_count
, unsigned long page_offset
)
807 unsigned long vip_control2
= READ_VIP32 (VIP_CONTROL2
);
809 /* SET THE NEW PAGE COUNT */
811 vip_control2
&= ~VIP_CONTROL2_PAGECNT_MASK
;
812 vip_control2
|= (page_count
<< VIP_CONTROL2_PAGECNT_SHIFT
) & VIP_CONTROL2_PAGECNT_MASK
;
814 /* WRITE THE PAGE OFFSET */
816 WRITE_VIP32 (VIP_CONTROL2
, vip_control2
);
817 WRITE_VIP32 (VIP_PAGE_OFFSET
, page_offset
);
819 return CIM_STATUS_OK
;
822 /*---------------------------------------------------------------------------
823 * vip_set_interrupt_line
825 * This routine sets the line at which a line interrupt should be generated.
826 *---------------------------------------------------------------------------*/
828 int vip_set_interrupt_line (int line
)
830 WRITE_VIP32 (VIP_CURRENT_TARGET
, (line
<< VIP_CTARGET_TLINE_SHIFT
) & VIP_CTARGET_TLINE_MASK
);
832 return CIM_STATUS_OK
;
835 /*---------------------------------------------------------------------------
838 * This routine does a one-shot enable of the VIP hardware. It is useful
839 * for handling unrecoverable VIP errors.
840 *---------------------------------------------------------------------------*/
844 unsigned long vip_control1
, vip_control3
;
846 /* INVERT THE PAUSE BIT */
848 vip_control1
= READ_VIP32 (VIP_CONTROL1
);
849 vip_control3
= READ_VIP32 (VIP_CONTROL3
);
851 WRITE_VIP32 (VIP_CONTROL1
, vip_control1
| VIP_CONTROL1_RESET
);
852 WRITE_VIP32 (VIP_CONTROL1
, vip_control1
& ~VIP_CONTROL1_RESET
);
853 WRITE_VIP32 (VIP_CONTROL3
, vip_control3
| VIP_CONTROL3_FIFO_RESET
);
855 return CIM_STATUS_OK
;
858 /*---------------------------------------------------------------------------
859 * vip_set_subwindow_enable
861 * This routine turns on SubWindow capture, that is a portion of the incoming
862 * signal is captured rather than the entire frame. The window always has
863 * the same width as the frame, only the vertical component can be
865 *---------------------------------------------------------------------------*/
867 int vip_set_subwindow_enable (VIPSUBWINDOWBUFFER
*buffer
)
869 unsigned long vip_control2
;
872 return CIM_STATUS_INVALIDPARAMS
;
874 vip_control2
= READ_VIP32 (VIP_CONTROL2
);
877 /* WRITE THE WINDOW VALUE */
879 WRITE_VIP32(VIP_VERTICAL_START_STOP
,
880 ((buffer
->stop
<< VIP_VSTART_VERTEND_SHIFT
) & VIP_VSTART_VERTEND_MASK
) |
881 ((buffer
->start
<< VIP_VSTART_VERTSTART_SHIFT
) & VIP_VSTART_VERTSTART_MASK
));
883 /* ENABLE IN THE CONTROL REGISTER */
885 vip_control2
|= VIP_CONTROL2_SWC_ENABLE
;
889 /* DISABLE SUBWINDOW CAPTURE IN THE CONTROL REGISTER */
891 vip_control2
&= ~VIP_CONTROL2_SWC_ENABLE
;
893 WRITE_VIP32 (VIP_CONTROL2
, vip_control2
);
895 return CIM_STATUS_OK
;
898 /*---------------------------------------------------------------------------
899 * vip_reset_interrupt_state
901 * This routine resets the state of one or more interrupts.
902 *---------------------------------------------------------------------------*/
904 int vip_reset_interrupt_state(unsigned long interrupt_mask
)
908 temp
= READ_VIP32(VIP_INTERRUPT
);
909 WRITE_VIP32 (VIP_INTERRUPT
, temp
| (interrupt_mask
& VIP_ALL_INTERRUPTS
));
911 return CIM_STATUS_OK
;
914 /*---------------------------------------------------------------------------
917 * This routine saves the necessary register contents in order to restore
918 * at a later point to the same state.
920 * NOTE: Capture state is forced to OFF in this routine
921 *---------------------------------------------------------------------------*/
923 int vip_save_state(VIPSTATEBUFFER
*save_buffer
)
926 return CIM_STATUS_INVALIDPARAMS
;
928 /* FORCE CAPTURE TO BE DISABLED */
930 vip_set_capture_state (VIP_STOPCAPTURE
);
932 /* READ AND SAVE THE REGISTER CONTENTS */
934 save_buffer
->control1
= READ_VIP32(VIP_CONTROL1
);
935 save_buffer
->control2
= READ_VIP32(VIP_CONTROL2
);
936 save_buffer
->vip_int
= READ_VIP32(VIP_INTERRUPT
);
937 save_buffer
->current_target
= READ_VIP32(VIP_CURRENT_TARGET
);
938 save_buffer
->max_address
= READ_VIP32(VIP_MAX_ADDRESS
);
939 save_buffer
->taska_evenbase
= READ_VIP32(VIP_TASKA_VID_EVEN_BASE
);
940 save_buffer
->taska_oddbase
= READ_VIP32(VIP_TASKA_VID_ODD_BASE
);
941 save_buffer
->taska_vbi_evenbase
= READ_VIP32(VIP_TASKA_VBI_EVEN_BASE
);
942 save_buffer
->taska_vbi_oddbase
= READ_VIP32(VIP_TASKA_VBI_ODD_BASE
);
943 save_buffer
->taska_data_pitch
= READ_VIP32(VIP_TASKA_VID_PITCH
);
944 save_buffer
->control3
= READ_VIP32(VIP_CONTROL3
);
945 save_buffer
->taska_v_oddoffset
= READ_VIP32(VIP_TASKA_U_OFFSET
);
946 save_buffer
->taska_u_oddoffset
= READ_VIP32(VIP_TASKA_V_OFFSET
);
947 save_buffer
->taskb_evenbase
= READ_VIP32(VIP_TASKB_VID_EVEN_BASE
);
948 save_buffer
->taskb_oddbase
= READ_VIP32(VIP_TASKB_VID_ODD_BASE
);
949 save_buffer
->taskb_vbi_evenbase
= READ_VIP32(VIP_TASKB_VBI_EVEN_BASE
);
950 save_buffer
->taskb_vbi_oddbase
= READ_VIP32(VIP_TASKB_VBI_ODD_BASE
);
951 save_buffer
->taskb_pitch
= READ_VIP32(VIP_TASKB_VID_PITCH
);
952 save_buffer
->taskb_voffset
= READ_VIP32(VIP_TASKB_U_OFFSET
);
953 save_buffer
->taskb_uoffset
= READ_VIP32(VIP_TASKB_V_OFFSET
);
954 save_buffer
->msg1_base
= READ_VIP32(VIP_ANC_MSG1_BASE
);
955 save_buffer
->msg2_base
= READ_VIP32(VIP_ANC_MSG2_BASE
);
956 save_buffer
->msg_size
= READ_VIP32(VIP_ANC_MSG_SIZE
);
957 save_buffer
->page_offset
= READ_VIP32(VIP_PAGE_OFFSET
);
958 save_buffer
->vert_start_stop
= READ_VIP32(VIP_VERTICAL_START_STOP
);
959 save_buffer
->vsync_err_count
= READ_VIP32(VIP_VSYNC_ERR_COUNT
);
960 save_buffer
->taska_u_evenoffset
= READ_VIP32(VIP_TASKA_U_EVEN_OFFSET
);
961 save_buffer
->taska_v_evenoffset
= READ_VIP32(VIP_TASKA_V_EVEN_OFFSET
);
963 /* READ ALL VIP MSRS */
965 msr_read64 (MSR_DEVICE_GEODELX_VIP
, MSR_GEODELINK_CONFIG
, &(save_buffer
->msr_config
));
966 msr_read64 (MSR_DEVICE_GEODELX_VIP
, MSR_GEODELINK_SMI
, &(save_buffer
->msr_smi
));
967 msr_read64 (MSR_DEVICE_GEODELX_VIP
, MSR_GEODELINK_PM
, &(save_buffer
->msr_pm
));
968 msr_read64 (MSR_DEVICE_GEODELX_VIP
, MSR_GEODELINK_DIAG
, &(save_buffer
->msr_diag
));
970 return CIM_STATUS_OK
;
973 /*---------------------------------------------------------------------------
976 * This routine restores the state of the vip registers - which were
977 * previously saved using vip_save_state.
978 *---------------------------------------------------------------------------*/
980 int vip_restore_state (VIPSTATEBUFFER
*restore_buffer
)
983 return CIM_STATUS_OK
;
985 /* RESTORE THE REGISTERS */
987 WRITE_VIP32(VIP_CURRENT_TARGET
, restore_buffer
->current_target
);
988 WRITE_VIP32(VIP_MAX_ADDRESS
, restore_buffer
->max_address
);
989 WRITE_VIP32(VIP_TASKA_VID_EVEN_BASE
, restore_buffer
->taska_evenbase
);
990 WRITE_VIP32(VIP_TASKA_VID_ODD_BASE
, restore_buffer
->taska_oddbase
);
991 WRITE_VIP32(VIP_TASKA_VBI_EVEN_BASE
, restore_buffer
->taska_vbi_evenbase
);
992 WRITE_VIP32(VIP_TASKA_VBI_ODD_BASE
, restore_buffer
->taska_vbi_oddbase
);
993 WRITE_VIP32(VIP_TASKA_VID_PITCH
, restore_buffer
->taska_data_pitch
);
994 WRITE_VIP32(VIP_CONTROL3
, restore_buffer
->control3
);
995 WRITE_VIP32(VIP_TASKA_U_OFFSET
, restore_buffer
->taska_v_oddoffset
);
996 WRITE_VIP32(VIP_TASKA_V_OFFSET
, restore_buffer
->taska_u_oddoffset
);
997 WRITE_VIP32(VIP_TASKB_VID_EVEN_BASE
, restore_buffer
->taskb_evenbase
);
998 WRITE_VIP32(VIP_TASKB_VID_ODD_BASE
, restore_buffer
->taskb_oddbase
);
999 WRITE_VIP32(VIP_TASKB_VBI_EVEN_BASE
, restore_buffer
->taskb_vbi_evenbase
);
1000 WRITE_VIP32(VIP_TASKB_VBI_ODD_BASE
, restore_buffer
->taskb_vbi_oddbase
);
1001 WRITE_VIP32(VIP_TASKB_VID_PITCH
, restore_buffer
->taskb_pitch
);
1002 WRITE_VIP32(VIP_TASKB_U_OFFSET
, restore_buffer
->taskb_voffset
);
1003 WRITE_VIP32(VIP_TASKB_V_OFFSET
, restore_buffer
->taskb_uoffset
);
1004 WRITE_VIP32(VIP_ANC_MSG1_BASE
, restore_buffer
->msg1_base
);
1005 WRITE_VIP32(VIP_ANC_MSG2_BASE
, restore_buffer
->msg2_base
);
1006 WRITE_VIP32(VIP_ANC_MSG_SIZE
, restore_buffer
->msg_size
);
1007 WRITE_VIP32(VIP_PAGE_OFFSET
, restore_buffer
->page_offset
);
1008 WRITE_VIP32(VIP_VERTICAL_START_STOP
, restore_buffer
->vert_start_stop
);
1009 WRITE_VIP32(VIP_VSYNC_ERR_COUNT
, restore_buffer
->vsync_err_count
);
1010 WRITE_VIP32(VIP_TASKA_U_EVEN_OFFSET
, restore_buffer
->taska_u_evenoffset
);
1011 WRITE_VIP32(VIP_TASKA_V_EVEN_OFFSET
, restore_buffer
->taska_v_evenoffset
);
1013 /* RESTORE THE VIP MSRS */
1015 msr_write64 (MSR_DEVICE_GEODELX_VIP
, MSR_GEODELINK_CONFIG
, &(restore_buffer
->msr_config
));
1016 msr_write64 (MSR_DEVICE_GEODELX_VIP
, MSR_GEODELINK_SMI
, &(restore_buffer
->msr_smi
));
1017 msr_write64 (MSR_DEVICE_GEODELX_VIP
, MSR_GEODELINK_PM
, &(restore_buffer
->msr_pm
));
1018 msr_write64 (MSR_DEVICE_GEODELX_VIP
, MSR_GEODELINK_DIAG
, &(restore_buffer
->msr_diag
));
1020 /* RESTORE THE CONTROL WORDS LAST */
1022 WRITE_VIP32(VIP_CONTROL1
, restore_buffer
->control1
);
1023 WRITE_VIP32(VIP_CONTROL2
, restore_buffer
->control2
);
1024 WRITE_VIP32(VIP_CONTROL3
, restore_buffer
->control3
);
1026 return CIM_STATUS_OK
;
1029 /*---------------------------------------------------------------------------
1030 * vip_get_interrupt_state
1032 * This routine returns the current interrupt state of the system. The
1033 * rv can be tested with the following flags to determine if the appropriate
1034 * event has occured.
1035 *---------------------------------------------------------------------------*/
1037 unsigned long vip_get_interrupt_state(void)
1039 unsigned long interrupt_mask
= READ_VIP32(VIP_INTERRUPT
);
1041 return (~(interrupt_mask
<< 16) & interrupt_mask
& VIP_ALL_INTERRUPTS
);
1044 /*---------------------------------------------------------------------------
1045 * vip_test_genlock_active
1047 * This routine reads the live status of the genlock connection between the VIP
1049 *---------------------------------------------------------------------------*/
1051 int vip_test_genlock_active (void)
1053 if (READ_REG32 (DC3_GENLK_CTL
) & DC3_GC_GENLK_ACTIVE
)
1059 /*---------------------------------------------------------------------------
1060 * vip_test_signal_status
1062 * This routine reads the live signal status coming into the VIP block.
1063 *---------------------------------------------------------------------------*/
1065 int vip_test_signal_status (void)
1067 if (READ_REG32 (DC3_GENLK_CTL
) & DC3_GC_VIP_VID_OK
)
1073 /*---------------------------------------------------------------------------
1074 * vip_get_current_field
1076 * This routine returns the current field being received.
1077 *---------------------------------------------------------------------------*/
1079 unsigned long vip_get_current_field (void)
1081 if (READ_VIP32(VIP_STATUS
) & VIP_STATUS_FIELD
)
1082 return VIP_EVEN_FIELD
;
1084 return VIP_ODD_FIELD
;
1087 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1088 * CIMARRON VIP READ ROUTINES
1089 * These routines are included for use in diagnostics or when debugging. They
1090 * can be optionally excluded from a project.
1091 *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
1093 #if CIMARRON_INCLUDE_VIP_READ_ROUTINES
1095 /*---------------------------------------------------------------------------
1096 * vip_get_current_mode
1098 * This routine reads the current VIP operating mode.
1099 *---------------------------------------------------------------------------*/
1101 int vip_get_current_mode (VIPSETMODEBUFFER
*buffer
)
1103 unsigned long vip_control1
, vip_control2
, vip_control3
;
1106 return CIM_STATUS_INVALIDPARAMS
;
1108 vip_control1
= READ_VIP32 (VIP_CONTROL1
);
1109 vip_control2
= READ_VIP32 (VIP_CONTROL2
);
1110 vip_control3
= READ_VIP32 (VIP_CONTROL3
);
1112 /* READ CURRENT OPERATING MODE AND ENABLES */
1114 buffer
->stream_enables
= vip_control1
& VIP_ENABLE_ALL
;
1115 buffer
->operating_mode
= vip_control1
& VIP_CONTROL1_MODE_MASK
;
1117 /* READ CURRENT PLANAR CAPTURE SETTINGS */
1120 buffer
->planar_capture
= 0;
1121 if (vip_control1
& VIP_CONTROL1_PLANAR
)
1123 buffer
->flags
|= VIP_MODEFLAG_PLANARCAPTURE
;
1124 if (vip_control1
& VIP_CONTROL1_DISABLE_DECIMATION
)
1126 if (vip_control3
& VIP_CONTROL3_DECIMATE_EVEN
)
1127 buffer
->planar_capture
= VIP_420CAPTURE_ALTERNATINGFIELDS
;
1129 buffer
->planar_capture
= VIP_420CAPTURE_EVERYLINE
;
1132 buffer
->planar_capture
= VIP_420CAPTURE_ALTERNATINGLINES
;
1135 /* READ MISCELLANEOUS FLAGS */
1137 if (vip_control1
& VIP_CONTROL1_NON_INTERLACED
)
1138 buffer
->flags
|= VIP_MODEFLAG_PROGRESSIVE
;
1139 if (vip_control3
& VIP_CONTROL3_BASE_UPDATE
)
1140 buffer
->flags
|= VIP_MODEFLAG_TOGGLEEACHFIELD
;
1141 if (vip_control2
& VIP_CONTROL2_INVERT_POLARITY
)
1142 buffer
->flags
|= VIP_MODEFLAG_INVERTPOLARITY
;
1143 if (vip_control1
& VIP_CONTROL1_MSG_STRM_CTRL
)
1144 buffer
->flags
|= VIP_MODEFLAG_FLIPMESSAGEWHENFULL
;
1145 if (vip_control2
& VIP_CONTROL2_REPEAT_ENABLE
)
1146 buffer
->flags
|= VIP_MODEFLAG_ENABLEREPEATFLAG
;
1147 if (vip_control3
& VIP_CONTROL3_TASK_POLARITY
)
1148 buffer
->flags
|= VIP_MODEFLAG_INVERTTASKPOLARITY
;
1149 if (vip_control1
& VIP_CONTROL1_DISABLE_ZERO_DETECT
)
1150 buffer
->flags
|= VIP_MODEFLAG_DISABLEZERODETECT
;
1151 if (vip_control2
& VIP_CONTROL2_ANC10
)
1152 buffer
->flags
|= VIP_MODEFLAG_10BITANCILLARY
;
1154 /* READ THE CURRENT VIP 601 SETTINGS */
1156 vip_get_601_configuration (&buffer
->vip601_settings
);
1158 return CIM_STATUS_OK
;
1161 /*---------------------------------------------------------------------------
1162 * vip_get_601_configuration
1164 * This routine returns the current 601 configuration information.
1165 *---------------------------------------------------------------------------*/
1167 int vip_get_601_configuration (VIP_601PARAMS
*buffer
)
1169 unsigned long vip_control3
, vip_control1
;
1172 return CIM_STATUS_INVALIDPARAMS
;
1174 vip_control1
= READ_VIP32 (VIP_CONTROL3
);
1175 vip_control3
= READ_VIP32 (VIP_CONTROL3
);
1178 if (vip_control3
& VIP_CONTROL3_VSYNC_POLARITY
) buffer
->flags
|= VIP_MODEFLAG_VSYNCACTIVEHIGH
;
1179 if (vip_control3
& VIP_CONTROL3_HSYNC_POLARITY
) buffer
->flags
|= VIP_MODEFLAG_HSYNCACTIVEHIGH
;
1181 buffer
->horz_start
= READ_VIP32 (VIP_601_HORZ_START
);
1182 buffer
->vbi_start
= READ_VIP32 (VIP_601_VBI_START
);
1183 buffer
->vbi_height
= READ_VIP32 (VIP_601_VBI_END
) - buffer
->vbi_start
+ 1;
1184 buffer
->vert_start_even
= READ_VIP32 (VIP_601_EVEN_START_STOP
) & 0xFFFF;
1185 buffer
->even_height
= (READ_VIP32 (VIP_601_EVEN_START_STOP
) >> 16) - buffer
->vert_start_even
+ 1;
1186 buffer
->vert_start_odd
= READ_VIP32 (VIP_601_ODD_START_STOP
) & 0xFFFF;
1187 buffer
->odd_height
= (READ_VIP32 (VIP_601_ODD_START_STOP
) >> 16) - buffer
->vert_start_odd
+ 1;
1188 buffer
->odd_detect_start
= READ_VIP32 (VIP_ODD_FIELD_DETECT
) & 0xFFFF;
1189 buffer
->odd_detect_end
= READ_VIP32 (VIP_ODD_FIELD_DETECT
) >> 16;
1191 /* SPECIAL CASE FOR HORIZONTAL DATA */
1192 /* 601 horizontal parameters are based on the number of clocks and not the */
1193 /* number of pixels. */
1195 if ((vip_control1
& VIP_CONTROL1_MODE_MASK
) == VIP_MODE_16BIT601
)
1196 buffer
->width
= (READ_VIP32 (VIP_601_HORZ_END
) - buffer
->horz_start
- 3) >> 1;
1198 buffer
->width
= (READ_VIP32 (VIP_601_HORZ_END
) - buffer
->horz_start
- 3);
1200 return CIM_STATUS_OK
;
1203 /*---------------------------------------------------------------------------
1204 * vip_get_buffer_configuration
1206 * This routine reads the current buffer configuration for Task A, Task B,
1207 * ancillary or message data. The current_buffer member indicates which
1208 * array index should hold the new values for Task A or Task B data.
1209 *---------------------------------------------------------------------------*/
1211 int vip_get_buffer_configuration (int buffer_type
, VIPINPUTBUFFER
*buffer
)
1213 unsigned long cur_buffer
= buffer
->current_buffer
;
1214 VIPINPUTBUFFER_ADDR
*offsets
;
1217 return CIM_STATUS_INVALIDPARAMS
;
1219 if (buffer_type
== VIP_BUFFER_A
)
1221 offsets
= &buffer
->offsets
[VIP_BUFFER_TASK_A
];
1223 /* READ VIDEO PITCH */
1225 offsets
->y_pitch
= READ_VIP32 (VIP_TASKA_VID_PITCH
) & 0xFFFF;
1226 offsets
->uv_pitch
= READ_VIP32 (VIP_TASKA_VID_PITCH
) >> 16;
1228 /* READ BASE OFFSETS */
1230 if (buffer
->flags
& VIP_INPUTFLAG_INVERTPOLARITY
)
1232 offsets
->even_base
[cur_buffer
] = READ_VIP32 (VIP_TASKA_VID_ODD_BASE
);
1233 offsets
->odd_base
[cur_buffer
] = READ_VIP32 (VIP_TASKA_VID_EVEN_BASE
);
1235 if (buffer
->flags
& VIP_INPUTFLAG_VBI
)
1237 offsets
->vbi_even_base
= READ_VIP32 (VIP_TASKA_VBI_ODD_BASE
);
1238 offsets
->vbi_odd_base
= READ_VIP32 (VIP_TASKA_VBI_EVEN_BASE
);
1243 offsets
->even_base
[cur_buffer
] = READ_VIP32 (VIP_TASKA_VID_EVEN_BASE
);
1244 offsets
->odd_base
[cur_buffer
] = READ_VIP32 (VIP_TASKA_VID_ODD_BASE
);
1246 if (buffer
->flags
& VIP_INPUTFLAG_VBI
)
1248 offsets
->vbi_even_base
= READ_VIP32 (VIP_TASKA_VBI_EVEN_BASE
);
1249 offsets
->vbi_odd_base
= READ_VIP32 (VIP_TASKA_VBI_ODD_BASE
);
1253 /* READ 4:2:0 OFFSETS */
1255 if (buffer
->flags
& VIP_INPUTFLAG_PLANAR
)
1257 offsets
->odd_uoffset
= READ_VIP32 (VIP_TASKA_U_OFFSET
);
1258 offsets
->odd_voffset
= READ_VIP32 (VIP_TASKA_V_OFFSET
);
1259 offsets
->even_uoffset
= READ_VIP32 (VIP_TASKA_U_EVEN_OFFSET
);
1260 offsets
->even_voffset
= READ_VIP32 (VIP_TASKA_V_EVEN_OFFSET
);
1263 else if (buffer_type
== VIP_BUFFER_B
)
1265 offsets
= &buffer
->offsets
[VIP_BUFFER_TASK_B
];
1267 /* READ VIDEO PITCH */
1269 offsets
->y_pitch
= READ_VIP32 (VIP_TASKB_VID_PITCH
) & 0xFFFF;
1270 offsets
->uv_pitch
= READ_VIP32 (VIP_TASKB_VID_PITCH
) >> 16;
1272 /* READ BASE OFFSETS */
1274 if (buffer
->flags
& VIP_INPUTFLAG_INVERTPOLARITY
)
1276 offsets
->even_base
[cur_buffer
] = READ_VIP32 (VIP_TASKB_VID_ODD_BASE
);
1277 offsets
->odd_base
[cur_buffer
] = READ_VIP32 (VIP_TASKB_VID_EVEN_BASE
);
1279 if (buffer
->flags
& VIP_INPUTFLAG_VBI
)
1281 offsets
->vbi_even_base
= READ_VIP32 (VIP_TASKB_VBI_ODD_BASE
);
1282 offsets
->vbi_odd_base
= READ_VIP32 (VIP_TASKB_VBI_EVEN_BASE
);
1287 offsets
->even_base
[cur_buffer
] = READ_VIP32 (VIP_TASKB_VID_EVEN_BASE
);
1288 offsets
->odd_base
[cur_buffer
] = READ_VIP32 (VIP_TASKB_VID_ODD_BASE
);
1290 if (buffer
->flags
& VIP_INPUTFLAG_VBI
)
1292 offsets
->vbi_even_base
= READ_VIP32 (VIP_TASKB_VBI_EVEN_BASE
);
1293 offsets
->vbi_odd_base
= READ_VIP32 (VIP_TASKB_VBI_ODD_BASE
);
1297 /* READ 4:2:0 OFFSETS */
1299 if (buffer
->flags
& VIP_INPUTFLAG_PLANAR
)
1301 offsets
->odd_uoffset
= READ_VIP32 (VIP_TASKB_U_OFFSET
);
1302 offsets
->odd_voffset
= READ_VIP32 (VIP_TASKB_V_OFFSET
);
1305 else if (buffer_type
== VIP_BUFFER_ANC
|| buffer_type
== VIP_BUFFER_MSG
)
1307 buffer
->ancillaryData
.msg1_base
= READ_VIP32(VIP_ANC_MSG1_BASE
);
1308 buffer
->ancillaryData
.msg2_base
= READ_VIP32(VIP_ANC_MSG2_BASE
);
1309 buffer
->ancillaryData
.msg_size
= READ_VIP32(VIP_ANC_MSG_SIZE
);
1313 return CIM_STATUS_INVALIDPARAMS
;
1316 return CIM_STATUS_OK
;
1319 /*---------------------------------------------------------------------------
1320 * vip_get_genlock_configuration
1322 * This routine reads the current genlock configuration.
1323 *---------------------------------------------------------------------------*/
1325 int vip_get_genlock_configuration (VIPGENLOCKBUFFER
*buffer
)
1327 unsigned long vip_control1
, vip_control2
;
1328 unsigned long genlk_ctl
;
1331 return CIM_STATUS_INVALIDPARAMS
;
1333 genlk_ctl
= READ_REG32 (DC3_GENLK_CTL
);
1334 vip_control1
= READ_VIP32 (VIP_CONTROL1
);
1335 vip_control2
= READ_VIP32 (VIP_CONTROL2
);
1337 /* READ ERROR DETECTION, CURRENT FIELD AND CURRENT VSYNC */
1338 /* These flags are used to indicate the ways in which the VIP signal can */
1339 /* be considered 'lost'. */
1341 buffer
->vip_signal_loss
= vip_control1
& VIP_CONTROL1_VDE_FF_MASK
;
1342 buffer
->field_to_vg
= vip_control2
& VIP_CONTROL2_FIELD2VG_MASK
;
1343 buffer
->vsync_to_vg
= vip_control2
& VIP_CONTROL2_SYNC2VG_MASK
;
1345 /* GENLOCK TIMEOUT ENABLE */
1347 buffer
->enable_timeout
= 0;
1348 if (genlk_ctl
& DC3_GC_GENLOCK_TO_ENABLE
)
1349 buffer
->enable_timeout
= 1;
1353 buffer
->genlock_skew
= genlk_ctl
& DC3_GC_GENLOCK_SKEW_MASK
;
1355 return CIM_STATUS_OK
;
1358 /*---------------------------------------------------------------------------
1359 * vip_get_genlock_enable
1361 * This routine returns the current enable status of genlock in the VG.
1362 *---------------------------------------------------------------------------*/
1364 int vip_get_genlock_enable (void)
1366 if (READ_REG32 (DC3_GENLK_CTL
) & DC3_GC_GENLOCK_ENABLE
)
1372 /*---------------------------------------------------------------------------
1373 * vip_is_buffer_update_latched
1375 * This routine indicates whether changes to the VIP offsets have been latched by
1377 *---------------------------------------------------------------------------*/
1379 int vip_is_buffer_update_latched (void)
1381 return (!(READ_VIP32(VIP_STATUS
) & VIP_STATUS_BASEREG_NOTUPDT
));
1384 /*---------------------------------------------------------------------------
1385 * vip_get_capture_state
1387 * This routine reads the current capture status of the VIP hardware.
1388 *---------------------------------------------------------------------------*/
1390 unsigned long vip_get_capture_state (void)
1392 return ((READ_VIP32(VIP_CONTROL1
) & VIP_CONTROL1_RUNMODE_MASK
) >> VIP_CONTROL1_RUNMODE_SHIFT
);
1395 /*---------------------------------------------------------------------------
1396 * vip_get_current_line
1398 * This routine returns the current line that is being processed.
1399 *---------------------------------------------------------------------------*/
1401 unsigned long vip_get_current_line (void)
1403 return (READ_VIP32(VIP_CURRENT_TARGET
) & VIP_CTARGET_CLINE_MASK
);
1406 /*---------------------------------------------------------------------------
1409 * This routine reads from the specified fifo address. As the fifo access
1410 * enable should be disabled when running in normal vip mode, this routine
1411 * enables and disables access around the read.
1412 * DIAGNOSTIC USE ONLY
1413 *---------------------------------------------------------------------------*/
1415 unsigned long vip_read_fifo(unsigned long dwFifoAddress
)
1417 unsigned long fifo_data
;
1419 /* ENABLE FIFO ACCESS */
1421 vip_enable_fifo_access (1);
1423 /* NOW READ THE DATA */
1425 WRITE_VIP32(VIP_FIFO_ADDRESS
, dwFifoAddress
);
1426 fifo_data
= READ_VIP32(VIP_FIFO_DATA
);
1428 /* DISABLE FIFO ACCESS */
1430 vip_enable_fifo_access (0);
1435 /*---------------------------------------------------------------------------
1439 * This routine writes to the specified fifo address. As the fifo access
1440 * enable should be disabled when running in normal vip mode, this routine
1441 * enables and disables access around the write.
1442 * DIAGNOSTIC USE ONLY
1443 *---------------------------------------------------------------------------*/
1445 int vip_write_fifo (unsigned long dwFifoAddress
, unsigned long dwFifoData
)
1447 /* ENABLE FIFO ACCESS */
1449 vip_enable_fifo_access(1);
1451 /* WRITE THE FIFO DATA */
1453 WRITE_VIP32(VIP_FIFO_ADDRESS
, dwFifoAddress
);
1454 WRITE_VIP32(VIP_FIFO_DATA
, dwFifoData
);
1456 /* DISABLE FIFO ACCESS */
1458 vip_enable_fifo_access(0);
1460 return CIM_STATUS_OK
;
1463 /*---------------------------------------------------------------------------
1464 * vip_enable_fifo_access
1466 * This routine enables/disables access to the vip fifo.
1467 * DIAGNOSTIC USE ONLY
1468 *---------------------------------------------------------------------------*/
1470 int vip_enable_fifo_access (int enable
)
1474 cw2
= READ_VIP32(VIP_CONTROL2
);
1476 if (enable
) cw2
|= VIP_CONTROL2_FIFO_ACCESS
;
1477 else cw2
&= ~VIP_CONTROL2_FIFO_ACCESS
;
1479 WRITE_VIP32(VIP_CONTROL2
, cw2
);
1481 return CIM_STATUS_OK
;
1484 /*---------------------------------------------------------------------------
1485 * vip_get_power_characteristics
1487 * This routine returns the current VIP clock gating state in a VIPPOWERBUFFER.
1488 *---------------------------------------------------------------------------*/
1490 int vip_get_power_characteristics(VIPPOWERBUFFER
*buffer
)
1495 return CIM_STATUS_INVALIDPARAMS
;
1497 /* READ THE EXISTING STATE */
1499 msr_read64(MSR_DEVICE_GEODELX_VIP
, MSR_GEODELINK_PM
, &q_word
);
1501 /* DECODE THE CLOCK GATING BITS */
1503 buffer
->glink_clock_mode
= (int)(q_word
.low
& VIP_MSR_POWER_GLINK
);
1504 buffer
->vip_clock_mode
= (int)(q_word
.low
& VIP_MSR_POWER_CLOCK
);
1506 return CIM_STATUS_OK
;
1509 /*---------------------------------------------------------------------------
1510 * vip_get_priority_characteristics
1512 * This routine returns the priority characteristics in the supplied
1513 * VIPPRIORITYBUFFER.
1514 *---------------------------------------------------------------------------*/
1516 int vip_get_priority_characteristics(VIPPRIORITYBUFFER
*buffer
)
1521 return CIM_STATUS_INVALIDPARAMS
;
1523 /* READ THE CURRENT STATE */
1525 msr_read64 (MSR_DEVICE_GEODELX_VIP
, MSR_GEODELINK_CONFIG
, &q_word
);
1527 /* DECODE THE PRIORITIES */
1529 buffer
->secondary
= (q_word
.low
& VIP_MSR_MCR_SECOND_PRIORITY_MASK
) >> VIP_MSR_MCR_SECOND_PRIORITY_SHIFT
;
1530 buffer
->primary
= (q_word
.low
& VIP_MSR_MCR_PRIMARY_PRIORITY_MASK
) >> VIP_MSR_MCR_PRIMARY_PRIORITY_SHIFT
;
1531 buffer
->pid
= q_word
.low
& VIP_MSR_MCR_PID_MASK
;
1533 return CIM_STATUS_OK
;
1536 /*---------------------------------------------------------------------------
1537 * vip_get_capability_characteristics
1539 * This routine returns revision information for the device.
1540 *---------------------------------------------------------------------------*/
1542 int vip_get_capability_characteristics(VIPCAPABILITIESBUFFER
*buffer
)
1547 return CIM_STATUS_INVALIDPARAMS
;
1549 /* READ THE CURRENT MSR CONTENTS */
1551 msr_read64 (MSR_DEVICE_GEODELX_VIP
, MSR_GEODELINK_CAP
, &q_word
);
1553 /* DECODE THE REVISIONS */
1555 buffer
->revision_id
= (q_word
.low
& VIP_MSR_CAP_REVID_MASK
) >> VIP_MSR_CAP_REVID_SHIFT
;
1556 buffer
->device_id
= (q_word
.low
& VIP_MSR_CAP_DEVID_MASK
) >> VIP_MSR_CAP_DEVID_SHIFT
;
1557 buffer
->n_clock_domains
= (q_word
.low
& VIP_MSR_CAP_NCLK_MASK
) >> VIP_MSR_CAP_NCLK_SHIFT
;
1558 buffer
->n_smi_registers
= (q_word
.low
& VIP_MSR_CAP_NSMI_MASK
) >> VIP_MSR_CAP_NSMI_SHIFT
;
1560 return CIM_STATUS_OK
;