1f29dbc25Smrg/*
2f29dbc25Smrg * Copyright (c) 2006 Advanced Micro Devices, Inc.
3f29dbc25Smrg *
4f29dbc25Smrg * Permission is hereby granted, free of charge, to any person obtaining a
5f29dbc25Smrg * copy of this software and associated documentation files (the "Software"),
6f29dbc25Smrg * to deal in the Software without restriction, including without limitation
7f29dbc25Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8f29dbc25Smrg * and/or sell copies of the Software, and to permit persons to whom the
9f29dbc25Smrg * Software is furnished to do so, subject to the following conditions:
10f29dbc25Smrg *
11f29dbc25Smrg * The above copyright notice and this permission notice shall be included in
12f29dbc25Smrg * all copies or substantial portions of the Software.
13f29dbc25Smrg *
14f29dbc25Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15f29dbc25Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16f29dbc25Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17f29dbc25Smrg * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18f29dbc25Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19f29dbc25Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20f29dbc25Smrg * DEALINGS IN THE SOFTWARE.
21f29dbc25Smrg *
22f29dbc25Smrg * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
23f29dbc25Smrg * contributors may be used to endorse or promote products derived from this
24f29dbc25Smrg * software without specific prior written permission.
25f29dbc25Smrg */
26f29dbc25Smrg
27f29dbc25Smrg /*
28f29dbc25Smrg  * Cimarron VOP configuration routines.
29f29dbc25Smrg  */
30f29dbc25Smrg
31f29dbc25Smrg/*---------------------------------------------------------------------------
32f29dbc25Smrg * vop_set_vbi_window
33f29dbc25Smrg *
34f29dbc25Smrg * This routine configures the output position and location in memory of
35f29dbc25Smrg * VBI data.
36f29dbc25Smrg *--------------------------------------------------------------------------*/
37f29dbc25Smrg
38f29dbc25Smrgint
39f29dbc25Smrgvop_set_vbi_window(VOPVBIWINDOWBUFFER * buffer)
40f29dbc25Smrg{
41f29dbc25Smrg    unsigned long unlock, temp;
42f29dbc25Smrg    unsigned long hstart, hstop;
43f29dbc25Smrg    unsigned long htotal, hsyncstart;
44f29dbc25Smrg
45f29dbc25Smrg    if (!buffer)
46f29dbc25Smrg        return CIM_STATUS_INVALIDPARAMS;
47f29dbc25Smrg
48f29dbc25Smrg    unlock = READ_REG32(DC3_UNLOCK);
49f29dbc25Smrg    WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE);
50f29dbc25Smrg
51f29dbc25Smrg    /* PROGRAM HORIZONTAL POSITION
52f29dbc25Smrg     * The horizontal position is a little tricky.  The counter for the
53f29dbc25Smrg     * horizontal timings is reused for the VBI counter.  Consequently, the
54f29dbc25Smrg     * horizontal start and stop values are based off the beginning of active
55f29dbc25Smrg     * data.  However, the VG has a quirk.  If the counter start position is
56f29dbc25Smrg     * before the beginning of HSync, it applies to the previous line.  If
57f29dbc25Smrg     * the counter is after the beginning of HSync it applies to the current
58f29dbc25Smrg     * line.  So, for one line the real range can be thought of as
59f29dbc25Smrg     * HSync_start to (HSync_start + htotal - 1).  However, the counters
60f29dbc25Smrg     * must be between 0 and htotal - 1.  When placing VBI data before the
61f29dbc25Smrg     * start of active data, the horizontal end position will thus be *less*
62f29dbc25Smrg     * than the horizontal start.
63f29dbc25Smrg     */
64f29dbc25Smrg
65f29dbc25Smrg    htotal = ((READ_REG32(DC3_H_ACTIVE_TIMING) >> 16) & 0xFFF) + 1;
66f29dbc25Smrg    hsyncstart = (READ_REG32(DC3_H_SYNC_TIMING) & 0xFFF) + 1;
67f29dbc25Smrg
68f29dbc25Smrg    if (buffer->horz_from_hsync) {
69f29dbc25Smrg        /* VERIFY THAT THE INPUT IS VALID */
70f29dbc25Smrg
71f29dbc25Smrg        if (buffer->horz_start < 0
72f29dbc25Smrg            || (buffer->horz_start + buffer->vbi_width) > htotal)
73f29dbc25Smrg            return CIM_STATUS_INVALIDPARAMS;
74f29dbc25Smrg
75f29dbc25Smrg        hstart = buffer->horz_start + hsyncstart;
7604007ebaSmrg    }
7704007ebaSmrg    else {
78f29dbc25Smrg        /* VERIFY THAT THE INPUT IS VALID */
79f29dbc25Smrg
8004007ebaSmrg        if (buffer->horz_start < ((long) hsyncstart - (long) htotal) ||
8104007ebaSmrg            buffer->horz_start > (long) hsyncstart ||
82f29dbc25Smrg            buffer->vbi_width > htotal) {
83f29dbc25Smrg            return CIM_STATUS_INVALIDPARAMS;
84f29dbc25Smrg        }
85f29dbc25Smrg
86f29dbc25Smrg        hstart = buffer->horz_start + htotal;
87f29dbc25Smrg    }
88f29dbc25Smrg
89f29dbc25Smrg    hstop = hstart + buffer->vbi_width;
90f29dbc25Smrg    if (hstart > htotal)
91f29dbc25Smrg        hstart -= htotal;
92f29dbc25Smrg    if (hstop > htotal)
93f29dbc25Smrg        hstop -= htotal;
94f29dbc25Smrg    hstart--;
95f29dbc25Smrg    hstop--;
96f29dbc25Smrg    WRITE_REG32(DC3_VBI_HOR, ((hstop << DC3_VBI_HOR_END_SHIFT) &
9704007ebaSmrg                              DC3_VBI_HOR_END_MASK) | (hstart &
9804007ebaSmrg                                                       DC3_VBI_HOR_START_MASK));
99f29dbc25Smrg
100f29dbc25Smrg    /* WRITE LINE CAPTURE MASKS */
101f29dbc25Smrg
102f29dbc25Smrg    WRITE_REG32(DC3_VBI_LN_ODD, ((buffer->odd_line_offset <<
10304007ebaSmrg                                  DC3_VBI_ODD_LINE_SHIFT) &
10404007ebaSmrg                                 DC3_VBI_ODD_LINE_MASK) |
10504007ebaSmrg                (buffer->odd_line_capture_mask & DC3_VBI_ODD_ENABLE_MASK));
106f29dbc25Smrg
107f29dbc25Smrg    WRITE_REG32(DC3_VBI_LN_EVEN, ((buffer->even_line_offset <<
10804007ebaSmrg                                   DC3_VBI_EVEN_LINE_SHIFT) &
10904007ebaSmrg                                  DC3_VBI_EVEN_LINE_MASK) |
11004007ebaSmrg                (buffer->even_line_capture_mask & DC3_VBI_EVEN_ENABLE_MASK));
111f29dbc25Smrg
112f29dbc25Smrg    /* PROGRAM SOURCE OFFSETS
113f29dbc25Smrg     * Start with the even offsets.  Note that we always enable 16-bit VBI,
114f29dbc25Smrg     * as this is the only way to get VBI data on each VOP clock.
115f29dbc25Smrg     */
116f29dbc25Smrg
117f29dbc25Smrg    temp = READ_REG32(DC3_VBI_EVEN_CTL) & ~DC3_VBI_EVEN_CTL_OFFSET_MASK;
118f29dbc25Smrg    temp |= DC3_VBI_EVEN_CTL_ENABLE_16;
119f29dbc25Smrg    if (buffer->enable_upscale)
120f29dbc25Smrg        temp |= DC3_VBI_EVEN_CTL_UPSCALE;
121f29dbc25Smrg    WRITE_REG32(DC3_VBI_EVEN_CTL, temp |
12204007ebaSmrg                (buffer->even_address_offset & DC3_VBI_EVEN_CTL_OFFSET_MASK));
123f29dbc25Smrg
124f29dbc25Smrg    /* ODD OFFSET */
125f29dbc25Smrg
126f29dbc25Smrg    temp = READ_REG32(DC3_VBI_ODD_CTL) & ~DC3_VBI_ODD_CTL_OFFSET_MASK;
127f29dbc25Smrg    WRITE_REG32(DC3_VBI_ODD_CTL, temp |
12804007ebaSmrg                (buffer->odd_address_offset & DC3_VBI_ODD_CTL_OFFSET_MASK));
129f29dbc25Smrg
130f29dbc25Smrg    /* PITCH */
131f29dbc25Smrg
132f29dbc25Smrg    temp = ((buffer->data_size >> 3) << 16) | ((buffer->data_pitch >> 3) &
13304007ebaSmrg                                               0x0000FFFF);
134f29dbc25Smrg    WRITE_REG32(DC3_VBI_PITCH, temp);
135f29dbc25Smrg
136f29dbc25Smrg    WRITE_REG32(DC3_UNLOCK, unlock);
137f29dbc25Smrg
138f29dbc25Smrg    return CIM_STATUS_OK;
139f29dbc25Smrg}
140f29dbc25Smrg
141f29dbc25Smrg/*---------------------------------------------------------------------------
142f29dbc25Smrg * vop_enable_vbi_output
143f29dbc25Smrg *
144f29dbc25Smrg * This routine enables/disables VBI fetching inside the video generator.
145f29dbc25Smrg *--------------------------------------------------------------------------*/
146f29dbc25Smrg
147f29dbc25Smrgint
148f29dbc25Smrgvop_enable_vbi_output(int enable)
149f29dbc25Smrg{
150f29dbc25Smrg    unsigned long unlock, temp;
151f29dbc25Smrg
152f29dbc25Smrg    unlock = READ_REG32(DC3_UNLOCK);
153f29dbc25Smrg    temp = READ_REG32(DC3_VBI_EVEN_CTL);
154f29dbc25Smrg
155f29dbc25Smrg    if (enable)
156f29dbc25Smrg        temp |= DC3_VBI_ENABLE;
157f29dbc25Smrg    else
158f29dbc25Smrg        temp &= ~DC3_VBI_ENABLE;
159f29dbc25Smrg
160f29dbc25Smrg    WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE);
161f29dbc25Smrg    WRITE_REG32(DC3_VBI_EVEN_CTL, temp);
162f29dbc25Smrg    WRITE_REG32(DC3_UNLOCK, unlock);
163f29dbc25Smrg
164f29dbc25Smrg    return CIM_STATUS_OK;
165f29dbc25Smrg}
166f29dbc25Smrg
167f29dbc25Smrg/*---------------------------------------------------------------------------
168f29dbc25Smrg * vop_set_configuration
169f29dbc25Smrg *
170f29dbc25Smrg * This routine is passed a VOP_CONFIGURATION structure that contains all
171f29dbc25Smrg * the necessary information to configure VOP output.
172f29dbc25Smrg *--------------------------------------------------------------------------*/
173f29dbc25Smrg
174f29dbc25Smrgint
175f29dbc25Smrgvop_set_configuration(VOPCONFIGURATIONBUFFER * config)
176f29dbc25Smrg{
177f29dbc25Smrg    unsigned long vop_config = 0;
178f29dbc25Smrg    unsigned long alpha, control2;
179f29dbc25Smrg    unsigned long unlock;
180f29dbc25Smrg    unsigned long delta;
181f29dbc25Smrg    Q_WORD msr_value;
182f29dbc25Smrg    int rgb = 0;
183f29dbc25Smrg
184f29dbc25Smrg    if (!config)
185f29dbc25Smrg        return CIM_STATUS_INVALIDPARAMS;
186f29dbc25Smrg
187f29dbc25Smrg    unlock = READ_REG32(DC3_UNLOCK);
188f29dbc25Smrg    delta = READ_REG32(DC3_VID_DS_DELTA) & DC3_DS_DELTA_MASK;
189f29dbc25Smrg
190f29dbc25Smrg    /* OVERRIDE THE OUTPUT SETTINGS TO ENABLE VOP OUTPUT */
191f29dbc25Smrg
192f29dbc25Smrg    if (config->mode != VOP_MODE_DISABLED) {
193f29dbc25Smrg        msr_read64(MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_CONFIG, &msr_value);
194f29dbc25Smrg        msr_value.low &= ~DF_CONFIG_OUTPUT_MASK;
195f29dbc25Smrg        msr_value.low |= DF_OUTPUT_VOP;
196f29dbc25Smrg        msr_write64(MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_CONFIG, &msr_value);
197f29dbc25Smrg    }
198f29dbc25Smrg
199f29dbc25Smrg    /* SET THE UNIVERSAL VOP OPTIONS */
200f29dbc25Smrg
201f29dbc25Smrg    if (config->flags & VOP_FLAG_SWAP_UV)
202f29dbc25Smrg        vop_config |= VOP_CONFIG_SWAPUV;
203f29dbc25Smrg    if (config->flags & VOP_FLAG_SWAP_VBI)
204f29dbc25Smrg        vop_config |= VOP_CONFIG_SWAPVBI;
205f29dbc25Smrg
206f29dbc25Smrg    /* SET THE MODE SPECIFIC PARAMETERS */
207f29dbc25Smrg
208f29dbc25Smrg    if (config->mode == VOP_MODE_601) {
209f29dbc25Smrg        vop_config |= config->vop601.flags;
210f29dbc25Smrg        vop_config |= config->vop601.vsync_shift;
211f29dbc25Smrg        vop_config |= VOP_CONFIG_ENABLE_601 | VOP_CONFIG_VIP2_0;
212f29dbc25Smrg
213f29dbc25Smrg        switch (config->vop601.output_mode) {
214f29dbc25Smrg        case VOP_601_YUV_16BIT:
215f29dbc25Smrg            vop_config |= VOP_CONFIG_VIP2_16BIT;
216f29dbc25Smrg            break;
217f29dbc25Smrg        case VOP_601_YUV_4_4_4:
218f29dbc25Smrg            vop_config |= VOP_CONFIG_DISABLE_DECIMATE;
219f29dbc25Smrg            break;
220f29dbc25Smrg        case VOP_601_RGB_8_8_8:
221f29dbc25Smrg            vop_config |= VOP_CONFIG_DISABLE_DECIMATE | VOP_CONFIG_RGBMODE;
222f29dbc25Smrg            rgb = 1;
223f29dbc25Smrg            break;
224f29dbc25Smrg        }
225f29dbc25Smrg
226f29dbc25Smrg        if (config->vop601.vsync_shift == VOP_VSYNC_LATER_BY_X) {
227f29dbc25Smrg            delta |= (config->vop601.vsync_shift_count &
22804007ebaSmrg                      DC3_601_VSYNC_SHIFT_MASK);
229f29dbc25Smrg            delta |= DC3_601_VSYNC_SHIFT_ENABLE;
230f29dbc25Smrg        }
23104007ebaSmrg    }
23204007ebaSmrg    else {
233f29dbc25Smrg        if (config->flags & VOP_FLAG_VBI)
234f29dbc25Smrg            vop_config |= VOP_CONFIG_VBI;
235f29dbc25Smrg        if (config->flags & VOP_FLAG_TASK)
236f29dbc25Smrg            vop_config |= VOP_CONFIG_TASK;
237f29dbc25Smrg        if (config->flags & VOP_FLAG_SINGLECHIPCOMPAT)
238f29dbc25Smrg            vop_config |= VOP_CONFIG_SC_COMPATIBLE;
239f29dbc25Smrg        if (config->flags & VOP_FLAG_EXTENDEDSAV)
240f29dbc25Smrg            vop_config |= VOP_CONFIG_EXTENDED_SAV;
241f29dbc25Smrg
242f29dbc25Smrg        switch (config->mode) {
243f29dbc25Smrg        case VOP_MODE_DISABLED:
244f29dbc25Smrg            vop_config |= VOP_CONFIG_DISABLED;
245f29dbc25Smrg            break;
246f29dbc25Smrg        case VOP_MODE_VIP11:
247f29dbc25Smrg            vop_config |= VOP_CONFIG_VIP1_1;
248f29dbc25Smrg            break;
249f29dbc25Smrg        case VOP_MODE_CCIR656:
250f29dbc25Smrg            vop_config |= VOP_CONFIG_CCIR656;
251f29dbc25Smrg            break;
252f29dbc25Smrg        case VOP_MODE_VIP20_8BIT:
253f29dbc25Smrg            vop_config |= VOP_CONFIG_VIP2_0;
254f29dbc25Smrg            break;
255f29dbc25Smrg        case VOP_MODE_VIP20_16BIT:
256f29dbc25Smrg            vop_config |= VOP_CONFIG_VIP2_0 | VOP_CONFIG_VIP2_16BIT;
257f29dbc25Smrg            break;
258f29dbc25Smrg        }
259f29dbc25Smrg    }
260f29dbc25Smrg
261f29dbc25Smrg    /* SET THE 4:4:4 TO 4:2:2 DECIMATION ALGORITHM */
262f29dbc25Smrg
263f29dbc25Smrg    vop_config |= (config->conversion_mode);
264f29dbc25Smrg
265f29dbc25Smrg    /* SET THE VSYNC OUT OPTIONS */
266f29dbc25Smrg
267f29dbc25Smrg    control2 = READ_VIP32(VIP_CONTROL2) & ~VIP_CONTROL2_SYNC2PIN_MASK;
268f29dbc25Smrg    control2 |= config->vsync_out;
269f29dbc25Smrg    WRITE_VIP32(VIP_CONTROL2, control2);
270f29dbc25Smrg
271f29dbc25Smrg    /* FORCE THE CORRECT VOP COLOR SPACE */
272f29dbc25Smrg    /* The output of the mixer will be either RGB or YUV.  We must enable */
273f29dbc25Smrg    /* or disable the VOP CSC based on the desired output format.         */
274f29dbc25Smrg
275f29dbc25Smrg    alpha = READ_VID32(DF_VID_ALPHA_CONTROL);
276f29dbc25Smrg    if (!(alpha & DF_CSC_GRAPHICS_RGB_TO_YUV)) {
277f29dbc25Smrg        /* RGB OUTPUT FROM THE MIXER */
278f29dbc25Smrg
279f29dbc25Smrg        if (!rgb)
280f29dbc25Smrg            alpha |= DF_CSC_VOP_RGB_TO_YUV;
281f29dbc25Smrg        else
282f29dbc25Smrg            alpha &= ~DF_CSC_VOP_RGB_TO_YUV;
28304007ebaSmrg    }
28404007ebaSmrg    else {
285f29dbc25Smrg        /* YUV OUTPUT FROM THE MIXER */
286f29dbc25Smrg        /* As there is no YUV->RGB VOP conversion, we simply disable the */
287f29dbc25Smrg        /* VOP CSC and trust that the user is competent.                 */
288f29dbc25Smrg
289f29dbc25Smrg        alpha &= ~DF_CSC_VOP_RGB_TO_YUV;
290f29dbc25Smrg    }
291f29dbc25Smrg
292f29dbc25Smrg    /* AND WRITE THE CONFIGURATION */
293f29dbc25Smrg
294f29dbc25Smrg    WRITE_VID32(DF_VID_ALPHA_CONTROL, alpha);
295f29dbc25Smrg    WRITE_VOP32(VOP_CONFIGURATION, vop_config);
296f29dbc25Smrg    WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE);
297f29dbc25Smrg    WRITE_REG32(DC3_VID_DS_DELTA, delta);
298f29dbc25Smrg    WRITE_REG32(DC3_UNLOCK, unlock);
299f29dbc25Smrg
300f29dbc25Smrg    return CIM_STATUS_OK;
301f29dbc25Smrg}
302f29dbc25Smrg
303f29dbc25Smrg/*---------------------------------------------------------------------------
304f29dbc25Smrg * vop_save_state
305f29dbc25Smrg *
306f29dbc25Smrg * This routine saves the necessary register contents in order to restore
307f29dbc25Smrg * at a later point to the same state.  Note that the capture state is
308f29dbc25Smrg * forced to OFF in this routine.
309f29dbc25Smrg *--------------------------------------------------------------------------*/
310f29dbc25Smrg
311f29dbc25Smrgint
312f29dbc25Smrgvop_save_state(VOPSTATEBUFFER * save_buffer)
313f29dbc25Smrg{
314f29dbc25Smrg    if (!save_buffer)
315f29dbc25Smrg        return CIM_STATUS_INVALIDPARAMS;
316f29dbc25Smrg
317f29dbc25Smrg    save_buffer->config = READ_VOP32(VOP_CONFIGURATION);
318f29dbc25Smrg
319f29dbc25Smrg    return CIM_STATUS_OK;
320f29dbc25Smrg}
321f29dbc25Smrg
322f29dbc25Smrg/*---------------------------------------------------------------------------
323f29dbc25Smrg * vop_restore_state
324f29dbc25Smrg *
325f29dbc25Smrg * This routine restores the state of the vop registers - which were
326f29dbc25Smrg * previously saved using vop_save_state.
327f29dbc25Smrg *--------------------------------------------------------------------------*/
328f29dbc25Smrg
329f29dbc25Smrgint
330f29dbc25Smrgvop_restore_state(VOPSTATEBUFFER * restore_buffer)
331f29dbc25Smrg{
332f29dbc25Smrg    if (!restore_buffer)
333f29dbc25Smrg        return CIM_STATUS_INVALIDPARAMS;
334f29dbc25Smrg
335f29dbc25Smrg    WRITE_VOP32(VOP_CONFIGURATION, restore_buffer->config);
336f29dbc25Smrg
337f29dbc25Smrg    return CIM_STATUS_OK;
338f29dbc25Smrg}
339f29dbc25Smrg
340f29dbc25Smrg/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
341f29dbc25Smrg * CIMARRON VOP READ ROUTINES
342f29dbc25Smrg * These routines are included for use in diagnostics or when debugging.  They
343f29dbc25Smrg * can be optionally excluded from a project.
344f29dbc25Smrg *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
345f29dbc25Smrg
346f29dbc25Smrg#if CIMARRON_INCLUDE_VOP_READ_ROUTINES
347f29dbc25Smrg
348f29dbc25Smrg/*---------------------------------------------------------------------------
349f29dbc25Smrg * vop_get_current_mode
350f29dbc25Smrg *
351f29dbc25Smrg * This routine reads the current VIP operating mode and stores it in the
352f29dbc25Smrg * passed VOP_CONFIGURATION structure.
353f29dbc25Smrg *--------------------------------------------------------------------------*/
354f29dbc25Smrg
355f29dbc25Smrgint
356f29dbc25Smrgvop_get_current_mode(VOPCONFIGURATIONBUFFER * config)
357f29dbc25Smrg{
358f29dbc25Smrg    unsigned long vop_config = 0;
359f29dbc25Smrg    unsigned long alpha;
360f29dbc25Smrg
361f29dbc25Smrg    if (!config)
362f29dbc25Smrg        return CIM_STATUS_INVALIDPARAMS;
363f29dbc25Smrg
364f29dbc25Smrg    vop_config = READ_VOP32(VOP_CONFIGURATION);
365f29dbc25Smrg    alpha = READ_VID32(DF_VID_ALPHA_CONTROL);
366f29dbc25Smrg
367f29dbc25Smrg    /* READ THE CURRENT MODE */
368f29dbc25Smrg
369f29dbc25Smrg    switch (vop_config & VOP_CONFIG_MODE_MASK) {
370f29dbc25Smrg    case VOP_CONFIG_DISABLED:
371f29dbc25Smrg        config->mode = VOP_MODE_DISABLED;
372f29dbc25Smrg        break;
373f29dbc25Smrg    case VOP_CONFIG_VIP1_1:
374f29dbc25Smrg        config->mode = VOP_MODE_VIP11;
375f29dbc25Smrg        break;
376f29dbc25Smrg    case VOP_CONFIG_CCIR656:
377f29dbc25Smrg        config->mode = VOP_MODE_CCIR656;
378f29dbc25Smrg        break;
379f29dbc25Smrg    case VOP_CONFIG_VIP2_0:
380f29dbc25Smrg
381f29dbc25Smrg        if (vop_config & VOP_CONFIG_ENABLE_601)
382f29dbc25Smrg            config->mode = VOP_MODE_601;
383f29dbc25Smrg        else if (vop_config & VOP_CONFIG_VIP2_16BIT)
384f29dbc25Smrg            config->mode = VOP_MODE_VIP20_16BIT;
385f29dbc25Smrg        else
386f29dbc25Smrg            config->mode = VOP_MODE_VIP20_8BIT;
387f29dbc25Smrg        break;
388f29dbc25Smrg    }
389f29dbc25Smrg
390f29dbc25Smrg    /* READ 601 SETTINGS */
391f29dbc25Smrg
392f29dbc25Smrg    config->vop601.flags = vop_config & (VOP_CONFIG_INVERT_DISPE |
39304007ebaSmrg                                         VOP_CONFIG_INVERT_HSYNC |
39404007ebaSmrg                                         VOP_CONFIG_INVERT_VSYNC);
395f29dbc25Smrg
396f29dbc25Smrg    config->vop601.vsync_shift = vop_config & VOP_CONFIG_VSYNC_MASK;
397f29dbc25Smrg    config->vop601.vsync_shift_count =
398f29dbc25Smrg        READ_REG32(DC3_VID_DS_DELTA) & DC3_601_VSYNC_SHIFT_MASK;
399f29dbc25Smrg
40004007ebaSmrg    if ((alpha & DF_CSC_GRAPHICS_RGB_TO_YUV) || (alpha & DF_CSC_VOP_RGB_TO_YUV)) {
401f29dbc25Smrg        /* YUV OUTPUT */
402f29dbc25Smrg
403f29dbc25Smrg        if (vop_config & VOP_CONFIG_DISABLE_DECIMATE)
404f29dbc25Smrg            config->vop601.output_mode = VOP_601_YUV_4_4_4;
405f29dbc25Smrg        else if (vop_config & VOP_CONFIG_VIP2_16BIT)
406f29dbc25Smrg            config->vop601.output_mode = VOP_601_YUV_16BIT;
407f29dbc25Smrg        else
408f29dbc25Smrg            config->vop601.output_mode = VOP_601_YUV_8BIT;
40904007ebaSmrg    }
41004007ebaSmrg    else {
411f29dbc25Smrg        config->vop601.output_mode = VOP_601_RGB_8_8_8;
412f29dbc25Smrg    }
413f29dbc25Smrg
414f29dbc25Smrg    config->flags = 0;
415f29dbc25Smrg
416f29dbc25Smrg    /* READ THE UNIVERSAL VOP OPTIONS */
417f29dbc25Smrg
418f29dbc25Smrg    if (vop_config & VOP_CONFIG_SWAPUV)
419f29dbc25Smrg        config->flags |= VOP_FLAG_SWAP_UV;
420f29dbc25Smrg    if (vop_config & VOP_CONFIG_SWAPVBI)
421f29dbc25Smrg        config->flags |= VOP_FLAG_SWAP_VBI;
422f29dbc25Smrg    if (vop_config & VOP_CONFIG_VBI)
423f29dbc25Smrg        config->flags |= VOP_FLAG_VBI;
424f29dbc25Smrg    if (vop_config & VOP_CONFIG_TASK)
425f29dbc25Smrg        config->flags |= VOP_FLAG_TASK;
426f29dbc25Smrg    if (vop_config & VOP_CONFIG_SC_COMPATIBLE)
427f29dbc25Smrg        config->flags |= VOP_FLAG_SINGLECHIPCOMPAT;
428f29dbc25Smrg    if (vop_config & VOP_CONFIG_EXTENDED_SAV)
429f29dbc25Smrg        config->flags |= VOP_FLAG_EXTENDEDSAV;
430f29dbc25Smrg
431f29dbc25Smrg    config->conversion_mode = vop_config & VOP_CONFIG_422_MASK;
432f29dbc25Smrg
433f29dbc25Smrg    config->vsync_out = READ_VIP32(VIP_CONTROL2) & VIP_CONTROL2_SYNC2PIN_MASK;
434f29dbc25Smrg
435f29dbc25Smrg    return CIM_STATUS_OK;
436f29dbc25Smrg}
437f29dbc25Smrg
438f29dbc25Smrg/*---------------------------------------------------------------------------
439f29dbc25Smrg * vop_get_vbi_window
440f29dbc25Smrg *
441f29dbc25Smrg * This routine reads the current VBI configuration for VOP output.
442f29dbc25Smrg *--------------------------------------------------------------------------*/
443f29dbc25Smrg
444f29dbc25Smrgint
445f29dbc25Smrgvop_get_vbi_configuration(VOPVBIWINDOWBUFFER * buffer)
446f29dbc25Smrg{
447f29dbc25Smrg    unsigned long temp;
448f29dbc25Smrg    unsigned long hstart, hstop;
449f29dbc25Smrg    unsigned long htotal, hsyncstart;
450f29dbc25Smrg
451f29dbc25Smrg    if (!buffer)
452f29dbc25Smrg        return CIM_STATUS_INVALIDPARAMS;
453f29dbc25Smrg
454f29dbc25Smrg    htotal = ((READ_REG32(DC3_H_ACTIVE_TIMING) >> 16) & 0xFFF) + 1;
455f29dbc25Smrg    hsyncstart = (READ_REG32(DC3_H_SYNC_TIMING) & 0xFFF) + 1;
456f29dbc25Smrg
457f29dbc25Smrg    /* DECODE HORIZONTAL POSITION */
458f29dbc25Smrg    /* This is done according to the requested horizontal origin */
459f29dbc25Smrg
460f29dbc25Smrg    temp = READ_REG32(DC3_VBI_HOR);
461f29dbc25Smrg    hstart = (temp & DC3_VBI_HOR_START_MASK) + 1;
462f29dbc25Smrg    hstop = ((temp & DC3_VBI_HOR_END_MASK) >> DC3_VBI_HOR_END_SHIFT) + 1;
463f29dbc25Smrg    if (buffer->horz_from_hsync) {
464f29dbc25Smrg        buffer->horz_start = hstart + htotal - hsyncstart;
46504007ebaSmrg        if (buffer->horz_start >= (long) htotal)
466f29dbc25Smrg            buffer->horz_start -= htotal;
46704007ebaSmrg    }
46804007ebaSmrg    else {
469f29dbc25Smrg        if (hstart > hsyncstart)
47004007ebaSmrg            buffer->horz_start = (long) hstart - (long) htotal;
471f29dbc25Smrg        else
472f29dbc25Smrg            buffer->horz_start = hstart;
473f29dbc25Smrg    }
474f29dbc25Smrg
475f29dbc25Smrg    if (hstop > hstart)
476f29dbc25Smrg        buffer->vbi_width = hstop - hstart;
477f29dbc25Smrg    else
478f29dbc25Smrg        buffer->vbi_width = (htotal - hstart) + hstop;
479f29dbc25Smrg
480f29dbc25Smrg    /* READ LINE MASKS */
481f29dbc25Smrg
482f29dbc25Smrg    temp = READ_REG32(DC3_VBI_LN_ODD);
483f29dbc25Smrg    buffer->odd_line_offset = (temp & DC3_VBI_ODD_LINE_MASK) >>
484f29dbc25Smrg        DC3_VBI_ODD_LINE_SHIFT;
485f29dbc25Smrg    buffer->odd_line_capture_mask = (temp & DC3_VBI_ODD_ENABLE_MASK);
486f29dbc25Smrg
487f29dbc25Smrg    temp = READ_REG32(DC3_VBI_LN_EVEN);
488f29dbc25Smrg    buffer->even_line_offset = (temp & DC3_VBI_EVEN_LINE_MASK) >>
489f29dbc25Smrg        DC3_VBI_EVEN_LINE_SHIFT;
490f29dbc25Smrg    buffer->even_line_capture_mask = (temp & DC3_VBI_EVEN_ENABLE_MASK);
491f29dbc25Smrg
492f29dbc25Smrg    /* READ VBI UPSCALE SETTINGS */
493f29dbc25Smrg
494f29dbc25Smrg    buffer->enable_upscale = 0;
495f29dbc25Smrg    temp = READ_REG32(DC3_VBI_EVEN_CTL);
496f29dbc25Smrg    if (temp & DC3_VBI_EVEN_CTL_UPSCALE)
497f29dbc25Smrg        buffer->enable_upscale = 1;
498f29dbc25Smrg
499f29dbc25Smrg    /* READ SOURCE OFFSETS */
500f29dbc25Smrg
501f29dbc25Smrg    buffer->even_address_offset = temp & DC3_VBI_EVEN_CTL_OFFSET_MASK;
502f29dbc25Smrg    buffer->odd_address_offset =
503f29dbc25Smrg        READ_REG32(DC3_VBI_ODD_CTL) & DC3_VBI_ODD_CTL_OFFSET_MASK;
504f29dbc25Smrg
505f29dbc25Smrg    /* PITCH AND SIZE */
506f29dbc25Smrg
507f29dbc25Smrg    temp = READ_REG32(DC3_VBI_PITCH);
508f29dbc25Smrg    buffer->data_size = (temp >> 16) << 3;
509f29dbc25Smrg    buffer->data_pitch = (temp & 0xFFFF);
510f29dbc25Smrg
511f29dbc25Smrg    return CIM_STATUS_OK;
512f29dbc25Smrg}
513f29dbc25Smrg
514f29dbc25Smrg/*---------------------------------------------------------------------------
515f29dbc25Smrg * vop_get_vbi_enable
516f29dbc25Smrg *
517f29dbc25Smrg * This routine reads the current enable status of VBI output.
518f29dbc25Smrg *--------------------------------------------------------------------------*/
519f29dbc25Smrg
520f29dbc25Smrgint
521f29dbc25Smrgvop_get_vbi_enable(void)
522f29dbc25Smrg{
523f29dbc25Smrg    if (READ_REG32(DC3_VBI_EVEN_CTL) & DC3_VBI_ENABLE)
524f29dbc25Smrg        return 1;
525f29dbc25Smrg
526f29dbc25Smrg    return 0;
527f29dbc25Smrg}
528f29dbc25Smrg
529f29dbc25Smrg/*---------------------------------------------------------------------------
530f29dbc25Smrg * vop_get_crc
531f29dbc25Smrg *
532f29dbc25Smrg * This routine returns a CRC of the current VOP data
533f29dbc25Smrg --------------------------------------------------------------------------*/
534f29dbc25Smrg
535f29dbc25Smrgunsigned long
536f29dbc25Smrgvop_get_crc(void)
537f29dbc25Smrg{
538f29dbc25Smrg    unsigned long crc;
539f29dbc25Smrg    unsigned long config = READ_VOP32(VOP_CONFIGURATION);
540f29dbc25Smrg    unsigned long timeout = 1000;
541f29dbc25Smrg
542f29dbc25Smrg    if (!(READ_REG32(DC3_DISPLAY_CFG) & DC3_DCFG_TGEN))
543f29dbc25Smrg        return 0xFFFFFFFF;
544f29dbc25Smrg
545f29dbc25Smrg    /* RESET CRC */
546f29dbc25Smrg
547f29dbc25Smrg    WRITE_VOP32(VOP_CONFIGURATION, config & ~VOP_CONFIG_ENABLE_SIGNATURE);
548f29dbc25Smrg
549f29dbc25Smrg    /* WAIT FOR THE RESET TO BE LATCHED */
550f29dbc25Smrg
551f29dbc25Smrg    while ((READ_VOP32(VOP_SIGNATURE) != 0x00000001) && timeout)
552f29dbc25Smrg        timeout--;
553f29dbc25Smrg
554f29dbc25Smrg    WRITE_VOP32(VOP_CONFIGURATION, config | VOP_CONFIG_ENABLE_SIGNATURE);
555f29dbc25Smrg
556f29dbc25Smrg    /* WAIT UNTIL NOT ACTIVE, THEN ACTIVE, NOT ACTIVE, THEN ACTIVE */
557f29dbc25Smrg
55804007ebaSmrg    while (!(READ_VOP32(VOP_CONFIGURATION) & VOP_CONFIG_SIGVAL));
559f29dbc25Smrg
560f29dbc25Smrg    crc = READ_VOP32(VOP_SIGNATURE);
561f29dbc25Smrg
562f29dbc25Smrg    return crc;
563f29dbc25Smrg}
564f29dbc25Smrg
565f29dbc25Smrg/*---------------------------------------------------------------------------
566f29dbc25Smrg * vop_read_vbi_crc
567f29dbc25Smrg *
568f29dbc25Smrg * This routine returns a CRC of the current VBI data
569f29dbc25Smrg ---------------------------------------------------------------------------*/
570f29dbc25Smrg
571f29dbc25Smrgunsigned long
572f29dbc25Smrgvop_read_vbi_crc(void)
573f29dbc25Smrg{
574f29dbc25Smrg    unsigned long gcfg, unlock, vbi_even;
575f29dbc25Smrg    unsigned long crc;
576f29dbc25Smrg
577f29dbc25Smrg    if (!(READ_REG32(DC3_DISPLAY_CFG) & DC3_DCFG_TGEN) ||
578f29dbc25Smrg        !(READ_REG32(DC3_VBI_EVEN_CTL) & DC3_VBI_ENABLE)) {
579f29dbc25Smrg        return 0xFFFFFFFF;
580f29dbc25Smrg    }
581f29dbc25Smrg
582f29dbc25Smrg    unlock = READ_REG32(DC3_UNLOCK);
583f29dbc25Smrg    gcfg = READ_REG32(DC3_GENERAL_CFG);
584f29dbc25Smrg    vbi_even = READ_REG32(DC3_VBI_EVEN_CTL);
585f29dbc25Smrg
586f29dbc25Smrg    gcfg |= DC3_GCFG_SGRE | DC3_GCFG_CRC_MODE;
587f29dbc25Smrg    gcfg &= ~(DC3_GCFG_SGFR | DC3_GCFG_SIG_SEL);
588f29dbc25Smrg    vbi_even |= DC3_VBI_EVEN_ENABLE_CRC;
589f29dbc25Smrg
590f29dbc25Smrg    WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE);
591f29dbc25Smrg    WRITE_REG32(DC3_VBI_EVEN_CTL, vbi_even);
592f29dbc25Smrg    WRITE_REG32(DC3_GENERAL_CFG, gcfg & ~DC3_GCFG_SIGE);
593f29dbc25Smrg    WRITE_REG32(DC3_GENERAL_CFG, gcfg | DC3_GCFG_SIGE);
594f29dbc25Smrg
595f29dbc25Smrg    /* WAIT FOR THE CRC TO BE COMPLETED */
596f29dbc25Smrg
59704007ebaSmrg    while (!(READ_REG32(DC3_LINE_CNT_STATUS) & DC3_LNCNT_SIGC));
598f29dbc25Smrg
599f29dbc25Smrg    /* READ THE COMPLETED CRC */
600f29dbc25Smrg
601f29dbc25Smrg    crc = READ_REG32(DC3_PAL_DATA);
602f29dbc25Smrg
603f29dbc25Smrg    /* RESTORE THE PALETTE SETTINGS */
604f29dbc25Smrg
605f29dbc25Smrg    gcfg &= ~DC3_GCFG_SGRE;
606f29dbc25Smrg    WRITE_REG32(DC3_GENERAL_CFG, gcfg);
607f29dbc25Smrg    WRITE_REG32(DC3_UNLOCK, unlock);
608f29dbc25Smrg
609f29dbc25Smrg    return crc;
610f29dbc25Smrg}
611f29dbc25Smrg
612f29dbc25Smrg#endif
613