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
2604007ebaSmrgvoid gu1_enable_compression(void);      /* private routine definition */
2704007ebaSmrgvoid gu1_disable_compression(void);     /* private routine definition */
2804007ebaSmrgvoid 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
8604007ebaSmrg    if (total_ticks > ((unsigned long) 0xffffffff - timer_start))
87f29dbc25Smrg        /* wrap-around */
8804007ebaSmrg        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    }
11304007ebaSmrg#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
15504007ebaSmrg#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 */
20404007ebaSmrg    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 */
21304007ebaSmrg    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 */
29804007ebaSmrg    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 */
30804007ebaSmrg    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 */
31204007ebaSmrg    gcfg &= ~(unsigned long) (DC_GCFG_DDCK | DC_GCFG_DPCK | DC_GCFG_DFCK);
31304007ebaSmrg    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;
36604007ebaSmrg    }
36704007ebaSmrg    else {
368f29dbc25Smrg        if (gfx_cpu_version == GFX_CPU_PYRAMID)
369f29dbc25Smrg            pitch = (size <= 2048) ? 2048 : 4096;
370f29dbc25Smrg        else
371f29dbc25Smrg            pitch = 2048;
372f29dbc25Smrg    }
373f29dbc25Smrg
374f29dbc25Smrg    WRITE_REG32(DC_LINE_DELTA, pitch >> 2);
375f29dbc25Smrg
376f29dbc25Smrg    if (PanelEnable) {
377f29dbc25Smrg        size = pMode->hactive;
378f29dbc25Smrg        if (bpp > 8)
379f29dbc25Smrg            size <<= 1;
380f29dbc25Smrg    }
381f29dbc25Smrg
382f29dbc25Smrg    /* ADD 2 TO SIZE FOR POSSIBLE START ADDRESS ALIGNMENTS */
383f29dbc25Smrg    WRITE_REG32(DC_BUF_SIZE, (size >> 3) + 2);
384f29dbc25Smrg
385f29dbc25Smrg    /* ALWAYS ENABLE "PANEL" DATA FROM MEDIAGX */
386f29dbc25Smrg    /* That is really just the 18 BPP data bus to the companion chip */
387f29dbc25Smrg    ocfg = DC_OCFG_PCKE | DC_OCFG_PDEL | DC_OCFG_PDEH;
388f29dbc25Smrg
389f29dbc25Smrg    /* SET PIXEL FORMAT */
390f29dbc25Smrg    if (bpp == 8)
391f29dbc25Smrg        ocfg |= DC_OCFG_8BPP;
392f29dbc25Smrg    else if (bpp == 15)
393f29dbc25Smrg        ocfg |= DC_OCFG_555;
394f29dbc25Smrg
395f29dbc25Smrg    /* ENABLE TIMING GENERATOR, SYNCS, AND FP DATA */
396f29dbc25Smrg    tcfg = DC_TCFG_FPPE | DC_TCFG_HSYE | DC_TCFG_VSYE | DC_TCFG_BLKE |
397f29dbc25Smrg        DC_TCFG_TGEN;
398f29dbc25Smrg
399f29dbc25Smrg    /* SET FIFO PRIORITY, DCLK MULTIPLIER, AND FIFO ENABLE */
400f29dbc25Smrg    /* Default 6/5 for FIFO, 2x for DCLK multiplier. */
40104007ebaSmrg    gcfg = (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
46304007ebaSmrg    value = (unsigned long) (hactive - 1) |
46404007ebaSmrg        (((unsigned long) (pMode->htotal - 1)) << 16);
465f29dbc25Smrg    WRITE_REG32(DC_H_TIMING_1, value);
46604007ebaSmrg    value = (unsigned long) (pMode->hblankstart - 1) |
46704007ebaSmrg        (((unsigned long) (pMode->hblankend - 1)) << 16);
468f29dbc25Smrg    WRITE_REG32(DC_H_TIMING_2, value);
46904007ebaSmrg    value = (unsigned long) (pMode->hsyncstart - 1) |
47004007ebaSmrg        (((unsigned long) (pMode->hsyncend - 1)) << 16);
471f29dbc25Smrg    WRITE_REG32(DC_H_TIMING_3, value);
472f29dbc25Smrg    WRITE_REG32(DC_FP_H_TIMING, value);
47304007ebaSmrg    value = (unsigned long) (vactive - 1) |
47404007ebaSmrg        (((unsigned long) (pMode->vtotal - 1)) << 16);
475f29dbc25Smrg    WRITE_REG32(DC_V_TIMING_1, value);
47604007ebaSmrg    value = (unsigned long) (pMode->vblankstart - 1) |
47704007ebaSmrg        (((unsigned long) (pMode->vblankend - 1)) << 16);
478f29dbc25Smrg    WRITE_REG32(DC_V_TIMING_2, value);
47904007ebaSmrg    value = (unsigned long) (pMode->vsyncstart - 1) |
48004007ebaSmrg        (((unsigned long) (pMode->vsyncend - 1)) << 16);
481f29dbc25Smrg    WRITE_REG32(DC_V_TIMING_3, value);
48204007ebaSmrg    value = (unsigned long) (pMode->vsyncstart - 2) |
48304007ebaSmrg        (((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);
48804007ebaSmrg    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);
49904007ebaSmrg            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) |
50504007ebaSmrg                            ((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
52004007ebaSmrg    WRITE_REG16(GP_BLIT_STATUS, (unsigned short) value);
521f29dbc25Smrg
522f29dbc25Smrg    return GFX_STATUS_OK;
52304007ebaSmrg}                               /* 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)
57404007ebaSmrg            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++) {
57904007ebaSmrg        if ((DisplayParams[mode].hactive == (unsigned short) xres) &&
58004007ebaSmrg            (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) {
61604007ebaSmrg        if (gu1_set_specified_mode(&DisplayParams[mode], bpp) == GFX_STATUS_OK)
617f29dbc25Smrg            return (1);
618f29dbc25Smrg    }
619f29dbc25Smrg    return (0);
620f29dbc25Smrg}
621f29dbc25Smrg
622f29dbc25Smrg/*----------------------------------------------------------------------------
623f29dbc25Smrg * GFX_SET_DISPLAY_TIMINGS
624f29dbc25Smrg *
625f29dbc25Smrg * This routine sets the display controller mode using the specified timing
626f29dbc25Smrg * values (as opposed to using the tables internal to Durango).
627f29dbc25Smrg *
628f29dbc25Smrg * Returns GFX_STATUS_OK on success, GFX_STATUS_ERROR otherwise.
629f29dbc25Smrg *----------------------------------------------------------------------------
630f29dbc25Smrg */
631f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
632f29dbc25Smrgint
633f29dbc25Smrggu1_set_display_timings(unsigned short bpp, unsigned short flags,
63404007ebaSmrg                        unsigned short hactive, unsigned short hblankstart,
63504007ebaSmrg                        unsigned short hsyncstart, unsigned short hsyncend,
63604007ebaSmrg                        unsigned short hblankend, unsigned short htotal,
63704007ebaSmrg                        unsigned short vactive, unsigned short vblankstart,
63804007ebaSmrg                        unsigned short vsyncstart, unsigned short vsyncend,
63904007ebaSmrg                        unsigned short vblankend, unsigned short vtotal,
64004007ebaSmrg                        unsigned long frequency)
641f29dbc25Smrg#else
642f29dbc25Smrgint
643f29dbc25Smrggfx_set_display_timings(unsigned short bpp, unsigned short flags,
64404007ebaSmrg                        unsigned short hactive, unsigned short hblankstart,
64504007ebaSmrg                        unsigned short hsyncstart, unsigned short hsyncend,
64604007ebaSmrg                        unsigned short hblankend, unsigned short htotal,
64704007ebaSmrg                        unsigned short vactive, unsigned short vblankstart,
64804007ebaSmrg                        unsigned short vsyncstart, unsigned short vsyncend,
64904007ebaSmrg                        unsigned short vblankend, unsigned short vtotal,
65004007ebaSmrg                        unsigned long frequency)
651f29dbc25Smrg#endif
652f29dbc25Smrg{
653f29dbc25Smrg    /* SET MODE STRUCTURE WITH SPECIFIED VALUES */
654f29dbc25Smrg
655f29dbc25Smrg    gfx_display_mode.flags = 0;
656f29dbc25Smrg    if (flags & 1)
657f29dbc25Smrg        gfx_display_mode.flags |= GFX_MODE_NEG_HSYNC;
658f29dbc25Smrg    if (flags & 2)
659f29dbc25Smrg        gfx_display_mode.flags |= GFX_MODE_NEG_VSYNC;
660f29dbc25Smrg    if (flags & 0x1000)
661f29dbc25Smrg        gfx_display_mode.flags |= GFX_MODE_LOCK_TIMING;
662f29dbc25Smrg    gfx_display_mode.hactive = hactive;
663f29dbc25Smrg    gfx_display_mode.hblankstart = hblankstart;
664f29dbc25Smrg    gfx_display_mode.hsyncstart = hsyncstart;
665f29dbc25Smrg    gfx_display_mode.hsyncend = hsyncend;
666f29dbc25Smrg    gfx_display_mode.hblankend = hblankend;
667f29dbc25Smrg    gfx_display_mode.htotal = htotal;
668f29dbc25Smrg    gfx_display_mode.vactive = vactive;
669f29dbc25Smrg    gfx_display_mode.vblankstart = vblankstart;
670f29dbc25Smrg    gfx_display_mode.vsyncstart = vsyncstart;
671f29dbc25Smrg    gfx_display_mode.vsyncend = vsyncend;
672f29dbc25Smrg    gfx_display_mode.vblankend = vblankend;
673f29dbc25Smrg    gfx_display_mode.vtotal = vtotal;
674f29dbc25Smrg    gfx_display_mode.frequency = frequency;
675f29dbc25Smrg
676f29dbc25Smrg    /* CALL ROUTINE TO SET MODE */
677f29dbc25Smrg    return (gu1_set_specified_mode(&gfx_display_mode, bpp));
678f29dbc25Smrg}
679f29dbc25Smrg
680f29dbc25Smrg/*----------------------------------------------------------------------------
681f29dbc25Smrg * GFX_SET_VTOTAL
682f29dbc25Smrg *
683f29dbc25Smrg * This routine sets the display controller vertical total to
684f29dbc25Smrg * "vtotal". As a side effect it also sets vertical blank end.
685f29dbc25Smrg * It should be used when only this value needs to be changed,
686f29dbc25Smrg * due to speed considerations.
687f29dbc25Smrg *
688f29dbc25Smrg * Note: it is the caller's responsibility to make sure that
689f29dbc25Smrg * a legal vtotal is used, i.e. that "vtotal" is greater than or
690f29dbc25Smrg * equal to vsync end.
691f29dbc25Smrg *
692f29dbc25Smrg * Always returns 0.
693f29dbc25Smrg *----------------------------------------------------------------------------
694f29dbc25Smrg */
695f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
696f29dbc25Smrgint
697f29dbc25Smrggu1_set_vtotal(unsigned short vtotal)
698f29dbc25Smrg#else
699f29dbc25Smrgint
700f29dbc25Smrggfx_set_vtotal(unsigned short vtotal)
701f29dbc25Smrg#endif
702f29dbc25Smrg{
703f29dbc25Smrg    unsigned long unlock, tcfg, timing1, timing2;
704f29dbc25Smrg
705f29dbc25Smrg    /* UNLOCK THE DISPLAY CONTROLLER REGISTERS */
706f29dbc25Smrg    unlock = READ_REG32(DC_UNLOCK);
707f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
708f29dbc25Smrg
709f29dbc25Smrg    /* READ THE CURRENT GX VALUES */
710f29dbc25Smrg    tcfg = READ_REG32(DC_TIMING_CFG);
711f29dbc25Smrg    timing1 = READ_REG32(DC_V_TIMING_1);
712f29dbc25Smrg    timing2 = READ_REG32(DC_V_TIMING_2);
713f29dbc25Smrg
714f29dbc25Smrg    /* DISABLE THE TIMING GENERATOR */
71504007ebaSmrg    WRITE_REG32(DC_TIMING_CFG, tcfg & ~(unsigned long) DC_TCFG_TGEN);
716f29dbc25Smrg
717f29dbc25Smrg    /* WRITE NEW TIMING VALUES */
718f29dbc25Smrg    WRITE_REG32(DC_V_TIMING_1,
71904007ebaSmrg                (timing1 & 0xffff) | (unsigned long) (vtotal - 1) << 16);
720f29dbc25Smrg    WRITE_REG32(DC_V_TIMING_2,
72104007ebaSmrg                (timing2 & 0xffff) | (unsigned long) (vtotal - 1) << 16);
722f29dbc25Smrg
723f29dbc25Smrg    /* RESTORE GX VALUES */
724f29dbc25Smrg    WRITE_REG32(DC_TIMING_CFG, tcfg);
725f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, unlock);
726f29dbc25Smrg
727f29dbc25Smrg    return (0);
728f29dbc25Smrg}
729f29dbc25Smrg
730f29dbc25Smrg/*---------------------------------------------------------------------------
731f29dbc25Smrg * gfx_set_display_pitch
732f29dbc25Smrg *
733f29dbc25Smrg * This routine sets the pitch of the frame buffer to the specified value.
734f29dbc25Smrg *---------------------------------------------------------------------------
735f29dbc25Smrg */
736f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
737f29dbc25Smrgvoid
738f29dbc25Smrggu1_set_display_pitch(unsigned short pitch)
739f29dbc25Smrg#else
740f29dbc25Smrgvoid
741f29dbc25Smrggfx_set_display_pitch(unsigned short pitch)
742f29dbc25Smrg#endif
743f29dbc25Smrg{
744f29dbc25Smrg    unsigned long value = 0;
745f29dbc25Smrg    unsigned long lock = READ_REG32(DC_UNLOCK);
746f29dbc25Smrg
747f29dbc25Smrg    value = READ_REG32(DC_LINE_DELTA) & 0xFFFFF000;
748f29dbc25Smrg    value |= (pitch >> 2);
749f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
750f29dbc25Smrg    WRITE_REG32(DC_LINE_DELTA, value);
751f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, lock);
752f29dbc25Smrg
753f29dbc25Smrg    /* ALSO UPDATE PITCH IN GRAPHICS ENGINE */
754f29dbc25Smrg    /* Pyramid alone supports 4K line pitch */
75504007ebaSmrg    value = (unsigned long) READ_REG16(GP_BLIT_STATUS);
756f29dbc25Smrg    value &= ~(BC_FB_WIDTH_2048 | BC_FB_WIDTH_4096);
757f29dbc25Smrg
758f29dbc25Smrg    if ((gfx_cpu_version == GFX_CPU_PYRAMID) && (pitch > 2048))
759f29dbc25Smrg        value |= BC_FB_WIDTH_4096;
760f29dbc25Smrg
761f29dbc25Smrg    else if (pitch > 1024)
762f29dbc25Smrg        value |= BC_FB_WIDTH_2048;
763f29dbc25Smrg
76404007ebaSmrg    WRITE_REG16(GP_BLIT_STATUS, (unsigned short) value);
765f29dbc25Smrg    return;
766f29dbc25Smrg}
767f29dbc25Smrg
768f29dbc25Smrg/*---------------------------------------------------------------------------
769f29dbc25Smrg * gfx_set_display_offset
770f29dbc25Smrg *
771f29dbc25Smrg * This routine sets the start address of the frame buffer.  It is
772f29dbc25Smrg * typically used to pan across a virtual desktop (frame buffer larger than
773f29dbc25Smrg * the displayed screen) or to flip the display between multiple buffers.
774f29dbc25Smrg *---------------------------------------------------------------------------
775f29dbc25Smrg */
776f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
777f29dbc25Smrgvoid
778f29dbc25Smrggu1_set_display_offset(unsigned long offset)
779f29dbc25Smrg#else
780f29dbc25Smrgvoid
781f29dbc25Smrggfx_set_display_offset(unsigned long offset)
782f29dbc25Smrg#endif
783f29dbc25Smrg{
784f29dbc25Smrg    /* UPDATE FRAME BUFFER OFFSET */
785f29dbc25Smrg
786f29dbc25Smrg    unsigned long lock;
787f29dbc25Smrg
788f29dbc25Smrg    lock = READ_REG32(DC_UNLOCK);
789f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
790f29dbc25Smrg
791f29dbc25Smrg    /* START ADDRESS EFFECTS DISPLAY COMPRESSION */
79279d5fcd7Smrg    /* Disable compression for non-zero start address values.              */
79379d5fcd7Smrg    /* Enable compression if offset is zero and compression is intended to */
79479d5fcd7Smrg    /* be enabled from a previous call to "gfx_set_compression_enable".    */
79579d5fcd7Smrg    /* Compression should be disabled BEFORE the offset is changed         */
79679d5fcd7Smrg    /* and enabled AFTER the offset is changed.                            */
797f29dbc25Smrg    if (offset == 0) {
798f29dbc25Smrg        WRITE_REG32(DC_FB_ST_OFFSET, offset);
799f29dbc25Smrg        if (gfx_compression_enabled) {
800f29dbc25Smrg            /* WAIT FOR THE OFFSET TO BE LATCHED */
801f29dbc25Smrg            gfx_wait_vertical_blank();
802f29dbc25Smrg            gu1_enable_compression();
803f29dbc25Smrg        }
80404007ebaSmrg    }
80504007ebaSmrg    else {
806f29dbc25Smrg        /* ONLY DISABLE COMPRESSION ONCE */
807f29dbc25Smrg        if (gfx_compression_active)
808f29dbc25Smrg            gu1_disable_compression();
809f29dbc25Smrg
810f29dbc25Smrg        WRITE_REG32(DC_FB_ST_OFFSET, offset);
811f29dbc25Smrg    }
812f29dbc25Smrg
813f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, lock);
814f29dbc25Smrg}
815f29dbc25Smrg
816f29dbc25Smrg/*---------------------------------------------------------------------------
817f29dbc25Smrg * gfx_set_display_palette_entry
818f29dbc25Smrg *
819f29dbc25Smrg * This routine sets an palette entry in the display controller.
820f29dbc25Smrg * A 32-bit X:R:G:B value.
821f29dbc25Smrg *---------------------------------------------------------------------------
822f29dbc25Smrg */
823f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
824f29dbc25Smrgint
825f29dbc25Smrggu1_set_display_palette_entry(unsigned long index, unsigned long palette)
826f29dbc25Smrg#else
827f29dbc25Smrgint
828f29dbc25Smrggfx_set_display_palette_entry(unsigned long index, unsigned long palette)
829f29dbc25Smrg#endif
830f29dbc25Smrg{
831f29dbc25Smrg    unsigned long data;
832f29dbc25Smrg
833f29dbc25Smrg    if (index > 0xFF)
834f29dbc25Smrg        return GFX_STATUS_BAD_PARAMETER;
835f29dbc25Smrg
836f29dbc25Smrg    WRITE_REG32(DC_PAL_ADDRESS, index);
837f29dbc25Smrg    data = ((palette >> 2) & 0x0003F) |
838f29dbc25Smrg        ((palette >> 4) & 0x00FC0) | ((palette >> 6) & 0x3F000);
839f29dbc25Smrg    WRITE_REG32(DC_PAL_DATA, data);
840f29dbc25Smrg
841f29dbc25Smrg    return (0);
842f29dbc25Smrg}
843f29dbc25Smrg
844f29dbc25Smrg/*---------------------------------------------------------------------------
845f29dbc25Smrg * gfx_set_display_palette
846f29dbc25Smrg *
847f29dbc25Smrg * This routine sets the entire palette in the display controller.
848f29dbc25Smrg * A pointer is provided to a 256 entry table of 32-bit X:R:G:B values.
849f29dbc25Smrg *
850f29dbc25Smrg * Restriction:
851f29dbc25Smrg * Due to SC1200 Issue #748 (in Notes DB) this function should be called only
852f29dbc25Smrg * when DCLK is active, i.e PLL is already powered up and genlock is not
853f29dbc25Smrg * active.
854f29dbc25Smrg *---------------------------------------------------------------------------
855f29dbc25Smrg */
856f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
857f29dbc25Smrgint
858f29dbc25Smrggu1_set_display_palette(unsigned long *palette)
859f29dbc25Smrg#else
860f29dbc25Smrgint
861f29dbc25Smrggfx_set_display_palette(unsigned long *palette)
862f29dbc25Smrg#endif
863f29dbc25Smrg{
864f29dbc25Smrg    unsigned long data, i;
865f29dbc25Smrg
866f29dbc25Smrg    WRITE_REG32(DC_PAL_ADDRESS, 0);
867f29dbc25Smrg    if (palette) {
868f29dbc25Smrg        for (i = 0; i < 256; i++) {
869f29dbc25Smrg            /* CONVERT 24 BPP COLOR DATA TO 18 BPP COLOR DATA */
870f29dbc25Smrg            data = ((palette[i] >> 2) & 0x0003F) |
871f29dbc25Smrg                ((palette[i] >> 4) & 0x00FC0) | ((palette[i] >> 6) & 0x3F000);
872f29dbc25Smrg            WRITE_REG32(DC_PAL_DATA, data);
873f29dbc25Smrg        }
874f29dbc25Smrg    }
875f29dbc25Smrg    return (0);
876f29dbc25Smrg}
877f29dbc25Smrg
878f29dbc25Smrg/*---------------------------------------------------------------------------
879f29dbc25Smrg * gfx_set_cursor_enable
880f29dbc25Smrg *
881f29dbc25Smrg * This routine enables or disables the hardware cursor.
882f29dbc25Smrg *
883f29dbc25Smrg * WARNING: The cusrsor start offset must be set by setting the cursor
884f29dbc25Smrg * position before calling this routine to assure that memory reads do not
885f29dbc25Smrg * go past the end of graphics memory (this can hang GXm).
886f29dbc25Smrg *---------------------------------------------------------------------------
887f29dbc25Smrg */
888f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
889f29dbc25Smrgvoid
890f29dbc25Smrggu1_set_cursor_enable(int enable)
891f29dbc25Smrg#else
892f29dbc25Smrgvoid
893f29dbc25Smrggfx_set_cursor_enable(int enable)
894f29dbc25Smrg#endif
895f29dbc25Smrg{
896f29dbc25Smrg    unsigned long unlock, gcfg;
897f29dbc25Smrg
898f29dbc25Smrg    /* SET OR CLEAR CURSOR ENABLE BIT */
899f29dbc25Smrg    unlock = READ_REG32(DC_UNLOCK);
900f29dbc25Smrg    gcfg = READ_REG32(DC_GENERAL_CFG);
901f29dbc25Smrg    if (enable)
902f29dbc25Smrg        gcfg |= DC_GCFG_CURE;
903f29dbc25Smrg    else
904f29dbc25Smrg        gcfg &= ~(DC_GCFG_CURE);
905f29dbc25Smrg
906f29dbc25Smrg    /* WRITE NEW REGISTER VALUE */
907f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
908f29dbc25Smrg    WRITE_REG32(DC_GENERAL_CFG, gcfg);
909f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, unlock);
910f29dbc25Smrg}
911f29dbc25Smrg
912f29dbc25Smrg/*---------------------------------------------------------------------------
913f29dbc25Smrg * gfx_set_cursor_colors
914f29dbc25Smrg *
915f29dbc25Smrg * This routine sets the colors of the hardware cursor.
916f29dbc25Smrg *
917f29dbc25Smrg * Restriction:
918f29dbc25Smrg * Due to SC1200 Issue #748 (in Notes DB) this function should be called only
919f29dbc25Smrg * when DCLK is active, i.e PLL is already powered up.
920f29dbc25Smrg *---------------------------------------------------------------------------
921f29dbc25Smrg */
922f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
923f29dbc25Smrgvoid
924f29dbc25Smrggu1_set_cursor_colors(unsigned long bkcolor, unsigned long fgcolor)
925f29dbc25Smrg#else
926f29dbc25Smrgvoid
927f29dbc25Smrggfx_set_cursor_colors(unsigned long bkcolor, unsigned long fgcolor)
928f29dbc25Smrg#endif
929f29dbc25Smrg{
930f29dbc25Smrg    unsigned long value;
931f29dbc25Smrg
932f29dbc25Smrg    /* If genlock is enabled DCLK might be disabled in vertical blank. */
933f29dbc25Smrg    /* Due to SC1200 Issue #748 in Notes DB this would fail the cursor color settings */
934f29dbc25Smrg    /* So Wait for vertical blank to end */
935f29dbc25Smrg
936f29dbc25Smrg#if GFX_VIDEO_SC1200
937f29dbc25Smrg    if (gfx_test_timing_active())
93804007ebaSmrg        while ((gfx_get_vline()) > gfx_get_vactive());
939f29dbc25Smrg#endif
940f29dbc25Smrg    /* SET CURSOR COLORS */
941f29dbc25Smrg    WRITE_REG32(DC_PAL_ADDRESS, 0x100);
942f29dbc25Smrg    value = ((bkcolor & 0x000000FC) >> 2) |
943f29dbc25Smrg        ((bkcolor & 0x0000FC00) >> (2 + 8 - 6)) |
944f29dbc25Smrg        ((bkcolor & 0x00FC0000) >> (2 + 16 - 12));
945f29dbc25Smrg    WRITE_REG32(DC_PAL_DATA, value);
946f29dbc25Smrg    value = ((fgcolor & 0x000000FC) >> 2) |
947f29dbc25Smrg        ((fgcolor & 0x0000FC00) >> (2 + 8 - 6)) |
948f29dbc25Smrg        ((fgcolor & 0x00FC0000) >> (2 + 16 - 12));
949f29dbc25Smrg    WRITE_REG32(DC_PAL_DATA, value);
950f29dbc25Smrg}
951f29dbc25Smrg
952f29dbc25Smrg/*---------------------------------------------------------------------------
953f29dbc25Smrg * gfx_set_cursor_position
954f29dbc25Smrg *
955f29dbc25Smrg * This routine sets the position of the hardware cusror.  The starting
956f29dbc25Smrg * offset of the cursor buffer must be specified so that the routine can
957f29dbc25Smrg * properly clip scanlines if the cursor is off the top of the screen.
958f29dbc25Smrg *---------------------------------------------------------------------------
959f29dbc25Smrg */
960f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
961f29dbc25Smrgvoid
962f29dbc25Smrggu1_set_cursor_position(unsigned long memoffset,
96304007ebaSmrg                        unsigned short xpos, unsigned short ypos,
96404007ebaSmrg                        unsigned short xhotspot, unsigned short yhotspot)
965f29dbc25Smrg#else
966f29dbc25Smrgvoid
967f29dbc25Smrggfx_set_cursor_position(unsigned long memoffset,
96804007ebaSmrg                        unsigned short xpos, unsigned short ypos,
96904007ebaSmrg                        unsigned short xhotspot, unsigned short yhotspot)
970f29dbc25Smrg#endif
971f29dbc25Smrg{
972f29dbc25Smrg    unsigned long unlock;
973f29dbc25Smrg
974f29dbc25Smrg    short x, y;
975f29dbc25Smrg    short xoffset = 0;
976f29dbc25Smrg    short yoffset = 0;
977f29dbc25Smrg
978f29dbc25Smrg    /* SUPPORT CURSOR IN EMULATED VGA MODES */
979f29dbc25Smrg    /* Timings are for twice the resolution */
980f29dbc25Smrg    if (gfx_pixel_double)
981f29dbc25Smrg        xpos <<= 1;
982f29dbc25Smrg
983f29dbc25Smrg    if (gfx_line_double)
984f29dbc25Smrg        ypos <<= 1;
985f29dbc25Smrg
98604007ebaSmrg    x = (short) xpos - (short) xhotspot;
98704007ebaSmrg    y = (short) ypos - (short) yhotspot;
988f29dbc25Smrg    if (x < -31)
989f29dbc25Smrg        return;
990f29dbc25Smrg
991f29dbc25Smrg    if (y < -31)
992f29dbc25Smrg        return;
993f29dbc25Smrg
994f29dbc25Smrg    if (x < 0) {
995f29dbc25Smrg        xoffset = -x;
996f29dbc25Smrg        x = 0;
997f29dbc25Smrg    }
998f29dbc25Smrg
999f29dbc25Smrg    if (y < 0) {
1000f29dbc25Smrg        yoffset = -y;
1001f29dbc25Smrg        y = 0;
1002f29dbc25Smrg    }
1003f29dbc25Smrg
100404007ebaSmrg    memoffset += (unsigned long) yoffset << 3;
1005f29dbc25Smrg
1006f29dbc25Smrg    if (PanelEnable) {
1007f29dbc25Smrg        if ((ModeWidth > PanelWidth) || (ModeHeight > PanelHeight)) {
1008f29dbc25Smrg            gfx_enable_panning(xpos, ypos);
100904007ebaSmrg            x = x - (short) panelLeft;
101004007ebaSmrg            y = y - (short) panelTop;
1011f29dbc25Smrg        }
1012f29dbc25Smrg    }
1013f29dbc25Smrg
1014f29dbc25Smrg    /* SET CURSOR POSITION */
1015f29dbc25Smrg    unlock = READ_REG32(DC_UNLOCK);
1016f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
1017f29dbc25Smrg    WRITE_REG32(DC_CURS_ST_OFFSET, memoffset);
101804007ebaSmrg    WRITE_REG32(DC_CURSOR_X, (unsigned long) x |
101904007ebaSmrg                (((unsigned long) xoffset) << 11));
102004007ebaSmrg    WRITE_REG32(DC_CURSOR_Y, (unsigned long) y |
102104007ebaSmrg                (((unsigned long) yoffset) << 11));
1022f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, unlock);
1023f29dbc25Smrg}
1024f29dbc25Smrg
1025f29dbc25Smrg/*---------------------------------------------------------------------------
1026f29dbc25Smrg * gfx_set_cursor_shape32
1027f29dbc25Smrg *
1028f29dbc25Smrg * This routine loads 32x32 cursor data into the specified location in
1029f29dbc25Smrg * graphics memory.
1030f29dbc25Smrg *---------------------------------------------------------------------------
1031f29dbc25Smrg */
1032f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1033f29dbc25Smrgvoid
1034f29dbc25Smrggu1_set_cursor_shape32(unsigned long memoffset,
103504007ebaSmrg                       unsigned long *andmask, unsigned long *xormask)
1036f29dbc25Smrg#else
1037f29dbc25Smrgvoid
1038f29dbc25Smrggfx_set_cursor_shape32(unsigned long memoffset,
103904007ebaSmrg                       unsigned long *andmask, unsigned long *xormask)
1040f29dbc25Smrg#endif
1041f29dbc25Smrg{
1042f29dbc25Smrg    int i;
1043f29dbc25Smrg    unsigned long value;
1044f29dbc25Smrg
1045f29dbc25Smrg    for (i = 0; i < 32; i++) {
1046f29dbc25Smrg        /* CONVERT TO 16 BITS AND MASK, 16 BITS XOR MASK PER DWORD */
1047f29dbc25Smrg        value = (andmask[i] & 0xFFFF0000) | (xormask[i] >> 16);
1048f29dbc25Smrg        WRITE_FB32(memoffset, value);
1049f29dbc25Smrg        memoffset += 4;
1050f29dbc25Smrg        value = (andmask[i] << 16) | (xormask[i] & 0x0000FFFF);
1051f29dbc25Smrg        WRITE_FB32(memoffset, value);
1052f29dbc25Smrg        memoffset += 4;
1053f29dbc25Smrg    }
1054f29dbc25Smrg}
1055f29dbc25Smrg
1056f29dbc25Smrg/*---------------------------------------------------------------------------
1057f29dbc25Smrg * gu1_enable_compression
1058f29dbc25Smrg *
1059f29dbc25Smrg * This is a private routine to this module (not exposed in the Durango API).
1060f29dbc25Smrg * It enables display compression.
1061f29dbc25Smrg *---------------------------------------------------------------------------
1062f29dbc25Smrg */
1063f29dbc25Smrgvoid
1064f29dbc25Smrggu1_enable_compression(void)
1065f29dbc25Smrg{
1066f29dbc25Smrg    int i;
1067f29dbc25Smrg    unsigned long unlock, gcfg, offset;
1068f29dbc25Smrg
1069f29dbc25Smrg    /* DO NOT ENABLE IF START ADDRESS IS NOT ZERO */
1070f29dbc25Smrg    offset = READ_REG32(DC_FB_ST_OFFSET) & 0x003FFFFF;
1071f29dbc25Smrg    if (offset != 0)
1072f29dbc25Smrg        return;
1073f29dbc25Smrg
1074f29dbc25Smrg    /* DO NOT ENABLE IF WE ARE WITHIN AN EMULATED VGA MODE */
1075f29dbc25Smrg    if (gfx_line_double || gfx_pixel_double)
1076f29dbc25Smrg        return;
1077f29dbc25Smrg
1078f29dbc25Smrg    /* SET GLOBAL INDICATOR */
1079f29dbc25Smrg    gfx_compression_active = 1;
1080f29dbc25Smrg
1081f29dbc25Smrg    /* CLEAR DIRTY/VALID BITS IN MEMORY CONTROLLER */
1082f29dbc25Smrg    /* Software is required to do this before enabling compression. */
1083f29dbc25Smrg    /* Don't want controller to think that old lines are still valid. */
1084f29dbc25Smrg    for (i = 0; i < 1024; i++) {
1085f29dbc25Smrg        WRITE_REG32(MC_DR_ADD, i);
1086f29dbc25Smrg        WRITE_REG32(MC_DR_ACC, 0);
1087f29dbc25Smrg    }
1088f29dbc25Smrg
1089f29dbc25Smrg    /* TURN ON COMPRESSION CONTROL BITS */
1090f29dbc25Smrg    unlock = READ_REG32(DC_UNLOCK);
1091f29dbc25Smrg    gcfg = READ_REG32(DC_GENERAL_CFG);
1092f29dbc25Smrg    gcfg |= DC_GCFG_CMPE | DC_GCFG_DECE;
1093f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
1094f29dbc25Smrg    WRITE_REG32(DC_GENERAL_CFG, gcfg);
1095f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, unlock);
1096f29dbc25Smrg}
1097f29dbc25Smrg
1098f29dbc25Smrg/*---------------------------------------------------------------------------
1099f29dbc25Smrg * gu1_disable_compression
1100f29dbc25Smrg *
1101f29dbc25Smrg * This is a private routine to this module (not exposed in the Durango API).
1102f29dbc25Smrg * It disables display compression.
1103f29dbc25Smrg *---------------------------------------------------------------------------
1104f29dbc25Smrg */
1105f29dbc25Smrgvoid
1106f29dbc25Smrggu1_disable_compression(void)
1107f29dbc25Smrg{
1108f29dbc25Smrg    unsigned long unlock, gcfg;
1109f29dbc25Smrg
1110f29dbc25Smrg    /* SET GLOBAL INDICATOR */
1111f29dbc25Smrg    gfx_compression_active = 0;
1112f29dbc25Smrg
1113f29dbc25Smrg    /* TURN OFF COMPRESSION CONTROL BITS */
1114f29dbc25Smrg    unlock = READ_REG32(DC_UNLOCK);
1115f29dbc25Smrg    gcfg = READ_REG32(DC_GENERAL_CFG);
1116f29dbc25Smrg    gcfg &= ~(DC_GCFG_CMPE | DC_GCFG_DECE);
1117f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
1118f29dbc25Smrg    WRITE_REG32(DC_GENERAL_CFG, gcfg);
1119f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, unlock);
1120f29dbc25Smrg}
1121f29dbc25Smrg
1122f29dbc25Smrg/*---------------------------------------------------------------------------
1123f29dbc25Smrg * gfx_set_compression_enable
1124f29dbc25Smrg *
1125f29dbc25Smrg * This routine enables or disables display compression.
1126f29dbc25Smrg *---------------------------------------------------------------------------
1127f29dbc25Smrg */
1128f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1129f29dbc25Smrgint
1130f29dbc25Smrggu1_set_compression_enable(int enable)
1131f29dbc25Smrg#else
1132f29dbc25Smrgint
1133f29dbc25Smrggfx_set_compression_enable(int enable)
1134f29dbc25Smrg#endif
1135f29dbc25Smrg{
1136f29dbc25Smrg    /* SET GLOBAL VARIABLE FOR INTENDED STATE */
1137f29dbc25Smrg    /* Compression can only be enabled for non-zero start address values. */
1138f29dbc25Smrg    /* Keep state to enable compression on start address changes. */
1139f29dbc25Smrg    gfx_compression_enabled = enable;
1140f29dbc25Smrg    if (enable)
1141f29dbc25Smrg        gu1_enable_compression();
1142f29dbc25Smrg    else
1143f29dbc25Smrg        gu1_disable_compression();
1144f29dbc25Smrg
1145f29dbc25Smrg    return (0);
1146f29dbc25Smrg}
1147f29dbc25Smrg
1148f29dbc25Smrg/*---------------------------------------------------------------------------
1149f29dbc25Smrg * gfx_set_compression_offset
1150f29dbc25Smrg *
1151f29dbc25Smrg * This routine sets the base offset for the compression buffer.
1152f29dbc25Smrg *---------------------------------------------------------------------------
1153f29dbc25Smrg */
1154f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1155f29dbc25Smrgint
1156f29dbc25Smrggu1_set_compression_offset(unsigned long offset)
1157f29dbc25Smrg#else
1158f29dbc25Smrgint
1159f29dbc25Smrggfx_set_compression_offset(unsigned long offset)
1160f29dbc25Smrg#endif
1161f29dbc25Smrg{
1162f29dbc25Smrg    unsigned long lock;
1163f29dbc25Smrg
1164f29dbc25Smrg    /* MUST BE 16-BYTE ALIGNED FOR GXLV */
1165f29dbc25Smrg    if (offset & 0x0F)
1166f29dbc25Smrg        return (1);
1167f29dbc25Smrg
1168f29dbc25Smrg    /* SET REGISTER VALUE */
1169f29dbc25Smrg    lock = READ_REG32(DC_UNLOCK);
1170f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
1171f29dbc25Smrg    WRITE_REG32(DC_CB_ST_OFFSET, offset);
1172f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, lock);
1173f29dbc25Smrg    return (0);
1174f29dbc25Smrg}
1175f29dbc25Smrg
1176f29dbc25Smrg/*---------------------------------------------------------------------------
1177f29dbc25Smrg * gfx_set_compression_pitch
1178f29dbc25Smrg *
1179f29dbc25Smrg * This routine sets the pitch, in bytes, of the compression buffer.
1180f29dbc25Smrg *---------------------------------------------------------------------------
1181f29dbc25Smrg */
1182f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1183f29dbc25Smrgint
1184f29dbc25Smrggu1_set_compression_pitch(unsigned short pitch)
1185f29dbc25Smrg#else
1186f29dbc25Smrgint
1187f29dbc25Smrggfx_set_compression_pitch(unsigned short pitch)
1188f29dbc25Smrg#endif
1189f29dbc25Smrg{
1190f29dbc25Smrg    unsigned long lock, line_delta;
1191f29dbc25Smrg
1192f29dbc25Smrg    /* SET REGISTER VALUE */
1193f29dbc25Smrg    lock = READ_REG32(DC_UNLOCK);
1194f29dbc25Smrg    line_delta = READ_REG32(DC_LINE_DELTA) & 0xFF800FFF;
119504007ebaSmrg    line_delta |= ((unsigned long) pitch << 10l) & 0x007FF000;
1196f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
1197f29dbc25Smrg    WRITE_REG32(DC_LINE_DELTA, line_delta);
1198f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, lock);
1199f29dbc25Smrg    return (0);
1200f29dbc25Smrg}
1201f29dbc25Smrg
1202f29dbc25Smrg/*---------------------------------------------------------------------------
1203f29dbc25Smrg * gfx_set_compression_size
1204f29dbc25Smrg *
1205f29dbc25Smrg * This routine sets the line size of the compression buffer, which is the
1206f29dbc25Smrg * maximum number of bytes allowed to store a compressed line.
1207f29dbc25Smrg *---------------------------------------------------------------------------
1208f29dbc25Smrg */
1209f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1210f29dbc25Smrgint
1211f29dbc25Smrggu1_set_compression_size(unsigned short size)
1212f29dbc25Smrg#else
1213f29dbc25Smrgint
1214f29dbc25Smrggfx_set_compression_size(unsigned short size)
1215f29dbc25Smrg#endif
1216f29dbc25Smrg{
1217f29dbc25Smrg    unsigned long lock, buf_size;
1218f29dbc25Smrg
1219f29dbc25Smrg    /* SUBTRACT 16 FROM SIZE                          */
1220f29dbc25Smrg    /* The display controller will actually write     */
1221f29dbc25Smrg    /* 2 extra QWords.  So, if we assume that "size"  */
1222f29dbc25Smrg    /* refers to the allocated size, we must subtract */
1223f29dbc25Smrg    /* 16 bytes.                                      */
1224f29dbc25Smrg    size -= 16;
1225f29dbc25Smrg
1226f29dbc25Smrg    /* SET REGISTER VALUE */
1227f29dbc25Smrg    lock = READ_REG32(DC_UNLOCK);
1228f29dbc25Smrg    buf_size = READ_REG32(DC_BUF_SIZE) & 0xFFFF01FF;
1229f29dbc25Smrg    buf_size |= (((size >> 2) + 1) & 0x7F) << 9;
1230f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
1231f29dbc25Smrg    WRITE_REG32(DC_BUF_SIZE, buf_size);
1232f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, lock);
1233f29dbc25Smrg    return (0);
1234f29dbc25Smrg}
1235f29dbc25Smrg
1236f29dbc25Smrg/*---------------------------------------------------------------------------
1237f29dbc25Smrg * gfx_set_display_video_enable (PRIVATE ROUTINE - NOT PART OF API)
1238f29dbc25Smrg *
1239f29dbc25Smrg * This routine enables/disables video on GX.
1240f29dbc25Smrg *---------------------------------------------------------------------------
1241f29dbc25Smrg */
1242f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1243f29dbc25Smrgvoid
1244f29dbc25Smrggu1_set_display_video_enable(int enable)
1245f29dbc25Smrg#else
1246f29dbc25Smrgvoid
1247f29dbc25Smrggfx_set_display_video_enable(int enable)
1248f29dbc25Smrg#endif
1249f29dbc25Smrg{
1250f29dbc25Smrg    unsigned long lock, gcfg, buf_size;
1251f29dbc25Smrg
1252f29dbc25Smrg    lock = READ_REG32(DC_UNLOCK);
1253f29dbc25Smrg    gcfg = READ_REG32(DC_GENERAL_CFG);
1254f29dbc25Smrg    buf_size = READ_REG32(DC_BUF_SIZE);
1255f29dbc25Smrg
1256f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
1257f29dbc25Smrg
1258f29dbc25Smrg    vid_enabled = enable;
1259f29dbc25Smrg
1260f29dbc25Smrg    /* SET THE BUFFER SIZE TO A NON-ZERO VALUE ONLY WHEN */
1261f29dbc25Smrg    /* ENABLING VIDEO                                    */
1262f29dbc25Smrg    if (enable) {
1263f29dbc25Smrg        gcfg |= (DC_GCFG_VIDE | DC_GCFG_VRDY);
1264f29dbc25Smrg        WRITE_REG32(DC_GENERAL_CFG, gcfg);
1265f29dbc25Smrg
1266f29dbc25Smrg        WRITE_REG32(DC_BUF_SIZE, (buf_size & 0x0000FFFFl) | vid_buf_size);
1267f29dbc25Smrg    }
1268f29dbc25Smrg    /* CLEAR THE VIDEO BUFFER SIZE WHEN DISABLING VIDEO  */
1269f29dbc25Smrg    else {
1270f29dbc25Smrg        gcfg &= ~(DC_GCFG_VIDE);
1271f29dbc25Smrg        WRITE_REG32(DC_GENERAL_CFG, gcfg);
1272f29dbc25Smrg
1273f29dbc25Smrg        vid_buf_size = buf_size & 0xFFFF0000l;
1274f29dbc25Smrg        WRITE_REG32(DC_BUF_SIZE, buf_size & 0x0000FFFFl);
1275f29dbc25Smrg    }
1276f29dbc25Smrg
1277f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, lock);
1278f29dbc25Smrg    return;
1279f29dbc25Smrg}
1280f29dbc25Smrg
1281f29dbc25Smrg/*---------------------------------------------------------------------------
1282f29dbc25Smrg * gfx_set_display_video_size (PRIVATE ROUTINE - NOT PART OF API)
1283f29dbc25Smrg *
1284f29dbc25Smrg * This routine is called by "gfx_set_video_size".  It abstracts the
1285f29dbc25Smrg * version of the display controller from the video overlay routines.
1286f29dbc25Smrg *---------------------------------------------------------------------------
1287f29dbc25Smrg */
1288f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1289f29dbc25Smrgvoid
1290f29dbc25Smrggu1_set_display_video_size(unsigned short width, unsigned short height)
1291f29dbc25Smrg#else
1292f29dbc25Smrgvoid
1293f29dbc25Smrggfx_set_display_video_size(unsigned short width, unsigned short height)
1294f29dbc25Smrg#endif
1295f29dbc25Smrg{
1296f29dbc25Smrg    unsigned long lock, size, value;
1297f29dbc25Smrg
129804007ebaSmrg    size = (unsigned long) (width << 1) * (unsigned long) height;
1299f29dbc25Smrg
1300f29dbc25Smrg    /* STORE THE VIDEO BUFFER SIZE AS A GLOBAL */
1301f29dbc25Smrg    vid_buf_size = ((size + 63) >> 6) << 16;
1302f29dbc25Smrg
1303f29dbc25Smrg    lock = READ_REG32(DC_UNLOCK);
1304f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
1305f29dbc25Smrg    value = READ_REG32(DC_BUF_SIZE) & 0x0000FFFF;
1306f29dbc25Smrg    value |= vid_buf_size;
1307f29dbc25Smrg    WRITE_REG32(DC_BUF_SIZE, value);
1308f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, lock);
1309f29dbc25Smrg}
1310f29dbc25Smrg
1311f29dbc25Smrg/*---------------------------------------------------------------------------
1312f29dbc25Smrg * gfx_set_display_video_offset (PRIVATE ROUTINE - NOT PART OF API)
1313f29dbc25Smrg *
1314f29dbc25Smrg * This routine is called by "gfx_set_video_offset".  It abstracts the
1315f29dbc25Smrg * version of the display controller from the video overlay routines.
1316f29dbc25Smrg *---------------------------------------------------------------------------
1317f29dbc25Smrg */
1318f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1319f29dbc25Smrgvoid
1320f29dbc25Smrggu1_set_display_video_offset(unsigned long offset)
1321f29dbc25Smrg#else
1322f29dbc25Smrgvoid
1323f29dbc25Smrggfx_set_display_video_offset(unsigned long offset)
1324f29dbc25Smrg#endif
1325f29dbc25Smrg{
1326f29dbc25Smrg    unsigned long lock;
1327f29dbc25Smrg
1328f29dbc25Smrg    lock = READ_REG32(DC_UNLOCK);
1329f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
1330f29dbc25Smrg    offset &= 0x003FFFFF;
1331f29dbc25Smrg    WRITE_REG32(DC_VID_ST_OFFSET, offset);
1332f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, lock);
1333f29dbc25Smrg}
1334f29dbc25Smrg
1335f29dbc25Smrg/*---------------------------------------------------------------------------
1336f29dbc25Smrg * gfx_set_display_priority_high
1337f29dbc25Smrg *
1338f29dbc25Smrg * This routine controls the x-bus round robin arbitration mechanism.
1339f29dbc25Smrg * When enable is TRUE, graphics pipeline requests and non-critical display
1340f29dbc25Smrg * controller requests are arbitrated at the same priority as processor
1341f29dbc25Smrg * requests. When FALSE processor requests are arbitrated at a higher priority
1342f29dbc25Smrg *---------------------------------------------------------------------------
1343f29dbc25Smrg */
1344f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1345f29dbc25Smrgvoid
1346f29dbc25Smrggu1_set_display_priority_high(int enable)
1347f29dbc25Smrg#else
1348f29dbc25Smrgvoid
1349f29dbc25Smrggfx_set_display_priority_high(int enable)
1350f29dbc25Smrg#endif
1351f29dbc25Smrg{
1352f29dbc25Smrg    unsigned long lock, control;
1353f29dbc25Smrg
1354f29dbc25Smrg    lock = READ_REG32(DC_UNLOCK);
1355f29dbc25Smrg    control = READ_REG32(MC_MEM_CNTRL1);
1356f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
1357f29dbc25Smrg    if (enable)
1358f29dbc25Smrg        control |= MC_XBUSARB;
1359f29dbc25Smrg    else
1360f29dbc25Smrg        control &= ~(MC_XBUSARB);
1361f29dbc25Smrg    WRITE_REG32(MC_MEM_CNTRL1, control);
1362f29dbc25Smrg    WRITE_REG32(DC_UNLOCK, lock);
1363f29dbc25Smrg    return;
1364f29dbc25Smrg}
1365f29dbc25Smrg
1366f29dbc25Smrg/*---------------------------------------------------------------------------
1367f29dbc25Smrg * gfx_test_timing_active
1368f29dbc25Smrg *---------------------------------------------------------------------------
1369f29dbc25Smrg */
1370f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1371f29dbc25Smrgint
1372f29dbc25Smrggu1_test_timing_active(void)
1373f29dbc25Smrg#else
1374f29dbc25Smrgint
1375f29dbc25Smrggfx_test_timing_active(void)
1376f29dbc25Smrg#endif
1377f29dbc25Smrg{
1378f29dbc25Smrg    if (READ_REG32(DC_TIMING_CFG) & DC_TCFG_TGEN)
1379f29dbc25Smrg        return (1);
1380f29dbc25Smrg    else
1381f29dbc25Smrg        return (0);
1382f29dbc25Smrg}
1383f29dbc25Smrg
1384f29dbc25Smrg/*---------------------------------------------------------------------------
1385f29dbc25Smrg * gfx_test_vertical_active
1386f29dbc25Smrg *---------------------------------------------------------------------------
1387f29dbc25Smrg */
1388f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1389f29dbc25Smrgint
1390f29dbc25Smrggu1_test_vertical_active(void)
1391f29dbc25Smrg#else
1392f29dbc25Smrgint
1393f29dbc25Smrggfx_test_vertical_active(void)
1394f29dbc25Smrg#endif
1395f29dbc25Smrg{
1396f29dbc25Smrg    if (READ_REG32(DC_TIMING_CFG) & DC_TCFG_VNA)
1397f29dbc25Smrg        return (0);
1398f29dbc25Smrg    else
1399f29dbc25Smrg        return (1);
1400f29dbc25Smrg}
1401f29dbc25Smrg
1402f29dbc25Smrg/*---------------------------------------------------------------------------
1403f29dbc25Smrg * gfx_wait_vertical_blank
1404f29dbc25Smrg *---------------------------------------------------------------------------
1405f29dbc25Smrg */
1406f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1407f29dbc25Smrgint
1408f29dbc25Smrggu1_wait_vertical_blank(void)
1409f29dbc25Smrg#else
1410f29dbc25Smrgint
1411f29dbc25Smrggfx_wait_vertical_blank(void)
1412f29dbc25Smrg#endif
1413f29dbc25Smrg{
1414f29dbc25Smrg    if (gfx_test_timing_active()) {
141504007ebaSmrg        while (!gfx_test_vertical_active());
141604007ebaSmrg        while (gfx_test_vertical_active());
1417f29dbc25Smrg    }
1418f29dbc25Smrg
1419f29dbc25Smrg    return (0);
1420f29dbc25Smrg}
1421f29dbc25Smrg
1422f29dbc25Smrg/*---------------------------------------------------------------------------
1423f29dbc25Smrg * gfx_enable_panning
1424f29dbc25Smrg *
1425f29dbc25Smrg * This routine  enables the panning when the Mode is bigger than the panel
1426f29dbc25Smrg * size.
1427f29dbc25Smrg *---------------------------------------------------------------------------
1428f29dbc25Smrg */
1429f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1430f29dbc25Smrgvoid
1431f29dbc25Smrggu1_enable_panning(int x, int y)
1432f29dbc25Smrg#else
1433f29dbc25Smrgvoid
1434f29dbc25Smrggfx_enable_panning(int x, int y)
1435f29dbc25Smrg#endif
1436f29dbc25Smrg{
1437f29dbc25Smrg    unsigned long modeBytesPerPixel;
1438f29dbc25Smrg    unsigned long modeBytesPerScanline = 0;
1439f29dbc25Smrg    unsigned long startAddress = 0;
1440f29dbc25Smrg
1441f29dbc25Smrg    modeBytesPerPixel = (gbpp + 7) / 8;
1442f29dbc25Smrg    modeBytesPerScanline =
1443f29dbc25Smrg        (((ModeWidth + 1023) / 1024) * 1024) * modeBytesPerPixel;
1444f29dbc25Smrg
1445f29dbc25Smrg    /* TEST FOR NO-WORK */
144604007ebaSmrg    if (x >= DeltaX && (unsigned short) x < (PanelWidth + DeltaX) &&
144704007ebaSmrg        y >= DeltaY && (unsigned short) y < (PanelHeight + DeltaY))
1448f29dbc25Smrg        return;
1449f29dbc25Smrg
1450f29dbc25Smrg    /* ADJUST PANNING VARIABLES WHEN CURSOR EXCEEDS BOUNDARY       */
1451f29dbc25Smrg    /* Test the boundary conditions for each coordinate and update */
1452f29dbc25Smrg    /* all variables and the starting offset accordingly.          */
1453f29dbc25Smrg    if (x < DeltaX)
1454f29dbc25Smrg        DeltaX = x;
145504007ebaSmrg    else if ((unsigned short) x >= (DeltaX + PanelWidth))
1456f29dbc25Smrg        DeltaX = x - PanelWidth + 1;
1457f29dbc25Smrg
1458f29dbc25Smrg    if (y < DeltaY)
1459f29dbc25Smrg        DeltaY = y;
146004007ebaSmrg    else if ((unsigned short) y >= (DeltaY + PanelHeight))
1461f29dbc25Smrg        DeltaY = y - PanelHeight + 1;
1462f29dbc25Smrg
1463f29dbc25Smrg    /* CALCULATE THE START OFFSET */
1464f29dbc25Smrg    startAddress =
1465f29dbc25Smrg        (DeltaX * modeBytesPerPixel) + (DeltaY * modeBytesPerScanline);
1466f29dbc25Smrg
1467f29dbc25Smrg    gfx_set_display_offset(startAddress);
1468f29dbc25Smrg
1469f29dbc25Smrg    /* SET PANEL COORDINATES                    */
1470f29dbc25Smrg    /* Panel's x position must be DWORD aligned */
1471f29dbc25Smrg    panelTop = DeltaY;
1472f29dbc25Smrg    panelLeft = DeltaX * modeBytesPerPixel;
1473f29dbc25Smrg
1474f29dbc25Smrg    if (panelLeft & 3)
1475f29dbc25Smrg        panelLeft = (panelLeft & 0xFFFFFFFC) + 4;
1476f29dbc25Smrg
1477f29dbc25Smrg    panelLeft /= modeBytesPerPixel;
1478f29dbc25Smrg
1479f29dbc25Smrg}
1480f29dbc25Smrg
1481f29dbc25Smrg/*---------------------------------------------------------------------------
1482f29dbc25Smrg * gfx_set_fixed_timings
1483f29dbc25Smrg *---------------------------------------------------------------------------
1484f29dbc25Smrg */
1485f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1486f29dbc25Smrgint
1487f29dbc25Smrggu1_set_fixed_timings(int panelResX, int panelResY, unsigned short width,
148804007ebaSmrg                      unsigned short height, unsigned short bpp)
1489f29dbc25Smrg#else
1490f29dbc25Smrgint
1491f29dbc25Smrggfx_set_fixed_timings(int panelResX, int panelResY, unsigned short width,
149204007ebaSmrg                      unsigned short height, unsigned short bpp)
1493f29dbc25Smrg#endif
1494f29dbc25Smrg{
1495f29dbc25Smrg    unsigned int mode;
1496f29dbc25Smrg
1497f29dbc25Smrg    ModeWidth = width;
1498f29dbc25Smrg    ModeHeight = height;
149904007ebaSmrg    PanelWidth = (unsigned short) panelResX;
150004007ebaSmrg    PanelHeight = (unsigned short) panelResY;
1501f29dbc25Smrg    PanelEnable = 1;
1502f29dbc25Smrg
1503f29dbc25Smrg    /* LOOP THROUGH THE AVAILABLE MODES TO FIND A MATCH */
1504f29dbc25Smrg    for (mode = 0; mode < NUM_FIXED_TIMINGS_MODES; mode++) {
1505f29dbc25Smrg        if ((FixedParams[mode].xres == width) &&
1506f29dbc25Smrg            (FixedParams[mode].yres == height) &&
1507f29dbc25Smrg            (FixedParams[mode].panelresx == panelResX) &&
1508f29dbc25Smrg            (FixedParams[mode].panelresy == panelResY)) {
1509f29dbc25Smrg
1510f29dbc25Smrg            /* SET THE 92xx FOR THE SELECTED MODE */
1511f29dbc25Smrg            FIXEDTIMINGS *fmode = &FixedParams[mode];
1512f29dbc25Smrg
1513f29dbc25Smrg            gfx_set_display_timings(bpp, 3, fmode->hactive,
151404007ebaSmrg                                    fmode->hblankstart, fmode->hsyncstart,
151504007ebaSmrg                                    fmode->hsyncend, fmode->hblankend,
151604007ebaSmrg                                    fmode->htotal, fmode->vactive,
151704007ebaSmrg                                    fmode->vblankstart, fmode->vsyncstart,
151804007ebaSmrg                                    fmode->vsyncend, fmode->vblankend,
151904007ebaSmrg                                    fmode->vtotal, fmode->frequency);
1520f29dbc25Smrg
1521f29dbc25Smrg            return (1);
152204007ebaSmrg        }                       /* end if() */
152304007ebaSmrg    }                           /* end for() */
1524f29dbc25Smrg
1525f29dbc25Smrg    return (-1);
1526f29dbc25Smrg}
1527f29dbc25Smrg
1528f29dbc25Smrg/*---------------------------------------------------------------------------
1529f29dbc25Smrg * gfx_set_panel_present
1530f29dbc25Smrg *---------------------------------------------------------------------------
1531f29dbc25Smrg */
1532f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1533f29dbc25Smrgint
1534f29dbc25Smrggu1_set_panel_present(int panelResX, int panelResY, unsigned short width,
153504007ebaSmrg                      unsigned short height, unsigned short bpp)
1536f29dbc25Smrg#else
1537f29dbc25Smrgint
1538f29dbc25Smrggfx_set_panel_present(int panelResX, int panelResY, unsigned short width,
153904007ebaSmrg                      unsigned short height, unsigned short bpp)
1540f29dbc25Smrg#endif
1541f29dbc25Smrg{
1542f29dbc25Smrg    /* SET VALID BPP         */
1543f29dbc25Smrg    /* 16BPP is the default. */
1544f29dbc25Smrg    if (bpp != 8 && bpp != 15 && bpp != 16)
1545f29dbc25Smrg        bpp = 16;
1546f29dbc25Smrg
1547f29dbc25Smrg    /* RECORD PANEL PARAMETERS */
1548f29dbc25Smrg    /* This routine does not touch any panel timings.  It is used when custom
1549f29dbc25Smrg     * panel settings are set up in advance by the BIOS or an application, but
1550f29dbc25Smrg     * the application still requires access to other panel functionality
1551f29dbc25Smrg     * provided by Durango (i.e. panning)
1552f29dbc25Smrg     * */
1553f29dbc25Smrg
1554f29dbc25Smrg    ModeWidth = width;
1555f29dbc25Smrg    ModeHeight = height;
155604007ebaSmrg    PanelWidth = (unsigned short) panelResX;
155704007ebaSmrg    PanelHeight = (unsigned short) panelResY;
1558f29dbc25Smrg    PanelEnable = 1;
1559f29dbc25Smrg    gbpp = bpp;
1560f29dbc25Smrg
1561f29dbc25Smrg    /* PROGRAM THE BPP IN THE DISPLAY CONTROLLER */
1562f29dbc25Smrg    gfx_set_display_bpp(bpp);
1563f29dbc25Smrg
1564f29dbc25Smrg    return (GFX_STATUS_OK);
1565f29dbc25Smrg}
1566f29dbc25Smrg
1567f29dbc25Smrg/*-----------------------------------------------------------------------*
1568f29dbc25Smrg * THE FOLLOWING READ ROUTINES ARE ALWAYS INCLUDED:                      *
1569f29dbc25Smrg * gfx_get_hsync_end, gfx_get_htotal, gfx_get_vsync_end, gfx_get_vtotal  *
1570f29dbc25Smrg * are used by the video overlay routines.                               *
1571f29dbc25Smrg *                                                                       *
1572f29dbc25Smrg * gfx_get_vline and gfx_vactive are used to prevent an issue for the    *
1573f29dbc25Smrg * SC1200.                                                               *
1574f29dbc25Smrg *                                                                       *
1575f29dbc25Smrg * The others are part of the Durango API.                               *
1576f29dbc25Smrg *-----------------------------------------------------------------------*/
1577f29dbc25Smrg
1578f29dbc25Smrg/*---------------------------------------------------------------------------
1579f29dbc25Smrg * gfx_get_display_pitch
1580f29dbc25Smrg *
1581f29dbc25Smrg * This routine returns the current pitch of the frame buffer, in bytes.
1582f29dbc25Smrg *---------------------------------------------------------------------------
1583f29dbc25Smrg */
1584f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1585f29dbc25Smrgunsigned short
1586f29dbc25Smrggu1_get_display_pitch(void)
1587f29dbc25Smrg#else
1588f29dbc25Smrgunsigned short
1589f29dbc25Smrggfx_get_display_pitch(void)
1590f29dbc25Smrg#endif
1591f29dbc25Smrg{
1592f29dbc25Smrg    unsigned long value;
1593f29dbc25Smrg
1594f29dbc25Smrg    if (gfx_cpu_version == GFX_CPU_PYRAMID) {
1595f29dbc25Smrg        /* Pyramid update for 4KB line pitch */
1596f29dbc25Smrg        value = (READ_REG32(DC_LINE_DELTA) & 0x07FF) << 2;
159704007ebaSmrg    }
159804007ebaSmrg    else {
1599f29dbc25Smrg        value = (READ_REG32(DC_LINE_DELTA) & 0x03FF) << 2;
1600f29dbc25Smrg    }
1601f29dbc25Smrg
160204007ebaSmrg    return ((unsigned short) value);
1603f29dbc25Smrg}
1604f29dbc25Smrg
1605f29dbc25Smrg/*----------------------------------------------------------------------------
1606f29dbc25Smrg * GFX_GET_DISPLAY_DETAILS
1607f29dbc25Smrg *
1608f29dbc25Smrg * This routine gets the specified display mode.
1609f29dbc25Smrg *
1610f29dbc25Smrg * Returns 1 if successful, 0 if mode could not be get.
1611f29dbc25Smrg *----------------------------------------------------------------------------
1612f29dbc25Smrg */
1613f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1614f29dbc25Smrgint
1615f29dbc25Smrggu1_get_display_details(unsigned int mode, int *xres, int *yres, int *hz)
1616f29dbc25Smrg#else
1617f29dbc25Smrgint
1618f29dbc25Smrggfx_get_display_details(unsigned int mode, int *xres, int *yres, int *hz)
1619f29dbc25Smrg#endif
1620f29dbc25Smrg{
1621f29dbc25Smrg    if (mode < NUM_GX_DISPLAY_MODES) {
1622f29dbc25Smrg        if (DisplayParams[mode].flags & GFX_MODE_56HZ)
1623f29dbc25Smrg            *hz = 56;
1624f29dbc25Smrg        else if (DisplayParams[mode].flags & GFX_MODE_60HZ)
1625f29dbc25Smrg            *hz = 60;
1626f29dbc25Smrg        else if (DisplayParams[mode].flags & GFX_MODE_70HZ)
1627f29dbc25Smrg            *hz = 70;
1628f29dbc25Smrg        else if (DisplayParams[mode].flags & GFX_MODE_72HZ)
1629f29dbc25Smrg            *hz = 72;
1630f29dbc25Smrg        else if (DisplayParams[mode].flags & GFX_MODE_75HZ)
1631f29dbc25Smrg            *hz = 75;
1632f29dbc25Smrg        else if (DisplayParams[mode].flags & GFX_MODE_85HZ)
1633f29dbc25Smrg            *hz = 85;
1634f29dbc25Smrg
1635f29dbc25Smrg        *xres = DisplayParams[mode].hactive;
1636f29dbc25Smrg        *yres = DisplayParams[mode].vactive;
1637f29dbc25Smrg
1638f29dbc25Smrg        return (1);
1639f29dbc25Smrg    }
1640f29dbc25Smrg    return (0);
1641f29dbc25Smrg}
1642f29dbc25Smrg
1643f29dbc25Smrg/*----------------------------------------------------------------------------
1644f29dbc25Smrg * GFX_GET_DISPLAY_MODE_COUNT
1645f29dbc25Smrg *
1646f29dbc25Smrg * Returns number of modes supported.
1647f29dbc25Smrg *----------------------------------------------------------------------------
1648f29dbc25Smrg */
1649f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1650f29dbc25Smrgint
1651f29dbc25Smrggu1_get_display_mode_count(void)
1652f29dbc25Smrg#else
1653f29dbc25Smrgint
1654f29dbc25Smrggfx_get_display_mode_count(void)
1655f29dbc25Smrg#endif
1656f29dbc25Smrg{
1657f29dbc25Smrg    return (NUM_GX_DISPLAY_MODES);
1658f29dbc25Smrg}
1659f29dbc25Smrg
1660f29dbc25Smrg/*----------------------------------------------------------------------------
1661f29dbc25Smrg * gfx_get_frame_buffer_line_size
1662f29dbc25Smrg *
1663f29dbc25Smrg * Returns the current frame buffer line size, in bytes
1664f29dbc25Smrg *----------------------------------------------------------------------------
1665f29dbc25Smrg */
1666f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1667f29dbc25Smrgunsigned long
1668f29dbc25Smrggu1_get_frame_buffer_line_size(void)
1669f29dbc25Smrg#else
1670f29dbc25Smrgunsigned long
1671f29dbc25Smrggfx_get_frame_buffer_line_size(void)
1672f29dbc25Smrg#endif
1673f29dbc25Smrg{
1674f29dbc25Smrg    return ((READ_REG32(DC_BUF_SIZE) & 0x1FF) << 3);
1675f29dbc25Smrg}
1676f29dbc25Smrg
1677f29dbc25Smrg/*----------------------------------------------------------------------------
1678f29dbc25Smrg * gfx_mode_frequency_supported
1679f29dbc25Smrg *
1680f29dbc25Smrg * This routine examines if the requested mode with pixel frequency is supported.
1681f29dbc25Smrg *
1682f29dbc25Smrg * Returns >0 if successful , <0 if freq. could not be found and matched.
1683f29dbc25Smrg *----------------------------------------------------------------------------
1684f29dbc25Smrg */
1685f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1686f29dbc25Smrgint
1687f29dbc25Smrggu1_mode_frequency_supported(int xres, int yres, int bpp,
168804007ebaSmrg                             unsigned long frequency)
1689f29dbc25Smrg#else
1690f29dbc25Smrgint
1691f29dbc25Smrggfx_mode_frequency_supported(int xres, int yres, int bpp,
169204007ebaSmrg                             unsigned long frequency)
1693f29dbc25Smrg#endif
1694f29dbc25Smrg{
1695f29dbc25Smrg    unsigned int index;
1696f29dbc25Smrg    unsigned long value;
1697f29dbc25Smrg    unsigned long bpp_flag = 0;
1698f29dbc25Smrg
1699f29dbc25Smrg    bpp_flag = GFX_MODE_8BPP;
1700f29dbc25Smrg    if (bpp > 8)
1701f29dbc25Smrg        bpp_flag = GFX_MODE_16BPP;
1702f29dbc25Smrg
1703f29dbc25Smrg    for (index = 0; index < NUM_GX_DISPLAY_MODES; index++) {
170404007ebaSmrg        if ((DisplayParams[index].hactive == (unsigned short) xres) &&
170504007ebaSmrg            (DisplayParams[index].vactive == (unsigned short) yres) &&
1706f29dbc25Smrg            (DisplayParams[index].flags & bpp_flag) &&
1707f29dbc25Smrg            (DisplayParams[index].frequency == frequency)) {
1708f29dbc25Smrg            int hz = 0;
1709f29dbc25Smrg
1710f29dbc25Smrg            value = DisplayParams[index].flags;
1711f29dbc25Smrg
1712f29dbc25Smrg            if (value & GFX_MODE_56HZ)
1713f29dbc25Smrg                hz = 56;
1714f29dbc25Smrg            else if (value & GFX_MODE_60HZ)
1715f29dbc25Smrg                hz = 60;
1716f29dbc25Smrg            else if (value & GFX_MODE_70HZ)
1717f29dbc25Smrg                hz = 70;
1718f29dbc25Smrg            else if (value & GFX_MODE_72HZ)
1719f29dbc25Smrg                hz = 72;
1720f29dbc25Smrg            else if (value & GFX_MODE_75HZ)
1721f29dbc25Smrg                hz = 75;
1722f29dbc25Smrg            else if (value & GFX_MODE_85HZ)
1723f29dbc25Smrg                hz = 85;
1724f29dbc25Smrg
1725f29dbc25Smrg            return (hz);
1726f29dbc25Smrg        }
1727f29dbc25Smrg    }
1728f29dbc25Smrg    return (-1);
1729f29dbc25Smrg}
1730f29dbc25Smrg
1731f29dbc25Smrg/*----------------------------------------------------------------------------
1732f29dbc25Smrg * gfx_refreshrate_from_frequency
1733f29dbc25Smrg *
1734f29dbc25Smrg * This routine maps the frequency to close match refresh rate
1735f29dbc25Smrg *----------------------------------------------------------------------------
1736f29dbc25Smrg */
1737f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1738f29dbc25Smrgint
1739f29dbc25Smrggu1_get_refreshrate_from_frequency(int xres, int yres, int bpp, int *hz,
174004007ebaSmrg                                   unsigned long frequency)
1741f29dbc25Smrg#else
1742f29dbc25Smrgint
1743f29dbc25Smrggfx_get_refreshrate_from_frequency(int xres, int yres, int bpp, int *hz,
174404007ebaSmrg                                   unsigned long frequency)
1745f29dbc25Smrg#endif
1746f29dbc25Smrg{
1747f29dbc25Smrg    unsigned int index, closematch = 0;
1748f29dbc25Smrg    unsigned long value;
1749f29dbc25Smrg    unsigned long bpp_flag = 0;
1750f29dbc25Smrg    long min, diff;
1751f29dbc25Smrg
1752f29dbc25Smrg    *hz = 60;
1753f29dbc25Smrg
1754f29dbc25Smrg    bpp_flag = GFX_MODE_8BPP;
1755f29dbc25Smrg    if (bpp > 8)
1756f29dbc25Smrg        bpp_flag = GFX_MODE_16BPP;
1757f29dbc25Smrg
1758f29dbc25Smrg    /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */
1759f29dbc25Smrg    /* Search the table for the closest frequency (16.16 format). */
1760f29dbc25Smrg    min = 0x7fffffff;
1761f29dbc25Smrg    for (index = 0; index < NUM_GX_DISPLAY_MODES; index++) {
176204007ebaSmrg        if ((DisplayParams[index].htotal == (unsigned short) xres) &&
176304007ebaSmrg            (DisplayParams[index].vtotal == (unsigned short) yres) &&
1764f29dbc25Smrg            (DisplayParams[index].flags & bpp_flag)) {
176504007ebaSmrg            diff = (long) frequency - (long) DisplayParams[index].frequency;
1766f29dbc25Smrg            if (diff < 0)
1767f29dbc25Smrg                diff = -diff;
1768f29dbc25Smrg
1769f29dbc25Smrg            if (diff < min) {
1770f29dbc25Smrg                min = diff;
1771f29dbc25Smrg                closematch = index;
1772f29dbc25Smrg            }
1773f29dbc25Smrg        }
1774f29dbc25Smrg    }
1775f29dbc25Smrg
1776f29dbc25Smrg    value = DisplayParams[closematch].flags;
1777f29dbc25Smrg
1778f29dbc25Smrg    if (value & GFX_MODE_56HZ)
1779f29dbc25Smrg        *hz = 56;
1780f29dbc25Smrg    else if (value & GFX_MODE_60HZ)
1781f29dbc25Smrg        *hz = 60;
1782f29dbc25Smrg    else if (value & GFX_MODE_70HZ)
1783f29dbc25Smrg        *hz = 70;
1784f29dbc25Smrg    else if (value & GFX_MODE_72HZ)
1785f29dbc25Smrg        *hz = 72;
1786f29dbc25Smrg    else if (value & GFX_MODE_75HZ)
1787f29dbc25Smrg        *hz = 75;
1788f29dbc25Smrg    else if (value & GFX_MODE_85HZ)
1789f29dbc25Smrg        *hz = 85;
1790f29dbc25Smrg
1791f29dbc25Smrg    return (1);
1792f29dbc25Smrg}
1793f29dbc25Smrg
1794f29dbc25Smrg/*----------------------------------------------------------------------------
1795f29dbc25Smrg * gfx_refreshrate_from_mode
1796f29dbc25Smrg *
1797f29dbc25Smrg * This routine is identical to the gfx_get_refreshrate_from_frequency,
1798f29dbc25Smrg * except that the active timing values are compared instead of the total
1799f29dbc25Smrg * values.  Some modes (such as 70Hz and 72Hz) may be confused in this routine
1800f29dbc25Smrg *----------------------------------------------------------------------------
1801f29dbc25Smrg */
1802f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1803f29dbc25Smrgint
1804f29dbc25Smrggu1_get_refreshrate_from_mode(int xres, int yres, int bpp, int *hz,
180504007ebaSmrg                              unsigned long frequency)
1806f29dbc25Smrg#else
1807f29dbc25Smrgint
1808f29dbc25Smrggfx_get_refreshrate_from_mode(int xres, int yres, int bpp, int *hz,
180904007ebaSmrg                              unsigned long frequency)
1810f29dbc25Smrg#endif
1811f29dbc25Smrg{
1812f29dbc25Smrg    unsigned int index, closematch = 0;
1813f29dbc25Smrg    unsigned long value;
1814f29dbc25Smrg    unsigned long bpp_flag = 0;
1815f29dbc25Smrg    long min, diff;
1816f29dbc25Smrg
1817f29dbc25Smrg    *hz = 60;
1818f29dbc25Smrg
1819f29dbc25Smrg    bpp_flag = GFX_MODE_8BPP;
1820f29dbc25Smrg    if (bpp > 8)
1821f29dbc25Smrg        bpp_flag = GFX_MODE_16BPP;
1822f29dbc25Smrg
1823f29dbc25Smrg    /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */
1824f29dbc25Smrg    /* Search the table for the closest frequency (16.16 format). */
1825f29dbc25Smrg    min = 0x7fffffff;
1826f29dbc25Smrg    for (index = 0; index < NUM_GX_DISPLAY_MODES; index++) {
182704007ebaSmrg        if ((DisplayParams[index].hactive == (unsigned short) xres) &&
182804007ebaSmrg            (DisplayParams[index].vactive == (unsigned short) yres) &&
1829f29dbc25Smrg            (DisplayParams[index].flags & bpp_flag)) {
183004007ebaSmrg            diff = (long) frequency - (long) DisplayParams[index].frequency;
1831f29dbc25Smrg            if (diff < 0)
1832f29dbc25Smrg                diff = -diff;
1833f29dbc25Smrg
1834f29dbc25Smrg            if (diff < min) {
1835f29dbc25Smrg                min = diff;
1836f29dbc25Smrg                closematch = index;
1837f29dbc25Smrg            }
1838f29dbc25Smrg        }
1839f29dbc25Smrg    }
1840f29dbc25Smrg
1841f29dbc25Smrg    value = DisplayParams[closematch].flags;
1842f29dbc25Smrg
1843f29dbc25Smrg    if (value & GFX_MODE_56HZ)
1844f29dbc25Smrg        *hz = 56;
1845f29dbc25Smrg    else if (value & GFX_MODE_60HZ)
1846f29dbc25Smrg        *hz = 60;
1847f29dbc25Smrg    else if (value & GFX_MODE_70HZ)
1848f29dbc25Smrg        *hz = 70;
1849f29dbc25Smrg    else if (value & GFX_MODE_72HZ)
1850f29dbc25Smrg        *hz = 72;
1851f29dbc25Smrg    else if (value & GFX_MODE_75HZ)
1852f29dbc25Smrg        *hz = 75;
1853f29dbc25Smrg    else if (value & GFX_MODE_85HZ)
1854f29dbc25Smrg        *hz = 85;
1855f29dbc25Smrg
1856f29dbc25Smrg    return (1);
1857f29dbc25Smrg}
1858f29dbc25Smrg
1859f29dbc25Smrg/*----------------------------------------------------------------------------
1860f29dbc25Smrg * gfx_get_frequency_from_refreshrate
1861f29dbc25Smrg *
1862f29dbc25Smrg * This routine maps the refresh rate to the closest matching PLL frequency.
1863f29dbc25Smrg *----------------------------------------------------------------------------
1864f29dbc25Smrg */
1865f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1866f29dbc25Smrgint
1867f29dbc25Smrggu1_get_frequency_from_refreshrate(int xres, int yres, int bpp, int hz,
186804007ebaSmrg                                   int *frequency)
1869f29dbc25Smrg#else
1870f29dbc25Smrgint
1871f29dbc25Smrggfx_get_frequency_from_refreshrate(int xres, int yres, int bpp, int hz,
187204007ebaSmrg                                   int *frequency)
1873f29dbc25Smrg#endif
1874f29dbc25Smrg{
1875f29dbc25Smrg    unsigned int index;
1876f29dbc25Smrg    int retval = -1;
1877f29dbc25Smrg    unsigned long hz_flag = 0;
1878f29dbc25Smrg    unsigned long bpp_flag = 0;
1879f29dbc25Smrg
1880f29dbc25Smrg    *frequency = 0;
1881f29dbc25Smrg
1882f29dbc25Smrg    if (hz == 56)
1883f29dbc25Smrg        hz_flag = GFX_MODE_56HZ;
1884f29dbc25Smrg    else if (hz == 60)
1885f29dbc25Smrg        hz_flag = GFX_MODE_60HZ;
1886f29dbc25Smrg    else if (hz == 70)
1887f29dbc25Smrg        hz_flag = GFX_MODE_70HZ;
1888f29dbc25Smrg    else if (hz == 72)
1889f29dbc25Smrg        hz_flag = GFX_MODE_72HZ;
1890f29dbc25Smrg    else if (hz == 75)
1891f29dbc25Smrg        hz_flag = GFX_MODE_75HZ;
1892f29dbc25Smrg    else if (hz == 85)
1893f29dbc25Smrg        hz_flag = GFX_MODE_85HZ;
1894f29dbc25Smrg
1895f29dbc25Smrg    bpp_flag = GFX_MODE_8BPP;
1896f29dbc25Smrg    if (bpp > 8)
1897f29dbc25Smrg        bpp_flag = GFX_MODE_16BPP;
1898f29dbc25Smrg
1899f29dbc25Smrg    /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */
1900f29dbc25Smrg
1901f29dbc25Smrg    for (index = 0; index < NUM_GX_DISPLAY_MODES; index++) {
190204007ebaSmrg        if ((DisplayParams[index].hactive == (unsigned short) xres) &&
190304007ebaSmrg            (DisplayParams[index].vactive == (unsigned short) yres) &&
1904f29dbc25Smrg            (DisplayParams[index].flags & bpp_flag) &&
1905f29dbc25Smrg            (DisplayParams[index].flags & hz_flag)) {
1906f29dbc25Smrg            *frequency = DisplayParams[index].frequency;
1907f29dbc25Smrg            retval = 1;
1908f29dbc25Smrg        }
1909f29dbc25Smrg    }
1910f29dbc25Smrg    return retval;
1911f29dbc25Smrg}
1912f29dbc25Smrg
1913f29dbc25Smrg/*---------------------------------------------------------------------------
1914f29dbc25Smrg * gfx_get_max_supported_pixel_clock
1915f29dbc25Smrg *
1916f29dbc25Smrg * This routine returns the maximum recommended speed for the pixel clock.  The
1917f29dbc25Smrg * return value is an integer of the format xxxyyy, where xxx.yyy is the maximum
1918f29dbc25Smrg * floating point pixel clock speed.
1919f29dbc25Smrg *---------------------------------------------------------------------------
1920f29dbc25Smrg */
1921f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1922f29dbc25Smrgunsigned long
1923f29dbc25Smrggu1_get_max_supported_pixel_clock(void)
1924f29dbc25Smrg#else
1925f29dbc25Smrgunsigned long
1926f29dbc25Smrggfx_get_max_supported_pixel_clock(void)
1927f29dbc25Smrg#endif
1928f29dbc25Smrg{
1929f29dbc25Smrg    /* ALL CHIPS CAN HANDLE 1280X1024@85HZ - 157.5 MHz */
1930f29dbc25Smrg    return 157500;
1931f29dbc25Smrg}
1932f29dbc25Smrg
1933f29dbc25Smrg/*----------------------------------------------------------------------------
1934f29dbc25Smrg * gfx_get_display_mode
1935f29dbc25Smrg *
1936f29dbc25Smrg * This routine gets the specified display mode.
1937f29dbc25Smrg *
1938f29dbc25Smrg * Returns: >0 if successful and mode returned, <0 if mode could not be found.
1939f29dbc25Smrg *----------------------------------------------------------------------------
1940f29dbc25Smrg */
1941f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
1942f29dbc25Smrgint
1943f29dbc25Smrggu1_get_display_mode(int *xres, int *yres, int *bpp, int *hz)
1944f29dbc25Smrg#else
1945f29dbc25Smrgint
1946f29dbc25Smrggfx_get_display_mode(int *xres, int *yres, int *bpp, int *hz)
1947f29dbc25Smrg#endif
1948f29dbc25Smrg{
1949f29dbc25Smrg    unsigned int mode = 0;
1950f29dbc25Smrg    unsigned long pll_freq = 0, bpp_flag = 0;
1951f29dbc25Smrg
1952f29dbc25Smrg    *xres = gfx_get_hactive();
1953f29dbc25Smrg    *yres = gfx_get_vactive();
1954f29dbc25Smrg    *bpp = gfx_get_display_bpp();
1955f29dbc25Smrg    pll_freq = gfx_get_clock_frequency();
1956f29dbc25Smrg
1957f29dbc25Smrg    /* SUPPORT EMULATED VGA MODES */
1958f29dbc25Smrg    if (gfx_pixel_double)
1959f29dbc25Smrg        *xres >>= 1;
1960f29dbc25Smrg
1961f29dbc25Smrg    if (gfx_line_double)
1962f29dbc25Smrg        *yres >>= 1;
1963f29dbc25Smrg
1964f29dbc25Smrg    /* SET BPP FLAGS TO LIMIT MODE SELECTION */
1965f29dbc25Smrg    bpp_flag = GFX_MODE_8BPP;
1966f29dbc25Smrg    if (*bpp > 8)
1967f29dbc25Smrg        bpp_flag = GFX_MODE_16BPP;
1968f29dbc25Smrg
1969f29dbc25Smrg    for (mode = 0; mode < NUM_GX_DISPLAY_MODES; mode++) {
197004007ebaSmrg        if ((DisplayParams[mode].hactive == (unsigned short) *xres) &&
197104007ebaSmrg            (DisplayParams[mode].vactive == (unsigned short) *yres) &&
1972f29dbc25Smrg            (DisplayParams[mode].frequency == pll_freq) &&
1973f29dbc25Smrg            (DisplayParams[mode].flags & bpp_flag)) {
1974f29dbc25Smrg
1975f29dbc25Smrg            pll_freq = DisplayParams[mode].flags;
1976f29dbc25Smrg
1977f29dbc25Smrg            if (pll_freq & GFX_MODE_56HZ)
1978f29dbc25Smrg                *hz = 56;
1979f29dbc25Smrg            else if (pll_freq & GFX_MODE_60HZ)
1980f29dbc25Smrg                *hz = 60;
1981f29dbc25Smrg            else if (pll_freq & GFX_MODE_70HZ)
1982f29dbc25Smrg                *hz = 70;
1983f29dbc25Smrg            else if (pll_freq & GFX_MODE_72HZ)
1984f29dbc25Smrg                *hz = 72;
1985f29dbc25Smrg            else if (pll_freq & GFX_MODE_75HZ)
1986f29dbc25Smrg                *hz = 75;
1987f29dbc25Smrg            else if (pll_freq & GFX_MODE_85HZ)
1988f29dbc25Smrg                *hz = 85;
1989f29dbc25Smrg
1990f29dbc25Smrg            return (1);
1991f29dbc25Smrg        }
1992f29dbc25Smrg    }
1993f29dbc25Smrg    return (-1);
1994f29dbc25Smrg}
1995f29dbc25Smrg
1996f29dbc25Smrg/*---------------------------------------------------------------------------
1997f29dbc25Smrg * gfx_get_hactive
1998f29dbc25Smrg *---------------------------------------------------------------------------
1999f29dbc25Smrg */
2000f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2001f29dbc25Smrgunsigned short
2002f29dbc25Smrggu1_get_hactive(void)
2003f29dbc25Smrg#else
2004f29dbc25Smrgunsigned short
2005f29dbc25Smrggfx_get_hactive(void)
2006f29dbc25Smrg#endif
2007f29dbc25Smrg{
200804007ebaSmrg    return ((unsigned short) ((READ_REG32(DC_H_TIMING_1) & 0x07F8) + 8));
2009f29dbc25Smrg}
2010f29dbc25Smrg
2011f29dbc25Smrg/*---------------------------------------------------------------------------
2012f29dbc25Smrg * gfx_get_hsync_start
2013f29dbc25Smrg *---------------------------------------------------------------------------
2014f29dbc25Smrg */
2015f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2016f29dbc25Smrgunsigned short
2017f29dbc25Smrggu1_get_hsync_start(void)
2018f29dbc25Smrg#else
2019f29dbc25Smrgunsigned short
2020f29dbc25Smrggfx_get_hsync_start(void)
2021f29dbc25Smrg#endif
2022f29dbc25Smrg{
202304007ebaSmrg    return ((unsigned short) ((READ_REG32(DC_H_TIMING_3) & 0x07F8) + 8));
2024f29dbc25Smrg}
2025f29dbc25Smrg
2026f29dbc25Smrg/*---------------------------------------------------------------------------
2027f29dbc25Smrg * gfx_get_hsync_end
2028f29dbc25Smrg *---------------------------------------------------------------------------
2029f29dbc25Smrg */
2030f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2031f29dbc25Smrgunsigned short
2032f29dbc25Smrggu1_get_hsync_end(void)
2033f29dbc25Smrg#else
2034f29dbc25Smrgunsigned short
2035f29dbc25Smrggfx_get_hsync_end(void)
2036f29dbc25Smrg#endif
2037f29dbc25Smrg{
203804007ebaSmrg    return ((unsigned short) (((READ_REG32(DC_H_TIMING_3) >> 16) & 0x07F8) +
203904007ebaSmrg                              8));
2040f29dbc25Smrg}
2041f29dbc25Smrg
2042f29dbc25Smrg/*---------------------------------------------------------------------------
2043f29dbc25Smrg * gfx_get_htotal
2044f29dbc25Smrg *---------------------------------------------------------------------------
2045f29dbc25Smrg */
2046f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2047f29dbc25Smrgunsigned short
2048f29dbc25Smrggu1_get_htotal(void)
2049f29dbc25Smrg#else
2050f29dbc25Smrgunsigned short
2051f29dbc25Smrggfx_get_htotal(void)
2052f29dbc25Smrg#endif
2053f29dbc25Smrg{
205404007ebaSmrg    return ((unsigned short) (((READ_REG32(DC_H_TIMING_1) >> 16) & 0x07F8) +
205504007ebaSmrg                              8));
2056f29dbc25Smrg}
2057f29dbc25Smrg
2058f29dbc25Smrg/*---------------------------------------------------------------------------
2059f29dbc25Smrg * gfx_get_vactive
2060f29dbc25Smrg *---------------------------------------------------------------------------
2061f29dbc25Smrg */
2062f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2063f29dbc25Smrgunsigned short
2064f29dbc25Smrggu1_get_vactive(void)
2065f29dbc25Smrg#else
2066f29dbc25Smrgunsigned short
2067f29dbc25Smrggfx_get_vactive(void)
2068f29dbc25Smrg#endif
2069f29dbc25Smrg{
207004007ebaSmrg    return ((unsigned short) ((READ_REG32(DC_V_TIMING_1) & 0x07FF) + 1));
2071f29dbc25Smrg}
2072f29dbc25Smrg
2073f29dbc25Smrg/*---------------------------------------------------------------------------
2074f29dbc25Smrg * gfx_get_vsync_end
2075f29dbc25Smrg *---------------------------------------------------------------------------
2076f29dbc25Smrg */
2077f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2078f29dbc25Smrgunsigned short
2079f29dbc25Smrggu1_get_vsync_end(void)
2080f29dbc25Smrg#else
2081f29dbc25Smrgunsigned short
2082f29dbc25Smrggfx_get_vsync_end(void)
2083f29dbc25Smrg#endif
2084f29dbc25Smrg{
208504007ebaSmrg    return ((unsigned short) (((READ_REG32(DC_V_TIMING_3) >> 16) & 0x07FF) +
208604007ebaSmrg                              1));
2087f29dbc25Smrg}
2088f29dbc25Smrg
2089f29dbc25Smrg/*---------------------------------------------------------------------------
2090f29dbc25Smrg * gfx_get_vtotal
2091f29dbc25Smrg *---------------------------------------------------------------------------
2092f29dbc25Smrg */
2093f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2094f29dbc25Smrgunsigned short
2095f29dbc25Smrggu1_get_vtotal(void)
2096f29dbc25Smrg#else
2097f29dbc25Smrgunsigned short
2098f29dbc25Smrggfx_get_vtotal(void)
2099f29dbc25Smrg#endif
2100f29dbc25Smrg{
210104007ebaSmrg    return ((unsigned short) (((READ_REG32(DC_V_TIMING_1) >> 16) & 0x07FF) +
210204007ebaSmrg                              1));
2103f29dbc25Smrg}
2104f29dbc25Smrg
2105f29dbc25Smrg/*-----------------------------------------------------------------------------
2106f29dbc25Smrg * gfx_get_display_bpp
2107f29dbc25Smrg *
2108f29dbc25Smrg * This routine returns the current color depth of the active display.
2109f29dbc25Smrg *-----------------------------------------------------------------------------
2110f29dbc25Smrg */
2111f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2112f29dbc25Smrgunsigned short
2113f29dbc25Smrggu1_get_display_bpp(void)
2114f29dbc25Smrg#else
2115f29dbc25Smrgunsigned short
2116f29dbc25Smrggfx_get_display_bpp(void)
2117f29dbc25Smrg#endif
2118f29dbc25Smrg{
2119f29dbc25Smrg    switch (READ_REG32(DC_OUTPUT_CFG) & 3) {
2120f29dbc25Smrg    case 0:
2121f29dbc25Smrg        return (16);
2122f29dbc25Smrg    case 2:
2123f29dbc25Smrg        return (15);
2124f29dbc25Smrg    }
2125f29dbc25Smrg    return (8);
2126f29dbc25Smrg}
2127f29dbc25Smrg
2128f29dbc25Smrg/*---------------------------------------------------------------------------
2129f29dbc25Smrg * gfx_get_vline
2130f29dbc25Smrg *---------------------------------------------------------------------------
2131f29dbc25Smrg */
2132f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2133f29dbc25Smrgunsigned short
2134f29dbc25Smrggu1_get_vline(void)
2135f29dbc25Smrg#else
2136f29dbc25Smrgunsigned short
2137f29dbc25Smrggfx_get_vline(void)
2138f29dbc25Smrg#endif
2139f29dbc25Smrg{
2140f29dbc25Smrg    unsigned short current_scan_line;
2141f29dbc25Smrg
2142f29dbc25Smrg    /* Read similar value twice to ensure that the value is not transitioning */
2143f29dbc25Smrg    do {
214404007ebaSmrg        current_scan_line = (unsigned short) READ_REG32(DC_V_LINE_CNT) & 0x07FF;
2145f29dbc25Smrg    } while (current_scan_line !=
214604007ebaSmrg             (unsigned short) (READ_REG32(DC_V_LINE_CNT) & 0x07FF));
2147f29dbc25Smrg
2148f29dbc25Smrg    return (current_scan_line);
2149f29dbc25Smrg}
2150f29dbc25Smrg
2151f29dbc25Smrg/*-----------------------------------------------------------------------------
2152f29dbc25Smrg * gfx_get_display_offset
2153f29dbc25Smrg *-----------------------------------------------------------------------------
2154f29dbc25Smrg */
2155f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2156f29dbc25Smrgunsigned long
2157f29dbc25Smrggu1_get_display_offset(void)
2158f29dbc25Smrg#else
2159f29dbc25Smrgunsigned long
2160f29dbc25Smrggfx_get_display_offset(void)
2161f29dbc25Smrg#endif
2162f29dbc25Smrg{
2163f29dbc25Smrg    return (READ_REG32(DC_FB_ST_OFFSET) & 0x003FFFFF);
2164f29dbc25Smrg}
2165f29dbc25Smrg
2166f29dbc25Smrg/*-----------------------------------------------------------------------------
2167f29dbc25Smrg * gfx_get_cursor_offset
2168f29dbc25Smrg *-----------------------------------------------------------------------------
2169f29dbc25Smrg */
2170f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2171f29dbc25Smrgunsigned long
2172f29dbc25Smrggu1_get_cursor_offset(void)
2173f29dbc25Smrg#else
2174f29dbc25Smrgunsigned long
2175f29dbc25Smrggfx_get_cursor_offset(void)
2176f29dbc25Smrg#endif
2177f29dbc25Smrg{
2178f29dbc25Smrg    return (READ_REG32(DC_CURS_ST_OFFSET) & 0x003FFFFF);
2179f29dbc25Smrg}
2180f29dbc25Smrg
2181f29dbc25Smrg#if GFX_READ_ROUTINES
2182f29dbc25Smrg
2183f29dbc25Smrg/*************************************************************/
2184f29dbc25Smrg/*  READ ROUTINES  |  INCLUDED FOR DIAGNOSTIC PURPOSES ONLY  */
2185f29dbc25Smrg/*************************************************************/
2186f29dbc25Smrg
2187f29dbc25Smrg/*---------------------------------------------------------------------------
2188f29dbc25Smrg * gfx_get_hblank_start
2189f29dbc25Smrg *---------------------------------------------------------------------------
2190f29dbc25Smrg */
2191f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2192f29dbc25Smrgunsigned short
2193f29dbc25Smrggu1_get_hblank_start(void)
2194f29dbc25Smrg#else
2195f29dbc25Smrgunsigned short
2196f29dbc25Smrggfx_get_hblank_start(void)
2197f29dbc25Smrg#endif
2198f29dbc25Smrg{
219904007ebaSmrg    return ((unsigned short) ((READ_REG32(DC_H_TIMING_2) & 0x07F8) + 8));
2200f29dbc25Smrg}
2201f29dbc25Smrg
2202f29dbc25Smrg/*---------------------------------------------------------------------------
2203f29dbc25Smrg * gfx_get_hblank_end
2204f29dbc25Smrg *---------------------------------------------------------------------------
2205f29dbc25Smrg */
2206f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2207f29dbc25Smrgunsigned short
2208f29dbc25Smrggu1_get_hblank_end(void)
2209f29dbc25Smrg#else
2210f29dbc25Smrgunsigned short
2211f29dbc25Smrggfx_get_hblank_end(void)
2212f29dbc25Smrg#endif
2213f29dbc25Smrg{
221404007ebaSmrg    return ((unsigned short) (((READ_REG32(DC_H_TIMING_2) >> 16) & 0x07F8) +
221504007ebaSmrg                              8));
2216f29dbc25Smrg}
2217f29dbc25Smrg
2218f29dbc25Smrg/*---------------------------------------------------------------------------
2219f29dbc25Smrg * gfx_get_vblank_start
2220f29dbc25Smrg *---------------------------------------------------------------------------
2221f29dbc25Smrg */
2222f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2223f29dbc25Smrgunsigned short
2224f29dbc25Smrggu1_get_vblank_start(void)
2225f29dbc25Smrg#else
2226f29dbc25Smrgunsigned short
2227f29dbc25Smrggfx_get_vblank_start(void)
2228f29dbc25Smrg#endif
2229f29dbc25Smrg{
223004007ebaSmrg    return ((unsigned short) ((READ_REG32(DC_V_TIMING_2) & 0x07FF) + 1));
2231f29dbc25Smrg}
2232f29dbc25Smrg
2233f29dbc25Smrg/*---------------------------------------------------------------------------
2234f29dbc25Smrg * gfx_get_vsync_start
2235f29dbc25Smrg *---------------------------------------------------------------------------
2236f29dbc25Smrg */
2237f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2238f29dbc25Smrgunsigned short
2239f29dbc25Smrggu1_get_vsync_start(void)
2240f29dbc25Smrg#else
2241f29dbc25Smrgunsigned short
2242f29dbc25Smrggfx_get_vsync_start(void)
2243f29dbc25Smrg#endif
2244f29dbc25Smrg{
224504007ebaSmrg    return ((unsigned short) ((READ_REG32(DC_V_TIMING_3) & 0x07FF) + 1));
2246f29dbc25Smrg}
2247f29dbc25Smrg
2248f29dbc25Smrg/*---------------------------------------------------------------------------
2249f29dbc25Smrg * gfx_get_vblank_end
2250f29dbc25Smrg *---------------------------------------------------------------------------
2251f29dbc25Smrg */
2252f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2253f29dbc25Smrgunsigned short
2254f29dbc25Smrggu1_get_vblank_end(void)
2255f29dbc25Smrg#else
2256f29dbc25Smrgunsigned short
2257f29dbc25Smrggfx_get_vblank_end(void)
2258f29dbc25Smrg#endif
2259f29dbc25Smrg{
226004007ebaSmrg    return ((unsigned short) (((READ_REG32(DC_V_TIMING_2) >> 16) & 0x07FF) +
226104007ebaSmrg                              1));
2262f29dbc25Smrg}
2263f29dbc25Smrg
2264f29dbc25Smrg/*-----------------------------------------------------------------------------
2265f29dbc25Smrg * gfx_get_display_palette_entry
2266f29dbc25Smrg *-----------------------------------------------------------------------------
2267f29dbc25Smrg */
2268f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2269f29dbc25Smrgint
2270f29dbc25Smrggu1_get_display_palette_entry(unsigned long index, unsigned long *palette)
2271f29dbc25Smrg#else
2272f29dbc25Smrgint
2273f29dbc25Smrggfx_get_display_palette_entry(unsigned long index, unsigned long *palette)
2274f29dbc25Smrg#endif
2275f29dbc25Smrg{
2276f29dbc25Smrg    unsigned long data;
2277f29dbc25Smrg
2278f29dbc25Smrg    if (index > 0xFF)
2279f29dbc25Smrg        return GFX_STATUS_BAD_PARAMETER;
2280f29dbc25Smrg
2281f29dbc25Smrg    WRITE_REG32(DC_PAL_ADDRESS, index);
2282f29dbc25Smrg    data = READ_REG32(DC_PAL_DATA);
2283f29dbc25Smrg    data = ((data << 2) & 0x000000FC) |
2284f29dbc25Smrg        ((data << 4) & 0x0000FC00) | ((data << 6) & 0x00FC0000);
2285f29dbc25Smrg
2286f29dbc25Smrg    *palette = data;
2287f29dbc25Smrg    return 0;
2288f29dbc25Smrg}
2289f29dbc25Smrg
2290f29dbc25Smrg/*-----------------------------------------------------------------------------
2291f29dbc25Smrg * gfx_get_display_palette
2292f29dbc25Smrg *-----------------------------------------------------------------------------
2293f29dbc25Smrg */
2294f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2295f29dbc25Smrgvoid
2296f29dbc25Smrggu1_get_display_palette(unsigned long *palette)
2297f29dbc25Smrg#else
2298f29dbc25Smrgvoid
2299f29dbc25Smrggfx_get_display_palette(unsigned long *palette)
2300f29dbc25Smrg#endif
2301f29dbc25Smrg{
2302f29dbc25Smrg    unsigned long i, data;
2303f29dbc25Smrg
2304f29dbc25Smrg    WRITE_REG32(DC_PAL_ADDRESS, 0);
2305f29dbc25Smrg    for (i = 0; i < 256; i++) {
2306f29dbc25Smrg        data = READ_REG32(DC_PAL_DATA);
2307f29dbc25Smrg        data = ((data << 2) & 0x000000FC) |
2308f29dbc25Smrg            ((data << 4) & 0x0000FC00) | ((data << 6) & 0x00FC0000);
2309f29dbc25Smrg        palette[i] = data;
2310f29dbc25Smrg    }
2311f29dbc25Smrg}
2312f29dbc25Smrg
2313f29dbc25Smrg/*-----------------------------------------------------------------------------
2314f29dbc25Smrg * gfx_get_cursor_enable
2315f29dbc25Smrg *-----------------------------------------------------------------------------
2316f29dbc25Smrg */
2317f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2318f29dbc25Smrgunsigned long
2319f29dbc25Smrggu1_get_cursor_enable(void)
2320f29dbc25Smrg#else
2321f29dbc25Smrgunsigned long
2322f29dbc25Smrggfx_get_cursor_enable(void)
2323f29dbc25Smrg#endif
2324f29dbc25Smrg{
2325f29dbc25Smrg    return (READ_REG32(DC_GENERAL_CFG) & DC_GCFG_CURE);
2326f29dbc25Smrg}
2327f29dbc25Smrg
2328f29dbc25Smrg/*-----------------------------------------------------------------------------
2329f29dbc25Smrg * gfx_get_cursor_position
2330f29dbc25Smrg *-----------------------------------------------------------------------------
2331f29dbc25Smrg */
2332f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2333f29dbc25Smrgunsigned long
2334f29dbc25Smrggu1_get_cursor_position(void)
2335f29dbc25Smrg#else
2336f29dbc25Smrgunsigned long
2337f29dbc25Smrggfx_get_cursor_position(void)
2338f29dbc25Smrg#endif
2339f29dbc25Smrg{
2340f29dbc25Smrg    return ((READ_REG32(DC_CURSOR_X) & 0x07FF) |
234104007ebaSmrg            ((READ_REG32(DC_CURSOR_Y) << 16) & 0x03FF0000));
2342f29dbc25Smrg}
2343f29dbc25Smrg
2344f29dbc25Smrg/*-----------------------------------------------------------------------------
2345f29dbc25Smrg * gfx_get_cursor_clip
2346f29dbc25Smrg *-----------------------------------------------------------------------------
2347f29dbc25Smrg */
2348f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2349f29dbc25Smrgunsigned long
2350f29dbc25Smrggu1_get_cursor_clip(void)
2351f29dbc25Smrg#else
2352f29dbc25Smrgunsigned long
2353f29dbc25Smrggfx_get_cursor_clip(void)
2354f29dbc25Smrg#endif
2355f29dbc25Smrg{
2356f29dbc25Smrg    return (((READ_REG32(DC_CURSOR_X) >> 11) & 0x01F) |
235704007ebaSmrg            ((READ_REG32(DC_CURSOR_Y) << 5) & 0x1F0000));
2358f29dbc25Smrg}
2359f29dbc25Smrg
2360f29dbc25Smrg/*-----------------------------------------------------------------------------
2361f29dbc25Smrg * gfx_get_cursor_color
2362f29dbc25Smrg *-----------------------------------------------------------------------------
2363f29dbc25Smrg */
2364f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2365f29dbc25Smrgunsigned long
2366f29dbc25Smrggu1_get_cursor_color(int color)
2367f29dbc25Smrg#else
2368f29dbc25Smrgunsigned long
2369f29dbc25Smrggfx_get_cursor_color(int color)
2370f29dbc25Smrg#endif
2371f29dbc25Smrg{
2372f29dbc25Smrg    unsigned long data;
2373f29dbc25Smrg
2374f29dbc25Smrg    if (color) {
2375f29dbc25Smrg        WRITE_REG32(DC_PAL_ADDRESS, 0x101);
237604007ebaSmrg    }
237704007ebaSmrg    else {
2378f29dbc25Smrg        WRITE_REG32(DC_PAL_ADDRESS, 0x100);
2379f29dbc25Smrg    }
2380f29dbc25Smrg    data = READ_REG32(DC_PAL_DATA);
2381f29dbc25Smrg    data = ((data << 6) & 0x00FC0000) |
2382f29dbc25Smrg        ((data << 4) & 0x0000FC00) | ((data << 2) & 0x000000FC);
2383f29dbc25Smrg    return (data);
2384f29dbc25Smrg}
2385f29dbc25Smrg
2386f29dbc25Smrg/*-----------------------------------------------------------------------------
2387f29dbc25Smrg * gfx_get_compression_enable
2388f29dbc25Smrg *-----------------------------------------------------------------------------
2389f29dbc25Smrg */
2390f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2391f29dbc25Smrgint
2392f29dbc25Smrggu1_get_compression_enable(void)
2393f29dbc25Smrg#else
2394f29dbc25Smrgint
2395f29dbc25Smrggfx_get_compression_enable(void)
2396f29dbc25Smrg#endif
2397f29dbc25Smrg{
2398f29dbc25Smrg    unsigned long gcfg;
2399f29dbc25Smrg
2400f29dbc25Smrg    gcfg = READ_REG32(DC_GENERAL_CFG);
2401f29dbc25Smrg    if (gcfg & DC_GCFG_CMPE)
2402f29dbc25Smrg        return (1);
2403f29dbc25Smrg    else
2404f29dbc25Smrg        return (0);
2405f29dbc25Smrg}
2406f29dbc25Smrg
2407f29dbc25Smrg/*-----------------------------------------------------------------------------
2408f29dbc25Smrg * gfx_get_compression_offset
2409f29dbc25Smrg *-----------------------------------------------------------------------------
2410f29dbc25Smrg */
2411f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2412f29dbc25Smrgunsigned long
2413f29dbc25Smrggu1_get_compression_offset(void)
2414f29dbc25Smrg#else
2415f29dbc25Smrgunsigned long
2416f29dbc25Smrggfx_get_compression_offset(void)
2417f29dbc25Smrg#endif
2418f29dbc25Smrg{
2419f29dbc25Smrg    unsigned long offset;
2420f29dbc25Smrg
2421f29dbc25Smrg    offset = READ_REG32(DC_CB_ST_OFFSET) & 0x003FFFFF;
2422f29dbc25Smrg    return (offset);
2423f29dbc25Smrg}
2424f29dbc25Smrg
2425f29dbc25Smrg/*-----------------------------------------------------------------------------
2426f29dbc25Smrg * gfx_get_compression_pitch
2427f29dbc25Smrg *-----------------------------------------------------------------------------
2428f29dbc25Smrg */
2429f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2430f29dbc25Smrgunsigned short
2431f29dbc25Smrggu1_get_compression_pitch(void)
2432f29dbc25Smrg#else
2433f29dbc25Smrgunsigned short
2434f29dbc25Smrggfx_get_compression_pitch(void)
2435f29dbc25Smrg#endif
2436f29dbc25Smrg{
2437f29dbc25Smrg    unsigned short pitch;
2438f29dbc25Smrg
243904007ebaSmrg    pitch = (unsigned short) (READ_REG32(DC_LINE_DELTA) >> 12) & 0x03FF;
2440f29dbc25Smrg    return (pitch << 2);
2441f29dbc25Smrg}
2442f29dbc25Smrg
2443f29dbc25Smrg/*-----------------------------------------------------------------------------
2444f29dbc25Smrg * gfx_get_compression_size
2445f29dbc25Smrg *-----------------------------------------------------------------------------
2446f29dbc25Smrg */
2447f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2448f29dbc25Smrgunsigned short
2449f29dbc25Smrggu1_get_compression_size(void)
2450f29dbc25Smrg#else
2451f29dbc25Smrgunsigned short
2452f29dbc25Smrggfx_get_compression_size(void)
2453f29dbc25Smrg#endif
2454f29dbc25Smrg{
2455f29dbc25Smrg    unsigned short size;
2456f29dbc25Smrg
245704007ebaSmrg    size = (unsigned short) ((READ_REG32(DC_BUF_SIZE) >> 9) & 0x7F) - 1;
2458f29dbc25Smrg    return ((size << 2) + 16);
2459f29dbc25Smrg}
2460f29dbc25Smrg
2461f29dbc25Smrg/*-----------------------------------------------------------------------------
2462f29dbc25Smrg * gfx_get_valid_bit
2463f29dbc25Smrg *-----------------------------------------------------------------------------
2464f29dbc25Smrg */
2465f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2466f29dbc25Smrgint
2467f29dbc25Smrggu1_get_valid_bit(int line)
2468f29dbc25Smrg#else
2469f29dbc25Smrgint
2470f29dbc25Smrggfx_get_valid_bit(int line)
2471f29dbc25Smrg#endif
2472f29dbc25Smrg{
2473f29dbc25Smrg    int valid;
2474f29dbc25Smrg
2475f29dbc25Smrg    WRITE_REG32(MC_DR_ADD, line);
247604007ebaSmrg    valid = (int) READ_REG32(MC_DR_ACC) & 1;
2477f29dbc25Smrg    return (valid);
2478f29dbc25Smrg}
2479f29dbc25Smrg
2480f29dbc25Smrg/*---------------------------------------------------------------------------
2481f29dbc25Smrg * gfx_get_display_video_offset (PRIVATE ROUTINE - NOT PART OF API)
2482f29dbc25Smrg *
2483f29dbc25Smrg * This routine is called by "gfx_get_video_offset".  It abstracts the
2484f29dbc25Smrg * version of the display controller from the video overlay routines.
2485f29dbc25Smrg *---------------------------------------------------------------------------
2486f29dbc25Smrg */
2487f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2488f29dbc25Smrgunsigned long
2489f29dbc25Smrggu1_get_display_video_offset(void)
2490f29dbc25Smrg#else
2491f29dbc25Smrgunsigned long
2492f29dbc25Smrggfx_get_display_video_offset(void)
2493f29dbc25Smrg#endif
2494f29dbc25Smrg{
2495f29dbc25Smrg    return (READ_REG32(DC_VID_ST_OFFSET) & 0x003FFFFF);
2496f29dbc25Smrg}
2497f29dbc25Smrg
2498f29dbc25Smrg/*---------------------------------------------------------------------------
2499f29dbc25Smrg * gfx_get_display_video_size (PRIVATE ROUTINE - NOT PART OF API)
2500f29dbc25Smrg *
2501f29dbc25Smrg * This routine is called by "gfx_get_video_size".  It abstracts the
2502f29dbc25Smrg * version of the display controller from the video overlay routines.
2503f29dbc25Smrg *---------------------------------------------------------------------------
2504f29dbc25Smrg */
2505f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2506f29dbc25Smrgunsigned long
2507f29dbc25Smrggu1_get_display_video_size(void)
2508f29dbc25Smrg#else
2509f29dbc25Smrgunsigned long
2510f29dbc25Smrggfx_get_display_video_size(void)
2511f29dbc25Smrg#endif
2512f29dbc25Smrg{
2513f29dbc25Smrg    /* RETURN TOTAL SIZE, IN BYTES */
2514f29dbc25Smrg    return ((READ_REG32(DC_BUF_SIZE) >> 10) & 0x000FFFC0);
2515f29dbc25Smrg}
2516f29dbc25Smrg
2517f29dbc25Smrg/*-----------------------------------------------------------------------------
2518f29dbc25Smrg * gfx_get_display_priority_high
2519f29dbc25Smrg *-----------------------------------------------------------------------------
2520f29dbc25Smrg */
2521f29dbc25Smrg#if GFX_DISPLAY_DYNAMIC
2522f29dbc25Smrgint
2523f29dbc25Smrggu1_get_display_priority_high(void)
2524f29dbc25Smrg#else
2525f29dbc25Smrgint
2526f29dbc25Smrggfx_get_display_priority_high(void)
2527f29dbc25Smrg#endif
2528f29dbc25Smrg{
2529f29dbc25Smrg    if (READ_REG32(MC_MEM_CNTRL1) & MC_XBUSARB)
2530f29dbc25Smrg        return (1);
2531f29dbc25Smrg    else
2532f29dbc25Smrg        return (0);
2533f29dbc25Smrg}
2534f29dbc25Smrg
253504007ebaSmrg#endif                          /* GFX_READ_ROUTINES */
2536f29dbc25Smrg
2537f29dbc25Smrg/* END OF FILE */
2538