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;
798
primary << VIP_MSR_MCR_PRIMARY_PRIORITY_SHIFT) &
799
VIP_MSR_MCR_PRIMARY_PRIORITY_MASK;
800
q_word.low |= (buffer->pid << VIP_MSR_MCR_PID_SHIFT) & VIP_MSR_MCR_PID_MASK;
802
msr_write64(MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_CONFIG, &q_word);
804
return CIM_STATUS_OK;
807
/*---------------------------------------------------------------------------
808
* vip_set_debug_characteristics
810
* This routine configures the debug data that is exposed over the diag bus.
811
*--------------------------------------------------------------------------*/
814
vip_set_debug_characteristics(VIPDEBUGBUFFER * buffer)
819
return CIM_STATUS_INVALIDPARAMS;
821
q_word.low = q_word.high = 0;
823
q_word.high |= (buffer->bist << VIP_MSR_DIAG_BIST_SHIFT) &
824
VIP_MSR_DIAG_BIST_WMASK;
825
q_word.low |= (buffer->enable_upper ? VIP_MSR_DIAG_MSB_ENABLE : 0x00000000);
826
q_word.low |= (buffer->select_upper << VIP_MSR_DIAG_SEL_UPPER_SHIFT) &
827
VIP_MSR_DIAG_SEL_UPPER_MASK;
828
q_word.low |= (buffer->enable_lower ? VIP_MSR_DIAG_LSB_ENABLE : 0x00000000);
829
q_word.low |= (buffer->select_lower << VIP_MSR_DIAG_SEL_LOWER_SHIFT) &
830
VIP_MSR_DIAG_SEL_LOWER_MASK;
832
msr_write64(MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_DIAG, &q_word);
834
return CIM_STATUS_OK;
837
/*---------------------------------------------------------------------------
838
* vip_configure_pages
840
* This routine sets the number of pages, and their offset from each other.
841
*--------------------------------------------------------------------------*/
844
vip_configure_pages(int page_count, unsigned long page_offset)
846
unsigned long vip_control2 = READ_VIP32(VIP_CONTROL2);
848
/* SET THE NEW PAGE COUNT */
850
vip_control2 &= ~VIP_CONTROL2_PAGECNT_MASK;
851
vip_control2 |= (page_count << VIP_CONTROL2_PAGECNT_SHIFT) &
852
VIP_CONTROL2_PAGECNT_MASK;
854
/* WRITE THE PAGE OFFSET */
856
WRITE_VIP32(VIP_CONTROL2, vip_control2);
857
WRITE_VIP32(VIP_PAGE_OFFSET, page_offset);
859
return CIM_STATUS_OK;
862
/*---------------------------------------------------------------------------
863
* vip_set_interrupt_line
865
* This routine sets the line at which a line interrupt should be generated.
866
*--------------------------------------------------------------------------*/
869
vip_set_interrupt_line(int line)
871
WRITE_VIP32(VIP_CURRENT_TARGET,
872
(line << VIP_CTARGET_TLINE_SHIFT) & VIP_CTARGET_TLINE_MASK);
874
return CIM_STATUS_OK;
877
/*---------------------------------------------------------------------------
880
* This routine does a one-shot enable of the VIP hardware. It is useful
881
* for handling unrecoverable VIP errors.
882
*--------------------------------------------------------------------------*/
887
unsigned long vip_control1, vip_control3;
889
/* INVERT THE PAUSE BIT */
891
vip_control1 = READ_VIP32(VIP_CONTROL1);
892
vip_control3 = READ_VIP32(VIP_CONTROL3);
894
WRITE_VIP32(VIP_CONTROL1, vip_control1 | VIP_CONTROL1_RESET);
895
WRITE_VIP32(VIP_CONTROL1, vip_control1 & ~VIP_CONTROL1_RESET);
896
WRITE_VIP32(VIP_CONTROL3, vip_control3 | VIP_CONTROL3_FIFO_RESET);
898
return CIM_STATUS_OK;
901
/*---------------------------------------------------------------------------
902
* vip_set_subwindow_enable
904
* This routine turns on SubWindow capture, that is a portion of the incoming
905
* signal is captured rather than the entire frame. The window always has
906
* the same width as the frame, only the vertical component can be
908
*--------------------------------------------------------------------------*/
911
vip_set_subwindow_enable(VIPSUBWINDOWBUFFER * buffer)
913
unsigned long vip_control2;
916
return CIM_STATUS_INVALIDPARAMS;
918
vip_control2 = READ_VIP32(VIP_CONTROL2);
919
if (buffer->enable) {
920
/* WRITE THE WINDOW VALUE */
922
WRITE_VIP32(VIP_VERTICAL_START_STOP, ((buffer->stop <<
923
VIP_VSTART_VERTEND_SHIFT) &
924
VIP_VSTART_VERTEND_MASK) |
926
start << VIP_VSTART_VERTSTART_SHIFT) &
927
VIP_VSTART_VERTSTART_MASK));
929
/* ENABLE IN THE CONTROL REGISTER */
931
vip_control2 |= VIP_CONTROL2_SWC_ENABLE;
934
/* DISABLE SUBWINDOW CAPTURE IN THE CONTROL REGISTER */
936
vip_control2 &= ~VIP_CONTROL2_SWC_ENABLE;
938
WRITE_VIP32(VIP_CONTROL2, vip_control2);
940
return CIM_STATUS_OK;
943
/*---------------------------------------------------------------------------
944
* vip_reset_interrupt_state
946
* This routine resets the state of one or more interrupts.
947
*--------------------------------------------------------------------------*/
950
vip_reset_interrupt_state(unsigned long interrupt_mask)
954
temp = READ_VIP32(VIP_INTERRUPT);
955
WRITE_VIP32(VIP_INTERRUPT, temp | (interrupt_mask & VIP_ALL_INTERRUPTS));
957
return CIM_STATUS_OK;
960
/*---------------------------------------------------------------------------
963
* This routine saves the necessary register contents in order to restore
964
* at a later point to the same state.
966
* NOTE: Capture state is forced to OFF in this routine
967
*--------------------------------------------------------------------------*/
970
vip_save_state(VIPSTATEBUFFER * save_buffer)
973
return CIM_STATUS_INVALIDPARAMS;
975
/* FORCE CAPTURE TO BE DISABLED */
977
vip_set_capture_state(VIP_STOPCAPTURE);
979
/* READ AND SAVE THE REGISTER CONTENTS */
981
save_buffer->control1 = READ_VIP32(VIP_CONTROL1);
982
save_buffer->control2 = READ_VIP32(VIP_CONTROL2);
983
save_buffer->vip_int = READ_VIP32(VIP_INTERRUPT);
984
save_buffer->current_target = READ_VIP32(VIP_CURRENT_TARGET);
985
save_buffer->max_address = READ_VIP32(VIP_MAX_ADDRESS);
986
save_buffer->taska_evenbase = READ_VIP32(VIP_TASKA_VID_EVEN_BASE);
987
save_buffer->taska_oddbase = READ_VIP32(VIP_TASKA_VID_ODD_BASE);
988
save_buffer->taska_vbi_evenbase = READ_VIP32(VIP_TASKA_VBI_EVEN_BASE);
989
save_buffer->taska_vbi_oddbase = READ_VIP32(VIP_TASKA_VBI_ODD_BASE);
990
save_buffer->taska_data_pitch = READ_VIP32(VIP_TASKA_VID_PITCH);
991
save_buffer->control3 = READ_VIP32(VIP_CONTROL3);
992
save_buffer->taska_v_oddoffset = READ_VIP32(VIP_TASKA_U_OFFSET);
993
save_buffer->taska_u_oddoffset = READ_VIP32(VIP_TASKA_V_OFFSET);
994
save_buffer->taskb_evenbase = READ_VIP32(VIP_TASKB_VID_EVEN_BASE);
995
save_buffer->taskb_oddbase = READ_VIP32(VIP_TASKB_VID_ODD_BASE);
996
save_buffer->taskb_vbi_evenbase = READ_VIP32(VIP_TASKB_VBI_EVEN_BASE);
997
save_buffer->taskb_vbi_oddbase = READ_VIP32(VIP_TASKB_VBI_ODD_BASE);
998
save_buffer->taskb_pitch = READ_VIP32(VIP_TASKB_VID_PITCH);
999
save_buffer->taskb_voffset = READ_VIP32(VIP_TASKB_U_OFFSET);
1000
save_buffer->taskb_uoffset = READ_VIP32(VIP_TASKB_V_OFFSET);
1001
save_buffer->msg1_base = READ_VIP32(VIP_ANC_MSG1_BASE);
1002
save_buffer->msg2_base = READ_VIP32(VIP_ANC_MSG2_BASE);
1003
save_buffer->msg_size = READ_VIP32(VIP_ANC_MSG_SIZE);
1004
save_buffer->page_offset = READ_VIP32(VIP_PAGE_OFFSET);
1005
save_buffer->vert_start_stop = READ_VIP32(VIP_VERTICAL_START_STOP);
1006
save_buffer->vsync_err_count = READ_VIP32(VIP_VSYNC_ERR_COUNT);
1007
save_buffer->taska_u_evenoffset = READ_VIP32(VIP_TASKA_U_EVEN_OFFSET);
1008
save_buffer->taska_v_evenoffset = READ_VIP32(VIP_TASKA_V_EVEN_OFFSET);
1010
/* READ ALL VIP MSRS */
1012
msr_read64(MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_CONFIG,
1013
&(save_buffer->msr_config));
1014
msr_read64(MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_SMI,
1015
&(save_buffer->msr_smi));
1016
msr_read64(MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_PM,
1017
&(save_buffer->msr_pm));
1018
msr_read64(MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_DIAG,
1019
&(save_buffer->msr_diag));
1021
return CIM_STATUS_OK;
1024
/*---------------------------------------------------------------------------
1027
* This routine restores the state of the vip registers - which were
1028
* previously saved using vip_save_state.
1029
*--------------------------------------------------------------------------*/
1032
vip_restore_state(VIPSTATEBUFFER * restore_buffer)
1034
if (!restore_buffer)
1035
return CIM_STATUS_OK;
1037
/* RESTORE THE REGISTERS */
1039
WRITE_VIP32(VIP_CURRENT_TARGET, restore_buffer->current_target);
1040
WRITE_VIP32(VIP_MAX_ADDRESS, restore_buffer->max_address);
1041
WRITE_VIP32(VIP_TASKA_VID_EVEN_BASE, restore_buffer->taska_evenbase);
1042
WRITE_VIP32(VIP_TASKA_VID_ODD_BASE, restore_buffer->taska_oddbase);
1043
WRITE_VIP32(VIP_TASKA_VBI_EVEN_BASE, restore_buffer->taska_vbi_evenbase);
1044
WRITE_VIP32(VIP_TASKA_VBI_ODD_BASE, restore_buffer->taska_vbi_oddbase);
1045
WRITE_VIP32(VIP_TASKA_VID_PITCH, restore_buffer->taska_data_pitch);
1046
WRITE_VIP32(VIP_CONTROL3, restore_buffer->control3);
1047
WRITE_VIP32(VIP_TASKA_U_OFFSET, restore_buffer->taska_v_oddoffset);
1048
WRITE_VIP32(VIP_TASKA_V_OFFSET, restore_buffer->taska_u_oddoffset);
1049
WRITE_VIP32(VIP_TASKB_VID_EVEN_BASE, restore_buffer->taskb_evenbase);
1050
WRITE_VIP32(VIP_TASKB_VID_ODD_BASE, restore_buffer->taskb_oddbase);
1051
WRITE_VIP32(VIP_TASKB_VBI_EVEN_BASE, restore_buffer->taskb_vbi_evenbase);
1052
WRITE_VIP32(VIP_TASKB_VBI_ODD_BASE, restore_buffer->taskb_vbi_oddbase);
1053
WRITE_VIP32(VIP_TASKB_VID_PITCH, restore_buffer->taskb_pitch);
1054
WRITE_VIP32(VIP_TASKB_U_OFFSET, restore_buffer->taskb_voffset);
1055
WRITE_VIP32(VIP_TASKB_V_OFFSET, restore_buffer->taskb_uoffset);
1056
WRITE_VIP32(VIP_ANC_MSG1_BASE, restore_buffer->msg1_base);
1057
WRITE_VIP32(VIP_ANC_MSG2_BASE, restore_buffer->msg2_base);
1058
WRITE_VIP32(VIP_ANC_MSG_SIZE, restore_buffer->msg_size);
1059
WRITE_VIP32(VIP_PAGE_OFFSET, restore_buffer->page_offset);
1060
WRITE_VIP32(VIP_VERTICAL_START_STOP, restore_buffer->vert_start_stop);
1061
WRITE_VIP32(VIP_VSYNC_ERR_COUNT, restore_buffer->vsync_err_count);
1062
WRITE_VIP32(VIP_TASKA_U_EVEN_OFFSET, restore_buffer->taska_u_evenoffset);
1063
WRITE_VIP32(VIP_TASKA_V_EVEN_OFFSET, restore_buffer->taska_v_evenoffset);
1065
/* RESTORE THE VIP MSRS */
1067
msr_write64(MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_CONFIG,
1068
&(restore_buffer->msr_config));
1069
msr_write64(MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_SMI,
1070
&(restore_buffer->msr_smi));
1071
msr_write64(MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_PM,
1072
&(restore_buffer->msr_pm));
1073
msr_write64(MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_DIAG,
1074
&(restore_buffer->msr_diag));
1076
/* RESTORE THE CONTROL WORDS LAST */
1078
WRITE_VIP32(VIP_CONTROL1, restore_buffer->control1);
1079
WRITE_VIP32(VIP_CONTROL2, restore_buffer->control2);
1080
WRITE_VIP32(VIP_CONTROL3, restore_buffer->control3);
1082
return CIM_STATUS_OK;
1085
/*---------------------------------------------------------------------------
1086
* vip_get_interrupt_state
1088
* This routine returns the current interrupt state of the system. The
1089
* rv can be tested with the following flags to determine if the appropriate
1090
* event has occured.
1091
*--------------------------------------------------------------------------*/
1094
vip_get_interrupt_state(void)
1096
unsigned long interrupt_mask = READ_VIP32(VIP_INTERRUPT);
1098
return (~(interrupt_mask << 16) & interrupt_mask & VIP_ALL_INTERRUPTS);
1101
/*---------------------------------------------------------------------------
1102
* vip_test_genlock_active
1104
* This routine reads the live status of the genlock connection between the
1105
* VIP and VG blocks.
1106
*--------------------------------------------------------------------------*/
1109
vip_test_genlock_active(void)
1111
if (READ_REG32(DC3_GENLK_CTL) & DC3_GC_GENLK_ACTIVE)
1117
/*---------------------------------------------------------------------------
1118
* vip_test_signal_status
1120
* This routine reads the live signal status coming into the VIP block.
1121
*--------------------------------------------------------------------------*/
1124
vip_test_signal_status(void)
1126
if (READ_REG32(DC3_GENLK_CTL) & DC3_GC_VIP_VID_OK)
1132
/*---------------------------------------------------------------------------
1133
* vip_get_current_field
1135
* This routine returns the current field being received.
1136
*--------------------------------------------------------------------------*/
1139
vip_get_current_field(void)
1141
if (READ_VIP32(VIP_STATUS) & VIP_STATUS_FIELD)
1142
return VIP_EVEN_FIELD;
1144
return VIP_ODD_FIELD;
1147
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1148
* CIMARRON VIP READ ROUTINES
1149
* These routines are included for use in diagnostics or when debugging. They
1150
* can be optionally excluded from a project.
1151
*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
1153
#if CIMARRON_INCLUDE_VIP_READ_ROUTINES
1155
/*---------------------------------------------------------------------------
1156
* vip_get_current_mode
1158
* This routine reads the current VIP operating mode.
1159
*--------------------------------------------------------------------------*/
1162
vip_get_current_mode(VIPSETMODEBUFFER * buffer)
1164
unsigned long vip_control1, vip_control2, vip_control3;
1167
return CIM_STATUS_INVALIDPARAMS;
1169
vip_control1 = READ_VIP32(VIP_CONTROL1);
1170
vip_control2 = READ_VIP32(VIP_CONTROL2);
1171
vip_control3 = READ_VIP32(VIP_CONTROL3);
1173
/* READ CURRENT OPERATING MODE AND ENABLES */
1175
buffer->stream_enables = vip_control1 & VIP_ENABLE_ALL;
1176
buffer->operating_mode = vip_control1 & VIP_CONTROL1_MODE_MASK;
1178
/* READ CURRENT PLANAR CAPTURE SETTINGS */
1181
buffer->planar_capture = 0;
1182
if (vip_control1 & VIP_CONTROL1_PLANAR) {
1183
buffer->flags |= VIP_MODEFLAG_PLANARCAPTURE;
1184
if (vip_control1 & VIP_CONTROL1_DISABLE_DECIMATION) {
1185
if (vip_control3 & VIP_CONTROL3_DECIMATE_EVEN)
1186
buffer->planar_capture = VIP_420CAPTURE_ALTERNATINGFIELDS;
1188
buffer->planar_capture = VIP_420CAPTURE_EVERYLINE;
1191
buffer->planar_capture = VIP_420CAPTURE_ALTERNATINGLINES;
1194
/* READ MISCELLANEOUS FLAGS */
1196
if (vip_control1 & VIP_CONTROL1_NON_INTERLACED)
1197
buffer->flags |= VIP_MODEFLAG_PROGRESSIVE;
1198
if (vip_control3 & VIP_CONTROL3_BASE_UPDATE)
1199
buffer->flags |= VIP_MODEFLAG_TOGGLEEACHFIELD;
1200
if (vip_control2 & VIP_CONTROL2_INVERT_POLARITY)
1201
buffer->flags |= VIP_MODEFLAG_INVERTPOLARITY;
1202
if (vip_control1 & VIP_CONTROL1_MSG_STRM_CTRL)
1203
buffer->flags |= VIP_MODEFLAG_FLIPMESSAGEWHENFULL;
1204
if (vip_control2 & VIP_CONTROL2_REPEAT_ENABLE)
1205
buffer->flags |= VIP_MODEFLAG_ENABLEREPEATFLAG;
1206
if (vip_control3 & VIP_CONTROL3_TASK_POLARITY)
1207
buffer->flags |= VIP_MODEFLAG_INVERTTASKPOLARITY;
1208
if (vip_control1 & VIP_CONTROL1_DISABLE_ZERO_DETECT)
1209
buffer->flags |= VIP_MODEFLAG_DISABLEZERODETECT;
1210
if (vip_control2 & VIP_CONTROL2_ANC10)
1211
buffer->flags |= VIP_MODEFLAG_10BITANCILLARY;
1213
/* READ THE CURRENT VIP 601 SETTINGS */
1215
vip_get_601_configuration(&buffer->vip601_settings);
1217
return CIM_STATUS_OK;
1220
/*---------------------------------------------------------------------------
1221
* vip_get_601_configuration
1223
* This routine returns the current 601 configuration information.
1224
*--------------------------------------------------------------------------*/
1227
vip_get_601_configuration(VIP_601PARAMS * buffer)
1229
unsigned long vip_control3, vip_control1;
1232
return CIM_STATUS_INVALIDPARAMS;
1234
vip_control1 = READ_VIP32(VIP_CONTROL3);
1235
vip_control3 = READ_VIP32(VIP_CONTROL3);
1238
if (vip_control3 & VIP_CONTROL3_VSYNC_POLARITY)
1239
buffer->flags |= VIP_MODEFLAG_VSYNCACTIVEHIGH;
1240
if (vip_control3 & VIP_CONTROL3_HSYNC_POLARITY)
1241
buffer->flags |= VIP_MODEFLAG_HSYNCACTIVEHIGH;
1243
buffer->horz_start = READ_VIP32(VIP_601_HORZ_START);
1244
buffer->vbi_start = READ_VIP32(VIP_601_VBI_START);
1245
buffer->vbi_height = READ_VIP32(VIP_601_VBI_END) - buffer->vbi_start + 1;
1246
buffer->vert_start_even = READ_VIP32(VIP_601_EVEN_START_STOP) & 0xFFFF;
1247
buffer->even_height = (READ_VIP32(VIP_601_EVEN_START_STOP) >> 16) -
1248
buffer->vert_start_even + 1;
1249
buffer->vert_start_odd = READ_VIP32(VIP_601_ODD_START_STOP) & 0xFFFF;
1250
buffer->odd_height = (READ_VIP32(VIP_601_ODD_START_STOP) >> 16) -
1251
buffer->vert_start_odd + 1;
1252
buffer->odd_detect_start = READ_VIP32(VIP_ODD_FIELD_DETECT) & 0xFFFF;
1253
buffer->odd_detect_end = READ_VIP32(VIP_ODD_FIELD_DETECT) >> 16;
1255
/* SPECIAL CASE FOR HORIZONTAL DATA
1256
* 601 horizontal parameters are based on the number of clocks and not
1257
* the number of pixels.
1260
if ((vip_control1 & VIP_CONTROL1_MODE_MASK) == VIP_MODE_16BIT601)
1261
buffer->width = (READ_VIP32(VIP_601_HORZ_END) -
1262
buffer->horz_start - 3) >> 1;
1264
buffer->width = (READ_VIP32(VIP_601_HORZ_END) - buffer->horz_start - 3);
1266
return CIM_STATUS_OK;
1269
/*---------------------------------------------------------------------------
1270
* vip_get_buffer_configuration
1272
* This routine reads the current buffer configuration for Task A, Task B,
1273
* ancillary or message data. The current_buffer member indicates which
1274
* array index should hold the new values for Task A or Task B data.
1275
*--------------------------------------------------------------------------*/
1278
vip_get_buffer_configuration(int buffer_type, VIPINPUTBUFFER * buffer)
1280
unsigned long cur_buffer = buffer->current_buffer;
1281
VIPINPUTBUFFER_ADDR *offsets;
1284
return CIM_STATUS_INVALIDPARAMS;
1286
if (buffer_type == VIP_BUFFER_A) {
1287
offsets = &buffer->offsets[VIP_BUFFER_TASK_A];
1289
/* READ VIDEO PITCH */
1291
offsets->y_pitch = READ_VIP32(VIP_TASKA_VID_PITCH) & 0xFFFF;
1292
offsets->uv_pitch = READ_VIP32(VIP_TASKA_VID_PITCH) >> 16;
1294
/* READ BASE OFFSETS */
1296
if (buffer->flags & VIP_INPUTFLAG_INVERTPOLARITY) {
1297
offsets->even_base[cur_buffer] = READ_VIP32(VIP_TASKA_VID_ODD_BASE);
1298
offsets->odd_base[cur_buffer] = READ_VIP32(VIP_TASKA_VID_EVEN_BASE);
1300
if (buffer->flags & VIP_INPUTFLAG_VBI) {
1301
offsets->vbi_even_base = READ_VIP32(VIP_TASKA_VBI_ODD_BASE);
1302
offsets->vbi_odd_base = READ_VIP32(VIP_TASKA_VBI_EVEN_BASE);
1306
offsets->even_base[cur_buffer] =
1307
READ_VIP32(VIP_TASKA_VID_EVEN_BASE);
1308
offsets->odd_base[cur_buffer] = READ_VIP32(VIP_TASKA_VID_ODD_BASE);
1310
if (buffer->flags & VIP_INPUTFLAG_VBI) {
1311
offsets->vbi_even_base = READ_VIP32(VIP_TASKA_VBI_EVEN_BASE);
1312
offsets->vbi_odd_base = READ_VIP32(VIP_TASKA_VBI_ODD_BASE);
1316
/* READ 4:2:0 OFFSETS */
1318
if (buffer->flags & VIP_INPUTFLAG_PLANAR) {
1319
offsets->odd_uoffset = READ_VIP32(VIP_TASKA_U_OFFSET);
1320
offsets->odd_voffset = READ_VIP32(VIP_TASKA_V_OFFSET);
1321
offsets->even_uoffset = READ_VIP32(VIP_TASKA_U_EVEN_OFFSET);
1322
offsets->even_voffset = READ_VIP32(VIP_TASKA_V_EVEN_OFFSET);
1325
else if (buffer_type == VIP_BUFFER_B) {
1326
offsets = &buffer->offsets[VIP_BUFFER_TASK_B];
1328
/* READ VIDEO PITCH */
1330
offsets->y_pitch = READ_VIP32(VIP_TASKB_VID_PITCH) & 0xFFFF;
1331
offsets->uv_pitch = READ_VIP32(VIP_TASKB_VID_PITCH) >> 16;
1333
/* READ BASE OFFSETS */
1335
if (buffer->flags & VIP_INPUTFLAG_INVERTPOLARITY) {
1336
offsets->even_base[cur_buffer] = READ_VIP32(VIP_TASKB_VID_ODD_BASE);
1337
offsets->odd_base[cur_buffer] = READ_VIP32(VIP_TASKB_VID_EVEN_BASE);
1339
if (buffer->flags & VIP_INPUTFLAG_VBI) {
1340
offsets->vbi_even_base = READ_VIP32(VIP_TASKB_VBI_ODD_BASE);
1341
offsets->vbi_odd_base = READ_VIP32(VIP_TASKB_VBI_EVEN_BASE);
1345
offsets->even_base[cur_buffer] =
1346
READ_VIP32(VIP_TASKB_VID_EVEN_BASE);
1347
offsets->odd_base[cur_buffer] = READ_VIP32(VIP_TASKB_VID_ODD_BASE);
1349
if (buffer->flags & VIP_INPUTFLAG_VBI) {
1350
offsets->vbi_even_base = READ_VIP32(VIP_TASKB_VBI_EVEN_BASE);
1351
offsets->vbi_odd_base = READ_VIP32(VIP_TASKB_VBI_ODD_BASE);
1355
/* READ 4:2:0 OFFSETS */
1357
if (buffer->flags & VIP_INPUTFLAG_PLANAR) {
1358
offsets->odd_uoffset = READ_VIP32(VIP_TASKB_U_OFFSET);
1359
offsets->odd_voffset = READ_VIP32(VIP_TASKB_V_OFFSET);
1362
else if (buffer_type == VIP_BUFFER_ANC || buffer_type == VIP_BUFFER_MSG) {
1363
buffer->ancillaryData.msg1_base = READ_VIP32(VIP_ANC_MSG1_BASE);
1364
buffer->ancillaryData.msg2_base = READ_VIP32(VIP_ANC_MSG2_BASE);
1365
buffer->ancillaryData.msg_size = READ_VIP32(VIP_ANC_MSG_SIZE);
1368
return CIM_STATUS_INVALIDPARAMS;
1371
return CIM_STATUS_OK;
1374
/*---------------------------------------------------------------------------
1375
* vip_get_genlock_configuration
1377
* This routine reads the current genlock configuration.
1378
*--------------------------------------------------------------------------*/
1381
vip_get_genlock_configuration(VIPGENLOCKBUFFER * buffer)
1383
unsigned long vip_control1, vip_control2;
1384
unsigned long genlk_ctl;
1387
return CIM_STATUS_INVALIDPARAMS;
1389
genlk_ctl = READ_REG32(DC3_GENLK_CTL);
1390
vip_control1 = READ_VIP32(VIP_CONTROL1);
1391
vip_control2 = READ_VIP32(VIP_CONTROL2);
1393
/* READ ERROR DETECTION, CURRENT FIELD AND CURRENT VSYNC
1394
* These flags are used to indicate the ways in which the VIP signal can
1395
* be considered 'lost'.
1398
buffer->vip_signal_loss = vip_control1 & VIP_CONTROL1_VDE_FF_MASK;
1399
buffer->field_to_vg = vip_control2 & VIP_CONTROL2_FIELD2VG_MASK;
1400
buffer->vsync_to_vg = vip_control2 & VIP_CONTROL2_SYNC2VG_MASK;
1402
/* GENLOCK TIMEOUT ENABLE */
1404
buffer->enable_timeout = 0;
1405
if (genlk_ctl & DC3_GC_GENLOCK_TO_ENABLE)
1406
buffer->enable_timeout = 1;
1410
buffer->genlock_skew = genlk_ctl & DC3_GC_GENLOCK_SKEW_MASK;
1412
return CIM_STATUS_OK;
1415
/*---------------------------------------------------------------------------
1416
* vip_get_genlock_enable
1418
* This routine returns the current enable status of genlock in the VG.
1419
*--------------------------------------------------------------------------*/
1422
vip_get_genlock_enable(void)
1424
if (READ_REG32(DC3_GENLK_CTL) & DC3_GC_GENLOCK_ENABLE)
1430
/*---------------------------------------------------------------------------
1431
* vip_is_buffer_update_latched
1433
* This routine indicates whether changes to the VIP offsets have been
1434
* latched by the hardware.
1435
*--------------------------------------------------------------------------*/
1438
vip_is_buffer_update_latched(void)
1440
return (!(READ_VIP32(VIP_STATUS) & VIP_STATUS_BASEREG_NOTUPDT));
1443
/*---------------------------------------------------------------------------
1444
* vip_get_capture_state
1446
* This routine reads the current capture status of the VIP hardware.
1447
*--------------------------------------------------------------------------*/
1450
vip_get_capture_state(void)
1452
return ((READ_VIP32(VIP_CONTROL1) & VIP_CONTROL1_RUNMODE_MASK) >>
1453
VIP_CONTROL1_RUNMODE_SHIFT);
1456
/*---------------------------------------------------------------------------
1457
* vip_get_current_line
1459
* This routine returns the current line that is being processed.
1460
*--------------------------------------------------------------------------*/
1463
vip_get_current_line(void)
1465
return (READ_VIP32(VIP_CURRENT_TARGET) & VIP_CTARGET_CLINE_MASK);
1468
/*---------------------------------------------------------------------------
1471
* This routine reads from the specified fifo address. As the fifo access
1472
* enable should be disabled when running in normal vip mode, this routine
1473
* enables and disables access around the read.
1474
* DIAGNOSTIC USE ONLY
1475
*--------------------------------------------------------------------------*/
1478
vip_read_fifo(unsigned long dwFifoAddress)
1480
unsigned long fifo_data;
1482
/* ENABLE FIFO ACCESS */
1484
vip_enable_fifo_access(1);
1486
/* NOW READ THE DATA */
1488
WRITE_VIP32(VIP_FIFO_ADDRESS, dwFifoAddress);
1489
fifo_data = READ_VIP32(VIP_FIFO_DATA);
1491
/* DISABLE FIFO ACCESS */
1493
vip_enable_fifo_access(0);
1498
/*---------------------------------------------------------------------------
1502
* This routine writes to the specified fifo address. As the fifo access
1503
* enable should be disabled when running in normal vip mode, this routine
1504
* enables and disables access around the write.
1505
* DIAGNOSTIC USE ONLY
1506
*--------------------------------------------------------------------------*/
1509
vip_write_fifo(unsigned long dwFifoAddress, unsigned long dwFifoData)
1511
/* ENABLE FIFO ACCESS */
1513
vip_enable_fifo_access(1);
1515
/* WRITE THE FIFO DATA */
1517
WRITE_VIP32(VIP_FIFO_ADDRESS, dwFifoAddress);
1518
WRITE_VIP32(VIP_FIFO_DATA, dwFifoData);
1520
/* DISABLE FIFO ACCESS */
1522
vip_enable_fifo_access(0);
1524
return CIM_STATUS_OK;
1527
/*---------------------------------------------------------------------------
1528
* vip_enable_fifo_access
1530
* This routine enables/disables access to the vip fifo.
1531
* DIAGNOSTIC USE ONLY
1532
*--------------------------------------------------------------------------*/
1535
vip_enable_fifo_access(int enable)
1539
cw2 = READ_VIP32(VIP_CONTROL2);
1542
cw2 |= VIP_CONTROL2_FIFO_ACCESS;
1544
cw2 &= ~VIP_CONTROL2_FIFO_ACCESS;
1546
WRITE_VIP32(VIP_CONTROL2, cw2);
1548
return CIM_STATUS_OK;
1551
/*---------------------------------------------------------------------------
1552
* vip_get_power_characteristics
1554
* This routine returns the current VIP clock gating state in a
1556
*--------------------------------------------------------------------------*/
1559
vip_get_power_characteristics(VIPPOWERBUFFER * buffer)
1564
return CIM_STATUS_INVALIDPARAMS;
1566
/* READ THE EXISTING STATE */
1568
msr_read64(MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_PM, &q_word);
1570
/* DECODE THE CLOCK GATING BITS */
1572
buffer->glink_clock_mode = (int) (q_word.low & VIP_MSR_POWER_GLINK);
1573
buffer->vip_clock_mode = (int) (q_word.low & VIP_MSR_POWER_CLOCK);
1575
return CIM_STATUS_OK;
1578
/*---------------------------------------------------------------------------
1579
* vip_get_priority_characteristics
1581
* This routine returns the priority characteristics in the supplied
1582
* VIPPRIORITYBUFFER.
1583
*--------------------------------------------------------------------------*/
1586
vip_get_priority_characteristics(VIPPRIORITYBUFFER * buffer)
1591
return CIM_STATUS_INVALIDPARAMS;
1593
/* READ THE CURRENT STATE */
1595
msr_read64(MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_CONFIG, &q_word);
1597
/* DECODE THE PRIORITIES */
1599
buffer->secondary = (q_word.low & VIP_MSR_MCR_SECOND_PRIORITY_MASK) >>
1600
VIP_MSR_MCR_SECOND_PRIORITY_SHIFT;
1601
buffer->primary = (q_word.low & VIP_MSR_MCR_PRIMARY_PRIORITY_MASK) >>
1602
VIP_MSR_MCR_PRIMARY_PRIORITY_SHIFT;
1603
buffer->pid = q_word.low & VIP_MSR_MCR_PID_MASK;
1605
return CIM_STATUS_OK;
1608
/*---------------------------------------------------------------------------
1609
* vip_get_capability_characteristics
1611
* This routine returns revision information for the device.
1612
*--------------------------------------------------------------------------*/
1615
vip_get_capability_characteristics(VIPCAPABILITIESBUFFER * buffer)
1620
return CIM_STATUS_INVALIDPARAMS;
1622
/* READ THE CURRENT MSR CONTENTS */
1624
msr_read64(MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_CAP, &q_word);
1626
/* DECODE THE REVISIONS */
1628
buffer->revision_id = (q_word.low & VIP_MSR_CAP_REVID_MASK) >>
1629
VIP_MSR_CAP_REVID_SHIFT;
1630
buffer->device_id = (q_word.low & VIP_MSR_CAP_DEVID_MASK) >>
1631
VIP_MSR_CAP_DEVID_SHIFT;
1632
buffer->n_clock_domains = (q_word.low & VIP_MSR_CAP_NCLK_MASK) >>
1633
VIP_MSR_CAP_NCLK_SHIFT;
1634
buffer->n_smi_registers = (q_word.low & VIP_MSR_CAP_NSMI_MASK) >>
1635
VIP_MSR_CAP_NSMI_SHIFT;
1637
return CIM_STATUS_OK;