~ubuntu-branches/ubuntu/precise/xserver-xorg-video-geode-lts-quantal/precise-updates

« back to all changes in this revision

Viewing changes to src/gfx/disp_gu1.c

  • Committer: Package Import Robot
  • Author(s): Maarten Lankhorst
  • Date: 2012-11-30 20:59:48 UTC
  • Revision ID: package-import@ubuntu.com-20121130205948-8p83molp6tff7m8o
Tags: upstream-2.11.13+git20120726
ImportĀ upstreamĀ versionĀ 2.11.13+git20120726

Show diffs side-by-side

added added

removed removed

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