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