1/* Copyright (c) 2005 Advanced Micro Devices, Inc.
2 *
3 * Permission is hereby granted, free of charge, to any person obtaining a copy
4 * of this software and associated documentation files (the "Software"), to
5 * deal in the Software without restriction, including without limitation the
6 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7 * sell copies of the Software, and to permit persons to whom the Software is
8 * furnished to do so, subject to the following conditions:
9 *
10 * The above copyright notice and this permission notice shall be included in
11 * all copies or substantial portions of the Software.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19 * IN THE SOFTWARE.
20 *
21 * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
22 * contributors may be used to endorse or promote products derived from this
23 * software without specific prior written permission.
24 */
25
26/*
27 * This file contains routines for the second generation display controller.
28 * */
29
30void gu2_enable_compression(void);      /* private routine definition */
31void gu2_disable_compression(void);     /* private routine definition */
32int gfx_set_display_control(int sync_polarities);       /* private routine
33                                                         * definition */
34void gfx_reset_video(void);
35int gu2_set_specified_mode(DISPLAYMODE * pMode, int bpp);
36
37 /*---------------------------------------------------------------------------
38 * WARNING!!!! INACCURATE DELAY MECHANISM
39 *
40 * In an effort to keep the code self contained and operating system
41 * independent, the delay loop just performs reads of a display controller
42 * register.  This time will vary for faster processors.  The delay can always
43 * be longer than intended, only effecting the time of the mode switch
44 * (obviously want it to still be under a second).  Problems with the hardware
45 * only arise if the delay is not long enough.
46 *----------------------------------------------------------------------------
47 */
48#define RC_READS_PER_MILLISECOND 15000L
49
50#if GFX_DISPLAY_DYNAMIC
51void
52gu2_delay_milliseconds(unsigned long milliseconds)
53#else
54void
55gfx_delay_milliseconds(unsigned long milliseconds)
56#endif
57{
58    /* ASSUME 300 MHZ 20 CLOCKS PER READ */
59    unsigned long loop;
60
61    loop = milliseconds * RC_READS_PER_MILLISECOND;
62    while (loop-- > 0) {
63        READ_REG32(MDC_UNLOCK);
64    }
65}
66
67#if GFX_DISPLAY_DYNAMIC
68void
69gu2_delay_microseconds(unsigned long microseconds)
70#else
71void
72gfx_delay_microseconds(unsigned long microseconds)
73#endif
74{
75    /* ASSUME 400 MHz, 2 CLOCKS PER INCREMENT */
76    unsigned long loop_count = microseconds * 15;
77
78    while (loop_count-- > 0) {
79        READ_REG32(MDC_UNLOCK);
80    }
81}
82
83/*----------------------------------------------------------------------------
84 * GFX_SET_DISPLAY_BPP
85 *
86 * This routine programs the bpp in the display controller.
87 *----------------------------------------------------------------------------
88 */
89#if GFX_DISPLAY_DYNAMIC
90int
91gu2_set_display_bpp(unsigned short bpp)
92#else
93int
94gfx_set_display_bpp(unsigned short bpp)
95#endif
96{
97    unsigned long dcfg, lock;
98
99    dcfg =
100        READ_REG32(MDC_DISPLAY_CFG) & ~(MDC_DCFG_DISP_MODE_MASK |
101                                        MDC_DCFG_16BPP_MODE_MASK);
102    lock = READ_REG32(MDC_UNLOCK);
103
104    switch (bpp) {
105    case 12:
106        dcfg |= (MDC_DCFG_DISP_MODE_16BPP | MDC_DCFG_12BPP);
107        break;
108    case 15:
109        dcfg |= (MDC_DCFG_DISP_MODE_16BPP | MDC_DCFG_15BPP);
110        break;
111    case 16:
112        dcfg |= (MDC_DCFG_DISP_MODE_16BPP | MDC_DCFG_16BPP);
113        break;
114    case 32:
115        dcfg |= (MDC_DCFG_DISP_MODE_24BPP);
116        break;
117    case 8:
118        dcfg |= (MDC_DCFG_DISP_MODE_8BPP);
119        break;
120    default:
121        return GFX_STATUS_BAD_PARAMETER;
122    }
123
124    WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
125    WRITE_REG32(MDC_DISPLAY_CFG, dcfg);
126    WRITE_REG32(MDC_UNLOCK, lock);
127
128    /* SET BPP IN GRAPHICS PIPELINE */
129    gfx_set_bpp(bpp);
130
131    return 0;
132}
133
134/*----------------------------------------------------------------------------
135 * gu2_set_specified_mode (private routine)
136 * This routine uses the parameters in the specified display mode structure
137 * to program the display controller hardware.
138 *----------------------------------------------------------------------------
139 */
140int
141gu2_set_specified_mode(DISPLAYMODE * pMode, int bpp)
142{
143    unsigned long unlock, value;
144    unsigned long gcfg, dcfg;
145    unsigned long size, pitch;
146    unsigned long vid_buf_size;
147    unsigned long bpp_mask, temp, dv_size;
148
149    /* CHECK WHETHER TIMING CHANGE IS ALLOWED */
150    /* Flag used for locking also overrides timing change restriction */
151    if (gfx_timing_lock && !(pMode->flags & GFX_MODE_LOCK_TIMING))
152        return GFX_STATUS_ERROR;
153
154    /* CLEAR PANNING OFFSETS */
155    DeltaX = 0;
156    DeltaY = 0;
157    panelLeft = 0;
158    panelTop = 0;
159
160    /* SET GLOBAL FLAG */
161
162    if (pMode->flags & GFX_MODE_LOCK_TIMING)
163        gfx_timing_lock = 1;
164
165    /* CHECK FOR VALID BPP                          */
166    /* As this function can be called directly from */
167    /* gfx_set_display_timings, we must correct any */
168    /* invalid bpp settings.                        */
169    switch (bpp) {
170    case 12:
171        bpp_mask = 0x00000900;
172        break;
173    case 15:
174        bpp_mask = 0x00000500;
175        break;
176    case 16:
177        bpp_mask = 0x00000100;
178        break;
179    case 32:
180        bpp_mask = 0x00000200;
181        break;
182    default:
183        bpp_mask = 0x00000000;
184        bpp = 8;
185        break;
186    }
187
188    gbpp = bpp;
189
190    /* DISABLE COMPRESSION */
191    gu2_disable_compression();
192
193    /* ALSO DISABLE VIDEO */
194    /* Use private "reset video" routine to do all that is needed. */
195    /* SC1200, for example, also disables the alpha blending regions. */
196    gfx_reset_video();
197
198    /* UNLOCK THE DISPLAY CONTROLLER REGISTERS */
199    unlock = READ_REG32(MDC_UNLOCK);
200    WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
201
202    /* READ THE CURRENT REGISTER VALUES */
203    gcfg = READ_REG32(MDC_GENERAL_CFG);
204    dcfg = READ_REG32(MDC_DISPLAY_CFG);
205
206    /* BLANK THE DISPLAY IN THE DISPLAY FILTER */
207    gfx_set_crt_enable(0);
208
209    /* DISABLE THE TIMING GENERATOR */
210    dcfg &= ~(unsigned long) MDC_DCFG_TGEN;
211    WRITE_REG32(MDC_DISPLAY_CFG, dcfg);
212
213    /* DELAY: WAIT FOR PENDING MEMORY REQUESTS                            */
214    /* This delay is used to make sure that all pending requests to the   */
215    /* memory controller have completed before disabling the FIFO load.   */
216    gfx_delay_milliseconds(5);
217
218    /* DISABLE DISPLAY FIFO LOAD */
219    gcfg &= ~(unsigned long) MDC_GCFG_DFLE;
220    WRITE_REG32(MDC_GENERAL_CFG, gcfg);
221
222    /* PRESERVE VIDEO INFORMATION */
223    gcfg &= (unsigned long) (MDC_GCFG_YUVM | MDC_GCFG_VDSE);
224    dcfg = 0;
225
226    /* SET THE DOT CLOCK FREQUENCY             */
227    /* Mask off the divide by two bit (bit 31) */
228    if (!(pMode->flags & GFX_MODE_EXCLUDE_PLL))
229        gfx_set_clock_frequency(pMode->frequency & 0x7FFFFFFF);
230
231    /* DELAY: WAIT FOR THE PLL TO SETTLE */
232    /* This allows the dot clock frequency that was just set to settle. */
233    gfx_delay_milliseconds(10);
234
235    /* SET THE GX DISPLAY CONTROLLER PARAMETERS */
236    WRITE_REG32(MDC_FB_ST_OFFSET, 0);
237    WRITE_REG32(MDC_CB_ST_OFFSET, 0);
238    WRITE_REG32(MDC_CURS_ST_OFFSET, 0);
239    WRITE_REG32(MDC_ICON_ST_OFFSET, 0);
240
241    /* SET LINE SIZE AND PITCH */
242    /* 1. Flat Panels must use the mode width and not  */
243    /*    the timing width to set the pitch.           */
244    /* 2. Mode sets will use a pitch that is aligned   */
245    /*    on a 1K boundary to preserve legacy.  The    */
246    /*    pitch can be overridden by a subsequent call */
247    /*    to gfx_set_display_pitch.                    */
248    if (PanelEnable)
249        size = ModeWidth;
250    else
251        size = pMode->hactive;
252
253    if (bpp > 8)
254        size <<= 1;
255
256    if (bpp > 16)
257        size <<= 1;
258
259    pitch = 1024;
260    dv_size = MDC_DV_LINE_SIZE_1024;
261
262    if (size > 1024) {
263        pitch = 2048;
264        dv_size = MDC_DV_LINE_SIZE_2048;
265    }
266
267    if (size > 2048) {
268        pitch = 4096;
269        dv_size = MDC_DV_LINE_SIZE_4096;
270    }
271
272    if (size > 4096) {
273        pitch = 8192;
274        dv_size = MDC_DV_LINE_SIZE_8192;
275    }
276
277    WRITE_REG32(MDC_GFX_PITCH, pitch >> 3);
278
279    /* WRITE DIRTY/VALID CONTROL WITH LINE LENGTH */
280    temp = READ_REG32(MDC_DV_CTL);
281    WRITE_REG32(MDC_DV_CTL, (temp & ~MDC_DV_LINE_SIZE_MASK) | dv_size);
282
283    if (PanelEnable) {
284        size = pMode->hactive;
285        if (bpp > 8)
286            size <<= 1;
287        if (bpp > 16)
288            size <<= 1;
289    }
290
291    /* SAVE PREVIOUSLY STORED VIDEO LINE SIZE */
292    vid_buf_size = READ_REG32(MDC_LINE_SIZE) & 0xFF000000;
293
294    /* ADD 2 TO SIZE FOR POSSIBLE START ADDRESS ALIGNMENTS */
295    WRITE_REG32(MDC_LINE_SIZE, ((size >> 3) + 2) | vid_buf_size);
296
297    /* ALWAYS ENABLE VIDEO AND GRAPHICS DATA            */
298    /* These bits are relics from a previous design and */
299    /* should always be enabled.                        */
300    dcfg |= (unsigned long) (MDC_DCFG_VDEN | MDC_DCFG_GDEN);
301
302    /* SET PIXEL FORMAT */
303    dcfg |= bpp_mask;
304
305    /* ENABLE TIMING GENERATOR, TIM. REG. UPDATES, PALETTE BYPASS */
306    /* AND VERT. INT. SELECT                                      */
307    dcfg |=
308        (unsigned long) (MDC_DCFG_TGEN | MDC_DCFG_TRUP | MDC_DCFG_PALB |
309                         MDC_DCFG_VISL);
310
311    /* DISABLE ADDRESS MASKS */
312    dcfg |= MDC_DCFG_A20M;
313    dcfg |= MDC_DCFG_A18M;
314
315    /* SET FIFO PRIORITIES AND DISPLAY FIFO LOAD ENABLE     */
316    /* Set the priorities higher for high resolution modes. */
317    if (pMode->hactive > 1024 || bpp == 32)
318        gcfg |= 0x000A901;
319    else
320        gcfg |= 0x0006501;
321
322    /* ENABLE FLAT PANEL CENTERING                          */
323    /* For panel modes having a resolution smaller than the */
324    /* panel resolution, turn on data centering.            */
325    if (PanelEnable && ModeWidth < PanelWidth)
326        dcfg |= MDC_DCFG_DCEN;
327
328    /* COMBINE AND SET TIMING VALUES */
329    value = (unsigned long) (pMode->hactive - 1) |
330        (((unsigned long) (pMode->htotal - 1)) << 16);
331    WRITE_REG32(MDC_H_ACTIVE_TIMING, value);
332    value = (unsigned long) (pMode->hblankstart - 1) |
333        (((unsigned long) (pMode->hblankend - 1)) << 16);
334    WRITE_REG32(MDC_H_BLANK_TIMING, value);
335    value = (unsigned long) (pMode->hsyncstart - 1) |
336        (((unsigned long) (pMode->hsyncend - 1)) << 16);
337    WRITE_REG32(MDC_H_SYNC_TIMING, value);
338    value = (unsigned long) (pMode->vactive - 1) |
339        (((unsigned long) (pMode->vtotal - 1)) << 16);
340    WRITE_REG32(MDC_V_ACTIVE_TIMING, value);
341    value = (unsigned long) (pMode->vblankstart - 1) |
342        (((unsigned long) (pMode->vblankend - 1)) << 16);
343    WRITE_REG32(MDC_V_BLANK_TIMING, value);
344    value = (unsigned long) (pMode->vsyncstart - 1) |
345        (((unsigned long) (pMode->vsyncend - 1)) << 16);
346    WRITE_REG32(MDC_V_SYNC_TIMING, value);
347
348    WRITE_REG32(MDC_DISPLAY_CFG, dcfg);
349    WRITE_REG32(MDC_GENERAL_CFG, gcfg);
350
351    /* CONFIGURE DISPLAY OUTPUT FROM VIDEO PROCESSOR */
352    gfx_set_display_control(((pMode->flags & GFX_MODE_NEG_HSYNC) ? 1 : 0) |
353                            ((pMode->flags & GFX_MODE_NEG_VSYNC) ? 2 : 0));
354
355    /* RESTORE VALUE OF MDC_UNLOCK */
356    WRITE_REG32(MDC_UNLOCK, unlock);
357
358    /* RESET THE PITCH VALUES IN THE GP */
359    gfx_reset_pitch((unsigned short) pitch);
360
361    gfx_set_bpp((unsigned short) bpp);
362
363    return GFX_STATUS_OK;
364}
365
366/*----------------------------------------------------------------------------
367 * GFX_IS_DISPLAY_MODE_SUPPORTED
368 *
369 * This routine sets the specified display mode.
370 *
371 * Returns 1 if successful, 0 if mode could not be set.
372 *----------------------------------------------------------------------------
373 */
374#if GFX_DISPLAY_DYNAMIC
375int
376gu2_is_display_mode_supported(int xres, int yres, int bpp, int hz)
377#else
378int
379gfx_is_display_mode_supported(int xres, int yres, int bpp, int hz)
380#endif
381{
382    unsigned int mode;
383    unsigned long hz_flag = 0, bpp_flag = 0;
384
385    /* SET FLAGS TO MATCH REFRESH RATE */
386    gfx_mode_hz_conversion
387        /* SET BPP FLAGS TO LIMIT MODE SELECTION */
388        gfx_mode_bpp_conversion
389        /* LOOP THROUGH THE AVAILABLE MODES TO FIND A MATCH */
390        for (mode = 0; mode < NUM_RC_DISPLAY_MODES; mode++) {
391        if ((DisplayParams[mode].hactive == (unsigned short) xres) &&
392            (DisplayParams[mode].vactive == (unsigned short) yres) &&
393            (DisplayParams[mode].flags & hz_flag) &&
394            (DisplayParams[mode].flags & bpp_flag)) {
395
396            /* REDCLOUD DOES NOT SUPPORT EMULATED VGA MODES */
397            if ((DisplayParams[mode].flags & GFX_MODE_PIXEL_DOUBLE) ||
398                (DisplayParams[mode].flags & GFX_MODE_LINE_DOUBLE))
399                continue;
400
401            /* SET THE DISPLAY CONTROLLER FOR THE SELECTED MODE */
402            return (mode);
403        }
404    }
405    return (-1);
406}
407
408/*----------------------------------------------------------------------------
409 * gfx_set_display_mode
410 *
411 * This routine sets the specified display mode.
412 *
413 * Returns 1 if successful, 0 if mode could not be set.
414 *----------------------------------------------------------------------------
415 */
416#if GFX_DISPLAY_DYNAMIC
417int
418gu2_set_display_mode(int xres, int yres, int bpp, int hz)
419#else
420int
421gfx_set_display_mode(int xres, int yres, int bpp, int hz)
422#endif
423{
424    int mode;
425
426    /* DISABLE FLAT PANEL */
427    /* Flat Panel settings are enabled by the function gfx_set_fixed_timings
428     * and disabled by gfx_set_display_mode.
429     * */
430    PanelEnable = 0;
431
432    mode = gfx_is_display_mode_supported(xres, yres, bpp, hz);
433    if (mode >= 0) {
434        if (gu2_set_specified_mode(&DisplayParams[mode], bpp) == GFX_STATUS_OK)
435            return (1);
436    }
437    return (0);
438}
439
440/*----------------------------------------------------------------------------
441 * GFX_SET_DISPLAY_TIMINGS
442 *
443 * This routine sets the display controller mode using the specified timing
444 * values (as opposed to using the tables internal to Durango).
445 *
446 * Returns GFX_STATUS_OK ON SUCCESS, GFX_STATUS_ERROR otherwise.
447 *----------------------------------------------------------------------------
448 */
449#if GFX_DISPLAY_DYNAMIC
450int
451gu2_set_display_timings(unsigned short bpp, unsigned short flags,
452                        unsigned short hactive, unsigned short hblankstart,
453                        unsigned short hsyncstart, unsigned short hsyncend,
454                        unsigned short hblankend, unsigned short htotal,
455                        unsigned short vactive, unsigned short vblankstart,
456                        unsigned short vsyncstart, unsigned short vsyncend,
457                        unsigned short vblankend, unsigned short vtotal,
458                        unsigned long frequency)
459#else
460int
461gfx_set_display_timings(unsigned short bpp, unsigned short flags,
462                        unsigned short hactive, unsigned short hblankstart,
463                        unsigned short hsyncstart, unsigned short hsyncend,
464                        unsigned short hblankend, unsigned short htotal,
465                        unsigned short vactive, unsigned short vblankstart,
466                        unsigned short vsyncstart, unsigned short vsyncend,
467                        unsigned short vblankend, unsigned short vtotal,
468                        unsigned long frequency)
469#endif
470{
471    /* SET MODE STRUCTURE WITH SPECIFIED VALUES */
472
473    gfx_display_mode.flags = 0;
474    if (flags & 1)
475        gfx_display_mode.flags |= GFX_MODE_NEG_HSYNC;
476    if (flags & 2)
477        gfx_display_mode.flags |= GFX_MODE_NEG_VSYNC;
478    if (flags & 4)
479        gfx_display_mode.flags |= GFX_MODE_EXCLUDE_PLL;
480    if (flags & 0x1000)
481        gfx_display_mode.flags |= GFX_MODE_LOCK_TIMING;
482    gfx_display_mode.hactive = hactive;
483    gfx_display_mode.hblankstart = hblankstart;
484    gfx_display_mode.hsyncstart = hsyncstart;
485    gfx_display_mode.hsyncend = hsyncend;
486    gfx_display_mode.hblankend = hblankend;
487    gfx_display_mode.htotal = htotal;
488    gfx_display_mode.vactive = vactive;
489    gfx_display_mode.vblankstart = vblankstart;
490    gfx_display_mode.vsyncstart = vsyncstart;
491    gfx_display_mode.vsyncend = vsyncend;
492    gfx_display_mode.vblankend = vblankend;
493    gfx_display_mode.vtotal = vtotal;
494    gfx_display_mode.frequency = frequency;
495
496    /* CALL ROUTINE TO SET MODE */
497    return (gu2_set_specified_mode(&gfx_display_mode, bpp));
498}
499
500/*----------------------------------------------------------------------------
501 * GFX_SET_VTOTAL
502 *
503 * This routine sets the display controller vertical total to
504 * "vtotal". As a side effect it also sets vertical blank end.
505 * It should be used when only this value needs to be changed,
506 * due to speed considerations.
507 *
508 * Note: it is the caller's responsibility to make sure that
509 * a legal vtotal is used, i.e. that "vtotal" is greater than or
510 * equal to vsync end.
511 *
512 * Always returns 0.
513 *----------------------------------------------------------------------------
514 */
515#if GFX_DISPLAY_DYNAMIC
516int
517gu2_set_vtotal(unsigned short vtotal)
518#else
519int
520gfx_set_vtotal(unsigned short vtotal)
521#endif
522{
523    unsigned long unlock, dcfg, vactive, vblank;
524
525    /* UNLOCK THE DISPLAY CONTROLLER REGISTERS */
526    unlock = READ_REG32(MDC_UNLOCK);
527    WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
528
529    /* READ THE CURRENT RC VALUES */
530    dcfg = READ_REG32(MDC_DISPLAY_CFG);
531    vactive = READ_REG32(MDC_V_ACTIVE_TIMING);
532    vblank = READ_REG32(MDC_V_BLANK_TIMING);
533
534    /* DISABLE TIMING REGISTER UPDATES */
535    WRITE_REG32(MDC_DISPLAY_CFG, dcfg & ~(unsigned long) MDC_DCFG_TRUP);
536
537    /* WRITE NEW TIMING VALUES */
538    WRITE_REG32(MDC_V_ACTIVE_TIMING,
539                (vactive & MDC_VAT_VA_MASK) | (unsigned long) (vtotal -
540                                                               1) << 16);
541    WRITE_REG32(MDC_V_BLANK_TIMING,
542                (vblank & MDC_VBT_VBS_MASK) | (unsigned long) (vtotal -
543                                                               1) << 16);
544
545    /* RESTORE OLD RC VALUES */
546    WRITE_REG32(MDC_DISPLAY_CFG, dcfg);
547    WRITE_REG32(MDC_UNLOCK, unlock);
548
549    return (0);
550}
551
552/*---------------------------------------------------------------------------
553 * gfx_set_display_pitch
554 *
555 * This routine sets the pitch of the frame buffer to the specified value.
556 *---------------------------------------------------------------------------
557 */
558#if GFX_DISPLAY_DYNAMIC
559void
560gu2_set_display_pitch(unsigned short pitch)
561#else
562void
563gfx_set_display_pitch(unsigned short pitch)
564#endif
565{
566    unsigned long value = 0;
567    unsigned long lock = READ_REG32(MDC_UNLOCK);
568
569    value = READ_REG32(MDC_GFX_PITCH) & 0xFFFF0000;
570    value |= (pitch >> 3);
571    WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
572    WRITE_REG32(MDC_GFX_PITCH, value);
573
574    /* SET RENDERING PITCHES TO MATCH */
575    gfx_reset_pitch(pitch);
576
577    /* SET THE FRAME DIRTY MODE                  */
578    /* Non-standard pitches, i.e. pitches that   */
579    /* are not 1K, 2K or 4K must mark the entire */
580    /* frame as dirty when writing to the frame  */
581    /* buffer.                                   */
582    value = READ_REG32(MDC_GENERAL_CFG);
583
584    if (pitch == 1024 || pitch == 2048 || pitch == 4096 || pitch == 8192)
585        value &= ~(unsigned long) (MDC_GCFG_FDTY);
586    else
587        value |= (unsigned long) (MDC_GCFG_FDTY);
588
589    WRITE_REG32(MDC_GENERAL_CFG, value);
590    WRITE_REG32(MDC_UNLOCK, lock);
591}
592
593/*---------------------------------------------------------------------------
594 * gfx_set_display_offset
595 *
596 * This routine sets the start address of the frame buffer.  It is
597 * typically used to pan across a virtual desktop (frame buffer larger than
598 * the displayed screen) or to flip the display between multiple buffers.
599 *---------------------------------------------------------------------------
600 */
601#if GFX_DISPLAY_DYNAMIC
602void
603gu2_set_display_offset(unsigned long offset)
604#else
605void
606gfx_set_display_offset(unsigned long offset)
607#endif
608{
609    /* UPDATE FRAME BUFFER OFFSET */
610    unsigned long lock;
611
612    lock = READ_REG32(MDC_UNLOCK);
613    WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
614
615    /* START ADDRESS EFFECTS DISPLAY COMPRESSION */
616    /* Disable compression for non-zero start address values.              */
617    /* Enable compression if offset is zero and compression is intended to */
618    /* be enabled from a previous call to "gfx_set_compression_enable".    */
619    /* Compression should be disabled BEFORE the offset is changed         */
620    /* and enabled AFTER the offset is changed.                            */
621    if (offset == 0) {
622        WRITE_REG32(MDC_FB_ST_OFFSET, offset);
623        if (gfx_compression_enabled) {
624            /* WAIT FOR THE OFFSET TO BE LATCHED */
625            gfx_wait_vertical_blank();
626            gu2_enable_compression();
627        }
628    }
629    else {
630        /* ONLY DISABLE COMPRESSION ONCE */
631        if (gfx_compression_active)
632            gu2_disable_compression();
633
634        WRITE_REG32(MDC_FB_ST_OFFSET, offset);
635    }
636
637    WRITE_REG32(MDC_UNLOCK, lock);
638}
639
640/*---------------------------------------------------------------------------
641 * gfx_set_display_palette_entry
642 *
643 * This routine sets an palette entry in the display controller.
644 * A 32-bit X:R:G:B value.
645 *---------------------------------------------------------------------------
646 */
647#if GFX_DISPLAY_DYNAMIC
648int
649gu2_set_display_palette_entry(unsigned long index, unsigned long palette)
650#else
651int
652gfx_set_display_palette_entry(unsigned long index, unsigned long palette)
653#endif
654{
655    unsigned long dcfg, unlock;
656
657    if (index > 0xFF)
658        return GFX_STATUS_BAD_PARAMETER;
659
660    unlock = READ_REG32(MDC_UNLOCK);
661    dcfg = READ_REG32(MDC_DISPLAY_CFG);
662
663    WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
664    WRITE_REG32(MDC_DISPLAY_CFG, dcfg & ~MDC_DCFG_PALB);
665    WRITE_REG32(MDC_UNLOCK, unlock);
666
667    WRITE_REG32(MDC_PAL_ADDRESS, index);
668    WRITE_REG32(MDC_PAL_DATA, palette);
669
670    return GFX_STATUS_OK;
671}
672
673/*---------------------------------------------------------------------------
674 * gfx_set_display_palette
675 *
676 * This routine sets the entire palette in the display controller.
677 * A pointer is provided to a 256 entry table of 32-bit X:R:G:B values.
678 *---------------------------------------------------------------------------
679 */
680#if GFX_DISPLAY_DYNAMIC
681int
682gu2_set_display_palette(unsigned long *palette)
683#else
684int
685gfx_set_display_palette(unsigned long *palette)
686#endif
687{
688    unsigned long unlock, dcfg, i;
689
690    WRITE_REG32(MDC_PAL_ADDRESS, 0);
691
692    if (palette) {
693        unlock = READ_REG32(MDC_UNLOCK);
694        dcfg = READ_REG32(MDC_DISPLAY_CFG);
695
696        WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
697        WRITE_REG32(MDC_DISPLAY_CFG, dcfg & ~MDC_DCFG_PALB);
698        WRITE_REG32(MDC_UNLOCK, unlock);
699
700        for (i = 0; i < 256; i++)
701            WRITE_REG32(MDC_PAL_DATA, palette[i]);
702
703        return GFX_STATUS_OK;
704    }
705    return GFX_STATUS_BAD_PARAMETER;
706}
707
708/*---------------------------------------------------------------------------
709 * gfx_set_cursor_enable
710 *
711 * This routine enables or disables the hardware cursor.
712 *
713 * WARNING: The cursor start offset must be set by setting the cursor
714 * position before calling this routine to assure that memory reads do not
715 * go past the end of graphics memory (this can hang GXm).
716 *---------------------------------------------------------------------------
717 */
718#if GFX_DISPLAY_DYNAMIC
719void
720gu2_set_cursor_enable(int enable)
721#else
722void
723gfx_set_cursor_enable(int enable)
724#endif
725{
726    unsigned long unlock, gcfg;
727
728    /* SET OR CLEAR CURSOR ENABLE BIT */
729    unlock = READ_REG32(MDC_UNLOCK);
730    gcfg = READ_REG32(MDC_GENERAL_CFG);
731    if (enable)
732        gcfg |= MDC_GCFG_CURE;
733    else
734        gcfg &= ~(MDC_GCFG_CURE);
735
736    /* WRITE NEW REGISTER VALUE */
737    WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
738    WRITE_REG32(MDC_GENERAL_CFG, gcfg);
739    WRITE_REG32(MDC_UNLOCK, unlock);
740}
741
742/*---------------------------------------------------------------------------
743 * gfx_set_cursor_colors
744 *
745 * This routine sets the colors of the hardware cursor.
746 *---------------------------------------------------------------------------
747 */
748#if GFX_DISPLAY_DYNAMIC
749void
750gu2_set_cursor_colors(unsigned long bkcolor, unsigned long fgcolor)
751#else
752void
753gfx_set_cursor_colors(unsigned long bkcolor, unsigned long fgcolor)
754#endif
755{
756    /* SET CURSOR COLORS */
757    WRITE_REG32(MDC_PAL_ADDRESS, 0x100);
758    WRITE_REG32(MDC_PAL_DATA, bkcolor);
759    WRITE_REG32(MDC_PAL_DATA, fgcolor);
760}
761
762/*---------------------------------------------------------------------------
763 * gfx_set_cursor_position
764 *
765 * This routine sets the position of the hardware cusror.  The starting
766 * offset of the cursor buffer must be specified so that the routine can
767 * properly clip scanlines if the cursor is off the top of the screen.
768 *---------------------------------------------------------------------------
769 */
770#if GFX_DISPLAY_DYNAMIC
771void
772gu2_set_cursor_position(unsigned long memoffset,
773                        unsigned short xpos, unsigned short ypos,
774                        unsigned short xhotspot, unsigned short yhotspot)
775#else
776void
777gfx_set_cursor_position(unsigned long memoffset,
778                        unsigned short xpos, unsigned short ypos,
779                        unsigned short xhotspot, unsigned short yhotspot)
780#endif
781{
782    unsigned long unlock;
783
784    short x = (short) xpos - (short) xhotspot;
785    short y = (short) ypos - (short) yhotspot;
786    short xoffset = 0;
787    short yoffset = 0;
788
789    if (x < -63)
790        return;
791    if (y < -63)
792        return;
793
794    if (PanelEnable) {
795        if ((ModeWidth > PanelWidth) || (ModeHeight > PanelHeight)) {
796            gfx_enable_panning(xpos, ypos);
797            x = x - (unsigned short) panelLeft;
798            y = y - (unsigned short) panelTop;
799        }
800    }
801
802    /* ADJUST OFFSETS */
803    /* Cursor movement and panning work as follows:  The cursor position   */
804    /* refers to where the hotspot of the cursor is located.  However, for */
805    /* non-zero hotspots, the cursor buffer actually begins before the     */
806    /* specified position.                                                 */
807    if (x < 0) {
808        xoffset = -x;
809        x = 0;
810    }
811
812    if (y < 0) {
813        yoffset = -y;
814        y = 0;
815    }
816    memoffset += (unsigned long) yoffset << 4;
817
818    /* SET CURSOR POSITION */
819    unlock = READ_REG32(MDC_UNLOCK);
820    WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
821    WRITE_REG32(MDC_CURS_ST_OFFSET, memoffset);
822    WRITE_REG32(MDC_CURSOR_X, (unsigned long) x |
823                (((unsigned long) xoffset) << 11));
824    WRITE_REG32(MDC_CURSOR_Y, (unsigned long) y |
825                (((unsigned long) yoffset) << 11));
826    WRITE_REG32(MDC_UNLOCK, unlock);
827}
828
829/*---------------------------------------------------------------------------
830 * gfx_set_cursor_shape32
831 *
832 * This routine loads 32x32 cursor data into the cursor buffer in graphics
833 * memory.
834 * As the Redcloud cursor is actually 64x64, we must pad the outside of the
835 * cursor data with transparent pixels.
836 *---------------------------------------------------------------------------
837 */
838#if GFX_DISPLAY_DYNAMIC
839void
840gu2_set_cursor_shape32(unsigned long memoffset,
841                       unsigned long *andmask, unsigned long *xormask)
842#else
843void
844gfx_set_cursor_shape32(unsigned long memoffset,
845                       unsigned long *andmask, unsigned long *xormask)
846#endif
847{
848    int i;
849
850    for (i = 0; i < 32; i++) {
851        /* EVEN QWORDS CONTAIN THE AND MASK */
852        WRITE_FB32(memoffset, 0xFFFFFFFF);
853        WRITE_FB32(memoffset + 4, andmask[i]);
854
855        /* ODD QWORDS CONTAIN THE XOR MASK  */
856        WRITE_FB32(memoffset + 8, 0x00000000);
857        WRITE_FB32(memoffset + 12, xormask[i]);
858
859        memoffset += 16;
860    }
861
862    /* FILL THE LOWER HALF OF THE BUFFER WITH TRANSPARENT PIXELS */
863    for (i = 0; i < 32; i++) {
864        WRITE_FB32(memoffset, 0xFFFFFFFF);
865        WRITE_FB32(memoffset + 4, 0xFFFFFFFF);
866        WRITE_FB32(memoffset + 8, 0x00000000);
867        WRITE_FB32(memoffset + 12, 0x00000000);
868
869        memoffset += 16;
870    }
871}
872
873/*---------------------------------------------------------------------------
874 * gfx_set_cursor_shape64
875 *
876 * This routine loads 64x64 cursor data into the cursor buffer in graphics
877 * memory.
878 *---------------------------------------------------------------------------
879 */
880#if GFX_DISPLAY_DYNAMIC
881void
882gu2_set_cursor_shape64(unsigned long memoffset,
883                       unsigned long *andmask, unsigned long *xormask)
884#else
885void
886gfx_set_cursor_shape64(unsigned long memoffset,
887                       unsigned long *andmask, unsigned long *xormask)
888#endif
889{
890    int i;
891
892    for (i = 0; i < 128; i += 2) {
893        /* EVEN QWORDS CONTAIN THE AND MASK */
894        /* We invert the dwords to prevent the calling            */
895        /* application from having to think in terms of Qwords.   */
896        /* The hardware data order is actually 63:0, or 31:0 of   */
897        /* the second dword followed by 31:0 of the first dword.  */
898        WRITE_FB32(memoffset, andmask[i + 1]);
899        WRITE_FB32(memoffset + 4, andmask[i]);
900
901        /* ODD QWORDS CONTAIN THE XOR MASK  */
902        WRITE_FB32(memoffset + 8, xormask[i + 1]);
903        WRITE_FB32(memoffset + 12, xormask[i]);
904
905        memoffset += 16;
906    }
907}
908
909/*---------------------------------------------------------------------------
910 * gfx_set_icon_enable
911 *
912 * This routine enables or disables the hardware icon.  The icon position
913 * and colors should be programmed prior to calling this routine for the
914 * first time.
915 *---------------------------------------------------------------------------
916 */
917#if GFX_DISPLAY_DYNAMIC
918void
919gu2_set_icon_enable(int enable)
920#else
921void
922gfx_set_icon_enable(int enable)
923#endif
924{
925    unsigned long unlock, gcfg;
926
927    /* SET OR CLEAR ICON ENABLE BIT */
928    unlock = READ_REG32(MDC_UNLOCK);
929    gcfg = READ_REG32(MDC_GENERAL_CFG);
930    if (enable)
931        gcfg |= MDC_GCFG_ICNE;
932    else
933        gcfg &= ~(MDC_GCFG_ICNE);
934
935    /* WRITE NEW REGISTER VALUE */
936    WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
937    WRITE_REG32(MDC_GENERAL_CFG, gcfg);
938    WRITE_REG32(MDC_UNLOCK, unlock);
939}
940
941/*---------------------------------------------------------------------------
942 * gfx_set_icon_colors
943 *
944 * This routine sets the three icon colors.
945 *---------------------------------------------------------------------------
946 */
947#if GFX_DISPLAY_DYNAMIC
948void
949gu2_set_icon_colors(unsigned long color0, unsigned long color1,
950                    unsigned long color2)
951#else
952void
953gfx_set_icon_colors(unsigned long color0, unsigned long color1,
954                    unsigned long color2)
955#endif
956{
957    /* ICON COLORS LOCATED AT PALETTE INDEXES 102-104h */
958    WRITE_REG32(MDC_PAL_ADDRESS, 0x102);
959
960    WRITE_REG32(MDC_PAL_DATA, color0);
961    WRITE_REG32(MDC_PAL_DATA, color1);
962    WRITE_REG32(MDC_PAL_DATA, color2);
963}
964
965/*---------------------------------------------------------------------------
966 * gfx_set_icon_position
967 *
968 * This routine sets the starting X coordinate for the hardware icon and the
969 * memory offset for the icon buffer.
970 *---------------------------------------------------------------------------
971 */
972#if GFX_DISPLAY_DYNAMIC
973void
974gu2_set_icon_position(unsigned long memoffset, unsigned short xpos)
975#else
976void
977gfx_set_icon_position(unsigned long memoffset, unsigned short xpos)
978#endif
979{
980    unsigned long lock = READ_REG32(MDC_UNLOCK);
981
982    WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
983
984    /* PROGRAM THE MEMORY OFFSET */
985    WRITE_REG32(MDC_ICON_ST_OFFSET, memoffset & 0x0FFFFFFF);
986
987    /* PROGRAM THE XCOORDINATE */
988    WRITE_REG32(MDC_ICON_X, (unsigned long) (xpos & 0x07FF));
989
990    WRITE_REG32(MDC_UNLOCK, lock);
991}
992
993/*---------------------------------------------------------------------------
994 * gfx_set_icon_shape64
995 *
996 * This routine initializes the icon buffer according to the current mode.
997 *---------------------------------------------------------------------------
998 */
999#if GFX_DISPLAY_DYNAMIC
1000void
1001gu2_set_icon_shape64(unsigned long memoffset, unsigned long *andmask,
1002                     unsigned long *xormask, unsigned int lines)
1003#else
1004void
1005gfx_set_icon_shape64(unsigned long memoffset, unsigned long *andmask,
1006                     unsigned long *xormask, unsigned int lines)
1007#endif
1008{
1009    unsigned short i, height;
1010
1011    height = lines << 1;
1012
1013    for (i = 0; i < height; i += 2) {
1014        /* EVEN QWORDS CONTAIN THE AND MASK     */
1015        /* Swap dwords to hide qword constraint */
1016        WRITE_FB32(memoffset, andmask[i + 1]);
1017        WRITE_FB32(memoffset + 4, andmask[i]);
1018
1019        /* ODD QWORDS CONTAIN THE XOR MASK */
1020        WRITE_FB32(memoffset + 8, xormask[i + 1]);
1021        WRITE_FB32(memoffset + 12, xormask[i]);
1022
1023        memoffset += 16;
1024    }
1025}
1026
1027/*---------------------------------------------------------------------------
1028 * gu2_enable_compression
1029 *
1030 * This is a private routine to this module (not exposed in the Durango API).
1031 * It enables display compression.
1032 *---------------------------------------------------------------------------
1033 */
1034void
1035gu2_enable_compression(void)
1036{
1037    unsigned long unlock, gcfg, temp;
1038
1039    /* DO NOT ENABLE IF START ADDRESS IS NOT ZERO */
1040    if (READ_REG32(MDC_FB_ST_OFFSET) & 0x0FFFFFFF)
1041        return;
1042
1043    /* SET GLOBAL INDICATOR */
1044    gfx_compression_active = 1;
1045
1046    /* CLEAR DIRTY/VALID BITS IN MEMORY CONTROLLER */
1047    /* Software is required to do this before enabling compression.   */
1048    /* Don't want controller to think that old lines are still valid. */
1049    /* Writing a 1 to bit 0 of the DV Control register will force the */
1050    /* hardware to clear all the valid bits.                          */
1051    temp = READ_REG32(MDC_DV_CTL);
1052    WRITE_REG32(MDC_DV_CTL, temp | 0x00000001);
1053
1054    /* TURN ON COMPRESSION CONTROL BITS */
1055    unlock = READ_REG32(MDC_UNLOCK);
1056    gcfg = READ_REG32(MDC_GENERAL_CFG);
1057    gcfg |= MDC_GCFG_CMPE | MDC_GCFG_DECE;
1058    WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
1059    WRITE_REG32(MDC_GENERAL_CFG, gcfg);
1060    WRITE_REG32(MDC_UNLOCK, unlock);
1061}
1062
1063/*---------------------------------------------------------------------------
1064 * gu2_disable_compression
1065 *
1066 * This is a private routine to this module (not exposed in the Durango API).
1067 * It disables display compression.
1068 *---------------------------------------------------------------------------
1069 */
1070void
1071gu2_disable_compression(void)
1072{
1073    unsigned long unlock, gcfg;
1074
1075    /* SET GLOBAL INDICATOR */
1076
1077    gfx_compression_active = 0;
1078
1079    /* TURN OFF COMPRESSION CONTROL BITS */
1080
1081    unlock = READ_REG32(MDC_UNLOCK);
1082    gcfg = READ_REG32(MDC_GENERAL_CFG);
1083    gcfg &= ~(MDC_GCFG_CMPE | MDC_GCFG_DECE);
1084    WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
1085    WRITE_REG32(MDC_GENERAL_CFG, gcfg);
1086    WRITE_REG32(MDC_UNLOCK, unlock);
1087}
1088
1089/*---------------------------------------------------------------------------
1090 * gfx_set_compression_enable
1091 *
1092 * This routine enables or disables display compression.
1093 *---------------------------------------------------------------------------
1094 */
1095#if GFX_DISPLAY_DYNAMIC
1096int
1097gu2_set_compression_enable(int enable)
1098#else
1099int
1100gfx_set_compression_enable(int enable)
1101#endif
1102{
1103    /* SET GLOBAL VARIABLE FOR INTENDED STATE */
1104    /* Compression can only be enabled for non-zero start address values. */
1105    /* Keep state to enable compression on start address changes. */
1106
1107    gfx_compression_enabled = enable;
1108    if (enable)
1109        gu2_enable_compression();
1110    else
1111        gu2_disable_compression();
1112    return (0);
1113}
1114
1115/*---------------------------------------------------------------------------
1116 * gfx_set_compression_offset
1117 *
1118 * This routine sets the base offset for the compression buffer.
1119 *---------------------------------------------------------------------------
1120 */
1121#if GFX_DISPLAY_DYNAMIC
1122int
1123gu2_set_compression_offset(unsigned long offset)
1124#else
1125int
1126gfx_set_compression_offset(unsigned long offset)
1127#endif
1128{
1129    unsigned long lock;
1130
1131    /* MUST BE 16-BYTE ALIGNED FOR REDCLOUD */
1132
1133    if (offset & 0x0F)
1134        return (1);
1135
1136    /* SET REGISTER VALUE */
1137
1138    lock = READ_REG32(MDC_UNLOCK);
1139    WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
1140    WRITE_REG32(MDC_CB_ST_OFFSET, offset & 0x0FFFFFFF);
1141    WRITE_REG32(MDC_UNLOCK, lock);
1142
1143    return (0);
1144}
1145
1146/*---------------------------------------------------------------------------
1147 * gfx_set_compression_pitch
1148 *
1149 * This routine sets the pitch, in bytes, of the compression buffer.
1150 *---------------------------------------------------------------------------
1151 */
1152#if GFX_DISPLAY_DYNAMIC
1153int
1154gu2_set_compression_pitch(unsigned short pitch)
1155#else
1156int
1157gfx_set_compression_pitch(unsigned short pitch)
1158#endif
1159{
1160    unsigned long lock, line_delta;
1161
1162    lock = READ_REG32(MDC_UNLOCK);
1163
1164    /* SET REGISTER VALUE */
1165
1166    line_delta = READ_REG32(MDC_GFX_PITCH) & 0x0000FFFF;
1167    line_delta |= (((unsigned long) pitch << 13) & 0xFFFF0000);
1168    WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
1169    WRITE_REG32(MDC_GFX_PITCH, line_delta);
1170    WRITE_REG32(MDC_UNLOCK, lock);
1171    return (0);
1172}
1173
1174/*---------------------------------------------------------------------------
1175 * gfx_set_compression_size
1176 *
1177 * This routine sets the line size of the compression buffer, which is the
1178 * maximum number of bytes allowed to store a compressed line.
1179 *---------------------------------------------------------------------------
1180 */
1181#if GFX_DISPLAY_DYNAMIC
1182int
1183gu2_set_compression_size(unsigned short size)
1184#else
1185int
1186gfx_set_compression_size(unsigned short size)
1187#endif
1188{
1189    unsigned long lock, buf_size;
1190
1191    /* SUBTRACT 32 FROM SIZE                          */
1192    /* The display controller will actually write     */
1193    /* 4 extra QWords.  So, if we assume that "size"  */
1194    /* refers to the allocated size, we must subtract */
1195    /* 32 bytes.                                      */
1196
1197    size -= 32;
1198
1199    /* SET REGISTER VALUE */
1200
1201    lock = READ_REG32(MDC_UNLOCK);
1202    buf_size = READ_REG32(MDC_LINE_SIZE) & 0xFF80FFFF;
1203    buf_size |= ((((unsigned long) size >> 3) + 1) & 0x7F) << 16;
1204    WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
1205    WRITE_REG32(MDC_LINE_SIZE, buf_size);
1206    WRITE_REG32(MDC_UNLOCK, lock);
1207    return (0);
1208}
1209
1210/*---------------------------------------------------------------------------
1211 * gfx_set_display_video_format (PRIVATE ROUTINE - NOT PART OF API)
1212 *
1213 * This routine is called by "gfx_set_video_format".  It abstracts the
1214 * version of the display controller from the video overlay routines.
1215 *---------------------------------------------------------------------------
1216 */
1217#if GFX_DISPLAY_DYNAMIC
1218void
1219gu2_set_display_video_format(unsigned long format)
1220#else
1221void
1222gfx_set_display_video_format(unsigned long format)
1223#endif
1224{
1225    unsigned long gcfg, lock;
1226
1227    lock = READ_REG32(MDC_UNLOCK);
1228    gcfg = READ_REG32(MDC_GENERAL_CFG);
1229
1230    switch (format) {
1231    case VIDEO_FORMAT_Y0Y1Y2Y3:
1232    case VIDEO_FORMAT_Y3Y2Y1Y0:
1233    case VIDEO_FORMAT_Y1Y0Y3Y2:
1234    case VIDEO_FORMAT_Y1Y2Y3Y0:
1235        gcfg |= MDC_GCFG_YUVM;
1236        break;
1237
1238    default:
1239        gcfg &= ~MDC_GCFG_YUVM;
1240        break;
1241    }
1242
1243    WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
1244    WRITE_REG32(MDC_GENERAL_CFG, gcfg);
1245    WRITE_REG32(MDC_UNLOCK, lock);
1246}
1247
1248/*---------------------------------------------------------------------------
1249 * gfx_set_display_video_enable (PRIVATE ROUTINE - NOT PART OF API)
1250 *
1251 * This routine is called by "gfx_set_video_enable".  It abstracts the
1252 * version of the display controller from the video overlay routines.
1253 *---------------------------------------------------------------------------
1254 */
1255#if GFX_DISPLAY_DYNAMIC
1256void
1257gu2_set_display_video_enable(int enable)
1258#else
1259void
1260gfx_set_display_video_enable(int enable)
1261#endif
1262{
1263    unsigned long lock, gcfg, dcfg;
1264
1265    /* READ CURRENT VALUES */
1266
1267    lock = READ_REG32(MDC_UNLOCK);
1268    gcfg = READ_REG32(MDC_GENERAL_CFG);
1269    dcfg = READ_REG32(MDC_DISPLAY_CFG);
1270
1271    /* SET OR CLEAR VIDEO ENABLE IN GENERAL_CFG */
1272
1273    if (enable)
1274        gcfg |= MDC_GCFG_VIDE;
1275    else
1276        gcfg &= ~MDC_GCFG_VIDE;
1277
1278    /* WRITE REGISTER */
1279
1280    WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
1281    WRITE_REG32(MDC_GENERAL_CFG, gcfg);
1282    WRITE_REG32(MDC_UNLOCK, lock);
1283}
1284
1285/*---------------------------------------------------------------------------
1286 * gfx_set_display_video_size (PRIVATE ROUTINE - NOT PART OF API)
1287 *
1288 * This routine is called by "gfx_set_video_size".  It abstracts the
1289 * version of the display controller from the video overlay routines.
1290 *---------------------------------------------------------------------------
1291 */
1292#if GFX_DISPLAY_DYNAMIC
1293void
1294gu2_set_display_video_size(unsigned short width, unsigned short height)
1295#else
1296void
1297gfx_set_display_video_size(unsigned short width, unsigned short height)
1298#endif
1299{
1300    unsigned long lock, value, yuv_420;
1301
1302    /* READ CURRENT VALUES */
1303
1304    lock = READ_REG32(MDC_UNLOCK);
1305    value = READ_REG32(MDC_LINE_SIZE) & 0x00FFFFFF;
1306    yuv_420 = READ_REG32(MDC_GENERAL_CFG) & MDC_GCFG_YUVM;
1307
1308    /* LINE WIDTH IS 1/4 FOR 4:2:0 VIDEO */
1309    /* All data must be 32-byte aligned. */
1310
1311    if (yuv_420) {
1312        width >>= 1;
1313        width = (width + 7) & 0xFFF8;
1314    }
1315    else {
1316        width <<= 1;
1317        width = (width + 31) & 0xFFE0;
1318    }
1319
1320    /* ONLY THE LINE SIZE IS PROGRAMMED IN THE DISPLAY CONTROLLER */
1321
1322    value |= ((unsigned long) width << 21);
1323
1324    /* WRITE THE REGISTER */
1325
1326    WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
1327    WRITE_REG32(MDC_LINE_SIZE, value);
1328    WRITE_REG32(MDC_UNLOCK, lock);
1329}
1330
1331/*---------------------------------------------------------------------------
1332 * gfx_set_display_video_offset (PRIVATE ROUTINE - NOT PART OF API)
1333 *
1334 * This routine is called by "gfx_set_video_offset".  It abstracts the
1335 * version of the display controller from the video overlay routines.
1336 *---------------------------------------------------------------------------
1337 */
1338#if GFX_DISPLAY_DYNAMIC
1339void
1340gu2_set_display_video_offset(unsigned long offset)
1341#else
1342void
1343gfx_set_display_video_offset(unsigned long offset)
1344#endif
1345{
1346    unsigned long lock;
1347
1348    lock = READ_REG32(MDC_UNLOCK);
1349    WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
1350    offset &= 0x0FFFFFF0;
1351    WRITE_REG32(MDC_VID_Y_ST_OFFSET, offset);
1352    WRITE_REG32(MDC_UNLOCK, lock);
1353}
1354
1355/*---------------------------------------------------------------------------
1356 * gfx_set_display_video_yuv_offsets (PRIVATE ROUTINE - NOT PART OF API)
1357 *
1358 * This routine is called by gfx_set_video_yuv_offsets.  It abstracts the
1359 * version of the display controller from the video overlay routines.
1360 *---------------------------------------------------------------------------
1361 */
1362#if GFX_DISPLAY_DYNAMIC
1363void
1364gu2_set_display_video_yuv_offsets(unsigned long yoffset,
1365                                  unsigned long uoffset, unsigned long voffset)
1366#else
1367void
1368gfx_set_display_video_yuv_offsets(unsigned long yoffset,
1369                                  unsigned long uoffset, unsigned long voffset)
1370#endif
1371{
1372    unsigned long lock;
1373
1374    lock = READ_REG32(MDC_UNLOCK);
1375
1376    yoffset &= 0x0FFFFFF0;
1377    uoffset &= 0x0FFFFFF8;
1378    voffset &= 0x0FFFFFF8;
1379
1380    WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
1381    WRITE_REG32(MDC_VID_Y_ST_OFFSET, yoffset);
1382    WRITE_REG32(MDC_VID_U_ST_OFFSET, uoffset);
1383    WRITE_REG32(MDC_VID_V_ST_OFFSET, voffset);
1384    WRITE_REG32(MDC_UNLOCK, lock);
1385}
1386
1387/*---------------------------------------------------------------------------
1388 * gfx_set_display_video_yuv_pitch (PRIVATE ROUTINE - NOT PART OF API)
1389 *
1390 * This routine is called by gfx_set_video_yuv_pitch.  It abstracts the
1391 * version of the display controller from the video overlay routines.
1392 *---------------------------------------------------------------------------
1393 */
1394#if GFX_DISPLAY_DYNAMIC
1395void
1396gu2_set_display_video_yuv_pitch(unsigned long ypitch, unsigned long uvpitch)
1397#else
1398void
1399gfx_set_display_video_yuv_pitch(unsigned long ypitch, unsigned long uvpitch)
1400#endif
1401{
1402    unsigned long lock, pitch;
1403
1404    lock = READ_REG32(MDC_UNLOCK);
1405
1406    pitch = ((uvpitch << 13) & 0xFFFF0000) | ((ypitch >> 3) & 0xFFFF);
1407
1408    WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
1409    WRITE_REG32(MDC_VID_YUV_PITCH, pitch);
1410    WRITE_REG32(MDC_UNLOCK, lock);
1411}
1412
1413/*---------------------------------------------------------------------------
1414 * gfx_set_display_video_downscale (PRIVATE ROUTINE - NOT PART OF API)
1415 *
1416 * This routine is called by gfx_set_video_vertical_downscale.  It abstracts
1417 * the version of the display controller from the video overlay routines.
1418 *---------------------------------------------------------------------------
1419 */
1420#if GFX_DISPLAY_DYNAMIC
1421void
1422gu2_set_display_video_downscale(unsigned short srch, unsigned short dsth)
1423#else
1424void
1425gfx_set_display_video_downscale(unsigned short srch, unsigned short dsth)
1426#endif
1427{
1428    unsigned long lock, delta;
1429
1430    lock = READ_REG32(MDC_UNLOCK);
1431
1432    /* CLIP SCALING LIMITS */
1433    /* Upscaling is performed in a separate function. */
1434    /* Maximum scale ratio is 1/2.                    */
1435
1436    if (dsth > srch || dsth <= (srch >> 1))
1437        delta = 0;
1438    else
1439        delta = (((unsigned long) srch << 14) / (unsigned long) dsth) << 18;
1440
1441    WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
1442    WRITE_REG32(MDC_VID_DS_DELTA, delta);
1443    WRITE_REG32(MDC_UNLOCK, lock);
1444}
1445
1446/*---------------------------------------------------------------------------
1447 * gfx_set_display_video_downscale_enable (PRIVATE ROUTINE - NOT PART OF API)
1448 *
1449 * This routine is called by "gfx_set_video_vertical_downscale_enable".
1450 * It abstracts the version of the display controller from the video overlay
1451 * routines.
1452 *---------------------------------------------------------------------------
1453 */
1454#if GFX_DISPLAY_DYNAMIC
1455void
1456gu2_set_display_video_vertical_downscale_enable(int enable)
1457#else
1458void
1459gfx_set_display_video_vertical_downscale_enable(int enable)
1460#endif
1461{
1462    unsigned long gcfg, unlock;
1463
1464    unlock = READ_REG32(MDC_UNLOCK);
1465    gcfg = READ_REG32(MDC_GENERAL_CFG);
1466
1467    if (enable)
1468        gcfg |= MDC_GCFG_VDSE;
1469    else
1470        gcfg &= ~MDC_GCFG_VDSE;
1471
1472    WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
1473    WRITE_REG32(MDC_GENERAL_CFG, gcfg);
1474    WRITE_REG32(MDC_UNLOCK, unlock);
1475}
1476
1477/*---------------------------------------------------------------------------
1478 * gfx_test_timing_active
1479 *---------------------------------------------------------------------------
1480 */
1481#if GFX_DISPLAY_DYNAMIC
1482int
1483gu2_test_timing_active(void)
1484#else
1485int
1486gfx_test_timing_active(void)
1487#endif
1488{
1489    if (READ_REG32(MDC_DISPLAY_CFG) & MDC_DCFG_TGEN)
1490        return (1);
1491    else
1492        return (0);
1493}
1494
1495/*---------------------------------------------------------------------------
1496 * gfx_test_vertical_active
1497 *---------------------------------------------------------------------------
1498 */
1499#if GFX_DISPLAY_DYNAMIC
1500int
1501gu2_test_vertical_active(void)
1502#else
1503int
1504gfx_test_vertical_active(void)
1505#endif
1506{
1507    if (READ_REG32(MDC_LINE_CNT_STATUS) & MDC_LNCNT_VNA)
1508        return (0);
1509
1510    return (1);
1511}
1512
1513/*---------------------------------------------------------------------------
1514 * gfx_wait_vertical_blank
1515 *---------------------------------------------------------------------------
1516 */
1517#if GFX_DISPLAY_DYNAMIC
1518int
1519gu2_wait_vertical_blank(void)
1520#else
1521int
1522gfx_wait_vertical_blank(void)
1523#endif
1524{
1525    if (gfx_test_timing_active()) {
1526        while (!gfx_test_vertical_active());
1527        while (gfx_test_vertical_active());
1528    }
1529    return (0);
1530}
1531
1532/*---------------------------------------------------------------------------
1533 * gfx_enable_panning
1534 *
1535 * This routine  enables the panning when the Mode is bigger than the panel
1536 * size.
1537 *---------------------------------------------------------------------------
1538 */
1539
1540#if GFX_DISPLAY_DYNAMIC
1541void
1542gu2_enable_panning(int x, int y)
1543#else
1544void
1545gfx_enable_panning(int x, int y)
1546#endif
1547{
1548    unsigned long modeBytesPerPixel;
1549    unsigned long modeBytesPerScanline = 0;
1550    unsigned long startAddress = 0;
1551
1552    modeBytesPerPixel = (gbpp + 7) / 8;
1553    modeBytesPerScanline = (READ_REG32(MDC_GFX_PITCH) & 0x0000FFFF) << 3;
1554
1555    /* TEST FOR NO-WORK */
1556
1557    if (x >= DeltaX && x < ((int) PanelWidth + DeltaX) &&
1558        y >= DeltaY && y < ((int) PanelHeight + DeltaY))
1559        return;
1560
1561    /* ADJUST PANNING VARIABLES WHEN CURSOR EXCEEDS BOUNDARY       */
1562    /* Test the boundary conditions for each coordinate and update */
1563    /* all variables and the starting offset accordingly.          */
1564
1565    if (x < DeltaX)
1566        DeltaX = x;
1567
1568    else if (x >= (DeltaX + (int) PanelWidth))
1569        DeltaX = x - (int) PanelWidth + 1;
1570
1571    if (y < DeltaY)
1572        DeltaY = y;
1573
1574    else if (y >= (DeltaY + (int) PanelHeight))
1575        DeltaY = y - (int) PanelHeight + 1;
1576
1577    /* CALCULATE THE START OFFSET */
1578
1579    startAddress =
1580        (DeltaX * modeBytesPerPixel) + (DeltaY * modeBytesPerScanline);
1581
1582    gfx_set_display_offset(startAddress);
1583
1584    /* SET PANEL COORDINATES                    */
1585    /* Panel's x position must be DWORD aligned */
1586
1587    panelTop = DeltaY;
1588    panelLeft = DeltaX * modeBytesPerPixel;
1589
1590    if (panelLeft & 3)
1591        panelLeft = (panelLeft & 0xFFFFFFFC) + 4;
1592
1593    panelLeft /= modeBytesPerPixel;
1594}
1595
1596/*---------------------------------------------------------------------------
1597 * gfx_is_panel_mode_supported
1598 *---------------------------------------------------------------------------
1599 */
1600
1601#if GFX_DISPLAY_DYNAMIC
1602int
1603gu2_is_panel_mode_supported(int panelResX, int panelResY,
1604                            unsigned short width, unsigned short height,
1605                            unsigned short bpp)
1606#else
1607int
1608gfx_is_panel_mode_supported(int panelResX, int panelResY,
1609                            unsigned short width, unsigned short height,
1610                            unsigned short bpp)
1611#endif
1612{
1613    unsigned int mode;
1614
1615    /* LOOP THROUGH THE AVAILABLE MODES TO FIND A MATCH */
1616    for (mode = 0; mode < NUM_FIXED_TIMINGS_MODES; mode++) {
1617        if ((FixedParams[mode].xres == width) &&
1618            (FixedParams[mode].yres == height) &&
1619            (FixedParams[mode].panelresx == panelResX) &&
1620            (FixedParams[mode].panelresy == panelResY)) {
1621            return ((int) mode);
1622        }
1623    }
1624
1625    return -1;
1626}
1627
1628/*---------------------------------------------------------------------------
1629 * gfx_set_fixed_timings
1630 *---------------------------------------------------------------------------
1631 */
1632
1633#if GFX_DISPLAY_DYNAMIC
1634int
1635gu2_set_fixed_timings(int panelResX, int panelResY, unsigned short width,
1636                      unsigned short height, unsigned short bpp)
1637#else
1638int
1639gfx_set_fixed_timings(int panelResX, int panelResY, unsigned short width,
1640                      unsigned short height, unsigned short bpp)
1641#endif
1642{
1643    unsigned int mode;
1644
1645    ModeWidth = width;
1646    ModeHeight = height;
1647    PanelWidth = (unsigned short) panelResX;
1648    PanelHeight = (unsigned short) panelResY;
1649    PanelEnable = 1;
1650
1651    /* LOOP THROUGH THE AVAILABLE MODES TO FIND A MATCH */
1652    for (mode = 0; mode < NUM_FIXED_TIMINGS_MODES; mode++) {
1653        if ((FixedParams[mode].xres == width) &&
1654            (FixedParams[mode].yres == height) &&
1655            (FixedParams[mode].panelresx == panelResX) &&
1656            (FixedParams[mode].panelresy == panelResY)) {
1657
1658            /* SET THE 92xx FOR THE SELECTED MODE */
1659            FIXEDTIMINGS *fmode = &FixedParams[mode];
1660
1661            gfx_set_display_timings(bpp, 3, fmode->hactive,
1662                                    fmode->hblankstart, fmode->hsyncstart,
1663                                    fmode->hsyncend, fmode->hblankend,
1664                                    fmode->htotal, fmode->vactive,
1665                                    fmode->vblankstart, fmode->vsyncstart,
1666                                    fmode->vsyncend, fmode->vblankend,
1667                                    fmode->vtotal, fmode->frequency);
1668
1669            return (1);
1670        }                       /* end if() */
1671    }                           /* end for() */
1672
1673    return (-1);
1674}
1675
1676/*---------------------------------------------------------------------------
1677 * gfx_set_panel_present
1678 *---------------------------------------------------------------------------
1679 */
1680#if GFX_DISPLAY_DYNAMIC
1681int
1682gu2_set_panel_present(int panelResX, int panelResY, unsigned short width,
1683                      unsigned short height, unsigned short bpp)
1684#else
1685int
1686gfx_set_panel_present(int panelResX, int panelResY, unsigned short width,
1687                      unsigned short height, unsigned short bpp)
1688#endif
1689{
1690    /* SET VALID BPP         */
1691    /* 16BPP is the default. */
1692
1693    if (bpp != 8 && bpp != 12 && bpp != 15 && bpp != 16 && bpp != 32)
1694        bpp = 16;
1695
1696    /* RECORD PANEL PARAMETERS */
1697    /* This routine does not touch any panel timings.  It is used when custom
1698     * panel settings are set up in advance by the BIOS or an application, but
1699     * the application still requires access to other panel functionality
1700     * provided by Durango (i.e. panning).
1701     * */
1702
1703    ModeWidth = width;
1704    ModeHeight = height;
1705    PanelWidth = (unsigned short) panelResX;
1706    PanelHeight = (unsigned short) panelResY;
1707    PanelEnable = 1;
1708    gbpp = bpp;
1709
1710    /* PROGRAM THE BPP IN THE DISPLAY CONTROLLER */
1711
1712    gfx_set_display_bpp(bpp);
1713
1714    return (GFX_STATUS_OK);
1715}
1716
1717/* THE FOLLOWING READ ROUTINES ARE ALWAYS INCLUDED: */
1718
1719/*---------------------------------------------------------------------------
1720 * gfx_get_display_pitch
1721 *
1722 * This routine returns the current pitch of the frame buffer, in bytes.
1723 *---------------------------------------------------------------------------
1724 */
1725#if GFX_DISPLAY_DYNAMIC
1726unsigned short
1727gu2_get_display_pitch(void)
1728#else
1729unsigned short
1730gfx_get_display_pitch(void)
1731#endif
1732{
1733    return ((unsigned short) (READ_REG32(MDC_GFX_PITCH) & 0x0000FFFF) << 3);
1734}
1735
1736/*----------------------------------------------------------------------------
1737 * gfx_mode_frequency_supported
1738 *
1739 * This routine examines if the requested mode with pixel frequency is
1740 * supported.
1741 *
1742 * Returns >0 if successful , <0 if freq. could not be found and matched.
1743 *----------------------------------------------------------------------------
1744 */
1745#if GFX_DISPLAY_DYNAMIC
1746int
1747gu2_mode_frequency_supported(int xres, int yres, int bpp,
1748                             unsigned long frequency)
1749#else
1750int
1751gfx_mode_frequency_supported(int xres, int yres, int bpp,
1752                             unsigned long frequency)
1753#endif
1754{
1755    unsigned int index;
1756    unsigned long value;
1757    unsigned long bpp_flag = 0;
1758
1759    gfx_mode_bpp_conversion_def(bpp)
1760
1761        for (index = 0; index < NUM_RC_DISPLAY_MODES; index++) {
1762        if ((DisplayParams[index].hactive == (unsigned int) xres) &&
1763            (DisplayParams[index].vactive == (unsigned int) yres) &&
1764            (DisplayParams[index].flags & bpp_flag) &&
1765            (DisplayParams[index].frequency == frequency)) {
1766            int hz = 0;
1767
1768            value = DisplayParams[index].flags;
1769
1770            if (value & GFX_MODE_56HZ)
1771                hz = 56;
1772            else if (value & GFX_MODE_60HZ)
1773                hz = 60;
1774            else if (value & GFX_MODE_70HZ)
1775                hz = 70;
1776            else if (value & GFX_MODE_72HZ)
1777                hz = 72;
1778            else if (value & GFX_MODE_75HZ)
1779                hz = 75;
1780            else if (value & GFX_MODE_85HZ)
1781                hz = 85;
1782            else if (value & GFX_MODE_90HZ)
1783                hz = 90;
1784            else if (value & GFX_MODE_100HZ)
1785                hz = 100;
1786            return (hz);
1787        }
1788    }
1789
1790    return (-1);
1791}
1792
1793/*----------------------------------------------------------------------------
1794 * gfx_refreshrate_from_frequency
1795 *
1796 * This routine maps the frequency to close match refresh rate
1797 *----------------------------------------------------------------------------
1798 */
1799#if GFX_DISPLAY_DYNAMIC
1800int
1801gu2_get_refreshrate_from_frequency(int xres, int yres, int bpp, int *hz,
1802                                   unsigned long frequency)
1803#else
1804int
1805gfx_get_refreshrate_from_frequency(int xres, int yres, int bpp, int *hz,
1806                                   unsigned long frequency)
1807#endif
1808{
1809    unsigned int index, closematch = 0;
1810    unsigned long value;
1811    unsigned long bpp_flag = 0;
1812    long min, diff;
1813
1814    *hz = 60;
1815
1816    gfx_mode_bpp_conversion_def(bpp)
1817
1818        /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */
1819        /* Search the table for the closest frequency (16.16 format). */
1820        min = 0x7fffffff;
1821    for (index = 0; index < NUM_RC_DISPLAY_MODES; index++) {
1822        if ((DisplayParams[index].htotal == (unsigned int) xres) &&
1823            (DisplayParams[index].vtotal == (unsigned int) yres) &&
1824            (DisplayParams[index].flags & bpp_flag)) {
1825            diff = (long) frequency - (long) DisplayParams[index].frequency;
1826            if (diff < 0)
1827                diff = -diff;
1828
1829            if (diff < min) {
1830                min = diff;
1831                closematch = index;
1832            }
1833        }
1834    }
1835
1836    value = DisplayParams[closematch].flags;
1837
1838    if (value & GFX_MODE_56HZ)
1839        *hz = 56;
1840    else if (value & GFX_MODE_60HZ)
1841        *hz = 60;
1842    else if (value & GFX_MODE_70HZ)
1843        *hz = 70;
1844    else if (value & GFX_MODE_72HZ)
1845        *hz = 72;
1846    else if (value & GFX_MODE_75HZ)
1847        *hz = 75;
1848    else if (value & GFX_MODE_85HZ)
1849        *hz = 85;
1850    else if (value & GFX_MODE_90HZ)
1851        *hz = 90;
1852    else if (value & GFX_MODE_100HZ)
1853        *hz = 100;
1854
1855    return (1);
1856}
1857
1858/*----------------------------------------------------------------------------
1859 * gfx_refreshrate_from_mode
1860 *
1861 * This routine is identical to the gfx_get_refreshrate_from_frequency,
1862 * except that the active timing values are compared instead of the total
1863 * values.  Some modes (such as 70Hz and 72Hz) may be confused in this routine
1864 *----------------------------------------------------------------------------
1865 */
1866#if GFX_DISPLAY_DYNAMIC
1867int
1868gu2_get_refreshrate_from_mode(int xres, int yres, int bpp, int *hz,
1869                              unsigned long frequency)
1870#else
1871int
1872gfx_get_refreshrate_from_mode(int xres, int yres, int bpp, int *hz,
1873                              unsigned long frequency)
1874#endif
1875{
1876    unsigned int index, closematch = 0;
1877    unsigned long value;
1878    unsigned long bpp_flag = 0;
1879    long min, diff;
1880
1881    *hz = 60;
1882
1883    gfx_mode_bpp_conversion_def(bpp)
1884
1885        /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */
1886        /* Search the table for the closest frequency (16.16 format). */
1887        min = 0x7fffffff;
1888    for (index = 0; index < NUM_RC_DISPLAY_MODES; index++) {
1889        if ((DisplayParams[index].hactive == (unsigned int) xres) &&
1890            (DisplayParams[index].vactive == (unsigned int) yres) &&
1891            (DisplayParams[index].flags & bpp_flag)) {
1892            diff = (long) frequency - (long) DisplayParams[index].frequency;
1893            if (diff < 0)
1894                diff = -diff;
1895
1896            if (diff < min) {
1897                min = diff;
1898                closematch = index;
1899            }
1900        }
1901    }
1902
1903    value = DisplayParams[closematch].flags;
1904
1905    if (value & GFX_MODE_56HZ)
1906        *hz = 56;
1907    else if (value & GFX_MODE_60HZ)
1908        *hz = 60;
1909    else if (value & GFX_MODE_70HZ)
1910        *hz = 70;
1911    else if (value & GFX_MODE_72HZ)
1912        *hz = 72;
1913    else if (value & GFX_MODE_75HZ)
1914        *hz = 75;
1915    else if (value & GFX_MODE_85HZ)
1916        *hz = 85;
1917    else if (value & GFX_MODE_90HZ)
1918        *hz = 90;
1919    else if (value & GFX_MODE_100HZ)
1920        *hz = 100;
1921
1922    return (1);
1923}
1924
1925/*----------------------------------------------------------------------------
1926 * gfx_get_frequency_from_refreshrate
1927 *
1928 * This routine maps the refresh rate to the closest matching PLL frequency.
1929 *----------------------------------------------------------------------------
1930 */
1931#if GFX_DISPLAY_DYNAMIC
1932int
1933gu2_get_frequency_from_refreshrate(int xres, int yres, int bpp, int hz,
1934                                   int *frequency)
1935#else
1936int
1937gfx_get_frequency_from_refreshrate(int xres, int yres, int bpp, int hz,
1938                                   int *frequency)
1939#endif
1940{
1941    unsigned int index;
1942    int retval = -1;
1943    unsigned long hz_flag = 0;
1944    unsigned long bpp_flag = 0;
1945
1946    *frequency = 0;
1947
1948    gfx_mode_hz_conversion gfx_mode_bpp_conversion_def(bpp)
1949
1950        /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */
1951        /* Search the table for the closest frequency (16.16 format). */
1952    for (index = 0; index < NUM_RC_DISPLAY_MODES; index++) {
1953        if ((DisplayParams[index].hactive == (unsigned short) xres) &&
1954            (DisplayParams[index].vactive == (unsigned short) yres) &&
1955            (DisplayParams[index].flags & bpp_flag) &&
1956            (DisplayParams[index].flags & hz_flag)) {
1957            *frequency = DisplayParams[index].frequency;
1958            retval = 1;
1959        }
1960    }
1961    return retval;
1962}
1963
1964/*---------------------------------------------------------------------------
1965 * gfx_get_max_supported_pixel_clock
1966 *
1967 * This routine returns the maximum recommended speed for the pixel clock. The
1968 * return value is an integer of the format xxxyyy, where xxx.yyy is the
1969 * maximum floating point pixel clock speed.
1970 *---------------------------------------------------------------------------
1971 */
1972#if GFX_DISPLAY_DYNAMIC
1973unsigned long
1974gu2_get_max_supported_pixel_clock(void)
1975#else
1976unsigned long
1977gfx_get_max_supported_pixel_clock(void)
1978#endif
1979{
1980    return 229500;
1981}
1982
1983/*----------------------------------------------------------------------------
1984 * gfx_get_display_mode
1985 *
1986 * This routine gets the specified display mode.
1987 *
1988 * Returns >0 if successful and mode returned, <0 if mode could not be found.
1989 *----------------------------------------------------------------------------
1990 */
1991#if GFX_DISPLAY_DYNAMIC
1992int
1993gu2_get_display_mode(int *xres, int *yres, int *bpp, int *hz)
1994#else
1995int
1996gfx_get_display_mode(int *xres, int *yres, int *bpp, int *hz)
1997#endif
1998{
1999    unsigned int mode = 0;
2000    unsigned long pll_freq = 0, bpp_flag = 0;
2001
2002    *xres = gfx_get_hactive();
2003    *yres = gfx_get_vactive();
2004    *bpp = gfx_get_display_bpp();
2005    pll_freq = gfx_get_clock_frequency();
2006
2007    /* SET BPP FLAGS TO LIMIT MODE SELECTION */
2008    gfx_mode_bpp_conversion_def(*bpp)
2009
2010        for (mode = 0; mode < NUM_RC_DISPLAY_MODES; mode++) {
2011        if ((DisplayParams[mode].hactive == (unsigned int) *xres) &&
2012            (DisplayParams[mode].vactive == (unsigned int) *yres) &&
2013            (DisplayParams[mode].frequency == pll_freq) &&
2014            (DisplayParams[mode].flags & bpp_flag)) {
2015
2016            pll_freq = DisplayParams[mode].flags;
2017
2018            if (pll_freq & GFX_MODE_56HZ)
2019                *hz = 56;
2020            else if (pll_freq & GFX_MODE_60HZ)
2021                *hz = 60;
2022            else if (pll_freq & GFX_MODE_70HZ)
2023                *hz = 70;
2024            else if (pll_freq & GFX_MODE_72HZ)
2025                *hz = 72;
2026            else if (pll_freq & GFX_MODE_75HZ)
2027                *hz = 75;
2028            else if (pll_freq & GFX_MODE_85HZ)
2029                *hz = 85;
2030            else if (pll_freq & GFX_MODE_90HZ)
2031                *hz = 90;
2032            else if (pll_freq & GFX_MODE_100HZ)
2033                *hz = 100;
2034
2035            return (1);
2036        }
2037    }
2038    return (-1);
2039}
2040
2041/*----------------------------------------------------------------------------
2042 * GFX_GET_DISPLAY_DETAILS
2043 *
2044 * This routine gets the specified display mode.
2045 *
2046 * Returns 1 if successful, 0 if mode could not be get.
2047 *----------------------------------------------------------------------------
2048 */
2049#if GFX_DISPLAY_DYNAMIC
2050int
2051gu2_get_display_details(unsigned int mode, int *xres, int *yres, int *hz)
2052#else
2053int
2054gfx_get_display_details(unsigned int mode, int *xres, int *yres, int *hz)
2055#endif
2056{
2057    if (mode < NUM_RC_DISPLAY_MODES) {
2058        if (DisplayParams[mode].flags & GFX_MODE_56HZ)
2059            *hz = 56;
2060        else if (DisplayParams[mode].flags & GFX_MODE_60HZ)
2061            *hz = 60;
2062        else if (DisplayParams[mode].flags & GFX_MODE_70HZ)
2063            *hz = 70;
2064        else if (DisplayParams[mode].flags & GFX_MODE_72HZ)
2065            *hz = 72;
2066        else if (DisplayParams[mode].flags & GFX_MODE_75HZ)
2067            *hz = 75;
2068        else if (DisplayParams[mode].flags & GFX_MODE_85HZ)
2069            *hz = 85;
2070        else if (DisplayParams[mode].flags & GFX_MODE_90HZ)
2071            *hz = 90;
2072        else if (DisplayParams[mode].flags & GFX_MODE_100HZ)
2073            *hz = 100;
2074
2075        *xres = DisplayParams[mode].hactive;
2076        *yres = DisplayParams[mode].vactive;
2077
2078        if (DisplayParams[mode].flags & GFX_MODE_PIXEL_DOUBLE)
2079            *xres >>= 1;
2080        if (DisplayParams[mode].flags & GFX_MODE_LINE_DOUBLE)
2081            *yres >>= 1;
2082
2083        return (1);
2084    }
2085    return (0);
2086}
2087
2088/*----------------------------------------------------------------------------
2089 * GFX_GET_DISPLAY_MODE_COUNT
2090 *
2091 * This routine gets the number of available display modes.
2092 *----------------------------------------------------------------------------
2093 */
2094#if GFX_DISPLAY_DYNAMIC
2095int
2096gu2_get_display_mode_count(void)
2097#else
2098int
2099gfx_get_display_mode_count(void)
2100#endif
2101{
2102    return (NUM_RC_DISPLAY_MODES);
2103}
2104
2105/*----------------------------------------------------------------------------
2106 * gfx_get_frame_buffer_line_size
2107 *
2108 * Returns the current frame buffer line size, in bytes
2109 *----------------------------------------------------------------------------
2110 */
2111#if GFX_DISPLAY_DYNAMIC
2112unsigned long
2113gu2_get_frame_buffer_line_size(void)
2114#else
2115unsigned long
2116gfx_get_frame_buffer_line_size(void)
2117#endif
2118{
2119    return ((READ_REG32(MDC_LINE_SIZE) & 0x7FF) << 3);
2120}
2121
2122/*---------------------------------------------------------------------------
2123 * gfx_get_hactive
2124 *---------------------------------------------------------------------------
2125 */
2126#if GFX_DISPLAY_DYNAMIC
2127unsigned short
2128gu2_get_hactive(void)
2129#else
2130unsigned short
2131gfx_get_hactive(void)
2132#endif
2133{
2134    return ((unsigned short) ((READ_REG32(MDC_H_ACTIVE_TIMING) & 0x0FF8) + 8));
2135}
2136
2137/*---------------------------------------------------------------------------
2138 * gfx_get_hsync_start
2139 *---------------------------------------------------------------------------
2140 */
2141#if GFX_DISPLAY_DYNAMIC
2142unsigned short
2143gu2_get_hsync_start(void)
2144#else
2145unsigned short
2146gfx_get_hsync_start(void)
2147#endif
2148{
2149    return ((unsigned short) ((READ_REG32(MDC_H_SYNC_TIMING) & 0x0FF8) + 8));
2150}
2151
2152/*---------------------------------------------------------------------------
2153 * gfx_get_hsync_end
2154 *---------------------------------------------------------------------------
2155 */
2156#if GFX_DISPLAY_DYNAMIC
2157unsigned short
2158gu2_get_hsync_end(void)
2159#else
2160unsigned short
2161gfx_get_hsync_end(void)
2162#endif
2163{
2164    return ((unsigned short) (((READ_REG32(MDC_H_SYNC_TIMING) >> 16) & 0x0FF8)
2165                              + 8));
2166}
2167
2168/*---------------------------------------------------------------------------
2169 * gfx_get_htotal
2170 *---------------------------------------------------------------------------
2171 */
2172#if GFX_DISPLAY_DYNAMIC
2173unsigned short
2174gu2_get_htotal(void)
2175#else
2176unsigned short
2177gfx_get_htotal(void)
2178#endif
2179{
2180    return ((unsigned short) (((READ_REG32(MDC_H_ACTIVE_TIMING) >> 16) &
2181                               0x0FF8) + 8));
2182}
2183
2184/*---------------------------------------------------------------------------
2185 * gfx_get_vactive
2186 *---------------------------------------------------------------------------
2187 */
2188#if GFX_DISPLAY_DYNAMIC
2189unsigned short
2190gu2_get_vactive(void)
2191#else
2192unsigned short
2193gfx_get_vactive(void)
2194#endif
2195{
2196    return ((unsigned short) ((READ_REG32(MDC_V_ACTIVE_TIMING) & 0x07FF) + 1));
2197}
2198
2199/*---------------------------------------------------------------------------
2200 * gfx_get_vsync_end
2201 *---------------------------------------------------------------------------
2202 */
2203#if GFX_DISPLAY_DYNAMIC
2204unsigned short
2205gu2_get_vsync_end(void)
2206#else
2207unsigned short
2208gfx_get_vsync_end(void)
2209#endif
2210{
2211    return ((unsigned short) (((READ_REG32(MDC_V_SYNC_TIMING) >> 16) & 0x07FF)
2212                              + 1));
2213}
2214
2215/*---------------------------------------------------------------------------
2216 * gfx_get_vtotal
2217 *---------------------------------------------------------------------------
2218 */
2219#if GFX_DISPLAY_DYNAMIC
2220unsigned short
2221gu2_get_vtotal(void)
2222#else
2223unsigned short
2224gfx_get_vtotal(void)
2225#endif
2226{
2227    return ((unsigned short) (((READ_REG32(MDC_V_ACTIVE_TIMING) >> 16) &
2228                               0x07FF) + 1));
2229}
2230
2231/*----------------------------------------------------------------------------
2232 * gfx_get_display_bpp
2233 *
2234 * This routine returns the current color depth of the active display.
2235 *----------------------------------------------------------------------------
2236 */
2237#if GFX_DISPLAY_DYNAMIC
2238unsigned short
2239gu2_get_display_bpp(void)
2240#else
2241unsigned short
2242gfx_get_display_bpp(void)
2243#endif
2244{
2245    unsigned long dcfg = READ_REG32(MDC_DISPLAY_CFG);
2246
2247    switch ((dcfg & MDC_DCFG_DISP_MODE_MASK) >> 8) {
2248    case 0:
2249        return (8);
2250    case 2:
2251        return (32);
2252    case 1:
2253        switch ((dcfg & MDC_DCFG_16BPP_MODE_MASK) >> 10) {
2254        case 0:
2255            return (16);
2256        case 1:
2257            return (15);
2258        case 2:
2259            return (12);
2260        default:
2261            return (0);
2262        }
2263    }
2264
2265    /* INVALID SETTING */
2266    return (0);
2267}
2268
2269/*---------------------------------------------------------------------------
2270 * gfx_get_vline
2271 *---------------------------------------------------------------------------
2272 */
2273#if GFX_DISPLAY_DYNAMIC
2274unsigned short
2275gu2_get_vline(void)
2276#else
2277unsigned short
2278gfx_get_vline(void)
2279#endif
2280{
2281    unsigned short current_scan_line;
2282
2283    /* Read similar value twice to ensure that the value is not
2284     * transitioning */
2285    do
2286        current_scan_line =
2287            (unsigned short) (READ_REG32(MDC_LINE_CNT_STATUS) &
2288                              MDC_LNCNT_V_LINE_CNT);
2289    while (current_scan_line !=
2290           (unsigned short) (READ_REG32(MDC_LINE_CNT_STATUS) &
2291                             MDC_LNCNT_V_LINE_CNT));
2292
2293    return (current_scan_line >> 16);
2294}
2295
2296/*-----------------------------------------------------------------------------
2297 * gfx_get_display_offset
2298 *-----------------------------------------------------------------------------
2299 */
2300#if GFX_DISPLAY_DYNAMIC
2301unsigned long
2302gu2_get_display_offset(void)
2303#else
2304unsigned long
2305gfx_get_display_offset(void)
2306#endif
2307{
2308    return (READ_REG32(MDC_FB_ST_OFFSET) & 0x0FFFFFFF);
2309}
2310
2311/*-----------------------------------------------------------------------------
2312 * gfx_get_cursor_offset
2313 *-----------------------------------------------------------------------------
2314 */
2315#if GFX_DISPLAY_DYNAMIC
2316unsigned long
2317gu2_get_cursor_offset(void)
2318#else
2319unsigned long
2320gfx_get_cursor_offset(void)
2321#endif
2322{
2323    return (READ_REG32(MDC_CURS_ST_OFFSET) & 0x0FFFFFFF);
2324}
2325
2326#if GFX_READ_ROUTINES
2327
2328/*************************************************************/
2329/*  READ ROUTINES  |  INCLUDED FOR DIAGNOSTIC PURPOSES ONLY  */
2330/*************************************************************/
2331
2332/*---------------------------------------------------------------------------
2333 * gfx_get_hblank_start
2334 *---------------------------------------------------------------------------
2335 */
2336#if GFX_DISPLAY_DYNAMIC
2337unsigned short
2338gu2_get_hblank_start(void)
2339#else
2340unsigned short
2341gfx_get_hblank_start(void)
2342#endif
2343{
2344    return ((unsigned short) ((READ_REG32(MDC_H_BLANK_TIMING) & 0x0FF8) + 8));
2345}
2346
2347/*---------------------------------------------------------------------------
2348 * gfx_get_hblank_end
2349 *---------------------------------------------------------------------------
2350 */
2351#if GFX_DISPLAY_DYNAMIC
2352unsigned short
2353gu2_get_hblank_end(void)
2354#else
2355unsigned short
2356gfx_get_hblank_end(void)
2357#endif
2358{
2359    return ((unsigned short) (((READ_REG32(MDC_H_BLANK_TIMING) >> 16) & 0x0FF8)
2360                              + 8));
2361}
2362
2363/*---------------------------------------------------------------------------
2364 * gfx_get_vblank_start
2365 *---------------------------------------------------------------------------
2366 */
2367#if GFX_DISPLAY_DYNAMIC
2368unsigned short
2369gu2_get_vblank_start(void)
2370#else
2371unsigned short
2372gfx_get_vblank_start(void)
2373#endif
2374{
2375    return ((unsigned short) ((READ_REG32(MDC_V_BLANK_TIMING) & 0x07FF) + 1));
2376}
2377
2378/*---------------------------------------------------------------------------
2379 * gfx_get_vsync_start
2380 *---------------------------------------------------------------------------
2381 */
2382#if GFX_DISPLAY_DYNAMIC
2383unsigned short
2384gu2_get_vsync_start(void)
2385#else
2386unsigned short
2387gfx_get_vsync_start(void)
2388#endif
2389{
2390    return ((unsigned short) ((READ_REG32(MDC_V_SYNC_TIMING) & 0x07FF) + 1));
2391}
2392
2393/*---------------------------------------------------------------------------
2394 * gfx_get_vblank_end
2395 *---------------------------------------------------------------------------
2396 */
2397#if GFX_DISPLAY_DYNAMIC
2398unsigned short
2399gu2_get_vblank_end(void)
2400#else
2401unsigned short
2402gfx_get_vblank_end(void)
2403#endif
2404{
2405    return ((unsigned short) (((READ_REG32(MDC_V_BLANK_TIMING) >> 16) & 0x07FF)
2406                              + 1));
2407}
2408
2409/*----------------------------------------------------------------------------
2410 * gfx_get_display_palette_entry
2411 *----------------------------------------------------------------------------
2412 */
2413#if GFX_DISPLAY_DYNAMIC
2414int
2415gu2_get_display_palette_entry(unsigned long index, unsigned long *palette)
2416#else
2417int
2418gfx_get_display_palette_entry(unsigned long index, unsigned long *palette)
2419#endif
2420{
2421    if (index > 0xFF)
2422        return GFX_STATUS_BAD_PARAMETER;
2423
2424    WRITE_REG32(MDC_PAL_ADDRESS, index);
2425    *palette = READ_REG32(MDC_PAL_DATA);
2426
2427    return 0;
2428}
2429
2430/*----------------------------------------------------------------------------
2431 * gfx_get_display_palette
2432 *----------------------------------------------------------------------------
2433 */
2434#if GFX_DISPLAY_DYNAMIC
2435void
2436gu2_get_display_palette(unsigned long *palette)
2437#else
2438void
2439gfx_get_display_palette(unsigned long *palette)
2440#endif
2441{
2442    unsigned long i;
2443
2444    WRITE_REG32(MDC_PAL_ADDRESS, 0);
2445    for (i = 0; i < 256; i++) {
2446        palette[i] = READ_REG32(MDC_PAL_DATA);
2447    }
2448}
2449
2450/*----------------------------------------------------------------------------
2451 * gfx_get_cursor_enable
2452 *----------------------------------------------------------------------------
2453 */
2454#if GFX_DISPLAY_DYNAMIC
2455unsigned long
2456gu2_get_cursor_enable(void)
2457#else
2458unsigned long
2459gfx_get_cursor_enable(void)
2460#endif
2461{
2462    return (READ_REG32(MDC_GENERAL_CFG) & MDC_GCFG_CURE);
2463}
2464
2465/*----------------------------------------------------------------------------
2466 * gfx_get_cursor_position
2467 *----------------------------------------------------------------------------
2468 */
2469#if GFX_DISPLAY_DYNAMIC
2470unsigned long
2471gu2_get_cursor_position(void)
2472#else
2473unsigned long
2474gfx_get_cursor_position(void)
2475#endif
2476{
2477    return ((READ_REG32(MDC_CURSOR_X) & 0x07FF) |
2478            ((READ_REG32(MDC_CURSOR_Y) << 16) & 0x07FF0000));
2479}
2480
2481/*----------------------------------------------------------------------------
2482 * gfx_get_cursor_offset
2483 *----------------------------------------------------------------------------
2484 */
2485#if GFX_DISPLAY_DYNAMIC
2486unsigned long
2487gu2_get_cursor_clip(void)
2488#else
2489unsigned long
2490gfx_get_cursor_clip(void)
2491#endif
2492{
2493    return (((READ_REG32(MDC_CURSOR_X) >> 11) & 0x03F) |
2494            ((READ_REG32(MDC_CURSOR_Y) << 5) & 0x3F0000));
2495}
2496
2497/*----------------------------------------------------------------------------
2498 * gfx_get_cursor_color
2499 *----------------------------------------------------------------------------
2500 */
2501#if GFX_DISPLAY_DYNAMIC
2502unsigned long
2503gu2_get_cursor_color(int color)
2504#else
2505unsigned long
2506gfx_get_cursor_color(int color)
2507#endif
2508{
2509    if (color) {
2510        WRITE_REG32(MDC_PAL_ADDRESS, 0x101);
2511    }
2512    else {
2513        WRITE_REG32(MDC_PAL_ADDRESS, 0x100);
2514    }
2515    return READ_REG32(MDC_PAL_DATA);
2516}
2517
2518/*----------------------------------------------------------------------------
2519 * gfx_get_icon_enable
2520 *----------------------------------------------------------------------------
2521 */
2522#if GFX_DISPLAY_DYNAMIC
2523unsigned long
2524gu2_get_icon_enable(void)
2525#else
2526unsigned long
2527gfx_get_icon_enable(void)
2528#endif
2529{
2530    return (READ_REG32(MDC_GENERAL_CFG) & MDC_GCFG_ICNE);
2531}
2532
2533/*----------------------------------------------------------------------------
2534 * gfx_get_icon_offset
2535 *----------------------------------------------------------------------------
2536 */
2537#if GFX_DISPLAY_DYNAMIC
2538unsigned long
2539gu2_get_icon_offset(void)
2540#else
2541unsigned long
2542gfx_get_icon_offset(void)
2543#endif
2544{
2545    return (READ_REG32(MDC_ICON_ST_OFFSET) & 0x0FFFFFFF);
2546}
2547
2548/*----------------------------------------------------------------------------
2549 * gfx_get_icon_position
2550 *----------------------------------------------------------------------------
2551 */
2552#if GFX_DISPLAY_DYNAMIC
2553unsigned long
2554gu2_get_icon_position(void)
2555#else
2556unsigned long
2557gfx_get_icon_position(void)
2558#endif
2559{
2560    return (READ_REG32(MDC_ICON_X) & 0x07FF);
2561}
2562
2563/*----------------------------------------------------------------------------
2564 * gfx_get_icon_color
2565 *----------------------------------------------------------------------------
2566 */
2567#if GFX_DISPLAY_DYNAMIC
2568unsigned long
2569gu2_get_icon_color(int color)
2570#else
2571unsigned long
2572gfx_get_icon_color(int color)
2573#endif
2574{
2575    if (color >= 3)
2576        return 0;
2577
2578    WRITE_REG32(MDC_PAL_ADDRESS, 0x102 + color);
2579
2580    return READ_REG32(MDC_PAL_DATA);
2581}
2582
2583/*----------------------------------------------------------------------------
2584 * gfx_get_compression_enable
2585 *----------------------------------------------------------------------------
2586 */
2587#if GFX_DISPLAY_DYNAMIC
2588int
2589gu2_get_compression_enable(void)
2590#else
2591int
2592gfx_get_compression_enable(void)
2593#endif
2594{
2595    if (READ_REG32(MDC_GENERAL_CFG) & MDC_GCFG_CMPE)
2596        return (1);
2597
2598    return (0);
2599}
2600
2601/*----------------------------------------------------------------------------
2602 * gfx_get_compression_offset
2603 *----------------------------------------------------------------------------
2604 */
2605#if GFX_DISPLAY_DYNAMIC
2606unsigned long
2607gu2_get_compression_offset(void)
2608#else
2609unsigned long
2610gfx_get_compression_offset(void)
2611#endif
2612{
2613    return (READ_REG32(MDC_CB_ST_OFFSET) & 0x007FFFFF);
2614}
2615
2616/*----------------------------------------------------------------------------
2617 * gfx_get_compression_pitch
2618 *----------------------------------------------------------------------------
2619 */
2620#if GFX_DISPLAY_DYNAMIC
2621unsigned short
2622gu2_get_compression_pitch(void)
2623#else
2624unsigned short
2625gfx_get_compression_pitch(void)
2626#endif
2627{
2628    unsigned short pitch;
2629
2630    pitch = (unsigned short) (READ_REG32(MDC_GFX_PITCH) >> 16);
2631    return (pitch << 3);
2632}
2633
2634/*----------------------------------------------------------------------------
2635 * gfx_get_compression_size
2636 *----------------------------------------------------------------------------
2637 */
2638#if GFX_DISPLAY_DYNAMIC
2639unsigned short
2640gu2_get_compression_size(void)
2641#else
2642unsigned short
2643gfx_get_compression_size(void)
2644#endif
2645{
2646    unsigned short size;
2647
2648    size = (unsigned short) ((READ_REG32(MDC_LINE_SIZE) >> 16) & 0x7F) - 1;
2649    return ((size << 3) + 32);
2650}
2651
2652/*----------------------------------------------------------------------------
2653 * gfx_get_valid_bit
2654 *----------------------------------------------------------------------------
2655 */
2656#if GFX_DISPLAY_DYNAMIC
2657int
2658gu2_get_valid_bit(int line)
2659#else
2660int
2661gfx_get_valid_bit(int line)
2662#endif
2663{
2664    unsigned long offset;
2665    int valid;
2666
2667    offset = READ_REG32(MDC_PHY_MEM_OFFSET) & 0xFF000000;
2668    offset |= line;
2669
2670    WRITE_REG32(MDC_PHY_MEM_OFFSET, offset);
2671    valid = (int) READ_REG32(MDC_DV_ACC) & 2;
2672
2673    if (valid)
2674        return 1;
2675    return 0;
2676}
2677
2678/*---------------------------------------------------------------------------
2679 * gfx_get_display_video_offset (PRIVATE ROUTINE - NOT PART OF API)
2680 *
2681 * This routine is called by "gfx_get_video_offset".  It abstracts the
2682 * version of the display controller from the video overlay routines.
2683 *---------------------------------------------------------------------------
2684 */
2685#if GFX_DISPLAY_DYNAMIC
2686unsigned long
2687gu2_get_display_video_offset(void)
2688#else
2689unsigned long
2690gfx_get_display_video_offset(void)
2691#endif
2692{
2693    return (READ_REG32(MDC_VID_Y_ST_OFFSET) & 0x0FFFFFFF);
2694}
2695
2696/*---------------------------------------------------------------------------
2697 * gfx_get_display_video_yuv_offsets (PRIVATE ROUTINE - NOT PART OF API)
2698 *
2699 * This routine is called by "gfx_get_video_yuv_offsets".  It abstracts the
2700 * version of the display controller from the video overlay routines.
2701 *---------------------------------------------------------------------------
2702 */
2703#if GFX_DISPLAY_DYNAMIC
2704void
2705gu2_get_display_video_yuv_offsets(unsigned long *yoffset,
2706                                  unsigned long *uoffset,
2707                                  unsigned long *voffset)
2708#else
2709void
2710gfx_get_display_video_yuv_offsets(unsigned long *yoffset,
2711                                  unsigned long *uoffset,
2712                                  unsigned long *voffset)
2713#endif
2714{
2715    *yoffset = (READ_REG32(MDC_VID_Y_ST_OFFSET) & 0x0FFFFFFF);
2716    *uoffset = (READ_REG32(MDC_VID_U_ST_OFFSET) & 0x0FFFFFFF);
2717    *voffset = (READ_REG32(MDC_VID_V_ST_OFFSET) & 0x0FFFFFFF);
2718}
2719
2720/*---------------------------------------------------------------------------
2721 * gfx_get_display_video_yuv_pitch (PRIVATE ROUTINE - NOT PART OF API)
2722 *
2723 * This routine is called by "gfx_get_video_yuv_pitch".  It abstracts the
2724 * version of the display controller from the video overlay routines.
2725 *---------------------------------------------------------------------------
2726 */
2727#if GFX_DISPLAY_DYNAMIC
2728void
2729gu2_get_display_video_yuv_pitch(unsigned long *ypitch, unsigned long *uvpitch)
2730#else
2731void
2732gfx_get_display_video_yuv_pitch(unsigned long *ypitch, unsigned long *uvpitch)
2733#endif
2734{
2735    unsigned long pitch = READ_REG32(MDC_VID_YUV_PITCH);
2736
2737    *ypitch = ((pitch & 0xFFFF) << 3);
2738    *uvpitch = (pitch >> 13) & 0x7FFF8;
2739}
2740
2741/*---------------------------------------------------------------------------
2742 * gfx_get_display_video_downscale_delta (PRIVATE ROUTINE - NOT PART OF API)
2743 *
2744 * This routine is called by "gfx_get_video_downscale_delta". It abstracts the
2745 * version of the display controller from the video overlay routines.
2746 *---------------------------------------------------------------------------
2747 */
2748#if GFX_DISPLAY_DYNAMIC
2749unsigned long
2750gu2_get_display_video_downscale_delta(void)
2751#else
2752unsigned long
2753gfx_get_display_video_downscale_delta(void)
2754#endif
2755{
2756    return (READ_REG32(MDC_VID_DS_DELTA) >> 18);
2757}
2758
2759/*---------------------------------------------------------------------------
2760 * gfx_get_display_video_downscale_enable (PRIVATE ROUTINE - NOT PART OF API)
2761 *
2762 * This routine is called by "gfx_get_video_vertical_downscale_enable".
2763 * It abstracts the version of the display controller from the video overlay
2764 * routines.
2765 *---------------------------------------------------------------------------
2766 */
2767#if GFX_DISPLAY_DYNAMIC
2768int
2769gu2_get_display_video_downscale_enable(void)
2770#else
2771int
2772gfx_get_display_video_downscale_enable(void)
2773#endif
2774{
2775    return ((int) ((READ_REG32(MDC_GENERAL_CFG) >> 19) & 1));
2776}
2777
2778/*---------------------------------------------------------------------------
2779 * gfx_get_display_video_size (PRIVATE ROUTINE - NOT PART OF API)
2780 *
2781 * This routine is called by "gfx_get_video_size".  It abstracts the
2782 * version of the display controller from the video overlay routines.
2783 *---------------------------------------------------------------------------
2784 */
2785#if GFX_DISPLAY_DYNAMIC
2786unsigned long
2787gu2_get_display_video_size(void)
2788#else
2789unsigned long
2790gfx_get_display_video_size(void)
2791#endif
2792{
2793    /* RETURN THE LINE SIZE, AS THIS IS ALL THAT IS AVAILABLE */
2794
2795    return ((READ_REG32(MDC_LINE_SIZE) >> 21) & 0x000007FF);
2796}
2797
2798#endif                          /* GFX_READ_ROUTINES */
2799
2800/* END OF FILE */
2801