disp_gu1.c revision f29dbc25
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
26f29dbc25Smrgvoid gu1_enable_compression(void);     /* private routine definition */
27f29dbc25Smrgvoid gu1_disable_compression(void);    /* private routine definition */
28f29dbc25Smrgvoid gfx_reset_video(void);            /* private routine definition */
29f29dbc25Smrgint gfx_set_display_control(int sync_polarities);       /* private routine
30f29dbc25Smrg                                                         * definition */
31f29dbc25Smrgint gu1_set_specified_mode(DISPLAYMODE * pMode, int bpp);
32f29dbc25Smrg
33f29dbc25Smrg/* VIDEO BUFFER SIZE */
34f29dbc25Smrg
35f29dbc25Smrgunsigned long vid_buf_size = 0;
36f29dbc25Smrgint vid_enabled = 0;
37f29dbc25Smrg
38f29dbc25Smrg/*----------------------------------------------------------------------------
39f29dbc25Smrg * GU1_DELAY_APPROXIMATE (PRIVATE ROUTINE - NOT PART OF DURANGO API)
40f29dbc25Smrg *
41f29dbc25Smrg * Delay the requested number of milliseconds by reading a register.  This
42f29dbc25Smrg * function generally takes longer than the requested time.
43f29dbc25Smrg *----------------------------------------------------------------------------
44f29dbc25Smrg */
45f29dbc25Smrg
46f29dbc25Smrg#define READS_PER_MILLISECOND 60000L
47f29dbc25Smrg
48f29dbc25Smrgvoid
49f29dbc25Smrggu1_delay_approximate(unsigned long milliseconds)
50f29dbc25Smrg{
51f29dbc25Smrg    /* ASSUME 300 MHz, 5 CLOCKS PER READ */
52f29dbc25Smrg
53f29dbc25Smrg    unsigned long loop;
54f29dbc25Smrg
55f29dbc25Smrg    loop = milliseconds * READS_PER_MILLISECOND;
56f29dbc25Smrg    while (loop-- > 0) {
57f29dbc25Smrg        READ_REG32(DC_UNLOCK);
58f29dbc25Smrg    }
59f29dbc25Smrg}
60f29dbc25Smrg
61f29dbc25Smrg/*----------------------------------------------------------------------------
62f29dbc25Smrg * GU1_DELAY_PRECISE (PRIVATE ROUTINE - NOT PART OF DURANGO API)
63f29dbc25Smrg *
64f29dbc25Smrg * Delay the number of milliseconds on a more precise level, varying only by
65f29dbc25Smrg * 1/10 of a ms.  This function should only be called if an SC1200 is present.
66f29dbc25Smrg *----------------------------------------------------------------------------
67f29dbc25Smrg */
68f29dbc25Smrgvoid
69f29dbc25Smrggu1_delay_precise(unsigned long milliseconds)
70f29dbc25Smrg{
71f29dbc25Smrg#if GFX_VIDEO_SC1200
72f29dbc25Smrg
73f29dbc25Smrg#define LOOP 1000
74f29dbc25Smrg    unsigned long i, timer_start, timer_end, total_ticks, previous_ticks,
75f29dbc25Smrg        temp_ticks;
76f29dbc25Smrg
77f29dbc25Smrg    /* Get current time */
78f29dbc25Smrg    timer_start = IND(SC1200_CB_BASE_ADDR + SC1200_CB_TMVALUE);
79f29dbc25Smrg
80f29dbc25Smrg    /* Calculate expected end time */
81f29dbc25Smrg    if (INB(SC1200_CB_BASE_ADDR + SC1200_CB_TMCNFG) & SC1200_TMCLKSEL_27MHZ)
82f29dbc25Smrg        total_ticks = 27000 * milliseconds;     /* timer resolution is 27 MHz */
83f29dbc25Smrg    else
84f29dbc25Smrg        total_ticks = 1000 * milliseconds;      /* timer resolution is 1 MHz */
85f29dbc25Smrg
86f29dbc25Smrg    if (total_ticks > ((unsigned long)0xffffffff - timer_start))
87f29dbc25Smrg        /* wrap-around */
88f29dbc25Smrg        timer_end = total_ticks - ((unsigned long)0xffffffff - timer_start);
89f29dbc25Smrg    else
90f29dbc25Smrg        timer_end = timer_start + total_ticks;
91f29dbc25Smrg
92f29dbc25Smrg    /* in case of wrap around */
93f29dbc25Smrg    if (timer_end < timer_start) {
94f29dbc25Smrg        previous_ticks = timer_start;
95f29dbc25Smrg        while (1) {
96f29dbc25Smrg            temp_ticks = IND(SC1200_CB_BASE_ADDR + SC1200_CB_TMVALUE);
97f29dbc25Smrg            if (temp_ticks < previous_ticks)
98f29dbc25Smrg                break;
99f29dbc25Smrg            else
100f29dbc25Smrg                previous_ticks = temp_ticks;
101f29dbc25Smrg            for (i = 0; i < LOOP; i++)
102f29dbc25Smrg                READ_REG32(DC_UNLOCK);
103f29dbc25Smrg        }
104f29dbc25Smrg    }
105f29dbc25Smrg
106f29dbc25Smrg    /* now the non-wrap around part */
107f29dbc25Smrg    while (1) {
108f29dbc25Smrg        for (i = 0; i < LOOP; i++)
109f29dbc25Smrg            READ_REG32(DC_UNLOCK);
110f29dbc25Smrg        if (IND(SC1200_CB_BASE_ADDR + SC1200_CB_TMVALUE) > timer_end)
111f29dbc25Smrg            break;
112f29dbc25Smrg    }
113f29dbc25Smrg#endif /* GFX_VIDEO_SC1200 */
114f29dbc25Smrg}
115f29dbc25Smrg
116f29dbc25Smrg/*----------------------------------------------------------------------------
117f29dbc25Smrg * WARNING!!!! INACCURATE DELAY MECHANISM
118f29dbc25Smrg *
119f29dbc25Smrg * In an effort to keep the code self contained and operating system
120f29dbc25Smrg * independent, the delay loop just performs reads of a display controller
121f29dbc25Smrg * register.  This time will vary for faster processors.  The delay can always
122f29dbc25Smrg * be longer than intended, only effecting the time of the mode switch
123f29dbc25Smrg * (obviously want it to still be under a second).  Problems with the hardware
124f29dbc25Smrg * only arise if the delay is not long enough.
125f29dbc25Smrg *
126f29dbc25Smrg * For the SC1200, the high resolution timer can be used as an accurate
127f29dbc25Smrg * mechanism for keeping time. However, in order to avoid a busy loop of IO
128f29dbc25Smrg * reads, the timer is polled in-between busy loops, and therefore the actual
129f29dbc25Smrg * delay might be longer than the requested delay by the time of one busy loop
130f29dbc25Smrg * (which on a 200 MHz system took 95 us)
131f29dbc25Smrg *
132f29dbc25Smrg * There are thus two delay functions which are called from the main API
133f29dbc25Smrg * routine.
134f29dbc25Smrg * One is meant to be more precise and should only called if an SC1200 is
135f29dbc25Smrg * present.
136f29dbc25Smrg *----------------------------------------------------------------------------
137f29dbc25Smrg */
138f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
139f29dbc25Smrgvoid
140f29dbc25Smrggu1_delay_milliseconds(unsigned long milliseconds)
141f29dbc25Smrg#else
142f29dbc25Smrgvoid
143f29dbc25Smrggfx_delay_milliseconds(unsigned long milliseconds)
144f29dbc25Smrg#endif
145f29dbc25Smrg{
146f29dbc25Smrg#if GFX_VIDEO_SC1200
147f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
148f29dbc25Smrg    if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) {
149f29dbc25Smrg#endif
150f29dbc25Smrg        gu1_delay_precise(milliseconds);
151f29dbc25Smrg        return;
152f29dbc25Smrg#if GFX_VIDEO_DYNAMIC
153f29dbc25Smrg    }
154f29dbc25Smrg#endif
155f29dbc25Smrg#endif /* GFX_VIDEO_SC1200 */
156f29dbc25Smrg    gu1_delay_approximate(milliseconds);
157f29dbc25Smrg}
158f29dbc25Smrg
159f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
160f29dbc25Smrgvoid
161f29dbc25Smrggu1_delay_microseconds(unsigned long microseconds)
162f29dbc25Smrg#else
163f29dbc25Smrgvoid
164f29dbc25Smrggfx_delay_microseconds(unsigned long microseconds)
165f29dbc25Smrg#endif
166f29dbc25Smrg{
167f29dbc25Smrg    /* ASSUME 300 MHz, 2 CLOCKS PER INCREMENT */
168f29dbc25Smrg    unsigned long loop_count = microseconds * 150;
169f29dbc25Smrg
170f29dbc25Smrg    while (loop_count-- > 0) {
171f29dbc25Smrg        ;
172f29dbc25Smrg    }
173f29dbc25Smrg}
174f29dbc25Smrg
175f29dbc25Smrg/*----------------------------------------------------------------------------
176f29dbc25Smrg * GFX_VIDEO_SHUTDOWN
177f29dbc25Smrg *
178f29dbc25Smrg * This routine disables the display controller output.
179f29dbc25Smrg *----------------------------------------------------------------------------
180f29dbc25Smrg */
181f29dbc25Smrgvoid
182f29dbc25Smrggu1_video_shutdown(void)
183f29dbc25Smrg{
184f29dbc25Smrg    unsigned long unlock;
185f29dbc25Smrg    unsigned long gcfg, tcfg;
186f29dbc25Smrg
187f29dbc25Smrg    /* DISABLE COMPRESSION */
188f29dbc25Smrg    gu1_disable_compression();
189f29dbc25Smrg
190f29dbc25Smrg    /* ALSO DISABLE VIDEO */
191f29dbc25Smrg    /* Use private "reset video" routine to do all that is needed. */
192f29dbc25Smrg    /* SC1200, for example, also disables the alpha blending regions. */
193f29dbc25Smrg    gfx_reset_video();
194f29dbc25Smrg
195f29dbc25Smrg    /* UNLOCK THE DISPLAY CONTROLLER REGISTERS */
196f29dbc25Smrg    unlock = READ_REG32(DC_UNLOCK);
197f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
198f29dbc25Smrg
199f29dbc25Smrg    /* READ THE CURRENT GX VALUES */
200f29dbc25Smrg    gcfg = READ_REG32(DC_GENERAL_CFG);
201f29dbc25Smrg    tcfg = READ_REG32(DC_TIMING_CFG);
202f29dbc25Smrg
203f29dbc25Smrg    /* BLANK THE GX DISPLAY AND DISABLE THE TIMING GENERATOR */
204f29dbc25Smrg    tcfg &= ~((unsigned long)DC_TCFG_BLKE | (unsigned long)DC_TCFG_TGEN);
205f29dbc25Smrg    WRITE_REG32(DC_TIMING_CFG, tcfg);
206f29dbc25Smrg
207f29dbc25Smrg    /* DELAY: WAIT FOR PENDING MEMORY REQUESTS */
208f29dbc25Smrg    /* This delay is used to make sure that all pending requests to the */
209f29dbc25Smrg    /* memory controller have completed before disabling the FIFO load. */
210f29dbc25Smrg    gfx_delay_milliseconds(1);
211f29dbc25Smrg
212f29dbc25Smrg    /* DISABLE DISPLAY FIFO LOAD AND DISABLE COMPRESSION */
213f29dbc25Smrg    gcfg &= ~(unsigned long)(DC_GCFG_DFLE | DC_GCFG_CMPE | DC_GCFG_DECE);
214f29dbc25Smrg    WRITE_REG32(DC_GENERAL_CFG, gcfg);
215f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, unlock);
216f29dbc25Smrg    return;
217f29dbc25Smrg}
218f29dbc25Smrg
219f29dbc25Smrg/*----------------------------------------------------------------------------
220f29dbc25Smrg * GFX_SET_DISPLAY_BPP
221f29dbc25Smrg *
222f29dbc25Smrg * This routine programs the bpp in the display controller.
223f29dbc25Smrg *----------------------------------------------------------------------------
224f29dbc25Smrg */
225f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
226f29dbc25Smrgint
227f29dbc25Smrggu1_set_display_bpp(unsigned short bpp)
228f29dbc25Smrg#else
229f29dbc25Smrgint
230f29dbc25Smrggfx_set_display_bpp(unsigned short bpp)
231f29dbc25Smrg#endif
232f29dbc25Smrg{
233f29dbc25Smrg    unsigned long ocfg, lock;
234f29dbc25Smrg
235f29dbc25Smrg    lock = READ_REG32(DC_UNLOCK);
236f29dbc25Smrg    ocfg = READ_REG32(DC_OUTPUT_CFG) & ~(DC_OCFG_8BPP | DC_OCFG_555);
237f29dbc25Smrg
238f29dbc25Smrg    /* SET DC PIXEL FORMAT */
239f29dbc25Smrg    if (bpp == 8)
240f29dbc25Smrg        ocfg |= DC_OCFG_8BPP;
241f29dbc25Smrg    else if (bpp == 15)
242f29dbc25Smrg        ocfg |= DC_OCFG_555;
243f29dbc25Smrg    else if (bpp != 16)
244f29dbc25Smrg        return GFX_STATUS_BAD_PARAMETER;
245f29dbc25Smrg
246f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
247f29dbc25Smrg    WRITE_REG32(DC_OUTPUT_CFG, ocfg);
248f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, lock);
249f29dbc25Smrg
250f29dbc25Smrg    /* SET BPP IN GRAPHICS PIPELINE */
251f29dbc25Smrg    gfx_set_bpp(bpp);
252f29dbc25Smrg
253f29dbc25Smrg    return 0;
254f29dbc25Smrg}
255f29dbc25Smrg
256f29dbc25Smrg/*----------------------------------------------------------------------------
257f29dbc25Smrg * GFX_SET_SPECIFIED_MODE
258f29dbc25Smrg * This routine uses the parameters in the specified display mode structure
259f29dbc25Smrg * to program the display controller hardware.
260f29dbc25Smrg *----------------------------------------------------------------------------
261f29dbc25Smrg */
262f29dbc25Smrgint
263f29dbc25Smrggu1_set_specified_mode(DISPLAYMODE * pMode, int bpp)
264f29dbc25Smrg{
265f29dbc25Smrg    unsigned long unlock, value;
266f29dbc25Smrg    unsigned long gcfg, tcfg, ocfg;
267f29dbc25Smrg    unsigned long size, pitch;
268f29dbc25Smrg    unsigned long hactive, vactive;
269f29dbc25Smrg
270f29dbc25Smrg    gbpp = bpp;
271f29dbc25Smrg
272f29dbc25Smrg    /* CHECK WHETHER TIMING CHANGE IS ALLOWED */
273f29dbc25Smrg    /* Flag used for locking also overrides timing change restriction */
274f29dbc25Smrg    if (gfx_timing_lock && !(pMode->flags & GFX_MODE_LOCK_TIMING))
275f29dbc25Smrg        return GFX_STATUS_ERROR;
276f29dbc25Smrg
277f29dbc25Smrg    /* SET GLOBAL FLAG */
278f29dbc25Smrg    if (pMode->flags & GFX_MODE_LOCK_TIMING)
279f29dbc25Smrg        gfx_timing_lock = 1;
280f29dbc25Smrg
281f29dbc25Smrg    /* DISABLE COMPRESSION */
282f29dbc25Smrg    gu1_disable_compression();
283f29dbc25Smrg
284f29dbc25Smrg    /* ALSO DISABLE VIDEO */
285f29dbc25Smrg    /* Use private "reset video" routine to do all that is needed. */
286f29dbc25Smrg    /* SC1200, for example, also disables the alpha blending regions. */
287f29dbc25Smrg    gfx_reset_video();
288f29dbc25Smrg
289f29dbc25Smrg    /* UNLOCK THE DISPLAY CONTROLLER REGISTERS */
290f29dbc25Smrg    unlock = READ_REG32(DC_UNLOCK);
291f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
292f29dbc25Smrg
293f29dbc25Smrg    /* READ THE CURRENT GX VALUES */
294f29dbc25Smrg    gcfg = READ_REG32(DC_GENERAL_CFG);
295f29dbc25Smrg    tcfg = READ_REG32(DC_TIMING_CFG);
296f29dbc25Smrg
297f29dbc25Smrg    /* BLANK THE GX DISPLAY AND DISABLE THE TIMING GENERATOR */
298f29dbc25Smrg    tcfg &= ~((unsigned long)DC_TCFG_BLKE | (unsigned long)DC_TCFG_TGEN);
299f29dbc25Smrg    WRITE_REG32(DC_TIMING_CFG, tcfg);
300f29dbc25Smrg
301f29dbc25Smrg    /* DELAY: WAIT FOR PENDING MEMORY REQUESTS
302f29dbc25Smrg     * This delay is used to make sure that all pending requests to the
303f29dbc25Smrg     * memory controller have completed before disabling the FIFO load.
304f29dbc25Smrg     */
305f29dbc25Smrg    gfx_delay_milliseconds(1);
306f29dbc25Smrg
307f29dbc25Smrg    /* DISABLE DISPLAY FIFO LOAD AND DISABLE COMPRESSION */
308f29dbc25Smrg    gcfg &= ~(unsigned long)(DC_GCFG_DFLE | DC_GCFG_CMPE | DC_GCFG_DECE);
309f29dbc25Smrg    WRITE_REG32(DC_GENERAL_CFG, gcfg);
310f29dbc25Smrg
311f29dbc25Smrg    /* CLEAR THE "DCLK_MUL" FIELD */
312f29dbc25Smrg    gcfg &= ~(unsigned long)(DC_GCFG_DDCK | DC_GCFG_DPCK | DC_GCFG_DFCK);
313f29dbc25Smrg    gcfg &= ~(unsigned long)DC_GCFG_DCLK_MASK;
314f29dbc25Smrg    WRITE_REG32(DC_GENERAL_CFG, gcfg);
315f29dbc25Smrg
316f29dbc25Smrg    /* SET THE DOT CLOCK FREQUENCY */
317f29dbc25Smrg    /* Mask off the divide by two bit (bit 31) */
318f29dbc25Smrg    gfx_set_clock_frequency(pMode->frequency & 0x7FFFFFFF);
319f29dbc25Smrg
320f29dbc25Smrg    /* DELAY: WAIT FOR THE PLL TO SETTLE */
321f29dbc25Smrg    /* This allows the dot clock frequency that was just set to settle. */
322f29dbc25Smrg    gfx_delay_milliseconds(1);
323f29dbc25Smrg
324f29dbc25Smrg    /* SET THE "DCLK_MUL" FIELD OF DC_GENERAL_CFG */
325f29dbc25Smrg    /* The GX hardware divides the dot clock, so 2x really means that the */
326f29dbc25Smrg    /* internal dot clock equals the external dot clock. */
327f29dbc25Smrg    if (pMode->frequency & 0x80000000)
328f29dbc25Smrg        gcfg |= 0x0040;
329f29dbc25Smrg    else
330f29dbc25Smrg        gcfg |= 0x0080;
331f29dbc25Smrg
332f29dbc25Smrg    WRITE_REG32(DC_GENERAL_CFG, gcfg);
333f29dbc25Smrg
334f29dbc25Smrg    /* DELAY: WAIT FOR THE ADL TO LOCK */
335f29dbc25Smrg    /* This allows the clock generatation within GX to settle.  This is */
336f29dbc25Smrg    /* needed since some of the register writes that follow require that */
337f29dbc25Smrg    /* clock to be present. */
338f29dbc25Smrg    gfx_delay_milliseconds(1);
339f29dbc25Smrg
340f29dbc25Smrg    /* SET THE GX DISPLAY CONTROLLER PARAMETERS */
341f29dbc25Smrg    WRITE_REG32(DC_FB_ST_OFFSET, 0);
342f29dbc25Smrg    WRITE_REG32(DC_CB_ST_OFFSET, 0);
343f29dbc25Smrg    WRITE_REG32(DC_CURS_ST_OFFSET, 0);
344f29dbc25Smrg
345f29dbc25Smrg    /* SET LINE SIZE AND PITCH */
346f29dbc25Smrg    /* Flat panels use the current flat panel line size to    */
347f29dbc25Smrg    /* calculate the pitch, but load the true line size       */
348f29dbc25Smrg    /* for the mode into the "Frame Buffer Line Size" field   */
349f29dbc25Smrg    /* of DC_BUF_SIZE.                                        */
350f29dbc25Smrg    if (PanelEnable)
351f29dbc25Smrg        size = ModeWidth;
352f29dbc25Smrg    else
353f29dbc25Smrg        size = pMode->hactive;
354f29dbc25Smrg
355f29dbc25Smrg    if (bpp > 8)
356f29dbc25Smrg        size <<= 1;
357f29dbc25Smrg
358f29dbc25Smrg    /* ONLY PYRAMID SUPPORTS 4K LINE SIZE */
359f29dbc25Smrg    if (size <= 1024) {
360f29dbc25Smrg        pitch = 1024;
361f29dbc25Smrg        /* SPECIAL CASE  */
362f29dbc25Smrg        /* Graphics acceleration in 16-bit pixel line double modes */
363f29dbc25Smrg        /* requires a pitch of 2048.                               */
364f29dbc25Smrg        if ((pMode->flags & GFX_MODE_LINE_DOUBLE) && bpp > 8)
365f29dbc25Smrg            pitch <<= 1;
366f29dbc25Smrg    } else {
367f29dbc25Smrg        if (gfx_cpu_version == GFX_CPU_PYRAMID)
368f29dbc25Smrg            pitch = (size <= 2048) ? 2048 : 4096;
369f29dbc25Smrg        else
370f29dbc25Smrg            pitch = 2048;
371f29dbc25Smrg    }
372f29dbc25Smrg
373f29dbc25Smrg    WRITE_REG32(DC_LINE_DELTA, pitch >> 2);
374f29dbc25Smrg
375f29dbc25Smrg    if (PanelEnable) {
376f29dbc25Smrg        size = pMode->hactive;
377f29dbc25Smrg        if (bpp > 8)
378f29dbc25Smrg            size <<= 1;
379f29dbc25Smrg    }
380f29dbc25Smrg
381f29dbc25Smrg    /* ADD 2 TO SIZE FOR POSSIBLE START ADDRESS ALIGNMENTS */
382f29dbc25Smrg    WRITE_REG32(DC_BUF_SIZE, (size >> 3) + 2);
383f29dbc25Smrg
384f29dbc25Smrg    /* ALWAYS ENABLE "PANEL" DATA FROM MEDIAGX */
385f29dbc25Smrg    /* That is really just the 18 BPP data bus to the companion chip */
386f29dbc25Smrg    ocfg = DC_OCFG_PCKE | DC_OCFG_PDEL | DC_OCFG_PDEH;
387f29dbc25Smrg
388f29dbc25Smrg    /* SET PIXEL FORMAT */
389f29dbc25Smrg    if (bpp == 8)
390f29dbc25Smrg        ocfg |= DC_OCFG_8BPP;
391f29dbc25Smrg    else if (bpp == 15)
392f29dbc25Smrg        ocfg |= DC_OCFG_555;
393f29dbc25Smrg
394f29dbc25Smrg    /* ENABLE TIMING GENERATOR, SYNCS, AND FP DATA */
395f29dbc25Smrg    tcfg = DC_TCFG_FPPE | DC_TCFG_HSYE | DC_TCFG_VSYE | DC_TCFG_BLKE |
396f29dbc25Smrg        DC_TCFG_TGEN;
397f29dbc25Smrg
398f29dbc25Smrg    /* SET FIFO PRIORITY, DCLK MULTIPLIER, AND FIFO ENABLE */
399f29dbc25Smrg    /* Default 6/5 for FIFO, 2x for DCLK multiplier. */
400f29dbc25Smrg    gcfg =
401f29dbc25Smrg        (6 << DC_GCFG_DFHPEL_POS) | (5 << DC_GCFG_DFHPSL_POS) | DC_GCFG_DFLE;
402f29dbc25Smrg
403f29dbc25Smrg    /* INCREASE FIFO PRIORITY FOR LARGE MODES */
404f29dbc25Smrg    if (pMode->hactive == 1280 && pMode->vactive == 1024) {
405f29dbc25Smrg        if ((bpp == 8) && (pMode->flags & GFX_MODE_85HZ))
406f29dbc25Smrg            gcfg =
407f29dbc25Smrg                (8l << DC_GCFG_DFHPEL_POS) | (7l << DC_GCFG_DFHPSL_POS) |
408f29dbc25Smrg                DC_GCFG_DFLE;
409f29dbc25Smrg
410f29dbc25Smrg        if ((bpp > 8) && (pMode->flags & GFX_MODE_75HZ))
411f29dbc25Smrg            gcfg =
412f29dbc25Smrg                (7l << DC_GCFG_DFHPEL_POS) | (6l << DC_GCFG_DFHPSL_POS) |
413f29dbc25Smrg                DC_GCFG_DFLE;
414f29dbc25Smrg
415f29dbc25Smrg        if ((bpp > 8) && (pMode->flags & GFX_MODE_85HZ))
416f29dbc25Smrg            gcfg =
417f29dbc25Smrg                (9l << DC_GCFG_DFHPEL_POS) | (8l << DC_GCFG_DFHPSL_POS) |
418f29dbc25Smrg                DC_GCFG_DFLE;
419f29dbc25Smrg    }
420f29dbc25Smrg
421f29dbc25Smrg    /* SET DOT CLOCK MULTIPLIER */
422f29dbc25Smrg    /* Bit 31 of frequency indicates divide frequency by two */
423f29dbc25Smrg    if (pMode->frequency & 0x80000000)
424f29dbc25Smrg        gcfg |= (1l << DC_GCFG_DCLK_POS);
425f29dbc25Smrg    else
426f29dbc25Smrg        gcfg |= (2l << DC_GCFG_DCLK_POS);
427f29dbc25Smrg
428f29dbc25Smrg    /* DIVIDE VIDEO CLOCK */
429f29dbc25Smrg    /* CPU core frequencies above 266 MHz will divide the video */
430f29dbc25Smrg    /* clock by 4 to ensure that we are running below 150 MHz.  */
431f29dbc25Smrg    if (gfx_cpu_frequency > 266)
432f29dbc25Smrg        gcfg |= DC_GCFG_VCLK_DIV;
433f29dbc25Smrg
434f29dbc25Smrg    /* ALWAYS ENABLE VIDEO IN THE DISPLAY CONTROLLER */
435f29dbc25Smrg    /* Enabling video at an inopportune momemt can corrupt the DC fetch */
436f29dbc25Smrg    /* engine and cause screen artifacts or system hang.                */
437f29dbc25Smrg    gcfg |= (DC_GCFG_VIDE | DC_GCFG_VRDY);
438f29dbc25Smrg
439f29dbc25Smrg    /* SET THE PIXEL AND LINE DOUBLE BITS IF NECESSARY */
440f29dbc25Smrg    hactive = pMode->hactive;
441f29dbc25Smrg    vactive = pMode->vactive;
442f29dbc25Smrg    gfx_line_double = 0;
443f29dbc25Smrg    gfx_pixel_double = 0;
444f29dbc25Smrg
445f29dbc25Smrg    if (pMode->flags & GFX_MODE_LINE_DOUBLE) {
446f29dbc25Smrg        gcfg |= DC_GCFG_LDBL;
447f29dbc25Smrg        hactive <<= 1;
448f29dbc25Smrg
449f29dbc25Smrg        /* SET GLOBAL FLAG */
450f29dbc25Smrg        gfx_line_double = 1;
451f29dbc25Smrg    }
452f29dbc25Smrg
453f29dbc25Smrg    if (pMode->flags & GFX_MODE_PIXEL_DOUBLE) {
454f29dbc25Smrg        tcfg |= DC_TCFG_PXDB;
455f29dbc25Smrg        vactive <<= 1;
456f29dbc25Smrg
457f29dbc25Smrg        /* SET GLOBAL FLAG */
458f29dbc25Smrg        gfx_pixel_double = 1;
459f29dbc25Smrg    }
460f29dbc25Smrg
461f29dbc25Smrg    /* COMBINE AND SET TIMING VALUES */
462f29dbc25Smrg
463f29dbc25Smrg    value = (unsigned long)(hactive - 1) |
464f29dbc25Smrg        (((unsigned long)(pMode->htotal - 1)) << 16);
465f29dbc25Smrg    WRITE_REG32(DC_H_TIMING_1, value);
466f29dbc25Smrg    value = (unsigned long)(pMode->hblankstart - 1) |
467f29dbc25Smrg        (((unsigned long)(pMode->hblankend - 1)) << 16);
468f29dbc25Smrg    WRITE_REG32(DC_H_TIMING_2, value);
469f29dbc25Smrg    value = (unsigned long)(pMode->hsyncstart - 1) |
470f29dbc25Smrg        (((unsigned long)(pMode->hsyncend - 1)) << 16);
471f29dbc25Smrg    WRITE_REG32(DC_H_TIMING_3, value);
472f29dbc25Smrg    WRITE_REG32(DC_FP_H_TIMING, value);
473f29dbc25Smrg    value = (unsigned long)(vactive - 1) |
474f29dbc25Smrg        (((unsigned long)(pMode->vtotal - 1)) << 16);
475f29dbc25Smrg    WRITE_REG32(DC_V_TIMING_1, value);
476f29dbc25Smrg    value = (unsigned long)(pMode->vblankstart - 1) |
477f29dbc25Smrg        (((unsigned long)(pMode->vblankend - 1)) << 16);
478f29dbc25Smrg    WRITE_REG32(DC_V_TIMING_2, value);
479f29dbc25Smrg    value = (unsigned long)(pMode->vsyncstart - 1) |
480f29dbc25Smrg        (((unsigned long)(pMode->vsyncend - 1)) << 16);
481f29dbc25Smrg    WRITE_REG32(DC_V_TIMING_3, value);
482f29dbc25Smrg    value = (unsigned long)(pMode->vsyncstart - 2) |
483f29dbc25Smrg        (((unsigned long)(pMode->vsyncend - 2)) << 16);
484f29dbc25Smrg    WRITE_REG32(DC_FP_V_TIMING, value);
485f29dbc25Smrg
486f29dbc25Smrg    WRITE_REG32(DC_OUTPUT_CFG, ocfg);
487f29dbc25Smrg    WRITE_REG32(DC_TIMING_CFG, tcfg);
488f29dbc25Smrg    gfx_delay_milliseconds(1);         /* delay after TIMING_CFG */
489f29dbc25Smrg    WRITE_REG32(DC_GENERAL_CFG, gcfg);
490f29dbc25Smrg
491f29dbc25Smrg    /* ENABLE FLAT PANEL CENTERING */
492f29dbc25Smrg    /* For 640x480 modes displayed with the 9211 within a 800x600 */
493f29dbc25Smrg    /* flat panel display, turn on flat panel centering.          */
494f29dbc25Smrg    if (PanelEnable) {
495f29dbc25Smrg        if (ModeWidth < PanelWidth) {
496f29dbc25Smrg            tcfg = READ_REG32(DC_TIMING_CFG);
497f29dbc25Smrg            tcfg = tcfg | DC_TCFG_FCEN;
498f29dbc25Smrg            WRITE_REG32(DC_TIMING_CFG, tcfg);
499f29dbc25Smrg            gfx_delay_milliseconds(1); /* delay after TIMING_CFG */
500f29dbc25Smrg        }
501f29dbc25Smrg    }
502f29dbc25Smrg
503f29dbc25Smrg    /* CONFIGURE DISPLAY OUTPUT FROM VIDEO PROCESSOR */
504f29dbc25Smrg    gfx_set_display_control(((pMode->flags & GFX_MODE_NEG_HSYNC) ? 1 : 0) |
505f29dbc25Smrg        ((pMode->flags & GFX_MODE_NEG_VSYNC) ? 2 : 0));
506f29dbc25Smrg
507f29dbc25Smrg    /* RESTORE VALUE OF DC_UNLOCK */
508f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, unlock);
509f29dbc25Smrg
510f29dbc25Smrg    /* ALSO WRITE GP_BLIT_STATUS FOR PITCH AND 8/18 BPP */
511f29dbc25Smrg    /* Remember, only Pyramid supports 4K line pitch    */
512f29dbc25Smrg    value = 0;
513f29dbc25Smrg    if (bpp > 8)
514f29dbc25Smrg        value |= BC_16BPP;
515f29dbc25Smrg    if ((gfx_cpu_version == GFX_CPU_PYRAMID) && (pitch > 2048))
516f29dbc25Smrg        value |= BC_FB_WIDTH_4096;
517f29dbc25Smrg    else if (pitch > 1024)
518f29dbc25Smrg        value |= BC_FB_WIDTH_2048;
519f29dbc25Smrg
520f29dbc25Smrg    WRITE_REG16(GP_BLIT_STATUS, (unsigned short)value);
521f29dbc25Smrg
522f29dbc25Smrg    return GFX_STATUS_OK;
523f29dbc25Smrg}                                      /* end gfx_set_specified_mode() */
524f29dbc25Smrg
525f29dbc25Smrg/*----------------------------------------------------------------------------
526f29dbc25Smrg * GFX_IS_DISPLAY_MODE_SUPPORTED
527f29dbc25Smrg *
528f29dbc25Smrg * This routine sets the specified display mode.
529f29dbc25Smrg *
530f29dbc25Smrg * Returns the index of the mode if successful and mode returned, -1 if the
531f29dbc25Smrg * mode could not be found.
532f29dbc25Smrg *----------------------------------------------------------------------------
533f29dbc25Smrg */
534f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
535f29dbc25Smrgint
536f29dbc25Smrggu1_is_display_mode_supported(int xres, int yres, int bpp, int hz)
537f29dbc25Smrg#else
538f29dbc25Smrgint
539f29dbc25Smrggfx_is_display_mode_supported(int xres, int yres, int bpp, int hz)
540f29dbc25Smrg#endif
541f29dbc25Smrg{
542f29dbc25Smrg    unsigned int mode = 0;
543f29dbc25Smrg    unsigned long hz_flag = 0, bpp_flag = 0;
544f29dbc25Smrg
545f29dbc25Smrg    /* SET FLAGS TO MATCH REFRESH RATE */
546f29dbc25Smrg    if (hz == 56)
547f29dbc25Smrg        hz_flag = GFX_MODE_56HZ;
548f29dbc25Smrg    else if (hz == 60)
549f29dbc25Smrg        hz_flag = GFX_MODE_60HZ;
550f29dbc25Smrg    else if (hz == 70)
551f29dbc25Smrg        hz_flag = GFX_MODE_70HZ;
552f29dbc25Smrg    else if (hz == 72)
553f29dbc25Smrg        hz_flag = GFX_MODE_72HZ;
554f29dbc25Smrg    else if (hz == 75)
555f29dbc25Smrg        hz_flag = GFX_MODE_75HZ;
556f29dbc25Smrg    else if (hz == 85)
557f29dbc25Smrg        hz_flag = GFX_MODE_85HZ;
558f29dbc25Smrg    else
559f29dbc25Smrg        return -1;
560f29dbc25Smrg
561f29dbc25Smrg    /* SET BPP FLAGS TO LIMIT MODE SELECTION */
562f29dbc25Smrg    if (bpp == 8)
563f29dbc25Smrg        bpp_flag = GFX_MODE_8BPP;
564f29dbc25Smrg    else if (bpp == 15)
565f29dbc25Smrg        bpp_flag = GFX_MODE_15BPP;
566f29dbc25Smrg    else if (bpp == 16)
567f29dbc25Smrg        bpp_flag = GFX_MODE_16BPP;
568f29dbc25Smrg    else
569f29dbc25Smrg        return -1;
570f29dbc25Smrg
571f29dbc25Smrg    /* ONLY PYRAMID SUPPORTS 4K PITCH */
572f29dbc25Smrg    if (gfx_cpu_version != GFX_CPU_PYRAMID && xres > 1024) {
573f29dbc25Smrg        if (bpp > 8)
574f29dbc25Smrg            return (-1);               /* return with mode not found */
575f29dbc25Smrg    }
576f29dbc25Smrg
577f29dbc25Smrg    /* LOOP THROUGH THE AVAILABLE MODES TO FIND A MATCH */
578f29dbc25Smrg    for (mode = 0; mode < NUM_GX_DISPLAY_MODES; mode++) {
579f29dbc25Smrg        if ((DisplayParams[mode].hactive == (unsigned short)xres) &&
580f29dbc25Smrg            (DisplayParams[mode].vactive == (unsigned short)yres) &&
581f29dbc25Smrg            (DisplayParams[mode].flags & hz_flag) &&
582f29dbc25Smrg            (DisplayParams[mode].flags & bpp_flag)) {
583f29dbc25Smrg
584f29dbc25Smrg            /* SET THE DISPLAY CONTROLLER FOR THE SELECTED MODE */
585f29dbc25Smrg            return (mode);
586f29dbc25Smrg        }
587f29dbc25Smrg    }
588f29dbc25Smrg    return (-1);
589f29dbc25Smrg}
590f29dbc25Smrg
591f29dbc25Smrg/*----------------------------------------------------------------------------
592f29dbc25Smrg * GFX_SET_DISPLAY_MODE
593f29dbc25Smrg *
594f29dbc25Smrg * This routine sets the specified display mode.
595f29dbc25Smrg *
596f29dbc25Smrg * Returns 1 if successful, 0 if mode could not be set.
597f29dbc25Smrg *----------------------------------------------------------------------------
598f29dbc25Smrg */
599f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
600f29dbc25Smrgint
601f29dbc25Smrggu1_set_display_mode(int xres, int yres, int bpp, int hz)
602f29dbc25Smrg#else
603f29dbc25Smrgint
604f29dbc25Smrggfx_set_display_mode(int xres, int yres, int bpp, int hz)
605f29dbc25Smrg#endif
606f29dbc25Smrg{
607f29dbc25Smrg    int mode;
608f29dbc25Smrg
609f29dbc25Smrg    /* DISABLE FLAT PANEL */
610f29dbc25Smrg    /* Flat Panel settings are enabled by the function gfx_set_fixed_timings
611f29dbc25Smrg     * and disabled by gfx_set_display_mode. */
612f29dbc25Smrg    PanelEnable = 0;
613f29dbc25Smrg
614f29dbc25Smrg    mode = gfx_is_display_mode_supported(xres, yres, bpp, hz);
615f29dbc25Smrg    if (mode >= 0) {
616f29dbc25Smrg        if (gu1_set_specified_mode(&DisplayParams[mode],
617f29dbc25Smrg                bpp) == GFX_STATUS_OK)
618f29dbc25Smrg            return (1);
619f29dbc25Smrg    }
620f29dbc25Smrg    return (0);
621f29dbc25Smrg}
622f29dbc25Smrg
623f29dbc25Smrg/*----------------------------------------------------------------------------
624f29dbc25Smrg * GFX_SET_DISPLAY_TIMINGS
625f29dbc25Smrg *
626f29dbc25Smrg * This routine sets the display controller mode using the specified timing
627f29dbc25Smrg * values (as opposed to using the tables internal to Durango).
628f29dbc25Smrg *
629f29dbc25Smrg * Returns GFX_STATUS_OK on success, GFX_STATUS_ERROR otherwise.
630f29dbc25Smrg *----------------------------------------------------------------------------
631f29dbc25Smrg */
632f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
633f29dbc25Smrgint
634f29dbc25Smrggu1_set_display_timings(unsigned short bpp, unsigned short flags,
635f29dbc25Smrg    unsigned short hactive, unsigned short hblankstart,
636f29dbc25Smrg    unsigned short hsyncstart, unsigned short hsyncend,
637f29dbc25Smrg    unsigned short hblankend, unsigned short htotal,
638f29dbc25Smrg    unsigned short vactive, unsigned short vblankstart,
639f29dbc25Smrg    unsigned short vsyncstart, unsigned short vsyncend,
640f29dbc25Smrg    unsigned short vblankend, unsigned short vtotal, unsigned long frequency)
641f29dbc25Smrg#else
642f29dbc25Smrgint
643f29dbc25Smrggfx_set_display_timings(unsigned short bpp, unsigned short flags,
644f29dbc25Smrg    unsigned short hactive, unsigned short hblankstart,
645f29dbc25Smrg    unsigned short hsyncstart, unsigned short hsyncend,
646f29dbc25Smrg    unsigned short hblankend, unsigned short htotal,
647f29dbc25Smrg    unsigned short vactive, unsigned short vblankstart,
648f29dbc25Smrg    unsigned short vsyncstart, unsigned short vsyncend,
649f29dbc25Smrg    unsigned short vblankend, unsigned short vtotal, unsigned long frequency)
650f29dbc25Smrg#endif
651f29dbc25Smrg{
652f29dbc25Smrg    /* SET MODE STRUCTURE WITH SPECIFIED VALUES */
653f29dbc25Smrg
654f29dbc25Smrg    gfx_display_mode.flags = 0;
655f29dbc25Smrg    if (flags & 1)
656f29dbc25Smrg        gfx_display_mode.flags |= GFX_MODE_NEG_HSYNC;
657f29dbc25Smrg    if (flags & 2)
658f29dbc25Smrg        gfx_display_mode.flags |= GFX_MODE_NEG_VSYNC;
659f29dbc25Smrg    if (flags & 0x1000)
660f29dbc25Smrg        gfx_display_mode.flags |= GFX_MODE_LOCK_TIMING;
661f29dbc25Smrg    gfx_display_mode.hactive = hactive;
662f29dbc25Smrg    gfx_display_mode.hblankstart = hblankstart;
663f29dbc25Smrg    gfx_display_mode.hsyncstart = hsyncstart;
664f29dbc25Smrg    gfx_display_mode.hsyncend = hsyncend;
665f29dbc25Smrg    gfx_display_mode.hblankend = hblankend;
666f29dbc25Smrg    gfx_display_mode.htotal = htotal;
667f29dbc25Smrg    gfx_display_mode.vactive = vactive;
668f29dbc25Smrg    gfx_display_mode.vblankstart = vblankstart;
669f29dbc25Smrg    gfx_display_mode.vsyncstart = vsyncstart;
670f29dbc25Smrg    gfx_display_mode.vsyncend = vsyncend;
671f29dbc25Smrg    gfx_display_mode.vblankend = vblankend;
672f29dbc25Smrg    gfx_display_mode.vtotal = vtotal;
673f29dbc25Smrg    gfx_display_mode.frequency = frequency;
674f29dbc25Smrg
675f29dbc25Smrg    /* CALL ROUTINE TO SET MODE */
676f29dbc25Smrg    return (gu1_set_specified_mode(&gfx_display_mode, bpp));
677f29dbc25Smrg}
678f29dbc25Smrg
679f29dbc25Smrg/*----------------------------------------------------------------------------
680f29dbc25Smrg * GFX_SET_VTOTAL
681f29dbc25Smrg *
682f29dbc25Smrg * This routine sets the display controller vertical total to
683f29dbc25Smrg * "vtotal". As a side effect it also sets vertical blank end.
684f29dbc25Smrg * It should be used when only this value needs to be changed,
685f29dbc25Smrg * due to speed considerations.
686f29dbc25Smrg *
687f29dbc25Smrg * Note: it is the caller's responsibility to make sure that
688f29dbc25Smrg * a legal vtotal is used, i.e. that "vtotal" is greater than or
689f29dbc25Smrg * equal to vsync end.
690f29dbc25Smrg *
691f29dbc25Smrg * Always returns 0.
692f29dbc25Smrg *----------------------------------------------------------------------------
693f29dbc25Smrg */
694f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
695f29dbc25Smrgint
696f29dbc25Smrggu1_set_vtotal(unsigned short vtotal)
697f29dbc25Smrg#else
698f29dbc25Smrgint
699f29dbc25Smrggfx_set_vtotal(unsigned short vtotal)
700f29dbc25Smrg#endif
701f29dbc25Smrg{
702f29dbc25Smrg    unsigned long unlock, tcfg, timing1, timing2;
703f29dbc25Smrg
704f29dbc25Smrg    /* UNLOCK THE DISPLAY CONTROLLER REGISTERS */
705f29dbc25Smrg    unlock = READ_REG32(DC_UNLOCK);
706f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
707f29dbc25Smrg
708f29dbc25Smrg    /* READ THE CURRENT GX VALUES */
709f29dbc25Smrg    tcfg = READ_REG32(DC_TIMING_CFG);
710f29dbc25Smrg    timing1 = READ_REG32(DC_V_TIMING_1);
711f29dbc25Smrg    timing2 = READ_REG32(DC_V_TIMING_2);
712f29dbc25Smrg
713f29dbc25Smrg    /* DISABLE THE TIMING GENERATOR */
714f29dbc25Smrg    WRITE_REG32(DC_TIMING_CFG, tcfg & ~(unsigned long)DC_TCFG_TGEN);
715f29dbc25Smrg
716f29dbc25Smrg    /* WRITE NEW TIMING VALUES */
717f29dbc25Smrg    WRITE_REG32(DC_V_TIMING_1,
718f29dbc25Smrg        (timing1 & 0xffff) | (unsigned long)(vtotal - 1) << 16);
719f29dbc25Smrg    WRITE_REG32(DC_V_TIMING_2,
720f29dbc25Smrg        (timing2 & 0xffff) | (unsigned long)(vtotal - 1) << 16);
721f29dbc25Smrg
722f29dbc25Smrg    /* RESTORE GX VALUES */
723f29dbc25Smrg    WRITE_REG32(DC_TIMING_CFG, tcfg);
724f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, unlock);
725f29dbc25Smrg
726f29dbc25Smrg    return (0);
727f29dbc25Smrg}
728f29dbc25Smrg
729f29dbc25Smrg/*---------------------------------------------------------------------------
730f29dbc25Smrg * gfx_set_display_pitch
731f29dbc25Smrg *
732f29dbc25Smrg * This routine sets the pitch of the frame buffer to the specified value.
733f29dbc25Smrg *---------------------------------------------------------------------------
734f29dbc25Smrg */
735f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
736f29dbc25Smrgvoid
737f29dbc25Smrggu1_set_display_pitch(unsigned short pitch)
738f29dbc25Smrg#else
739f29dbc25Smrgvoid
740f29dbc25Smrggfx_set_display_pitch(unsigned short pitch)
741f29dbc25Smrg#endif
742f29dbc25Smrg{
743f29dbc25Smrg    unsigned long value = 0;
744f29dbc25Smrg    unsigned long lock = READ_REG32(DC_UNLOCK);
745f29dbc25Smrg
746f29dbc25Smrg    value = READ_REG32(DC_LINE_DELTA) & 0xFFFFF000;
747f29dbc25Smrg    value |= (pitch >> 2);
748f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
749f29dbc25Smrg    WRITE_REG32(DC_LINE_DELTA, value);
750f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, lock);
751f29dbc25Smrg
752f29dbc25Smrg    /* ALSO UPDATE PITCH IN GRAPHICS ENGINE */
753f29dbc25Smrg    /* Pyramid alone supports 4K line pitch */
754f29dbc25Smrg    value = (unsigned long)READ_REG16(GP_BLIT_STATUS);
755f29dbc25Smrg    value &= ~(BC_FB_WIDTH_2048 | BC_FB_WIDTH_4096);
756f29dbc25Smrg
757f29dbc25Smrg    if ((gfx_cpu_version == GFX_CPU_PYRAMID) && (pitch > 2048))
758f29dbc25Smrg        value |= BC_FB_WIDTH_4096;
759f29dbc25Smrg
760f29dbc25Smrg    else if (pitch > 1024)
761f29dbc25Smrg        value |= BC_FB_WIDTH_2048;
762f29dbc25Smrg
763f29dbc25Smrg    WRITE_REG16(GP_BLIT_STATUS, (unsigned short)value);
764f29dbc25Smrg    return;
765f29dbc25Smrg}
766f29dbc25Smrg
767f29dbc25Smrg/*---------------------------------------------------------------------------
768f29dbc25Smrg * gfx_set_display_offset
769f29dbc25Smrg *
770f29dbc25Smrg * This routine sets the start address of the frame buffer.  It is
771f29dbc25Smrg * typically used to pan across a virtual desktop (frame buffer larger than
772f29dbc25Smrg * the displayed screen) or to flip the display between multiple buffers.
773f29dbc25Smrg *---------------------------------------------------------------------------
774f29dbc25Smrg */
775f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
776f29dbc25Smrgvoid
777f29dbc25Smrggu1_set_display_offset(unsigned long offset)
778f29dbc25Smrg#else
779f29dbc25Smrgvoid
780f29dbc25Smrggfx_set_display_offset(unsigned long offset)
781f29dbc25Smrg#endif
782f29dbc25Smrg{
783f29dbc25Smrg    /* UPDATE FRAME BUFFER OFFSET */
784f29dbc25Smrg
785f29dbc25Smrg    unsigned long lock;
786f29dbc25Smrg
787f29dbc25Smrg    lock = READ_REG32(DC_UNLOCK);
788f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
789f29dbc25Smrg
790f29dbc25Smrg    /* START ADDRESS EFFECTS DISPLAY COMPRESSION */
791f29dbc25Smrg    /* Disable compression for non-zero start addresss values.            */
792f29dbc25Smrg    /* Enable compression if offset is zero and comression is intended to */
793f29dbc25Smrg    /* be enabled from a previous call to "gfx_set_compression_enable".   */
794f29dbc25Smrg    /* Compression should be disabled BEFORE the offset is changed        */
795f29dbc25Smrg    /* and enabled AFTER the offset is changed.                           */
796f29dbc25Smrg    if (offset == 0) {
797f29dbc25Smrg        WRITE_REG32(DC_FB_ST_OFFSET, offset);
798f29dbc25Smrg        if (gfx_compression_enabled) {
799f29dbc25Smrg            /* WAIT FOR THE OFFSET TO BE LATCHED */
800f29dbc25Smrg            gfx_wait_vertical_blank();
801f29dbc25Smrg            gu1_enable_compression();
802f29dbc25Smrg        }
803f29dbc25Smrg    } else {
804f29dbc25Smrg        /* ONLY DISABLE COMPRESSION ONCE */
805f29dbc25Smrg        if (gfx_compression_active)
806f29dbc25Smrg            gu1_disable_compression();
807f29dbc25Smrg
808f29dbc25Smrg        WRITE_REG32(DC_FB_ST_OFFSET, offset);
809f29dbc25Smrg    }
810f29dbc25Smrg
811f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, lock);
812f29dbc25Smrg}
813f29dbc25Smrg
814f29dbc25Smrg/*---------------------------------------------------------------------------
815f29dbc25Smrg * gfx_set_display_palette_entry
816f29dbc25Smrg *
817f29dbc25Smrg * This routine sets an palette entry in the display controller.
818f29dbc25Smrg * A 32-bit X:R:G:B value.
819f29dbc25Smrg *---------------------------------------------------------------------------
820f29dbc25Smrg */
821f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
822f29dbc25Smrgint
823f29dbc25Smrggu1_set_display_palette_entry(unsigned long index, unsigned long palette)
824f29dbc25Smrg#else
825f29dbc25Smrgint
826f29dbc25Smrggfx_set_display_palette_entry(unsigned long index, unsigned long palette)
827f29dbc25Smrg#endif
828f29dbc25Smrg{
829f29dbc25Smrg    unsigned long data;
830f29dbc25Smrg
831f29dbc25Smrg    if (index > 0xFF)
832f29dbc25Smrg        return GFX_STATUS_BAD_PARAMETER;
833f29dbc25Smrg
834f29dbc25Smrg    WRITE_REG32(DC_PAL_ADDRESS, index);
835f29dbc25Smrg    data = ((palette >> 2) & 0x0003F) |
836f29dbc25Smrg        ((palette >> 4) & 0x00FC0) | ((palette >> 6) & 0x3F000);
837f29dbc25Smrg    WRITE_REG32(DC_PAL_DATA, data);
838f29dbc25Smrg
839f29dbc25Smrg    return (0);
840f29dbc25Smrg}
841f29dbc25Smrg
842f29dbc25Smrg/*---------------------------------------------------------------------------
843f29dbc25Smrg * gfx_set_display_palette
844f29dbc25Smrg *
845f29dbc25Smrg * This routine sets the entire palette in the display controller.
846f29dbc25Smrg * A pointer is provided to a 256 entry table of 32-bit X:R:G:B values.
847f29dbc25Smrg *
848f29dbc25Smrg * Restriction:
849f29dbc25Smrg * Due to SC1200 Issue #748 (in Notes DB) this function should be called only
850f29dbc25Smrg * when DCLK is active, i.e PLL is already powered up and genlock is not
851f29dbc25Smrg * active.
852f29dbc25Smrg *---------------------------------------------------------------------------
853f29dbc25Smrg */
854f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
855f29dbc25Smrgint
856f29dbc25Smrggu1_set_display_palette(unsigned long *palette)
857f29dbc25Smrg#else
858f29dbc25Smrgint
859f29dbc25Smrggfx_set_display_palette(unsigned long *palette)
860f29dbc25Smrg#endif
861f29dbc25Smrg{
862f29dbc25Smrg    unsigned long data, i;
863f29dbc25Smrg
864f29dbc25Smrg    WRITE_REG32(DC_PAL_ADDRESS, 0);
865f29dbc25Smrg    if (palette) {
866f29dbc25Smrg        for (i = 0; i < 256; i++) {
867f29dbc25Smrg            /* CONVERT 24 BPP COLOR DATA TO 18 BPP COLOR DATA */
868f29dbc25Smrg            data = ((palette[i] >> 2) & 0x0003F) |
869f29dbc25Smrg                ((palette[i] >> 4) & 0x00FC0) | ((palette[i] >> 6) & 0x3F000);
870f29dbc25Smrg            WRITE_REG32(DC_PAL_DATA, data);
871f29dbc25Smrg        }
872f29dbc25Smrg    }
873f29dbc25Smrg    return (0);
874f29dbc25Smrg}
875f29dbc25Smrg
876f29dbc25Smrg/*---------------------------------------------------------------------------
877f29dbc25Smrg * gfx_set_cursor_enable
878f29dbc25Smrg *
879f29dbc25Smrg * This routine enables or disables the hardware cursor.
880f29dbc25Smrg *
881f29dbc25Smrg * WARNING: The cusrsor start offset must be set by setting the cursor
882f29dbc25Smrg * position before calling this routine to assure that memory reads do not
883f29dbc25Smrg * go past the end of graphics memory (this can hang GXm).
884f29dbc25Smrg *---------------------------------------------------------------------------
885f29dbc25Smrg */
886f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
887f29dbc25Smrgvoid
888f29dbc25Smrggu1_set_cursor_enable(int enable)
889f29dbc25Smrg#else
890f29dbc25Smrgvoid
891f29dbc25Smrggfx_set_cursor_enable(int enable)
892f29dbc25Smrg#endif
893f29dbc25Smrg{
894f29dbc25Smrg    unsigned long unlock, gcfg;
895f29dbc25Smrg
896f29dbc25Smrg    /* SET OR CLEAR CURSOR ENABLE BIT */
897f29dbc25Smrg    unlock = READ_REG32(DC_UNLOCK);
898f29dbc25Smrg    gcfg = READ_REG32(DC_GENERAL_CFG);
899f29dbc25Smrg    if (enable)
900f29dbc25Smrg        gcfg |= DC_GCFG_CURE;
901f29dbc25Smrg    else
902f29dbc25Smrg        gcfg &= ~(DC_GCFG_CURE);
903f29dbc25Smrg
904f29dbc25Smrg    /* WRITE NEW REGISTER VALUE */
905f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
906f29dbc25Smrg    WRITE_REG32(DC_GENERAL_CFG, gcfg);
907f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, unlock);
908f29dbc25Smrg}
909f29dbc25Smrg
910f29dbc25Smrg/*---------------------------------------------------------------------------
911f29dbc25Smrg * gfx_set_cursor_colors
912f29dbc25Smrg *
913f29dbc25Smrg * This routine sets the colors of the hardware cursor.
914f29dbc25Smrg *
915f29dbc25Smrg * Restriction:
916f29dbc25Smrg * Due to SC1200 Issue #748 (in Notes DB) this function should be called only
917f29dbc25Smrg * when DCLK is active, i.e PLL is already powered up.
918f29dbc25Smrg *---------------------------------------------------------------------------
919f29dbc25Smrg */
920f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
921f29dbc25Smrgvoid
922f29dbc25Smrggu1_set_cursor_colors(unsigned long bkcolor, unsigned long fgcolor)
923f29dbc25Smrg#else
924f29dbc25Smrgvoid
925f29dbc25Smrggfx_set_cursor_colors(unsigned long bkcolor, unsigned long fgcolor)
926f29dbc25Smrg#endif
927f29dbc25Smrg{
928f29dbc25Smrg    unsigned long value;
929f29dbc25Smrg
930f29dbc25Smrg    /* If genlock is enabled DCLK might be disabled in vertical blank. */
931f29dbc25Smrg    /* Due to SC1200 Issue #748 in Notes DB this would fail the cursor color settings */
932f29dbc25Smrg    /* So Wait for vertical blank to end */
933f29dbc25Smrg
934f29dbc25Smrg#if GFX_VIDEO_SC1200
935f29dbc25Smrg    if (gfx_test_timing_active())
936f29dbc25Smrg        while ((gfx_get_vline()) > gfx_get_vactive()) ;
937f29dbc25Smrg#endif
938f29dbc25Smrg    /* SET CURSOR COLORS */
939f29dbc25Smrg    WRITE_REG32(DC_PAL_ADDRESS, 0x100);
940f29dbc25Smrg    value = ((bkcolor & 0x000000FC) >> 2) |
941f29dbc25Smrg        ((bkcolor & 0x0000FC00) >> (2 + 8 - 6)) |
942f29dbc25Smrg        ((bkcolor & 0x00FC0000) >> (2 + 16 - 12));
943f29dbc25Smrg    WRITE_REG32(DC_PAL_DATA, value);
944f29dbc25Smrg    value = ((fgcolor & 0x000000FC) >> 2) |
945f29dbc25Smrg        ((fgcolor & 0x0000FC00) >> (2 + 8 - 6)) |
946f29dbc25Smrg        ((fgcolor & 0x00FC0000) >> (2 + 16 - 12));
947f29dbc25Smrg    WRITE_REG32(DC_PAL_DATA, value);
948f29dbc25Smrg}
949f29dbc25Smrg
950f29dbc25Smrg/*---------------------------------------------------------------------------
951f29dbc25Smrg * gfx_set_cursor_position
952f29dbc25Smrg *
953f29dbc25Smrg * This routine sets the position of the hardware cusror.  The starting
954f29dbc25Smrg * offset of the cursor buffer must be specified so that the routine can
955f29dbc25Smrg * properly clip scanlines if the cursor is off the top of the screen.
956f29dbc25Smrg *---------------------------------------------------------------------------
957f29dbc25Smrg */
958f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
959f29dbc25Smrgvoid
960f29dbc25Smrggu1_set_cursor_position(unsigned long memoffset,
961f29dbc25Smrg    unsigned short xpos, unsigned short ypos,
962f29dbc25Smrg    unsigned short xhotspot, unsigned short yhotspot)
963f29dbc25Smrg#else
964f29dbc25Smrgvoid
965f29dbc25Smrggfx_set_cursor_position(unsigned long memoffset,
966f29dbc25Smrg    unsigned short xpos, unsigned short ypos,
967f29dbc25Smrg    unsigned short xhotspot, unsigned short yhotspot)
968f29dbc25Smrg#endif
969f29dbc25Smrg{
970f29dbc25Smrg    unsigned long unlock;
971f29dbc25Smrg
972f29dbc25Smrg    short x, y;
973f29dbc25Smrg    short xoffset = 0;
974f29dbc25Smrg    short yoffset = 0;
975f29dbc25Smrg
976f29dbc25Smrg    /* SUPPORT CURSOR IN EMULATED VGA MODES */
977f29dbc25Smrg    /* Timings are for twice the resolution */
978f29dbc25Smrg    if (gfx_pixel_double)
979f29dbc25Smrg        xpos <<= 1;
980f29dbc25Smrg
981f29dbc25Smrg    if (gfx_line_double)
982f29dbc25Smrg        ypos <<= 1;
983f29dbc25Smrg
984f29dbc25Smrg    x = (short)xpos - (short)xhotspot;
985f29dbc25Smrg    y = (short)ypos - (short)yhotspot;
986f29dbc25Smrg    if (x < -31)
987f29dbc25Smrg        return;
988f29dbc25Smrg
989f29dbc25Smrg    if (y < -31)
990f29dbc25Smrg        return;
991f29dbc25Smrg
992f29dbc25Smrg    if (x < 0) {
993f29dbc25Smrg        xoffset = -x;
994f29dbc25Smrg        x = 0;
995f29dbc25Smrg    }
996f29dbc25Smrg
997f29dbc25Smrg    if (y < 0) {
998f29dbc25Smrg        yoffset = -y;
999f29dbc25Smrg        y = 0;
1000f29dbc25Smrg    }
1001f29dbc25Smrg
1002f29dbc25Smrg    memoffset += (unsigned long)yoffset << 3;
1003f29dbc25Smrg
1004f29dbc25Smrg    if (PanelEnable) {
1005f29dbc25Smrg        if ((ModeWidth > PanelWidth) || (ModeHeight > PanelHeight)) {
1006f29dbc25Smrg            gfx_enable_panning(xpos, ypos);
1007f29dbc25Smrg            x = x - (short)panelLeft;
1008f29dbc25Smrg            y = y - (short)panelTop;
1009f29dbc25Smrg        }
1010f29dbc25Smrg    }
1011f29dbc25Smrg
1012f29dbc25Smrg    /* SET CURSOR POSITION */
1013f29dbc25Smrg    unlock = READ_REG32(DC_UNLOCK);
1014f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
1015f29dbc25Smrg    WRITE_REG32(DC_CURS_ST_OFFSET, memoffset);
1016f29dbc25Smrg    WRITE_REG32(DC_CURSOR_X, (unsigned long)x |
1017f29dbc25Smrg        (((unsigned long)xoffset) << 11));
1018f29dbc25Smrg    WRITE_REG32(DC_CURSOR_Y, (unsigned long)y |
1019f29dbc25Smrg        (((unsigned long)yoffset) << 11));
1020f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, unlock);
1021f29dbc25Smrg}
1022f29dbc25Smrg
1023f29dbc25Smrg/*---------------------------------------------------------------------------
1024f29dbc25Smrg * gfx_set_cursor_shape32
1025f29dbc25Smrg *
1026f29dbc25Smrg * This routine loads 32x32 cursor data into the specified location in
1027f29dbc25Smrg * graphics memory.
1028f29dbc25Smrg *---------------------------------------------------------------------------
1029f29dbc25Smrg */
1030f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1031f29dbc25Smrgvoid
1032f29dbc25Smrggu1_set_cursor_shape32(unsigned long memoffset,
1033f29dbc25Smrg    unsigned long *andmask, unsigned long *xormask)
1034f29dbc25Smrg#else
1035f29dbc25Smrgvoid
1036f29dbc25Smrggfx_set_cursor_shape32(unsigned long memoffset,
1037f29dbc25Smrg    unsigned long *andmask, unsigned long *xormask)
1038f29dbc25Smrg#endif
1039f29dbc25Smrg{
1040f29dbc25Smrg    int i;
1041f29dbc25Smrg    unsigned long value;
1042f29dbc25Smrg
1043f29dbc25Smrg    for (i = 0; i < 32; i++) {
1044f29dbc25Smrg        /* CONVERT TO 16 BITS AND MASK, 16 BITS XOR MASK PER DWORD */
1045f29dbc25Smrg        value = (andmask[i] & 0xFFFF0000) | (xormask[i] >> 16);
1046f29dbc25Smrg        WRITE_FB32(memoffset, value);
1047f29dbc25Smrg        memoffset += 4;
1048f29dbc25Smrg        value = (andmask[i] << 16) | (xormask[i] & 0x0000FFFF);
1049f29dbc25Smrg        WRITE_FB32(memoffset, value);
1050f29dbc25Smrg        memoffset += 4;
1051f29dbc25Smrg    }
1052f29dbc25Smrg}
1053f29dbc25Smrg
1054f29dbc25Smrg/*---------------------------------------------------------------------------
1055f29dbc25Smrg * gu1_enable_compression
1056f29dbc25Smrg *
1057f29dbc25Smrg * This is a private routine to this module (not exposed in the Durango API).
1058f29dbc25Smrg * It enables display compression.
1059f29dbc25Smrg *---------------------------------------------------------------------------
1060f29dbc25Smrg */
1061f29dbc25Smrgvoid
1062f29dbc25Smrggu1_enable_compression(void)
1063f29dbc25Smrg{
1064f29dbc25Smrg    int i;
1065f29dbc25Smrg    unsigned long unlock, gcfg, offset;
1066f29dbc25Smrg
1067f29dbc25Smrg    /* DO NOT ENABLE IF START ADDRESS IS NOT ZERO */
1068f29dbc25Smrg    offset = READ_REG32(DC_FB_ST_OFFSET) & 0x003FFFFF;
1069f29dbc25Smrg    if (offset != 0)
1070f29dbc25Smrg        return;
1071f29dbc25Smrg
1072f29dbc25Smrg    /* DO NOT ENABLE IF WE ARE WITHIN AN EMULATED VGA MODE */
1073f29dbc25Smrg    if (gfx_line_double || gfx_pixel_double)
1074f29dbc25Smrg        return;
1075f29dbc25Smrg
1076f29dbc25Smrg    /* SET GLOBAL INDICATOR */
1077f29dbc25Smrg    gfx_compression_active = 1;
1078f29dbc25Smrg
1079f29dbc25Smrg    /* CLEAR DIRTY/VALID BITS IN MEMORY CONTROLLER */
1080f29dbc25Smrg    /* Software is required to do this before enabling compression. */
1081f29dbc25Smrg    /* Don't want controller to think that old lines are still valid. */
1082f29dbc25Smrg    for (i = 0; i < 1024; i++) {
1083f29dbc25Smrg        WRITE_REG32(MC_DR_ADD, i);
1084f29dbc25Smrg        WRITE_REG32(MC_DR_ACC, 0);
1085f29dbc25Smrg    }
1086f29dbc25Smrg
1087f29dbc25Smrg    /* TURN ON COMPRESSION CONTROL BITS */
1088f29dbc25Smrg    unlock = READ_REG32(DC_UNLOCK);
1089f29dbc25Smrg    gcfg = READ_REG32(DC_GENERAL_CFG);
1090f29dbc25Smrg    gcfg |= DC_GCFG_CMPE | DC_GCFG_DECE;
1091f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
1092f29dbc25Smrg    WRITE_REG32(DC_GENERAL_CFG, gcfg);
1093f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, unlock);
1094f29dbc25Smrg}
1095f29dbc25Smrg
1096f29dbc25Smrg/*---------------------------------------------------------------------------
1097f29dbc25Smrg * gu1_disable_compression
1098f29dbc25Smrg *
1099f29dbc25Smrg * This is a private routine to this module (not exposed in the Durango API).
1100f29dbc25Smrg * It disables display compression.
1101f29dbc25Smrg *---------------------------------------------------------------------------
1102f29dbc25Smrg */
1103f29dbc25Smrgvoid
1104f29dbc25Smrggu1_disable_compression(void)
1105f29dbc25Smrg{
1106f29dbc25Smrg    unsigned long unlock, gcfg;
1107f29dbc25Smrg
1108f29dbc25Smrg    /* SET GLOBAL INDICATOR */
1109f29dbc25Smrg    gfx_compression_active = 0;
1110f29dbc25Smrg
1111f29dbc25Smrg    /* TURN OFF COMPRESSION CONTROL BITS */
1112f29dbc25Smrg    unlock = READ_REG32(DC_UNLOCK);
1113f29dbc25Smrg    gcfg = READ_REG32(DC_GENERAL_CFG);
1114f29dbc25Smrg    gcfg &= ~(DC_GCFG_CMPE | DC_GCFG_DECE);
1115f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
1116f29dbc25Smrg    WRITE_REG32(DC_GENERAL_CFG, gcfg);
1117f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, unlock);
1118f29dbc25Smrg}
1119f29dbc25Smrg
1120f29dbc25Smrg/*---------------------------------------------------------------------------
1121f29dbc25Smrg * gfx_set_compression_enable
1122f29dbc25Smrg *
1123f29dbc25Smrg * This routine enables or disables display compression.
1124f29dbc25Smrg *---------------------------------------------------------------------------
1125f29dbc25Smrg */
1126f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1127f29dbc25Smrgint
1128f29dbc25Smrggu1_set_compression_enable(int enable)
1129f29dbc25Smrg#else
1130f29dbc25Smrgint
1131f29dbc25Smrggfx_set_compression_enable(int enable)
1132f29dbc25Smrg#endif
1133f29dbc25Smrg{
1134f29dbc25Smrg    /* SET GLOBAL VARIABLE FOR INTENDED STATE */
1135f29dbc25Smrg    /* Compression can only be enabled for non-zero start address values. */
1136f29dbc25Smrg    /* Keep state to enable compression on start address changes. */
1137f29dbc25Smrg    gfx_compression_enabled = enable;
1138f29dbc25Smrg    if (enable)
1139f29dbc25Smrg        gu1_enable_compression();
1140f29dbc25Smrg    else
1141f29dbc25Smrg        gu1_disable_compression();
1142f29dbc25Smrg
1143f29dbc25Smrg    return (0);
1144f29dbc25Smrg}
1145f29dbc25Smrg
1146f29dbc25Smrg/*---------------------------------------------------------------------------
1147f29dbc25Smrg * gfx_set_compression_offset
1148f29dbc25Smrg *
1149f29dbc25Smrg * This routine sets the base offset for the compression buffer.
1150f29dbc25Smrg *---------------------------------------------------------------------------
1151f29dbc25Smrg */
1152f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1153f29dbc25Smrgint
1154f29dbc25Smrggu1_set_compression_offset(unsigned long offset)
1155f29dbc25Smrg#else
1156f29dbc25Smrgint
1157f29dbc25Smrggfx_set_compression_offset(unsigned long offset)
1158f29dbc25Smrg#endif
1159f29dbc25Smrg{
1160f29dbc25Smrg    unsigned long lock;
1161f29dbc25Smrg
1162f29dbc25Smrg    /* MUST BE 16-BYTE ALIGNED FOR GXLV */
1163f29dbc25Smrg    if (offset & 0x0F)
1164f29dbc25Smrg        return (1);
1165f29dbc25Smrg
1166f29dbc25Smrg    /* SET REGISTER VALUE */
1167f29dbc25Smrg    lock = READ_REG32(DC_UNLOCK);
1168f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
1169f29dbc25Smrg    WRITE_REG32(DC_CB_ST_OFFSET, offset);
1170f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, lock);
1171f29dbc25Smrg    return (0);
1172f29dbc25Smrg}
1173f29dbc25Smrg
1174f29dbc25Smrg/*---------------------------------------------------------------------------
1175f29dbc25Smrg * gfx_set_compression_pitch
1176f29dbc25Smrg *
1177f29dbc25Smrg * This routine sets the pitch, in bytes, of the compression buffer.
1178f29dbc25Smrg *---------------------------------------------------------------------------
1179f29dbc25Smrg */
1180f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1181f29dbc25Smrgint
1182f29dbc25Smrggu1_set_compression_pitch(unsigned short pitch)
1183f29dbc25Smrg#else
1184f29dbc25Smrgint
1185f29dbc25Smrggfx_set_compression_pitch(unsigned short pitch)
1186f29dbc25Smrg#endif
1187f29dbc25Smrg{
1188f29dbc25Smrg    unsigned long lock, line_delta;
1189f29dbc25Smrg
1190f29dbc25Smrg    /* SET REGISTER VALUE */
1191f29dbc25Smrg    lock = READ_REG32(DC_UNLOCK);
1192f29dbc25Smrg    line_delta = READ_REG32(DC_LINE_DELTA) & 0xFF800FFF;
1193f29dbc25Smrg    line_delta |= ((unsigned long)pitch << 10l) & 0x007FF000;
1194f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
1195f29dbc25Smrg    WRITE_REG32(DC_LINE_DELTA, line_delta);
1196f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, lock);
1197f29dbc25Smrg    return (0);
1198f29dbc25Smrg}
1199f29dbc25Smrg
1200f29dbc25Smrg/*---------------------------------------------------------------------------
1201f29dbc25Smrg * gfx_set_compression_size
1202f29dbc25Smrg *
1203f29dbc25Smrg * This routine sets the line size of the compression buffer, which is the
1204f29dbc25Smrg * maximum number of bytes allowed to store a compressed line.
1205f29dbc25Smrg *---------------------------------------------------------------------------
1206f29dbc25Smrg */
1207f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1208f29dbc25Smrgint
1209f29dbc25Smrggu1_set_compression_size(unsigned short size)
1210f29dbc25Smrg#else
1211f29dbc25Smrgint
1212f29dbc25Smrggfx_set_compression_size(unsigned short size)
1213f29dbc25Smrg#endif
1214f29dbc25Smrg{
1215f29dbc25Smrg    unsigned long lock, buf_size;
1216f29dbc25Smrg
1217f29dbc25Smrg    /* SUBTRACT 16 FROM SIZE                          */
1218f29dbc25Smrg    /* The display controller will actually write     */
1219f29dbc25Smrg    /* 2 extra QWords.  So, if we assume that "size"  */
1220f29dbc25Smrg    /* refers to the allocated size, we must subtract */
1221f29dbc25Smrg    /* 16 bytes.                                      */
1222f29dbc25Smrg    size -= 16;
1223f29dbc25Smrg
1224f29dbc25Smrg    /* SET REGISTER VALUE */
1225f29dbc25Smrg    lock = READ_REG32(DC_UNLOCK);
1226f29dbc25Smrg    buf_size = READ_REG32(DC_BUF_SIZE) & 0xFFFF01FF;
1227f29dbc25Smrg    buf_size |= (((size >> 2) + 1) & 0x7F) << 9;
1228f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
1229f29dbc25Smrg    WRITE_REG32(DC_BUF_SIZE, buf_size);
1230f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, lock);
1231f29dbc25Smrg    return (0);
1232f29dbc25Smrg}
1233f29dbc25Smrg
1234f29dbc25Smrg/*---------------------------------------------------------------------------
1235f29dbc25Smrg * gfx_set_display_video_enable (PRIVATE ROUTINE - NOT PART OF API)
1236f29dbc25Smrg *
1237f29dbc25Smrg * This routine enables/disables video on GX.
1238f29dbc25Smrg *---------------------------------------------------------------------------
1239f29dbc25Smrg */
1240f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1241f29dbc25Smrgvoid
1242f29dbc25Smrggu1_set_display_video_enable(int enable)
1243f29dbc25Smrg#else
1244f29dbc25Smrgvoid
1245f29dbc25Smrggfx_set_display_video_enable(int enable)
1246f29dbc25Smrg#endif
1247f29dbc25Smrg{
1248f29dbc25Smrg    unsigned long lock, gcfg, buf_size;
1249f29dbc25Smrg
1250f29dbc25Smrg    lock = READ_REG32(DC_UNLOCK);
1251f29dbc25Smrg    gcfg = READ_REG32(DC_GENERAL_CFG);
1252f29dbc25Smrg    buf_size = READ_REG32(DC_BUF_SIZE);
1253f29dbc25Smrg
1254f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
1255f29dbc25Smrg
1256f29dbc25Smrg    vid_enabled = enable;
1257f29dbc25Smrg
1258f29dbc25Smrg    /* SET THE BUFFER SIZE TO A NON-ZERO VALUE ONLY WHEN */
1259f29dbc25Smrg    /* ENABLING VIDEO                                    */
1260f29dbc25Smrg    if (enable) {
1261f29dbc25Smrg        gcfg |= (DC_GCFG_VIDE | DC_GCFG_VRDY);
1262f29dbc25Smrg        WRITE_REG32(DC_GENERAL_CFG, gcfg);
1263f29dbc25Smrg
1264f29dbc25Smrg        WRITE_REG32(DC_BUF_SIZE, (buf_size & 0x0000FFFFl) | vid_buf_size);
1265f29dbc25Smrg    }
1266f29dbc25Smrg    /* CLEAR THE VIDEO BUFFER SIZE WHEN DISABLING VIDEO  */
1267f29dbc25Smrg    else {
1268f29dbc25Smrg        gcfg &= ~(DC_GCFG_VIDE);
1269f29dbc25Smrg        WRITE_REG32(DC_GENERAL_CFG, gcfg);
1270f29dbc25Smrg
1271f29dbc25Smrg        vid_buf_size = buf_size & 0xFFFF0000l;
1272f29dbc25Smrg        WRITE_REG32(DC_BUF_SIZE, buf_size & 0x0000FFFFl);
1273f29dbc25Smrg    }
1274f29dbc25Smrg
1275f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, lock);
1276f29dbc25Smrg    return;
1277f29dbc25Smrg}
1278f29dbc25Smrg
1279f29dbc25Smrg/*---------------------------------------------------------------------------
1280f29dbc25Smrg * gfx_set_display_video_size (PRIVATE ROUTINE - NOT PART OF API)
1281f29dbc25Smrg *
1282f29dbc25Smrg * This routine is called by "gfx_set_video_size".  It abstracts the
1283f29dbc25Smrg * version of the display controller from the video overlay routines.
1284f29dbc25Smrg *---------------------------------------------------------------------------
1285f29dbc25Smrg */
1286f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1287f29dbc25Smrgvoid
1288f29dbc25Smrggu1_set_display_video_size(unsigned short width, unsigned short height)
1289f29dbc25Smrg#else
1290f29dbc25Smrgvoid
1291f29dbc25Smrggfx_set_display_video_size(unsigned short width, unsigned short height)
1292f29dbc25Smrg#endif
1293f29dbc25Smrg{
1294f29dbc25Smrg    unsigned long lock, size, value;
1295f29dbc25Smrg
1296f29dbc25Smrg    size = (unsigned long)(width << 1) * (unsigned long)height;
1297f29dbc25Smrg
1298f29dbc25Smrg    /* STORE THE VIDEO BUFFER SIZE AS A GLOBAL */
1299f29dbc25Smrg    vid_buf_size = ((size + 63) >> 6) << 16;
1300f29dbc25Smrg
1301f29dbc25Smrg    lock = READ_REG32(DC_UNLOCK);
1302f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
1303f29dbc25Smrg    value = READ_REG32(DC_BUF_SIZE) & 0x0000FFFF;
1304f29dbc25Smrg    value |= vid_buf_size;
1305f29dbc25Smrg    WRITE_REG32(DC_BUF_SIZE, value);
1306f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, lock);
1307f29dbc25Smrg}
1308f29dbc25Smrg
1309f29dbc25Smrg/*---------------------------------------------------------------------------
1310f29dbc25Smrg * gfx_set_display_video_offset (PRIVATE ROUTINE - NOT PART OF API)
1311f29dbc25Smrg *
1312f29dbc25Smrg * This routine is called by "gfx_set_video_offset".  It abstracts the
1313f29dbc25Smrg * version of the display controller from the video overlay routines.
1314f29dbc25Smrg *---------------------------------------------------------------------------
1315f29dbc25Smrg */
1316f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1317f29dbc25Smrgvoid
1318f29dbc25Smrggu1_set_display_video_offset(unsigned long offset)
1319f29dbc25Smrg#else
1320f29dbc25Smrgvoid
1321f29dbc25Smrggfx_set_display_video_offset(unsigned long offset)
1322f29dbc25Smrg#endif
1323f29dbc25Smrg{
1324f29dbc25Smrg    unsigned long lock;
1325f29dbc25Smrg
1326f29dbc25Smrg    lock = READ_REG32(DC_UNLOCK);
1327f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
1328f29dbc25Smrg    offset &= 0x003FFFFF;
1329f29dbc25Smrg    WRITE_REG32(DC_VID_ST_OFFSET, offset);
1330f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, lock);
1331f29dbc25Smrg}
1332f29dbc25Smrg
1333f29dbc25Smrg/*---------------------------------------------------------------------------
1334f29dbc25Smrg * gfx_set_display_priority_high
1335f29dbc25Smrg *
1336f29dbc25Smrg * This routine controls the x-bus round robin arbitration mechanism.
1337f29dbc25Smrg * When enable is TRUE, graphics pipeline requests and non-critical display
1338f29dbc25Smrg * controller requests are arbitrated at the same priority as processor
1339f29dbc25Smrg * requests. When FALSE processor requests are arbitrated at a higher priority
1340f29dbc25Smrg *---------------------------------------------------------------------------
1341f29dbc25Smrg */
1342f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1343f29dbc25Smrgvoid
1344f29dbc25Smrggu1_set_display_priority_high(int enable)
1345f29dbc25Smrg#else
1346f29dbc25Smrgvoid
1347f29dbc25Smrggfx_set_display_priority_high(int enable)
1348f29dbc25Smrg#endif
1349f29dbc25Smrg{
1350f29dbc25Smrg    unsigned long lock, control;
1351f29dbc25Smrg
1352f29dbc25Smrg    lock = READ_REG32(DC_UNLOCK);
1353f29dbc25Smrg    control = READ_REG32(MC_MEM_CNTRL1);
1354f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
1355f29dbc25Smrg    if (enable)
1356f29dbc25Smrg        control |= MC_XBUSARB;
1357f29dbc25Smrg    else
1358f29dbc25Smrg        control &= ~(MC_XBUSARB);
1359f29dbc25Smrg    WRITE_REG32(MC_MEM_CNTRL1, control);
1360f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, lock);
1361f29dbc25Smrg    return;
1362f29dbc25Smrg}
1363f29dbc25Smrg
1364f29dbc25Smrg/*---------------------------------------------------------------------------
1365f29dbc25Smrg * gfx_test_timing_active
1366f29dbc25Smrg *---------------------------------------------------------------------------
1367f29dbc25Smrg */
1368f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1369f29dbc25Smrgint
1370f29dbc25Smrggu1_test_timing_active(void)
1371f29dbc25Smrg#else
1372f29dbc25Smrgint
1373f29dbc25Smrggfx_test_timing_active(void)
1374f29dbc25Smrg#endif
1375f29dbc25Smrg{
1376f29dbc25Smrg    if (READ_REG32(DC_TIMING_CFG) & DC_TCFG_TGEN)
1377f29dbc25Smrg        return (1);
1378f29dbc25Smrg    else
1379f29dbc25Smrg        return (0);
1380f29dbc25Smrg}
1381f29dbc25Smrg
1382f29dbc25Smrg/*---------------------------------------------------------------------------
1383f29dbc25Smrg * gfx_test_vertical_active
1384f29dbc25Smrg *---------------------------------------------------------------------------
1385f29dbc25Smrg */
1386f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1387f29dbc25Smrgint
1388f29dbc25Smrggu1_test_vertical_active(void)
1389f29dbc25Smrg#else
1390f29dbc25Smrgint
1391f29dbc25Smrggfx_test_vertical_active(void)
1392f29dbc25Smrg#endif
1393f29dbc25Smrg{
1394f29dbc25Smrg    if (READ_REG32(DC_TIMING_CFG) & DC_TCFG_VNA)
1395f29dbc25Smrg        return (0);
1396f29dbc25Smrg    else
1397f29dbc25Smrg        return (1);
1398f29dbc25Smrg}
1399f29dbc25Smrg
1400f29dbc25Smrg/*---------------------------------------------------------------------------
1401f29dbc25Smrg * gfx_wait_vertical_blank
1402f29dbc25Smrg *---------------------------------------------------------------------------
1403f29dbc25Smrg */
1404f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1405f29dbc25Smrgint
1406f29dbc25Smrggu1_wait_vertical_blank(void)
1407f29dbc25Smrg#else
1408f29dbc25Smrgint
1409f29dbc25Smrggfx_wait_vertical_blank(void)
1410f29dbc25Smrg#endif
1411f29dbc25Smrg{
1412f29dbc25Smrg    if (gfx_test_timing_active()) {
1413f29dbc25Smrg        while (!gfx_test_vertical_active()) ;
1414f29dbc25Smrg        while (gfx_test_vertical_active()) ;
1415f29dbc25Smrg    }
1416f29dbc25Smrg
1417f29dbc25Smrg    return (0);
1418f29dbc25Smrg}
1419f29dbc25Smrg
1420f29dbc25Smrg/*---------------------------------------------------------------------------
1421f29dbc25Smrg * gfx_enable_panning
1422f29dbc25Smrg *
1423f29dbc25Smrg * This routine  enables the panning when the Mode is bigger than the panel
1424f29dbc25Smrg * size.
1425f29dbc25Smrg *---------------------------------------------------------------------------
1426f29dbc25Smrg */
1427f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1428f29dbc25Smrgvoid
1429f29dbc25Smrggu1_enable_panning(int x, int y)
1430f29dbc25Smrg#else
1431f29dbc25Smrgvoid
1432f29dbc25Smrggfx_enable_panning(int x, int y)
1433f29dbc25Smrg#endif
1434f29dbc25Smrg{
1435f29dbc25Smrg    unsigned long modeBytesPerPixel;
1436f29dbc25Smrg    unsigned long modeBytesPerScanline = 0;
1437f29dbc25Smrg    unsigned long startAddress = 0;
1438f29dbc25Smrg
1439f29dbc25Smrg    modeBytesPerPixel = (gbpp + 7) / 8;
1440f29dbc25Smrg    modeBytesPerScanline =
1441f29dbc25Smrg        (((ModeWidth + 1023) / 1024) * 1024) * modeBytesPerPixel;
1442f29dbc25Smrg
1443f29dbc25Smrg    /* TEST FOR NO-WORK */
1444f29dbc25Smrg    if (x >= DeltaX && (unsigned short)x < (PanelWidth + DeltaX) &&
1445f29dbc25Smrg        y >= DeltaY && (unsigned short)y < (PanelHeight + DeltaY))
1446f29dbc25Smrg        return;
1447f29dbc25Smrg
1448f29dbc25Smrg    /* ADJUST PANNING VARIABLES WHEN CURSOR EXCEEDS BOUNDARY       */
1449f29dbc25Smrg    /* Test the boundary conditions for each coordinate and update */
1450f29dbc25Smrg    /* all variables and the starting offset accordingly.          */
1451f29dbc25Smrg    if (x < DeltaX)
1452f29dbc25Smrg        DeltaX = x;
1453f29dbc25Smrg    else if ((unsigned short)x >= (DeltaX + PanelWidth))
1454f29dbc25Smrg        DeltaX = x - PanelWidth + 1;
1455f29dbc25Smrg
1456f29dbc25Smrg    if (y < DeltaY)
1457f29dbc25Smrg        DeltaY = y;
1458f29dbc25Smrg    else if ((unsigned short)y >= (DeltaY + PanelHeight))
1459f29dbc25Smrg        DeltaY = y - PanelHeight + 1;
1460f29dbc25Smrg
1461f29dbc25Smrg    /* CALCULATE THE START OFFSET */
1462f29dbc25Smrg    startAddress =
1463f29dbc25Smrg        (DeltaX * modeBytesPerPixel) + (DeltaY * modeBytesPerScanline);
1464f29dbc25Smrg
1465f29dbc25Smrg    gfx_set_display_offset(startAddress);
1466f29dbc25Smrg
1467f29dbc25Smrg    /* SET PANEL COORDINATES                    */
1468f29dbc25Smrg    /* Panel's x position must be DWORD aligned */
1469f29dbc25Smrg    panelTop = DeltaY;
1470f29dbc25Smrg    panelLeft = DeltaX * modeBytesPerPixel;
1471f29dbc25Smrg
1472f29dbc25Smrg    if (panelLeft & 3)
1473f29dbc25Smrg        panelLeft = (panelLeft & 0xFFFFFFFC) + 4;
1474f29dbc25Smrg
1475f29dbc25Smrg    panelLeft /= modeBytesPerPixel;
1476f29dbc25Smrg
1477f29dbc25Smrg}
1478f29dbc25Smrg
1479f29dbc25Smrg/*---------------------------------------------------------------------------
1480f29dbc25Smrg * gfx_set_fixed_timings
1481f29dbc25Smrg *---------------------------------------------------------------------------
1482f29dbc25Smrg */
1483f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1484f29dbc25Smrgint
1485f29dbc25Smrggu1_set_fixed_timings(int panelResX, int panelResY, unsigned short width,
1486f29dbc25Smrg    unsigned short height, unsigned short bpp)
1487f29dbc25Smrg#else
1488f29dbc25Smrgint
1489f29dbc25Smrggfx_set_fixed_timings(int panelResX, int panelResY, unsigned short width,
1490f29dbc25Smrg    unsigned short height, unsigned short bpp)
1491f29dbc25Smrg#endif
1492f29dbc25Smrg{
1493f29dbc25Smrg    unsigned int mode;
1494f29dbc25Smrg
1495f29dbc25Smrg    ModeWidth = width;
1496f29dbc25Smrg    ModeHeight = height;
1497f29dbc25Smrg    PanelWidth = (unsigned short)panelResX;
1498f29dbc25Smrg    PanelHeight = (unsigned short)panelResY;
1499f29dbc25Smrg    PanelEnable = 1;
1500f29dbc25Smrg
1501f29dbc25Smrg    /* LOOP THROUGH THE AVAILABLE MODES TO FIND A MATCH */
1502f29dbc25Smrg    for (mode = 0; mode < NUM_FIXED_TIMINGS_MODES; mode++) {
1503f29dbc25Smrg        if ((FixedParams[mode].xres == width) &&
1504f29dbc25Smrg            (FixedParams[mode].yres == height) &&
1505f29dbc25Smrg            (FixedParams[mode].panelresx == panelResX) &&
1506f29dbc25Smrg            (FixedParams[mode].panelresy == panelResY)) {
1507f29dbc25Smrg
1508f29dbc25Smrg            /* SET THE 92xx FOR THE SELECTED MODE */
1509f29dbc25Smrg            FIXEDTIMINGS *fmode = &FixedParams[mode];
1510f29dbc25Smrg
1511f29dbc25Smrg            gfx_set_display_timings(bpp, 3, fmode->hactive,
1512f29dbc25Smrg                fmode->hblankstart, fmode->hsyncstart, fmode->hsyncend,
1513f29dbc25Smrg                fmode->hblankend, fmode->htotal, fmode->vactive,
1514f29dbc25Smrg                fmode->vblankstart, fmode->vsyncstart, fmode->vsyncend,
1515f29dbc25Smrg                fmode->vblankend, fmode->vtotal, fmode->frequency);
1516f29dbc25Smrg
1517f29dbc25Smrg            return (1);
1518f29dbc25Smrg        }                              /* end if() */
1519f29dbc25Smrg    }                                  /* end for() */
1520f29dbc25Smrg
1521f29dbc25Smrg    return (-1);
1522f29dbc25Smrg}
1523f29dbc25Smrg
1524f29dbc25Smrg/*---------------------------------------------------------------------------
1525f29dbc25Smrg * gfx_set_panel_present
1526f29dbc25Smrg *---------------------------------------------------------------------------
1527f29dbc25Smrg */
1528f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1529f29dbc25Smrgint
1530f29dbc25Smrggu1_set_panel_present(int panelResX, int panelResY, unsigned short width,
1531f29dbc25Smrg    unsigned short height, unsigned short bpp)
1532f29dbc25Smrg#else
1533f29dbc25Smrgint
1534f29dbc25Smrggfx_set_panel_present(int panelResX, int panelResY, unsigned short width,
1535f29dbc25Smrg    unsigned short height, unsigned short bpp)
1536f29dbc25Smrg#endif
1537f29dbc25Smrg{
1538f29dbc25Smrg    /* SET VALID BPP         */
1539f29dbc25Smrg    /* 16BPP is the default. */
1540f29dbc25Smrg    if (bpp != 8 && bpp != 15 && bpp != 16)
1541f29dbc25Smrg        bpp = 16;
1542f29dbc25Smrg
1543f29dbc25Smrg    /* RECORD PANEL PARAMETERS */
1544f29dbc25Smrg    /* This routine does not touch any panel timings.  It is used when custom
1545f29dbc25Smrg     * panel settings are set up in advance by the BIOS or an application, but
1546f29dbc25Smrg     * the application still requires access to other panel functionality
1547f29dbc25Smrg     * provided by Durango (i.e. panning)
1548f29dbc25Smrg     * */
1549f29dbc25Smrg
1550f29dbc25Smrg    ModeWidth = width;
1551f29dbc25Smrg    ModeHeight = height;
1552f29dbc25Smrg    PanelWidth = (unsigned short)panelResX;
1553f29dbc25Smrg    PanelHeight = (unsigned short)panelResY;
1554f29dbc25Smrg    PanelEnable = 1;
1555f29dbc25Smrg    gbpp = bpp;
1556f29dbc25Smrg
1557f29dbc25Smrg    /* PROGRAM THE BPP IN THE DISPLAY CONTROLLER */
1558f29dbc25Smrg    gfx_set_display_bpp(bpp);
1559f29dbc25Smrg
1560f29dbc25Smrg    return (GFX_STATUS_OK);
1561f29dbc25Smrg}
1562f29dbc25Smrg
1563f29dbc25Smrg/*-----------------------------------------------------------------------*
1564f29dbc25Smrg * THE FOLLOWING READ ROUTINES ARE ALWAYS INCLUDED:                      *
1565f29dbc25Smrg * gfx_get_hsync_end, gfx_get_htotal, gfx_get_vsync_end, gfx_get_vtotal  *
1566f29dbc25Smrg * are used by the video overlay routines.                               *
1567f29dbc25Smrg *                                                                       *
1568f29dbc25Smrg * gfx_get_vline and gfx_vactive are used to prevent an issue for the    *
1569f29dbc25Smrg * SC1200.                                                               *
1570f29dbc25Smrg *                                                                       *
1571f29dbc25Smrg * The others are part of the Durango API.                               *
1572f29dbc25Smrg *-----------------------------------------------------------------------*/
1573f29dbc25Smrg
1574f29dbc25Smrg/*---------------------------------------------------------------------------
1575f29dbc25Smrg * gfx_get_display_pitch
1576f29dbc25Smrg *
1577f29dbc25Smrg * This routine returns the current pitch of the frame buffer, in bytes.
1578f29dbc25Smrg *---------------------------------------------------------------------------
1579f29dbc25Smrg */
1580f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1581f29dbc25Smrgunsigned short
1582f29dbc25Smrggu1_get_display_pitch(void)
1583f29dbc25Smrg#else
1584f29dbc25Smrgunsigned short
1585f29dbc25Smrggfx_get_display_pitch(void)
1586f29dbc25Smrg#endif
1587f29dbc25Smrg{
1588f29dbc25Smrg    unsigned long value;
1589f29dbc25Smrg
1590f29dbc25Smrg    if (gfx_cpu_version == GFX_CPU_PYRAMID) {
1591f29dbc25Smrg        /* Pyramid update for 4KB line pitch */
1592f29dbc25Smrg        value = (READ_REG32(DC_LINE_DELTA) & 0x07FF) << 2;
1593f29dbc25Smrg    } else {
1594f29dbc25Smrg        value = (READ_REG32(DC_LINE_DELTA) & 0x03FF) << 2;
1595f29dbc25Smrg    }
1596f29dbc25Smrg
1597f29dbc25Smrg    return ((unsigned short)value);
1598f29dbc25Smrg}
1599f29dbc25Smrg
1600f29dbc25Smrg/*----------------------------------------------------------------------------
1601f29dbc25Smrg * GFX_GET_DISPLAY_DETAILS
1602f29dbc25Smrg *
1603f29dbc25Smrg * This routine gets the specified display mode.
1604f29dbc25Smrg *
1605f29dbc25Smrg * Returns 1 if successful, 0 if mode could not be get.
1606f29dbc25Smrg *----------------------------------------------------------------------------
1607f29dbc25Smrg */
1608f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1609f29dbc25Smrgint
1610f29dbc25Smrggu1_get_display_details(unsigned int mode, int *xres, int *yres, int *hz)
1611f29dbc25Smrg#else
1612f29dbc25Smrgint
1613f29dbc25Smrggfx_get_display_details(unsigned int mode, int *xres, int *yres, int *hz)
1614f29dbc25Smrg#endif
1615f29dbc25Smrg{
1616f29dbc25Smrg    if (mode < NUM_GX_DISPLAY_MODES) {
1617f29dbc25Smrg        if (DisplayParams[mode].flags & GFX_MODE_56HZ)
1618f29dbc25Smrg            *hz = 56;
1619f29dbc25Smrg        else if (DisplayParams[mode].flags & GFX_MODE_60HZ)
1620f29dbc25Smrg            *hz = 60;
1621f29dbc25Smrg        else if (DisplayParams[mode].flags & GFX_MODE_70HZ)
1622f29dbc25Smrg            *hz = 70;
1623f29dbc25Smrg        else if (DisplayParams[mode].flags & GFX_MODE_72HZ)
1624f29dbc25Smrg            *hz = 72;
1625f29dbc25Smrg        else if (DisplayParams[mode].flags & GFX_MODE_75HZ)
1626f29dbc25Smrg            *hz = 75;
1627f29dbc25Smrg        else if (DisplayParams[mode].flags & GFX_MODE_85HZ)
1628f29dbc25Smrg            *hz = 85;
1629f29dbc25Smrg
1630f29dbc25Smrg        *xres = DisplayParams[mode].hactive;
1631f29dbc25Smrg        *yres = DisplayParams[mode].vactive;
1632f29dbc25Smrg
1633f29dbc25Smrg        return (1);
1634f29dbc25Smrg    }
1635f29dbc25Smrg    return (0);
1636f29dbc25Smrg}
1637f29dbc25Smrg
1638f29dbc25Smrg/*----------------------------------------------------------------------------
1639f29dbc25Smrg * GFX_GET_DISPLAY_MODE_COUNT
1640f29dbc25Smrg *
1641f29dbc25Smrg * Returns number of modes supported.
1642f29dbc25Smrg *----------------------------------------------------------------------------
1643f29dbc25Smrg */
1644f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1645f29dbc25Smrgint
1646f29dbc25Smrggu1_get_display_mode_count(void)
1647f29dbc25Smrg#else
1648f29dbc25Smrgint
1649f29dbc25Smrggfx_get_display_mode_count(void)
1650f29dbc25Smrg#endif
1651f29dbc25Smrg{
1652f29dbc25Smrg    return (NUM_GX_DISPLAY_MODES);
1653f29dbc25Smrg}
1654f29dbc25Smrg
1655f29dbc25Smrg/*----------------------------------------------------------------------------
1656f29dbc25Smrg * gfx_get_frame_buffer_line_size
1657f29dbc25Smrg *
1658f29dbc25Smrg * Returns the current frame buffer line size, in bytes
1659f29dbc25Smrg *----------------------------------------------------------------------------
1660f29dbc25Smrg */
1661f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1662f29dbc25Smrgunsigned long
1663f29dbc25Smrggu1_get_frame_buffer_line_size(void)
1664f29dbc25Smrg#else
1665f29dbc25Smrgunsigned long
1666f29dbc25Smrggfx_get_frame_buffer_line_size(void)
1667f29dbc25Smrg#endif
1668f29dbc25Smrg{
1669f29dbc25Smrg    return ((READ_REG32(DC_BUF_SIZE) & 0x1FF) << 3);
1670f29dbc25Smrg}
1671f29dbc25Smrg
1672f29dbc25Smrg/*----------------------------------------------------------------------------
1673f29dbc25Smrg * gfx_mode_frequency_supported
1674f29dbc25Smrg *
1675f29dbc25Smrg * This routine examines if the requested mode with pixel frequency is supported.
1676f29dbc25Smrg *
1677f29dbc25Smrg * Returns >0 if successful , <0 if freq. could not be found and matched.
1678f29dbc25Smrg *----------------------------------------------------------------------------
1679f29dbc25Smrg */
1680f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1681f29dbc25Smrgint
1682f29dbc25Smrggu1_mode_frequency_supported(int xres, int yres, int bpp,
1683f29dbc25Smrg    unsigned long frequency)
1684f29dbc25Smrg#else
1685f29dbc25Smrgint
1686f29dbc25Smrggfx_mode_frequency_supported(int xres, int yres, int bpp,
1687f29dbc25Smrg    unsigned long frequency)
1688f29dbc25Smrg#endif
1689f29dbc25Smrg{
1690f29dbc25Smrg    unsigned int index;
1691f29dbc25Smrg    unsigned long value;
1692f29dbc25Smrg    unsigned long bpp_flag = 0;
1693f29dbc25Smrg
1694f29dbc25Smrg    bpp_flag = GFX_MODE_8BPP;
1695f29dbc25Smrg    if (bpp > 8)
1696f29dbc25Smrg        bpp_flag = GFX_MODE_16BPP;
1697f29dbc25Smrg
1698f29dbc25Smrg    for (index = 0; index < NUM_GX_DISPLAY_MODES; index++) {
1699f29dbc25Smrg        if ((DisplayParams[index].hactive == (unsigned short)xres) &&
1700f29dbc25Smrg            (DisplayParams[index].vactive == (unsigned short)yres) &&
1701f29dbc25Smrg            (DisplayParams[index].flags & bpp_flag) &&
1702f29dbc25Smrg            (DisplayParams[index].frequency == frequency)) {
1703f29dbc25Smrg            int hz = 0;
1704f29dbc25Smrg
1705f29dbc25Smrg            value = DisplayParams[index].flags;
1706f29dbc25Smrg
1707f29dbc25Smrg            if (value & GFX_MODE_56HZ)
1708f29dbc25Smrg                hz = 56;
1709f29dbc25Smrg            else if (value & GFX_MODE_60HZ)
1710f29dbc25Smrg                hz = 60;
1711f29dbc25Smrg            else if (value & GFX_MODE_70HZ)
1712f29dbc25Smrg                hz = 70;
1713f29dbc25Smrg            else if (value & GFX_MODE_72HZ)
1714f29dbc25Smrg                hz = 72;
1715f29dbc25Smrg            else if (value & GFX_MODE_75HZ)
1716f29dbc25Smrg                hz = 75;
1717f29dbc25Smrg            else if (value & GFX_MODE_85HZ)
1718f29dbc25Smrg                hz = 85;
1719f29dbc25Smrg
1720f29dbc25Smrg            return (hz);
1721f29dbc25Smrg        }
1722f29dbc25Smrg    }
1723f29dbc25Smrg    return (-1);
1724f29dbc25Smrg}
1725f29dbc25Smrg
1726f29dbc25Smrg/*----------------------------------------------------------------------------
1727f29dbc25Smrg * gfx_refreshrate_from_frequency
1728f29dbc25Smrg *
1729f29dbc25Smrg * This routine maps the frequency to close match refresh rate
1730f29dbc25Smrg *----------------------------------------------------------------------------
1731f29dbc25Smrg */
1732f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1733f29dbc25Smrgint
1734f29dbc25Smrggu1_get_refreshrate_from_frequency(int xres, int yres, int bpp, int *hz,
1735f29dbc25Smrg    unsigned long frequency)
1736f29dbc25Smrg#else
1737f29dbc25Smrgint
1738f29dbc25Smrggfx_get_refreshrate_from_frequency(int xres, int yres, int bpp, int *hz,
1739f29dbc25Smrg    unsigned long frequency)
1740f29dbc25Smrg#endif
1741f29dbc25Smrg{
1742f29dbc25Smrg    unsigned int index, closematch = 0;
1743f29dbc25Smrg    unsigned long value;
1744f29dbc25Smrg    unsigned long bpp_flag = 0;
1745f29dbc25Smrg    long min, diff;
1746f29dbc25Smrg
1747f29dbc25Smrg    *hz = 60;
1748f29dbc25Smrg
1749f29dbc25Smrg    bpp_flag = GFX_MODE_8BPP;
1750f29dbc25Smrg    if (bpp > 8)
1751f29dbc25Smrg        bpp_flag = GFX_MODE_16BPP;
1752f29dbc25Smrg
1753f29dbc25Smrg    /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */
1754f29dbc25Smrg    /* Search the table for the closest frequency (16.16 format). */
1755f29dbc25Smrg    min = 0x7fffffff;
1756f29dbc25Smrg    for (index = 0; index < NUM_GX_DISPLAY_MODES; index++) {
1757f29dbc25Smrg        if ((DisplayParams[index].htotal == (unsigned short)xres) &&
1758f29dbc25Smrg            (DisplayParams[index].vtotal == (unsigned short)yres) &&
1759f29dbc25Smrg            (DisplayParams[index].flags & bpp_flag)) {
1760f29dbc25Smrg            diff = (long)frequency - (long)DisplayParams[index].frequency;
1761f29dbc25Smrg            if (diff < 0)
1762f29dbc25Smrg                diff = -diff;
1763f29dbc25Smrg
1764f29dbc25Smrg            if (diff < min) {
1765f29dbc25Smrg                min = diff;
1766f29dbc25Smrg                closematch = index;
1767f29dbc25Smrg            }
1768f29dbc25Smrg        }
1769f29dbc25Smrg    }
1770f29dbc25Smrg
1771f29dbc25Smrg    value = DisplayParams[closematch].flags;
1772f29dbc25Smrg
1773f29dbc25Smrg    if (value & GFX_MODE_56HZ)
1774f29dbc25Smrg        *hz = 56;
1775f29dbc25Smrg    else if (value & GFX_MODE_60HZ)
1776f29dbc25Smrg        *hz = 60;
1777f29dbc25Smrg    else if (value & GFX_MODE_70HZ)
1778f29dbc25Smrg        *hz = 70;
1779f29dbc25Smrg    else if (value & GFX_MODE_72HZ)
1780f29dbc25Smrg        *hz = 72;
1781f29dbc25Smrg    else if (value & GFX_MODE_75HZ)
1782f29dbc25Smrg        *hz = 75;
1783f29dbc25Smrg    else if (value & GFX_MODE_85HZ)
1784f29dbc25Smrg        *hz = 85;
1785f29dbc25Smrg
1786f29dbc25Smrg    return (1);
1787f29dbc25Smrg}
1788f29dbc25Smrg
1789f29dbc25Smrg/*----------------------------------------------------------------------------
1790f29dbc25Smrg * gfx_refreshrate_from_mode
1791f29dbc25Smrg *
1792f29dbc25Smrg * This routine is identical to the gfx_get_refreshrate_from_frequency,
1793f29dbc25Smrg * except that the active timing values are compared instead of the total
1794f29dbc25Smrg * values.  Some modes (such as 70Hz and 72Hz) may be confused in this routine
1795f29dbc25Smrg *----------------------------------------------------------------------------
1796f29dbc25Smrg */
1797f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1798f29dbc25Smrgint
1799f29dbc25Smrggu1_get_refreshrate_from_mode(int xres, int yres, int bpp, int *hz,
1800f29dbc25Smrg    unsigned long frequency)
1801f29dbc25Smrg#else
1802f29dbc25Smrgint
1803f29dbc25Smrggfx_get_refreshrate_from_mode(int xres, int yres, int bpp, int *hz,
1804f29dbc25Smrg    unsigned long frequency)
1805f29dbc25Smrg#endif
1806f29dbc25Smrg{
1807f29dbc25Smrg    unsigned int index, closematch = 0;
1808f29dbc25Smrg    unsigned long value;
1809f29dbc25Smrg    unsigned long bpp_flag = 0;
1810f29dbc25Smrg    long min, diff;
1811f29dbc25Smrg
1812f29dbc25Smrg    *hz = 60;
1813f29dbc25Smrg
1814f29dbc25Smrg    bpp_flag = GFX_MODE_8BPP;
1815f29dbc25Smrg    if (bpp > 8)
1816f29dbc25Smrg        bpp_flag = GFX_MODE_16BPP;
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_GX_DISPLAY_MODES; index++) {
1822f29dbc25Smrg        if ((DisplayParams[index].hactive == (unsigned short)xres) &&
1823f29dbc25Smrg            (DisplayParams[index].vactive == (unsigned short)yres) &&
1824f29dbc25Smrg            (DisplayParams[index].flags & bpp_flag)) {
1825f29dbc25Smrg            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
1851f29dbc25Smrg    return (1);
1852f29dbc25Smrg}
1853f29dbc25Smrg
1854f29dbc25Smrg/*----------------------------------------------------------------------------
1855f29dbc25Smrg * gfx_get_frequency_from_refreshrate
1856f29dbc25Smrg *
1857f29dbc25Smrg * This routine maps the refresh rate to the closest matching PLL frequency.
1858f29dbc25Smrg *----------------------------------------------------------------------------
1859f29dbc25Smrg */
1860f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1861f29dbc25Smrgint
1862f29dbc25Smrggu1_get_frequency_from_refreshrate(int xres, int yres, int bpp, int hz,
1863f29dbc25Smrg    int *frequency)
1864f29dbc25Smrg#else
1865f29dbc25Smrgint
1866f29dbc25Smrggfx_get_frequency_from_refreshrate(int xres, int yres, int bpp, int hz,
1867f29dbc25Smrg    int *frequency)
1868f29dbc25Smrg#endif
1869f29dbc25Smrg{
1870f29dbc25Smrg    unsigned int index;
1871f29dbc25Smrg    int retval = -1;
1872f29dbc25Smrg    unsigned long hz_flag = 0;
1873f29dbc25Smrg    unsigned long bpp_flag = 0;
1874f29dbc25Smrg
1875f29dbc25Smrg    *frequency = 0;
1876f29dbc25Smrg
1877f29dbc25Smrg    if (hz == 56)
1878f29dbc25Smrg        hz_flag = GFX_MODE_56HZ;
1879f29dbc25Smrg    else if (hz == 60)
1880f29dbc25Smrg        hz_flag = GFX_MODE_60HZ;
1881f29dbc25Smrg    else if (hz == 70)
1882f29dbc25Smrg        hz_flag = GFX_MODE_70HZ;
1883f29dbc25Smrg    else if (hz == 72)
1884f29dbc25Smrg        hz_flag = GFX_MODE_72HZ;
1885f29dbc25Smrg    else if (hz == 75)
1886f29dbc25Smrg        hz_flag = GFX_MODE_75HZ;
1887f29dbc25Smrg    else if (hz == 85)
1888f29dbc25Smrg        hz_flag = GFX_MODE_85HZ;
1889f29dbc25Smrg
1890f29dbc25Smrg    bpp_flag = GFX_MODE_8BPP;
1891f29dbc25Smrg    if (bpp > 8)
1892f29dbc25Smrg        bpp_flag = GFX_MODE_16BPP;
1893f29dbc25Smrg
1894f29dbc25Smrg    /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */
1895f29dbc25Smrg
1896f29dbc25Smrg    for (index = 0; index < NUM_GX_DISPLAY_MODES; index++) {
1897f29dbc25Smrg        if ((DisplayParams[index].hactive == (unsigned short)xres) &&
1898f29dbc25Smrg            (DisplayParams[index].vactive == (unsigned short)yres) &&
1899f29dbc25Smrg            (DisplayParams[index].flags & bpp_flag) &&
1900f29dbc25Smrg            (DisplayParams[index].flags & hz_flag)) {
1901f29dbc25Smrg            *frequency = DisplayParams[index].frequency;
1902f29dbc25Smrg            retval = 1;
1903f29dbc25Smrg        }
1904f29dbc25Smrg    }
1905f29dbc25Smrg    return retval;
1906f29dbc25Smrg}
1907f29dbc25Smrg
1908f29dbc25Smrg/*---------------------------------------------------------------------------
1909f29dbc25Smrg * gfx_get_max_supported_pixel_clock
1910f29dbc25Smrg *
1911f29dbc25Smrg * This routine returns the maximum recommended speed for the pixel clock.  The
1912f29dbc25Smrg * return value is an integer of the format xxxyyy, where xxx.yyy is the maximum
1913f29dbc25Smrg * floating point pixel clock speed.
1914f29dbc25Smrg *---------------------------------------------------------------------------
1915f29dbc25Smrg */
1916f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1917f29dbc25Smrgunsigned long
1918f29dbc25Smrggu1_get_max_supported_pixel_clock(void)
1919f29dbc25Smrg#else
1920f29dbc25Smrgunsigned long
1921f29dbc25Smrggfx_get_max_supported_pixel_clock(void)
1922f29dbc25Smrg#endif
1923f29dbc25Smrg{
1924f29dbc25Smrg    /* ALL CHIPS CAN HANDLE 1280X1024@85HZ - 157.5 MHz */
1925f29dbc25Smrg    return 157500;
1926f29dbc25Smrg}
1927f29dbc25Smrg
1928f29dbc25Smrg/*----------------------------------------------------------------------------
1929f29dbc25Smrg * gfx_get_display_mode
1930f29dbc25Smrg *
1931f29dbc25Smrg * This routine gets the specified display mode.
1932f29dbc25Smrg *
1933f29dbc25Smrg * Returns: >0 if successful and mode returned, <0 if mode could not be found.
1934f29dbc25Smrg *----------------------------------------------------------------------------
1935f29dbc25Smrg */
1936f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1937f29dbc25Smrgint
1938f29dbc25Smrggu1_get_display_mode(int *xres, int *yres, int *bpp, int *hz)
1939f29dbc25Smrg#else
1940f29dbc25Smrgint
1941f29dbc25Smrggfx_get_display_mode(int *xres, int *yres, int *bpp, int *hz)
1942f29dbc25Smrg#endif
1943f29dbc25Smrg{
1944f29dbc25Smrg    unsigned int mode = 0;
1945f29dbc25Smrg    unsigned long pll_freq = 0, bpp_flag = 0;
1946f29dbc25Smrg
1947f29dbc25Smrg    *xres = gfx_get_hactive();
1948f29dbc25Smrg    *yres = gfx_get_vactive();
1949f29dbc25Smrg    *bpp = gfx_get_display_bpp();
1950f29dbc25Smrg    pll_freq = gfx_get_clock_frequency();
1951f29dbc25Smrg
1952f29dbc25Smrg    /* SUPPORT EMULATED VGA MODES */
1953f29dbc25Smrg    if (gfx_pixel_double)
1954f29dbc25Smrg        *xres >>= 1;
1955f29dbc25Smrg
1956f29dbc25Smrg    if (gfx_line_double)
1957f29dbc25Smrg        *yres >>= 1;
1958f29dbc25Smrg
1959f29dbc25Smrg    /* SET BPP FLAGS TO LIMIT MODE SELECTION */
1960f29dbc25Smrg    bpp_flag = GFX_MODE_8BPP;
1961f29dbc25Smrg    if (*bpp > 8)
1962f29dbc25Smrg        bpp_flag = GFX_MODE_16BPP;
1963f29dbc25Smrg
1964f29dbc25Smrg    for (mode = 0; mode < NUM_GX_DISPLAY_MODES; mode++) {
1965f29dbc25Smrg        if ((DisplayParams[mode].hactive == (unsigned short)*xres) &&
1966f29dbc25Smrg            (DisplayParams[mode].vactive == (unsigned short)*yres) &&
1967f29dbc25Smrg            (DisplayParams[mode].frequency == pll_freq) &&
1968f29dbc25Smrg            (DisplayParams[mode].flags & bpp_flag)) {
1969f29dbc25Smrg
1970f29dbc25Smrg            pll_freq = DisplayParams[mode].flags;
1971f29dbc25Smrg
1972f29dbc25Smrg            if (pll_freq & GFX_MODE_56HZ)
1973f29dbc25Smrg                *hz = 56;
1974f29dbc25Smrg            else if (pll_freq & GFX_MODE_60HZ)
1975f29dbc25Smrg                *hz = 60;
1976f29dbc25Smrg            else if (pll_freq & GFX_MODE_70HZ)
1977f29dbc25Smrg                *hz = 70;
1978f29dbc25Smrg            else if (pll_freq & GFX_MODE_72HZ)
1979f29dbc25Smrg                *hz = 72;
1980f29dbc25Smrg            else if (pll_freq & GFX_MODE_75HZ)
1981f29dbc25Smrg                *hz = 75;
1982f29dbc25Smrg            else if (pll_freq & GFX_MODE_85HZ)
1983f29dbc25Smrg                *hz = 85;
1984f29dbc25Smrg
1985f29dbc25Smrg            return (1);
1986f29dbc25Smrg        }
1987f29dbc25Smrg    }
1988f29dbc25Smrg    return (-1);
1989f29dbc25Smrg}
1990f29dbc25Smrg
1991f29dbc25Smrg/*---------------------------------------------------------------------------
1992f29dbc25Smrg * gfx_get_hactive
1993f29dbc25Smrg *---------------------------------------------------------------------------
1994f29dbc25Smrg */
1995f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1996f29dbc25Smrgunsigned short
1997f29dbc25Smrggu1_get_hactive(void)
1998f29dbc25Smrg#else
1999f29dbc25Smrgunsigned short
2000f29dbc25Smrggfx_get_hactive(void)
2001f29dbc25Smrg#endif
2002f29dbc25Smrg{
2003f29dbc25Smrg    return ((unsigned short)((READ_REG32(DC_H_TIMING_1) & 0x07F8) + 8));
2004f29dbc25Smrg}
2005f29dbc25Smrg
2006f29dbc25Smrg/*---------------------------------------------------------------------------
2007f29dbc25Smrg * gfx_get_hsync_start
2008f29dbc25Smrg *---------------------------------------------------------------------------
2009f29dbc25Smrg */
2010f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2011f29dbc25Smrgunsigned short
2012f29dbc25Smrggu1_get_hsync_start(void)
2013f29dbc25Smrg#else
2014f29dbc25Smrgunsigned short
2015f29dbc25Smrggfx_get_hsync_start(void)
2016f29dbc25Smrg#endif
2017f29dbc25Smrg{
2018f29dbc25Smrg    return ((unsigned short)((READ_REG32(DC_H_TIMING_3) & 0x07F8) + 8));
2019f29dbc25Smrg}
2020f29dbc25Smrg
2021f29dbc25Smrg/*---------------------------------------------------------------------------
2022f29dbc25Smrg * gfx_get_hsync_end
2023f29dbc25Smrg *---------------------------------------------------------------------------
2024f29dbc25Smrg */
2025f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2026f29dbc25Smrgunsigned short
2027f29dbc25Smrggu1_get_hsync_end(void)
2028f29dbc25Smrg#else
2029f29dbc25Smrgunsigned short
2030f29dbc25Smrggfx_get_hsync_end(void)
2031f29dbc25Smrg#endif
2032f29dbc25Smrg{
2033f29dbc25Smrg    return ((unsigned short)(((READ_REG32(DC_H_TIMING_3) >> 16) & 0x07F8) +
2034f29dbc25Smrg            8));
2035f29dbc25Smrg}
2036f29dbc25Smrg
2037f29dbc25Smrg/*---------------------------------------------------------------------------
2038f29dbc25Smrg * gfx_get_htotal
2039f29dbc25Smrg *---------------------------------------------------------------------------
2040f29dbc25Smrg */
2041f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2042f29dbc25Smrgunsigned short
2043f29dbc25Smrggu1_get_htotal(void)
2044f29dbc25Smrg#else
2045f29dbc25Smrgunsigned short
2046f29dbc25Smrggfx_get_htotal(void)
2047f29dbc25Smrg#endif
2048f29dbc25Smrg{
2049f29dbc25Smrg    return ((unsigned short)(((READ_REG32(DC_H_TIMING_1) >> 16) & 0x07F8) +
2050f29dbc25Smrg            8));
2051f29dbc25Smrg}
2052f29dbc25Smrg
2053f29dbc25Smrg/*---------------------------------------------------------------------------
2054f29dbc25Smrg * gfx_get_vactive
2055f29dbc25Smrg *---------------------------------------------------------------------------
2056f29dbc25Smrg */
2057f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2058f29dbc25Smrgunsigned short
2059f29dbc25Smrggu1_get_vactive(void)
2060f29dbc25Smrg#else
2061f29dbc25Smrgunsigned short
2062f29dbc25Smrggfx_get_vactive(void)
2063f29dbc25Smrg#endif
2064f29dbc25Smrg{
2065f29dbc25Smrg    return ((unsigned short)((READ_REG32(DC_V_TIMING_1) & 0x07FF) + 1));
2066f29dbc25Smrg}
2067f29dbc25Smrg
2068f29dbc25Smrg/*---------------------------------------------------------------------------
2069f29dbc25Smrg * gfx_get_vsync_end
2070f29dbc25Smrg *---------------------------------------------------------------------------
2071f29dbc25Smrg */
2072f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2073f29dbc25Smrgunsigned short
2074f29dbc25Smrggu1_get_vsync_end(void)
2075f29dbc25Smrg#else
2076f29dbc25Smrgunsigned short
2077f29dbc25Smrggfx_get_vsync_end(void)
2078f29dbc25Smrg#endif
2079f29dbc25Smrg{
2080f29dbc25Smrg    return ((unsigned short)(((READ_REG32(DC_V_TIMING_3) >> 16) & 0x07FF) +
2081f29dbc25Smrg            1));
2082f29dbc25Smrg}
2083f29dbc25Smrg
2084f29dbc25Smrg/*---------------------------------------------------------------------------
2085f29dbc25Smrg * gfx_get_vtotal
2086f29dbc25Smrg *---------------------------------------------------------------------------
2087f29dbc25Smrg */
2088f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2089f29dbc25Smrgunsigned short
2090f29dbc25Smrggu1_get_vtotal(void)
2091f29dbc25Smrg#else
2092f29dbc25Smrgunsigned short
2093f29dbc25Smrggfx_get_vtotal(void)
2094f29dbc25Smrg#endif
2095f29dbc25Smrg{
2096f29dbc25Smrg    return ((unsigned short)(((READ_REG32(DC_V_TIMING_1) >> 16) & 0x07FF) +
2097f29dbc25Smrg            1));
2098f29dbc25Smrg}
2099f29dbc25Smrg
2100f29dbc25Smrg/*-----------------------------------------------------------------------------
2101f29dbc25Smrg * gfx_get_display_bpp
2102f29dbc25Smrg *
2103f29dbc25Smrg * This routine returns the current color depth of the active display.
2104f29dbc25Smrg *-----------------------------------------------------------------------------
2105f29dbc25Smrg */
2106f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2107f29dbc25Smrgunsigned short
2108f29dbc25Smrggu1_get_display_bpp(void)
2109f29dbc25Smrg#else
2110f29dbc25Smrgunsigned short
2111f29dbc25Smrggfx_get_display_bpp(void)
2112f29dbc25Smrg#endif
2113f29dbc25Smrg{
2114f29dbc25Smrg    switch (READ_REG32(DC_OUTPUT_CFG) & 3) {
2115f29dbc25Smrg    case 0:
2116f29dbc25Smrg        return (16);
2117f29dbc25Smrg    case 2:
2118f29dbc25Smrg        return (15);
2119f29dbc25Smrg    }
2120f29dbc25Smrg    return (8);
2121f29dbc25Smrg}
2122f29dbc25Smrg
2123f29dbc25Smrg/*---------------------------------------------------------------------------
2124f29dbc25Smrg * gfx_get_vline
2125f29dbc25Smrg *---------------------------------------------------------------------------
2126f29dbc25Smrg */
2127f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2128f29dbc25Smrgunsigned short
2129f29dbc25Smrggu1_get_vline(void)
2130f29dbc25Smrg#else
2131f29dbc25Smrgunsigned short
2132f29dbc25Smrggfx_get_vline(void)
2133f29dbc25Smrg#endif
2134f29dbc25Smrg{
2135f29dbc25Smrg    unsigned short current_scan_line;
2136f29dbc25Smrg
2137f29dbc25Smrg    /* Read similar value twice to ensure that the value is not transitioning */
2138f29dbc25Smrg    do {
2139f29dbc25Smrg        current_scan_line =
2140f29dbc25Smrg            (unsigned short)READ_REG32(DC_V_LINE_CNT) & 0x07FF;
2141f29dbc25Smrg    } while (current_scan_line !=
2142f29dbc25Smrg        (unsigned short)(READ_REG32(DC_V_LINE_CNT) & 0x07FF));
2143f29dbc25Smrg
2144f29dbc25Smrg    return (current_scan_line);
2145f29dbc25Smrg}
2146f29dbc25Smrg
2147f29dbc25Smrg/*-----------------------------------------------------------------------------
2148f29dbc25Smrg * gfx_get_display_offset
2149f29dbc25Smrg *-----------------------------------------------------------------------------
2150f29dbc25Smrg */
2151f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2152f29dbc25Smrgunsigned long
2153f29dbc25Smrggu1_get_display_offset(void)
2154f29dbc25Smrg#else
2155f29dbc25Smrgunsigned long
2156f29dbc25Smrggfx_get_display_offset(void)
2157f29dbc25Smrg#endif
2158f29dbc25Smrg{
2159f29dbc25Smrg    return (READ_REG32(DC_FB_ST_OFFSET) & 0x003FFFFF);
2160f29dbc25Smrg}
2161f29dbc25Smrg
2162f29dbc25Smrg/*-----------------------------------------------------------------------------
2163f29dbc25Smrg * gfx_get_cursor_offset
2164f29dbc25Smrg *-----------------------------------------------------------------------------
2165f29dbc25Smrg */
2166f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2167f29dbc25Smrgunsigned long
2168f29dbc25Smrggu1_get_cursor_offset(void)
2169f29dbc25Smrg#else
2170f29dbc25Smrgunsigned long
2171f29dbc25Smrggfx_get_cursor_offset(void)
2172f29dbc25Smrg#endif
2173f29dbc25Smrg{
2174f29dbc25Smrg    return (READ_REG32(DC_CURS_ST_OFFSET) & 0x003FFFFF);
2175f29dbc25Smrg}
2176f29dbc25Smrg
2177f29dbc25Smrg#if GFX_READ_ROUTINES
2178f29dbc25Smrg
2179f29dbc25Smrg/*************************************************************/
2180f29dbc25Smrg/*  READ ROUTINES  |  INCLUDED FOR DIAGNOSTIC PURPOSES ONLY  */
2181f29dbc25Smrg/*************************************************************/
2182f29dbc25Smrg
2183f29dbc25Smrg/*---------------------------------------------------------------------------
2184f29dbc25Smrg * gfx_get_hblank_start
2185f29dbc25Smrg *---------------------------------------------------------------------------
2186f29dbc25Smrg */
2187f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2188f29dbc25Smrgunsigned short
2189f29dbc25Smrggu1_get_hblank_start(void)
2190f29dbc25Smrg#else
2191f29dbc25Smrgunsigned short
2192f29dbc25Smrggfx_get_hblank_start(void)
2193f29dbc25Smrg#endif
2194f29dbc25Smrg{
2195f29dbc25Smrg    return ((unsigned short)((READ_REG32(DC_H_TIMING_2) & 0x07F8) + 8));
2196f29dbc25Smrg}
2197f29dbc25Smrg
2198f29dbc25Smrg/*---------------------------------------------------------------------------
2199f29dbc25Smrg * gfx_get_hblank_end
2200f29dbc25Smrg *---------------------------------------------------------------------------
2201f29dbc25Smrg */
2202f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2203f29dbc25Smrgunsigned short
2204f29dbc25Smrggu1_get_hblank_end(void)
2205f29dbc25Smrg#else
2206f29dbc25Smrgunsigned short
2207f29dbc25Smrggfx_get_hblank_end(void)
2208f29dbc25Smrg#endif
2209f29dbc25Smrg{
2210f29dbc25Smrg    return ((unsigned short)(((READ_REG32(DC_H_TIMING_2) >> 16) & 0x07F8) +
2211f29dbc25Smrg            8));
2212f29dbc25Smrg}
2213f29dbc25Smrg
2214f29dbc25Smrg/*---------------------------------------------------------------------------
2215f29dbc25Smrg * gfx_get_vblank_start
2216f29dbc25Smrg *---------------------------------------------------------------------------
2217f29dbc25Smrg */
2218f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2219f29dbc25Smrgunsigned short
2220f29dbc25Smrggu1_get_vblank_start(void)
2221f29dbc25Smrg#else
2222f29dbc25Smrgunsigned short
2223f29dbc25Smrggfx_get_vblank_start(void)
2224f29dbc25Smrg#endif
2225f29dbc25Smrg{
2226f29dbc25Smrg    return ((unsigned short)((READ_REG32(DC_V_TIMING_2) & 0x07FF) + 1));
2227f29dbc25Smrg}
2228f29dbc25Smrg
2229f29dbc25Smrg/*---------------------------------------------------------------------------
2230f29dbc25Smrg * gfx_get_vsync_start
2231f29dbc25Smrg *---------------------------------------------------------------------------
2232f29dbc25Smrg */
2233f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2234f29dbc25Smrgunsigned short
2235f29dbc25Smrggu1_get_vsync_start(void)
2236f29dbc25Smrg#else
2237f29dbc25Smrgunsigned short
2238f29dbc25Smrggfx_get_vsync_start(void)
2239f29dbc25Smrg#endif
2240f29dbc25Smrg{
2241f29dbc25Smrg    return ((unsigned short)((READ_REG32(DC_V_TIMING_3) & 0x07FF) + 1));
2242f29dbc25Smrg}
2243f29dbc25Smrg
2244f29dbc25Smrg/*---------------------------------------------------------------------------
2245f29dbc25Smrg * gfx_get_vblank_end
2246f29dbc25Smrg *---------------------------------------------------------------------------
2247f29dbc25Smrg */
2248f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2249f29dbc25Smrgunsigned short
2250f29dbc25Smrggu1_get_vblank_end(void)
2251f29dbc25Smrg#else
2252f29dbc25Smrgunsigned short
2253f29dbc25Smrggfx_get_vblank_end(void)
2254f29dbc25Smrg#endif
2255f29dbc25Smrg{
2256f29dbc25Smrg    return ((unsigned short)(((READ_REG32(DC_V_TIMING_2) >> 16) & 0x07FF) +
2257f29dbc25Smrg            1));
2258f29dbc25Smrg}
2259f29dbc25Smrg
2260f29dbc25Smrg/*-----------------------------------------------------------------------------
2261f29dbc25Smrg * gfx_get_display_palette_entry
2262f29dbc25Smrg *-----------------------------------------------------------------------------
2263f29dbc25Smrg */
2264f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2265f29dbc25Smrgint
2266f29dbc25Smrggu1_get_display_palette_entry(unsigned long index, unsigned long *palette)
2267f29dbc25Smrg#else
2268f29dbc25Smrgint
2269f29dbc25Smrggfx_get_display_palette_entry(unsigned long index, unsigned long *palette)
2270f29dbc25Smrg#endif
2271f29dbc25Smrg{
2272f29dbc25Smrg    unsigned long data;
2273f29dbc25Smrg
2274f29dbc25Smrg    if (index > 0xFF)
2275f29dbc25Smrg        return GFX_STATUS_BAD_PARAMETER;
2276f29dbc25Smrg
2277f29dbc25Smrg    WRITE_REG32(DC_PAL_ADDRESS, index);
2278f29dbc25Smrg    data = READ_REG32(DC_PAL_DATA);
2279f29dbc25Smrg    data = ((data << 2) & 0x000000FC) |
2280f29dbc25Smrg        ((data << 4) & 0x0000FC00) | ((data << 6) & 0x00FC0000);
2281f29dbc25Smrg
2282f29dbc25Smrg    *palette = data;
2283f29dbc25Smrg    return 0;
2284f29dbc25Smrg}
2285f29dbc25Smrg
2286f29dbc25Smrg/*-----------------------------------------------------------------------------
2287f29dbc25Smrg * gfx_get_display_palette
2288f29dbc25Smrg *-----------------------------------------------------------------------------
2289f29dbc25Smrg */
2290f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2291f29dbc25Smrgvoid
2292f29dbc25Smrggu1_get_display_palette(unsigned long *palette)
2293f29dbc25Smrg#else
2294f29dbc25Smrgvoid
2295f29dbc25Smrggfx_get_display_palette(unsigned long *palette)
2296f29dbc25Smrg#endif
2297f29dbc25Smrg{
2298f29dbc25Smrg    unsigned long i, data;
2299f29dbc25Smrg
2300f29dbc25Smrg    WRITE_REG32(DC_PAL_ADDRESS, 0);
2301f29dbc25Smrg    for (i = 0; i < 256; i++) {
2302f29dbc25Smrg        data = READ_REG32(DC_PAL_DATA);
2303f29dbc25Smrg        data = ((data << 2) & 0x000000FC) |
2304f29dbc25Smrg            ((data << 4) & 0x0000FC00) | ((data << 6) & 0x00FC0000);
2305f29dbc25Smrg        palette[i] = data;
2306f29dbc25Smrg    }
2307f29dbc25Smrg}
2308f29dbc25Smrg
2309f29dbc25Smrg/*-----------------------------------------------------------------------------
2310f29dbc25Smrg * gfx_get_cursor_enable
2311f29dbc25Smrg *-----------------------------------------------------------------------------
2312f29dbc25Smrg */
2313f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2314f29dbc25Smrgunsigned long
2315f29dbc25Smrggu1_get_cursor_enable(void)
2316f29dbc25Smrg#else
2317f29dbc25Smrgunsigned long
2318f29dbc25Smrggfx_get_cursor_enable(void)
2319f29dbc25Smrg#endif
2320f29dbc25Smrg{
2321f29dbc25Smrg    return (READ_REG32(DC_GENERAL_CFG) & DC_GCFG_CURE);
2322f29dbc25Smrg}
2323f29dbc25Smrg
2324f29dbc25Smrg/*-----------------------------------------------------------------------------
2325f29dbc25Smrg * gfx_get_cursor_position
2326f29dbc25Smrg *-----------------------------------------------------------------------------
2327f29dbc25Smrg */
2328f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2329f29dbc25Smrgunsigned long
2330f29dbc25Smrggu1_get_cursor_position(void)
2331f29dbc25Smrg#else
2332f29dbc25Smrgunsigned long
2333f29dbc25Smrggfx_get_cursor_position(void)
2334f29dbc25Smrg#endif
2335f29dbc25Smrg{
2336f29dbc25Smrg    return ((READ_REG32(DC_CURSOR_X) & 0x07FF) |
2337f29dbc25Smrg        ((READ_REG32(DC_CURSOR_Y) << 16) & 0x03FF0000));
2338f29dbc25Smrg}
2339f29dbc25Smrg
2340f29dbc25Smrg/*-----------------------------------------------------------------------------
2341f29dbc25Smrg * gfx_get_cursor_clip
2342f29dbc25Smrg *-----------------------------------------------------------------------------
2343f29dbc25Smrg */
2344f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2345f29dbc25Smrgunsigned long
2346f29dbc25Smrggu1_get_cursor_clip(void)
2347f29dbc25Smrg#else
2348f29dbc25Smrgunsigned long
2349f29dbc25Smrggfx_get_cursor_clip(void)
2350f29dbc25Smrg#endif
2351f29dbc25Smrg{
2352f29dbc25Smrg    return (((READ_REG32(DC_CURSOR_X) >> 11) & 0x01F) |
2353f29dbc25Smrg        ((READ_REG32(DC_CURSOR_Y) << 5) & 0x1F0000));
2354f29dbc25Smrg}
2355f29dbc25Smrg
2356f29dbc25Smrg/*-----------------------------------------------------------------------------
2357f29dbc25Smrg * gfx_get_cursor_color
2358f29dbc25Smrg *-----------------------------------------------------------------------------
2359f29dbc25Smrg */
2360f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2361f29dbc25Smrgunsigned long
2362f29dbc25Smrggu1_get_cursor_color(int color)
2363f29dbc25Smrg#else
2364f29dbc25Smrgunsigned long
2365f29dbc25Smrggfx_get_cursor_color(int color)
2366f29dbc25Smrg#endif
2367f29dbc25Smrg{
2368f29dbc25Smrg    unsigned long data;
2369f29dbc25Smrg
2370f29dbc25Smrg    if (color) {
2371f29dbc25Smrg        WRITE_REG32(DC_PAL_ADDRESS, 0x101);
2372f29dbc25Smrg    } else {
2373f29dbc25Smrg        WRITE_REG32(DC_PAL_ADDRESS, 0x100);
2374f29dbc25Smrg    }
2375f29dbc25Smrg    data = READ_REG32(DC_PAL_DATA);
2376f29dbc25Smrg    data = ((data << 6) & 0x00FC0000) |
2377f29dbc25Smrg        ((data << 4) & 0x0000FC00) | ((data << 2) & 0x000000FC);
2378f29dbc25Smrg    return (data);
2379f29dbc25Smrg}
2380f29dbc25Smrg
2381f29dbc25Smrg/*-----------------------------------------------------------------------------
2382f29dbc25Smrg * gfx_get_compression_enable
2383f29dbc25Smrg *-----------------------------------------------------------------------------
2384f29dbc25Smrg */
2385f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2386f29dbc25Smrgint
2387f29dbc25Smrggu1_get_compression_enable(void)
2388f29dbc25Smrg#else
2389f29dbc25Smrgint
2390f29dbc25Smrggfx_get_compression_enable(void)
2391f29dbc25Smrg#endif
2392f29dbc25Smrg{
2393f29dbc25Smrg    unsigned long gcfg;
2394f29dbc25Smrg
2395f29dbc25Smrg    gcfg = READ_REG32(DC_GENERAL_CFG);
2396f29dbc25Smrg    if (gcfg & DC_GCFG_CMPE)
2397f29dbc25Smrg        return (1);
2398f29dbc25Smrg    else
2399f29dbc25Smrg        return (0);
2400f29dbc25Smrg}
2401f29dbc25Smrg
2402f29dbc25Smrg/*-----------------------------------------------------------------------------
2403f29dbc25Smrg * gfx_get_compression_offset
2404f29dbc25Smrg *-----------------------------------------------------------------------------
2405f29dbc25Smrg */
2406f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2407f29dbc25Smrgunsigned long
2408f29dbc25Smrggu1_get_compression_offset(void)
2409f29dbc25Smrg#else
2410f29dbc25Smrgunsigned long
2411f29dbc25Smrggfx_get_compression_offset(void)
2412f29dbc25Smrg#endif
2413f29dbc25Smrg{
2414f29dbc25Smrg    unsigned long offset;
2415f29dbc25Smrg
2416f29dbc25Smrg    offset = READ_REG32(DC_CB_ST_OFFSET) & 0x003FFFFF;
2417f29dbc25Smrg    return (offset);
2418f29dbc25Smrg}
2419f29dbc25Smrg
2420f29dbc25Smrg/*-----------------------------------------------------------------------------
2421f29dbc25Smrg * gfx_get_compression_pitch
2422f29dbc25Smrg *-----------------------------------------------------------------------------
2423f29dbc25Smrg */
2424f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2425f29dbc25Smrgunsigned short
2426f29dbc25Smrggu1_get_compression_pitch(void)
2427f29dbc25Smrg#else
2428f29dbc25Smrgunsigned short
2429f29dbc25Smrggfx_get_compression_pitch(void)
2430f29dbc25Smrg#endif
2431f29dbc25Smrg{
2432f29dbc25Smrg    unsigned short pitch;
2433f29dbc25Smrg
2434f29dbc25Smrg    pitch = (unsigned short)(READ_REG32(DC_LINE_DELTA) >> 12) & 0x03FF;
2435f29dbc25Smrg    return (pitch << 2);
2436f29dbc25Smrg}
2437f29dbc25Smrg
2438f29dbc25Smrg/*-----------------------------------------------------------------------------
2439f29dbc25Smrg * gfx_get_compression_size
2440f29dbc25Smrg *-----------------------------------------------------------------------------
2441f29dbc25Smrg */
2442f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2443f29dbc25Smrgunsigned short
2444f29dbc25Smrggu1_get_compression_size(void)
2445f29dbc25Smrg#else
2446f29dbc25Smrgunsigned short
2447f29dbc25Smrggfx_get_compression_size(void)
2448f29dbc25Smrg#endif
2449f29dbc25Smrg{
2450f29dbc25Smrg    unsigned short size;
2451f29dbc25Smrg
2452f29dbc25Smrg    size = (unsigned short)((READ_REG32(DC_BUF_SIZE) >> 9) & 0x7F) - 1;
2453f29dbc25Smrg    return ((size << 2) + 16);
2454f29dbc25Smrg}
2455f29dbc25Smrg
2456f29dbc25Smrg/*-----------------------------------------------------------------------------
2457f29dbc25Smrg * gfx_get_valid_bit
2458f29dbc25Smrg *-----------------------------------------------------------------------------
2459f29dbc25Smrg */
2460f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2461f29dbc25Smrgint
2462f29dbc25Smrggu1_get_valid_bit(int line)
2463f29dbc25Smrg#else
2464f29dbc25Smrgint
2465f29dbc25Smrggfx_get_valid_bit(int line)
2466f29dbc25Smrg#endif
2467f29dbc25Smrg{
2468f29dbc25Smrg    int valid;
2469f29dbc25Smrg
2470f29dbc25Smrg    WRITE_REG32(MC_DR_ADD, line);
2471f29dbc25Smrg    valid = (int)READ_REG32(MC_DR_ACC) & 1;
2472f29dbc25Smrg    return (valid);
2473f29dbc25Smrg}
2474f29dbc25Smrg
2475f29dbc25Smrg/*---------------------------------------------------------------------------
2476f29dbc25Smrg * gfx_get_display_video_offset (PRIVATE ROUTINE - NOT PART OF API)
2477f29dbc25Smrg *
2478f29dbc25Smrg * This routine is called by "gfx_get_video_offset".  It abstracts the
2479f29dbc25Smrg * version of the display controller from the video overlay routines.
2480f29dbc25Smrg *---------------------------------------------------------------------------
2481f29dbc25Smrg */
2482f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2483f29dbc25Smrgunsigned long
2484f29dbc25Smrggu1_get_display_video_offset(void)
2485f29dbc25Smrg#else
2486f29dbc25Smrgunsigned long
2487f29dbc25Smrggfx_get_display_video_offset(void)
2488f29dbc25Smrg#endif
2489f29dbc25Smrg{
2490f29dbc25Smrg    return (READ_REG32(DC_VID_ST_OFFSET) & 0x003FFFFF);
2491f29dbc25Smrg}
2492f29dbc25Smrg
2493f29dbc25Smrg/*---------------------------------------------------------------------------
2494f29dbc25Smrg * gfx_get_display_video_size (PRIVATE ROUTINE - NOT PART OF API)
2495f29dbc25Smrg *
2496f29dbc25Smrg * This routine is called by "gfx_get_video_size".  It abstracts the
2497f29dbc25Smrg * version of the display controller from the video overlay routines.
2498f29dbc25Smrg *---------------------------------------------------------------------------
2499f29dbc25Smrg */
2500f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2501f29dbc25Smrgunsigned long
2502f29dbc25Smrggu1_get_display_video_size(void)
2503f29dbc25Smrg#else
2504f29dbc25Smrgunsigned long
2505f29dbc25Smrggfx_get_display_video_size(void)
2506f29dbc25Smrg#endif
2507f29dbc25Smrg{
2508f29dbc25Smrg    /* RETURN TOTAL SIZE, IN BYTES */
2509f29dbc25Smrg    return ((READ_REG32(DC_BUF_SIZE) >> 10) & 0x000FFFC0);
2510f29dbc25Smrg}
2511f29dbc25Smrg
2512f29dbc25Smrg/*-----------------------------------------------------------------------------
2513f29dbc25Smrg * gfx_get_display_priority_high
2514f29dbc25Smrg *-----------------------------------------------------------------------------
2515f29dbc25Smrg */
2516f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2517f29dbc25Smrgint
2518f29dbc25Smrggu1_get_display_priority_high(void)
2519f29dbc25Smrg#else
2520f29dbc25Smrgint
2521f29dbc25Smrggfx_get_display_priority_high(void)
2522f29dbc25Smrg#endif
2523f29dbc25Smrg{
2524f29dbc25Smrg    if (READ_REG32(MC_MEM_CNTRL1) & MC_XBUSARB)
2525f29dbc25Smrg        return (1);
2526f29dbc25Smrg    else
2527f29dbc25Smrg        return (0);
2528f29dbc25Smrg}
2529f29dbc25Smrg
2530f29dbc25Smrg#endif /* GFX_READ_ROUTINES */
2531f29dbc25Smrg
2532f29dbc25Smrg/* END OF FILE */
2533