~ubuntu-branches/ubuntu/precise/xserver-xorg-video-mach64-lts-quantal/precise-proposed

« back to all changes in this revision

Viewing changes to src/atimode.c

  • Committer: Package Import Robot
  • Author(s): Maarten Lankhorst
  • Date: 2012-11-30 20:59:57 UTC
  • Revision ID: package-import@ubuntu.com-20121130205957-cn3ei5b1ckwqht26
Tags: upstream-6.9.3
ImportĀ upstreamĀ versionĀ 6.9.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright 2000 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org
 
3
 *
 
4
 * Permission to use, copy, modify, distribute, and sell this software and its
 
5
 * documentation for any purpose is hereby granted without fee, provided that
 
6
 * the above copyright notice appear in all copies and that both that copyright
 
7
 * notice and this permission notice appear in supporting documentation, and
 
8
 * that the name of Marc Aurele La France not be used in advertising or
 
9
 * publicity pertaining to distribution of the software without specific,
 
10
 * written prior permission.  Marc Aurele La France makes no representations
 
11
 * about the suitability of this software for any purpose.  It is provided
 
12
 * "as-is" without express or implied warranty.
 
13
 *
 
14
 * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 
15
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.  IN NO
 
16
 * EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 
17
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 
18
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 
19
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 
20
 * PERFORMANCE OF THIS SOFTWARE.
 
21
 */
 
22
 
 
23
#ifdef HAVE_CONFIG_H
 
24
#include "config.h"
 
25
#endif
 
26
 
 
27
#include <string.h>
 
28
 
 
29
#include "ati.h"
 
30
#include "atichip.h"
 
31
#include "atidac.h"
 
32
#include "atidsp.h"
 
33
#include "atimach64.h"
 
34
#include "atimach64io.h"
 
35
#include "atimode.h"
 
36
#include "atiprint.h"
 
37
#include "atirgb514.h"
 
38
#include "ativga.h"
 
39
#include "atiwonder.h"
 
40
#include "atiwonderio.h"
 
41
 
 
42
#ifdef TV_OUT
 
43
 
 
44
#include "vbe.h"
 
45
 
 
46
#endif /* TV_OUT */
 
47
 
 
48
#ifndef AVOID_CPIO
 
49
 
 
50
/*
 
51
 * ATICopyVGAMemory --
 
52
 *
 
53
 * This function is called to copy one or all banks of a VGA plane.
 
54
 */
 
55
static void
 
56
ATICopyVGAMemory
 
57
(
 
58
    ATIPtr   pATI,
 
59
    ATIHWPtr pATIHW,
 
60
    pointer  *saveptr,
 
61
    pointer  *from,
 
62
    pointer  *to
 
63
)
 
64
{
 
65
    unsigned int iBank;
 
66
 
 
67
    for (iBank = 0;  iBank < pATIHW->nBank;  iBank++)
 
68
    {
 
69
        (*pATIHW->SetBank)(pATI, iBank);
 
70
        (void)memcpy(*to, *from, 0x00010000U);
 
71
        *saveptr = (char *)(*saveptr) + 0x00010000U;
 
72
    }
 
73
}
 
74
 
 
75
/*
 
76
 * ATISwap --
 
77
 *
 
78
 * This function saves/restores video memory contents during video mode
 
79
 * switches.
 
80
 */
 
81
static void
 
82
ATISwap
 
83
(
 
84
    int      iScreen,
 
85
    ATIPtr   pATI,
 
86
    ATIHWPtr pATIHW,
 
87
    Bool     ToFB
 
88
)
 
89
{
 
90
    pointer save, *from, *to;
 
91
    unsigned int iPlane = 0, PlaneMask = 1;
 
92
    CARD8 seq2, seq4, gra1, gra3, gra4, gra5, gra6, gra8;
 
93
 
 
94
    /*
 
95
     * This is only done for non-accelerator modes.  If the video state on
 
96
     * server entry was an accelerator mode, the application that relinquished
 
97
     * the console had better do the Right Thing (tm) anyway by saving and
 
98
     * restoring its own video memory contents.
 
99
     */
 
100
    if (pATIHW->crtc != ATI_CRTC_VGA)
 
101
        return;
 
102
 
 
103
    if (ToFB)
 
104
    {
 
105
        if (!pATIHW->frame_buffer)
 
106
            return;
 
107
 
 
108
        from = &save;
 
109
        to = &pATI->pBank;
 
110
    }
 
111
    else
 
112
    {
 
113
        /* Allocate the memory */
 
114
        if (!pATIHW->frame_buffer)
 
115
        {
 
116
            pATIHW->frame_buffer =
 
117
                (pointer)malloc(pATIHW->nBank * pATIHW->nPlane * 0x00010000U);
 
118
            if (!pATIHW->frame_buffer)
 
119
            {
 
120
                xf86DrvMsg(iScreen, X_WARNING,
 
121
                    "Temporary frame buffer could not be allocated.\n");
 
122
                return;
 
123
            }
 
124
        }
 
125
 
 
126
        from = &pATI->pBank;
 
127
        to = &save;
 
128
    }
 
129
 
 
130
    /* Turn off screen */
 
131
    ATIVGASaveScreen(pATI, SCREEN_SAVER_ON);
 
132
 
 
133
    /* Save register values to be modified */
 
134
    seq2 = GetReg(SEQX, 0x02U);
 
135
    seq4 = GetReg(SEQX, 0x04U);
 
136
    gra1 = GetReg(GRAX, 0x01U);
 
137
    gra3 = GetReg(GRAX, 0x03U);
 
138
    gra5 = GetReg(GRAX, 0x05U);
 
139
    gra6 = GetReg(GRAX, 0x06U);
 
140
    gra8 = GetReg(GRAX, 0x08U);
 
141
 
 
142
    save = pATIHW->frame_buffer;
 
143
 
 
144
    /* Temporarily normalise the mode */
 
145
    if (gra1 != 0x00U)
 
146
        PutReg(GRAX, 0x01U, 0x00U);
 
147
    if (gra3 != 0x00U)
 
148
        PutReg(GRAX, 0x03U, 0x00U);
 
149
    if (gra6 != 0x05U)
 
150
        PutReg(GRAX, 0x06U, 0x05U);
 
151
    if (gra8 != 0xFFU)
 
152
        PutReg(GRAX, 0x08U, 0xFFU);
 
153
 
 
154
    if (seq4 & 0x08U)
 
155
    {
 
156
        /* Setup packed mode memory */
 
157
        if (seq2 != 0x0FU)
 
158
            PutReg(SEQX, 0x02U, 0x0FU);
 
159
        if (seq4 != 0x0AU)
 
160
            PutReg(SEQX, 0x04U, 0x0AU);
 
161
        if (pATI->Chip < ATI_CHIP_264CT)
 
162
        {
 
163
            if (gra5 != 0x00U)
 
164
                PutReg(GRAX, 0x05U, 0x00U);
 
165
        }
 
166
        else
 
167
        {
 
168
            if (gra5 != 0x40U)
 
169
                PutReg(GRAX, 0x05U, 0x40U);
 
170
        }
 
171
 
 
172
        ATICopyVGAMemory(pATI, pATIHW, &save, from, to);
 
173
 
 
174
        if (seq2 != 0x0FU)
 
175
            PutReg(SEQX, 0x02U, seq2);
 
176
        if (seq4 != 0x0AU)
 
177
            PutReg(SEQX, 0x04U, seq4);
 
178
        if (pATI->Chip < ATI_CHIP_264CT)
 
179
        {
 
180
            if (gra5 != 0x00U)
 
181
                PutReg(GRAX, 0x05U, gra5);
 
182
        }
 
183
        else
 
184
        {
 
185
            if (gra5 != 0x40U)
 
186
                PutReg(GRAX, 0x05U, gra5);
 
187
        }
 
188
    }
 
189
    else
 
190
    {
 
191
        gra4 = GetReg(GRAX, 0x04U);
 
192
 
 
193
        /* Setup planar mode memory */
 
194
        if (seq4 != 0x06U)
 
195
            PutReg(SEQX, 0x04U, 0x06U);
 
196
        if (gra5 != 0x00U)
 
197
            PutReg(GRAX, 0x05U, 0x00U);
 
198
 
 
199
        for (;  iPlane < pATIHW->nPlane;  iPlane++)
 
200
        {
 
201
            PutReg(SEQX, 0x02U, PlaneMask);
 
202
            PutReg(GRAX, 0x04U, iPlane);
 
203
            ATICopyVGAMemory(pATI, pATIHW, &save, from, to);
 
204
            PlaneMask <<= 1;
 
205
        }
 
206
 
 
207
        PutReg(SEQX, 0x02U, seq2);
 
208
        if (seq4 != 0x06U)
 
209
            PutReg(SEQX, 0x04U, seq4);
 
210
        PutReg(GRAX, 0x04U, gra4);
 
211
        if (gra5 != 0x00U)
 
212
            PutReg(GRAX, 0x05U, gra5);
 
213
    }
 
214
 
 
215
    /* Restore registers */
 
216
    if (gra1 != 0x00U)
 
217
        PutReg(GRAX, 0x01U, gra1);
 
218
    if (gra3 != 0x00U)
 
219
        PutReg(GRAX, 0x03U, gra3);
 
220
    if (gra6 != 0x05U)
 
221
        PutReg(GRAX, 0x06U, gra6);
 
222
    if (gra8 != 0xFFU)
 
223
        PutReg(GRAX, 0x08U, gra8);
 
224
 
 
225
    /* Back to bank 0 */
 
226
    (*pATIHW->SetBank)(pATI, 0);
 
227
}
 
228
 
 
229
#endif /* AVOID_CPIO */
 
230
 
 
231
/*
 
232
 * ATIModePreInit --
 
233
 *
 
234
 * This function initialises an ATIHWRec with information common to all video
 
235
 * states generated by the driver.
 
236
 */
 
237
void
 
238
ATIModePreInit
 
239
(
 
240
    ScrnInfoPtr pScreenInfo,
 
241
    ATIPtr      pATI,
 
242
    ATIHWPtr    pATIHW
 
243
)
 
244
{
 
245
    CARD32 lcd_index;
 
246
 
 
247
#ifndef AVOID_CPIO
 
248
 
 
249
    if (pATI->VGAAdapter)
 
250
    {
 
251
        /* Fill in VGA data */
 
252
        ATIVGAPreInit(pATI, pATIHW);
 
253
 
 
254
        /* Fill in VGA Wonder data */
 
255
        if (pATI->CPIO_VGAWonder)
 
256
            ATIVGAWonderPreInit(pATI, pATIHW);
 
257
    }
 
258
 
 
259
#endif /* AVOID_CPIO */
 
260
 
 
261
    {
 
262
        /* Fill in Mach64 data */
 
263
        ATIMach64PreInit(pScreenInfo, pATI, pATIHW);
 
264
 
 
265
        if (pATI->Chip >= ATI_CHIP_264CT)
 
266
        {
 
267
            /* Ensure proper VCLK source */
 
268
            pATIHW->pll_vclk_cntl = ATIMach64GetPLLReg(PLL_VCLK_CNTL) |
 
269
                (PLL_VCLK_SRC_SEL | PLL_VCLK_RESET);
 
270
 
 
271
            /* Set provisional values for other PLL registers */
 
272
            pATIHW->pll_vclk_post_div = ATIMach64GetPLLReg(PLL_VCLK_POST_DIV);
 
273
            pATIHW->pll_vclk0_fb_div = ATIMach64GetPLLReg(PLL_VCLK0_FB_DIV);
 
274
            pATIHW->pll_vclk1_fb_div = ATIMach64GetPLLReg(PLL_VCLK1_FB_DIV);
 
275
            pATIHW->pll_vclk2_fb_div = ATIMach64GetPLLReg(PLL_VCLK2_FB_DIV);
 
276
            pATIHW->pll_vclk3_fb_div = ATIMach64GetPLLReg(PLL_VCLK3_FB_DIV);
 
277
            pATIHW->pll_xclk_cntl = ATIMach64GetPLLReg(PLL_XCLK_CNTL);
 
278
 
 
279
            /* For now disable extended reference and feedback dividers */
 
280
            if (pATI->Chip >= ATI_CHIP_264LT)
 
281
                pATIHW->pll_ext_vpll_cntl =
 
282
                    ATIMach64GetPLLReg(PLL_EXT_VPLL_CNTL) &
 
283
                    ~(PLL_EXT_VPLL_EN | PLL_EXT_VPLL_VGA_EN |
 
284
                      PLL_EXT_VPLL_INSYNC);
 
285
 
 
286
            /* Initialise CRTC data for LCD panels */
 
287
            if (pATI->LCDPanelID >= 0)
 
288
            {
 
289
                if (pATI->Chip == ATI_CHIP_264LT)
 
290
                {
 
291
                    pATIHW->lcd_gen_ctrl = inr(LCD_GEN_CTRL);
 
292
                }
 
293
                else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
 
294
                            (pATI->Chip == ATI_CHIP_264XL) ||
 
295
                            (pATI->Chip == ATI_CHIP_MOBILITY)) */
 
296
                {
 
297
                    lcd_index = inr(LCD_INDEX);
 
298
                    pATIHW->lcd_index = lcd_index &
 
299
                        ~(LCD_REG_INDEX | LCD_DISPLAY_DIS | LCD_SRC_SEL |
 
300
                          LCD_CRTC2_DISPLAY_DIS);
 
301
                    if (pATI->Chip != ATI_CHIP_264XL)
 
302
                        pATIHW->lcd_index |= LCD_CRTC2_DISPLAY_DIS;
 
303
                    pATIHW->config_panel =
 
304
                        ATIMach64GetLCDReg(LCD_CONFIG_PANEL) |
 
305
                        DONT_SHADOW_HEND;
 
306
                    pATIHW->lcd_gen_ctrl =
 
307
                        ATIMach64GetLCDReg(LCD_GEN_CNTL) & ~CRTC_RW_SELECT;
 
308
                    outr(LCD_INDEX, lcd_index);
 
309
                }
 
310
 
 
311
                pATIHW->lcd_gen_ctrl &=
 
312
                    ~(HORZ_DIVBY2_EN | DIS_HOR_CRT_DIVBY2 | MCLK_PM_EN |
 
313
                      VCLK_DAC_PM_EN | USE_SHADOWED_VEND |
 
314
                      USE_SHADOWED_ROWCUR | SHADOW_EN | SHADOW_RW_EN);
 
315
                pATIHW->lcd_gen_ctrl |= DONT_SHADOW_VPAR | LOCK_8DOT;
 
316
 
 
317
                if (!pATI->OptionPanelDisplay)
 
318
                {
 
319
                    /*
 
320
                     * Use primary CRTC to drive the CRT.  Turn off panel
 
321
                     * interface.
 
322
                     */
 
323
                    pATIHW->lcd_gen_ctrl &= ~LCD_ON;
 
324
                    pATIHW->lcd_gen_ctrl |= CRT_ON;
 
325
                }
 
326
                else
 
327
                {
 
328
                    /* Use primary CRTC to drive the panel */
 
329
                    pATIHW->lcd_gen_ctrl |= LCD_ON;
 
330
 
 
331
                    /* If requested, also force CRT on */
 
332
                    if (pATI->OptionCRTDisplay)
 
333
                        pATIHW->lcd_gen_ctrl |= CRT_ON;
 
334
                }
 
335
            }
 
336
        }
 
337
        else if (pATI->DAC == ATI_DAC_IBMRGB514)
 
338
        {
 
339
            ATIRGB514PreInit(pATI, pATIHW);
 
340
        }
 
341
    }
 
342
 
 
343
    /* Set RAMDAC data */
 
344
    ATIDACPreInit(pScreenInfo, pATI, pATIHW);
 
345
}
 
346
 
 
347
/*
 
348
 * ATIModeSave --
 
349
 *
 
350
 * This function saves the current video state.
 
351
 */
 
352
void
 
353
ATIModeSave
 
354
(
 
355
    ScrnInfoPtr pScreenInfo,
 
356
    ATIPtr      pATI,
 
357
    ATIHWPtr    pATIHW
 
358
)
 
359
{
 
360
 
 
361
#ifndef AVOID_CPIO
 
362
 
 
363
    int Index;
 
364
 
 
365
    /* Get back to bank 0 */
 
366
    (*pATIHW->SetBank)(pATI, 0);
 
367
 
 
368
#endif /* AVOID_CPIO */
 
369
 
 
370
    if (pATI->Chip >= ATI_CHIP_264CT)
 
371
    {
 
372
        pATIHW->pll_vclk_cntl = ATIMach64GetPLLReg(PLL_VCLK_CNTL) |
 
373
            PLL_VCLK_RESET;
 
374
        pATIHW->pll_vclk_post_div = ATIMach64GetPLLReg(PLL_VCLK_POST_DIV);
 
375
        pATIHW->pll_vclk0_fb_div = ATIMach64GetPLLReg(PLL_VCLK0_FB_DIV);
 
376
        pATIHW->pll_vclk1_fb_div = ATIMach64GetPLLReg(PLL_VCLK1_FB_DIV);
 
377
        pATIHW->pll_vclk2_fb_div = ATIMach64GetPLLReg(PLL_VCLK2_FB_DIV);
 
378
        pATIHW->pll_vclk3_fb_div = ATIMach64GetPLLReg(PLL_VCLK3_FB_DIV);
 
379
        pATIHW->pll_xclk_cntl = ATIMach64GetPLLReg(PLL_XCLK_CNTL);
 
380
        if (pATI->Chip >= ATI_CHIP_264LT)
 
381
            pATIHW->pll_ext_vpll_cntl = ATIMach64GetPLLReg(PLL_EXT_VPLL_CNTL);
 
382
 
 
383
        /* Save LCD registers */
 
384
        if (pATI->LCDPanelID >= 0)
 
385
        {
 
386
            if (pATI->Chip == ATI_CHIP_264LT)
 
387
            {
 
388
                pATIHW->horz_stretching = inr(HORZ_STRETCHING);
 
389
                pATIHW->vert_stretching = inr(VERT_STRETCHING);
 
390
                pATIHW->lcd_gen_ctrl = inr(LCD_GEN_CTRL);
 
391
 
 
392
                /* Set up to save non-shadow registers */
 
393
                outr(LCD_GEN_CTRL, pATIHW->lcd_gen_ctrl & ~SHADOW_RW_EN);
 
394
            }
 
395
            else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
 
396
                        (pATI->Chip == ATI_CHIP_264XL) ||
 
397
                        (pATI->Chip == ATI_CHIP_MOBILITY)) */
 
398
            {
 
399
                pATIHW->lcd_index = inr(LCD_INDEX);
 
400
                pATIHW->config_panel = ATIMach64GetLCDReg(LCD_CONFIG_PANEL);
 
401
                pATIHW->lcd_gen_ctrl = ATIMach64GetLCDReg(LCD_GEN_CNTL);
 
402
                pATIHW->horz_stretching =
 
403
                    ATIMach64GetLCDReg(LCD_HORZ_STRETCHING);
 
404
                pATIHW->vert_stretching =
 
405
                    ATIMach64GetLCDReg(LCD_VERT_STRETCHING);
 
406
                pATIHW->ext_vert_stretch =
 
407
                    ATIMach64GetLCDReg(LCD_EXT_VERT_STRETCH);
 
408
 
 
409
                /* Set up to save non-shadow registers */
 
410
                ATIMach64PutLCDReg(LCD_GEN_CNTL,
 
411
                    pATIHW->lcd_gen_ctrl & ~(CRTC_RW_SELECT | SHADOW_RW_EN));
 
412
            }
 
413
        }
 
414
    }
 
415
 
 
416
#ifndef AVOID_CPIO
 
417
 
 
418
    if (pATI->VGAAdapter)
 
419
    {
 
420
        /* Save VGA data */
 
421
        ATIVGASave(pATI, pATIHW);
 
422
 
 
423
        /* Save VGA Wonder data */
 
424
        if (pATI->CPIO_VGAWonder)
 
425
            ATIVGAWonderSave(pATI, pATIHW);
 
426
    }
 
427
 
 
428
#endif /* AVOID_CPIO */
 
429
 
 
430
    {
 
431
        /* Save Mach64 data */
 
432
        ATIMach64Save(pATI, pATIHW);
 
433
 
 
434
        if (pATI->Chip >= ATI_CHIP_264VTB)
 
435
        {
 
436
            /* Save DSP data */
 
437
            ATIDSPSave(pATI, pATIHW);
 
438
 
 
439
            if (pATI->LCDPanelID >= 0)
 
440
            {
 
441
                /* Switch to shadow registers */
 
442
                if (pATI->Chip == ATI_CHIP_264LT)
 
443
                    outr(LCD_GEN_CTRL, pATIHW->lcd_gen_ctrl | SHADOW_RW_EN);
 
444
                else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
 
445
                            (pATI->Chip == ATI_CHIP_264XL) ||
 
446
                            (pATI->Chip == ATI_CHIP_MOBILITY)) */
 
447
                    ATIMach64PutLCDReg(LCD_GEN_CNTL,
 
448
                        (pATIHW->lcd_gen_ctrl & ~CRTC_RW_SELECT) |
 
449
                        SHADOW_RW_EN);
 
450
 
 
451
#ifndef AVOID_CPIO
 
452
 
 
453
                /* Save shadow VGA CRTC registers */
 
454
                for (Index = 0;
 
455
                     Index < NumberOf(pATIHW->shadow_vga);
 
456
                     Index++)
 
457
                    pATIHW->shadow_vga[Index] =
 
458
                        GetReg(CRTX(pATI->CPIO_VGABase), Index);
 
459
 
 
460
#endif /* AVOID_CPIO */
 
461
 
 
462
                /* Save shadow Mach64 CRTC registers */
 
463
                pATIHW->shadow_h_total_disp = inr(CRTC_H_TOTAL_DISP);
 
464
                pATIHW->shadow_h_sync_strt_wid = inr(CRTC_H_SYNC_STRT_WID);
 
465
                pATIHW->shadow_v_total_disp = inr(CRTC_V_TOTAL_DISP);
 
466
                pATIHW->shadow_v_sync_strt_wid = inr(CRTC_V_SYNC_STRT_WID);
 
467
 
 
468
                /* Restore CRTC selection and shadow state */
 
469
                if (pATI->Chip == ATI_CHIP_264LT)
 
470
                {
 
471
                    outr(LCD_GEN_CTRL, pATIHW->lcd_gen_ctrl);
 
472
                }
 
473
                else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
 
474
                            (pATI->Chip == ATI_CHIP_264XL) ||
 
475
                            (pATI->Chip == ATI_CHIP_MOBILITY)) */
 
476
                {
 
477
                    ATIMach64PutLCDReg(LCD_GEN_CNTL, pATIHW->lcd_gen_ctrl);
 
478
                    outr(LCD_INDEX, pATIHW->lcd_index);
 
479
                }
 
480
            }
 
481
        }
 
482
        else if (pATI->DAC == ATI_DAC_IBMRGB514)
 
483
            ATIRGB514Save(pATI, pATIHW);
 
484
    }
 
485
 
 
486
    /* Save RAMDAC state */
 
487
    ATIDACSave(pATI, pATIHW);
 
488
 
 
489
    if (pATIHW != &pATI->NewHW)
 
490
    {
 
491
        pATIHW->FeedbackDivider = 0;    /* Don't programme clock */
 
492
    }
 
493
 
 
494
#ifndef AVOID_CPIO
 
495
 
 
496
        /* Save video memory */
 
497
        ATISwap(pScreenInfo->scrnIndex, pATI, pATIHW, FALSE);
 
498
 
 
499
    if (pATI->VGAAdapter)
 
500
        ATIVGASaveScreen(pATI, SCREEN_SAVER_OFF);       /* Turn on screen */
 
501
 
 
502
#endif /* AVOID_CPIO */
 
503
 
 
504
}
 
505
 
 
506
/*
 
507
 * ATIModeCalculate --
 
508
 *
 
509
 * This function fills in an ATIHWRec with all register values needed to enable
 
510
 * a video state.  It's important that this be done without modifying the
 
511
 * current video state.
 
512
 */
 
513
Bool
 
514
ATIModeCalculate
 
515
(
 
516
    int            iScreen,
 
517
    ATIPtr         pATI,
 
518
    ATIHWPtr       pATIHW,
 
519
    DisplayModePtr pMode
 
520
)
 
521
{
 
522
    CARD32 lcd_index;
 
523
    int Index, ECPClock, MaxScalerClock;
 
524
 
 
525
    /* Fill in Mach64 data */
 
526
    ATIMach64Calculate(pATI, pATIHW, pMode);
 
527
 
 
528
    /* Set up LCD register values */
 
529
    if (pATI->LCDPanelID >= 0)
 
530
    {
 
531
        int VDisplay = pMode->VDisplay;
 
532
 
 
533
        if (pMode->Flags & V_DBLSCAN)
 
534
            VDisplay <<= 1;
 
535
        if (pMode->VScan > 1)
 
536
            VDisplay *= pMode->VScan;
 
537
        if (pMode->Flags & V_INTERLACE)
 
538
            VDisplay >>= 1;
 
539
 
 
540
        /* Ensure secondary CRTC is completely disabled */
 
541
        pATIHW->crtc_gen_cntl &= ~(CRTC2_EN | CRTC2_PIX_WIDTH);
 
542
 
 
543
        if (pATI->Chip == ATI_CHIP_264LT)
 
544
        {
 
545
            pATIHW->horz_stretching = inr(HORZ_STRETCHING);
 
546
        }
 
547
        else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
 
548
                    (pATI->Chip == ATI_CHIP_264XL) ||
 
549
                    (pATI->Chip == ATI_CHIP_MOBILITY)) */
 
550
        {
 
551
            lcd_index = inr(LCD_INDEX);
 
552
            pATIHW->horz_stretching = ATIMach64GetLCDReg(LCD_HORZ_STRETCHING);
 
553
            pATIHW->ext_vert_stretch =
 
554
                ATIMach64GetLCDReg(LCD_EXT_VERT_STRETCH) &
 
555
                ~(AUTO_VERT_RATIO | VERT_STRETCH_MODE | VERT_STRETCH_RATIO3);
 
556
 
 
557
            /*
 
558
             * Don't use vertical blending if the mode is too wide or not
 
559
             * vertically stretched.
 
560
             */
 
561
            if (pATI->OptionPanelDisplay &&
 
562
                (pMode->HDisplay <= pATI->LCDVBlendFIFOSize) &&
 
563
                (VDisplay < pATI->LCDVertical))
 
564
                pATIHW->ext_vert_stretch |= VERT_STRETCH_MODE;
 
565
 
 
566
            outr(LCD_INDEX, lcd_index);
 
567
        }
 
568
 
 
569
        pATIHW->horz_stretching &=
 
570
            ~(HORZ_STRETCH_RATIO | HORZ_STRETCH_LOOP | AUTO_HORZ_RATIO |
 
571
              HORZ_STRETCH_MODE | HORZ_STRETCH_EN);
 
572
        if (pATI->OptionPanelDisplay &&
 
573
            (pMode->HDisplay < pATI->LCDHorizontal))
 
574
        do
 
575
        {
 
576
            /*
 
577
             * The horizontal blender misbehaves when HDisplay is less than a
 
578
             * a certain threshold (440 for a 1024-wide panel).  It doesn't
 
579
             * stretch such modes enough.  Use pixel replication instead of
 
580
             * blending to stretch modes that can be made to exactly fit the
 
581
             * panel width.  The undocumented "NoLCDBlend" option allows the
 
582
             * pixel-replicated mode to be slightly wider or narrower than the
 
583
             * panel width.  It also causes a mode that is exactly half as wide
 
584
             * as the panel to be pixel-replicated, rather than blended.
 
585
             */
 
586
            int HDisplay  = pMode->HDisplay & ~7;
 
587
            int nStretch  = pATI->LCDHorizontal / HDisplay;
 
588
            int Remainder = pATI->LCDHorizontal % HDisplay;
 
589
 
 
590
            if ((!Remainder && ((nStretch > 2) || !pATI->OptionBlend)) ||
 
591
                (((HDisplay * 16) / pATI->LCDHorizontal) < 7))
 
592
            {
 
593
                static const char StretchLoops[] = {10, 12, 13, 15, 16};
 
594
                int horz_stretch_loop = -1, BestRemainder;
 
595
                int Numerator = HDisplay, Denominator = pATI->LCDHorizontal;
 
596
 
 
597
                ATIReduceRatio(&Numerator, &Denominator);
 
598
 
 
599
                BestRemainder = (Numerator * 16) / Denominator;
 
600
                Index = NumberOf(StretchLoops);
 
601
                while (--Index >= 0)
 
602
                {
 
603
                    Remainder =
 
604
                        ((Denominator - Numerator) * StretchLoops[Index]) %
 
605
                        Denominator;
 
606
                    if (Remainder < BestRemainder)
 
607
                    {
 
608
                        horz_stretch_loop = Index;
 
609
                        if (!(BestRemainder = Remainder))
 
610
                            break;
 
611
                    }
 
612
#if 0
 
613
                    /*
 
614
                     * Enabling this code allows the pixel-replicated mode to
 
615
                     * be slightly wider than the panel width.
 
616
                     */
 
617
                    Remainder = Denominator - Remainder;
 
618
                    if (Remainder < BestRemainder)
 
619
                    {
 
620
                        horz_stretch_loop = Index;
 
621
                        BestRemainder = Remainder;
 
622
                    }
 
623
#endif
 
624
                }
 
625
 
 
626
                if ((horz_stretch_loop >= 0) &&
 
627
                    (!BestRemainder || !pATI->OptionBlend))
 
628
                {
 
629
                    int horz_stretch_ratio = 0, Accumulator = 0;
 
630
                    int reuse_previous = 1;
 
631
 
 
632
                    Index = StretchLoops[horz_stretch_loop];
 
633
 
 
634
                    while (--Index >= 0)
 
635
                    {
 
636
                        if (Accumulator > 0)
 
637
                            horz_stretch_ratio |= reuse_previous;
 
638
                        else
 
639
                            Accumulator += Denominator;
 
640
                        Accumulator -= Numerator;
 
641
                        reuse_previous <<= 1;
 
642
                    }
 
643
 
 
644
                    pATIHW->horz_stretching |= HORZ_STRETCH_EN |
 
645
                        SetBits(horz_stretch_loop, HORZ_STRETCH_LOOP) |
 
646
                        SetBits(horz_stretch_ratio, HORZ_STRETCH_RATIO);
 
647
                    break;      /* Out of the do { ... } while (0) */
 
648
                }
 
649
            }
 
650
 
 
651
            pATIHW->horz_stretching |= (HORZ_STRETCH_MODE | HORZ_STRETCH_EN) |
 
652
                SetBits((HDisplay * (MaxBits(HORZ_STRETCH_BLEND) + 1)) /
 
653
                        pATI->LCDHorizontal, HORZ_STRETCH_BLEND);
 
654
        } while (0);
 
655
 
 
656
        if (!pATI->OptionPanelDisplay || (VDisplay >= pATI->LCDVertical))
 
657
        {
 
658
            pATIHW->vert_stretching = 0;
 
659
        }
 
660
        else
 
661
        {
 
662
            pATIHW->vert_stretching = (VERT_STRETCH_USE0 | VERT_STRETCH_EN) |
 
663
                SetBits((VDisplay * (MaxBits(VERT_STRETCH_RATIO0) + 1)) /
 
664
                        pATI->LCDVertical, VERT_STRETCH_RATIO0);
 
665
        }
 
666
 
 
667
#ifndef AVOID_CPIO
 
668
 
 
669
        /* Copy non-shadow CRTC register values to the shadow set */
 
670
        for (Index = 0;  Index < NumberOf(pATIHW->shadow_vga);  Index++)
 
671
            pATIHW->shadow_vga[Index] = pATIHW->crt[Index];
 
672
 
 
673
#endif /* AVOID_CPIO */
 
674
 
 
675
        pATIHW->shadow_h_total_disp = pATIHW->crtc_h_total_disp;
 
676
        pATIHW->shadow_h_sync_strt_wid = pATIHW->crtc_h_sync_strt_wid;
 
677
        pATIHW->shadow_v_total_disp = pATIHW->crtc_v_total_disp;
 
678
        pATIHW->shadow_v_sync_strt_wid = pATIHW->crtc_v_sync_strt_wid;
 
679
    }
 
680
 
 
681
    /* Fill in clock data */
 
682
    if (!ATIClockCalculate(iScreen, pATI, pATIHW, pMode))
 
683
        return FALSE;
 
684
 
 
685
    /* Setup ECP clock divider */
 
686
    if (pATI->Chip >= ATI_CHIP_264VT)
 
687
    {
 
688
        if (pATI->Chip <= ATI_CHIP_264VT3)
 
689
            MaxScalerClock = 80000;
 
690
        else if (pATI->Chip <= ATI_CHIP_264GT2C)
 
691
            MaxScalerClock = 100000;
 
692
        else if (pATI->Chip == ATI_CHIP_264GTPRO)
 
693
            MaxScalerClock = 125000;
 
694
        else if (pATI->Chip <= ATI_CHIP_MOBILITY)
 
695
            MaxScalerClock = 135000;
 
696
        else
 
697
            MaxScalerClock = 80000;     /* Conservative */
 
698
        pATIHW->pll_vclk_cntl &= ~PLL_ECP_DIV;
 
699
#ifdef TV_OUT
 
700
        if (pATI->OptionTvOut) {
 
701
           /* XXX Don't do this for TVOut! */
 
702
        }
 
703
        else
 
704
#endif /* TV_OUT */
 
705
        {
 
706
           ECPClock = pMode->SynthClock;
 
707
           for (Index = 0;  (ECPClock > MaxScalerClock) && (Index < 2);  Index++)
 
708
              ECPClock >>= 1;
 
709
           pATIHW->pll_vclk_cntl |= SetBits(Index, PLL_ECP_DIV);
 
710
        }
 
711
    }
 
712
    else if (pATI->DAC == ATI_DAC_IBMRGB514)
 
713
    {
 
714
        ATIRGB514Calculate(pATI, pATIHW, pMode);
 
715
    }
 
716
 
 
717
    return TRUE;
 
718
}
 
719
 
 
720
#ifdef TV_OUT
 
721
 
 
722
static void
 
723
ATISetVBEMode
 
724
(
 
725
    ScrnInfoPtr pScreenInfo,
 
726
    ATIPtr      pATI,
 
727
    ATIHWPtr    pATIHW
 
728
)
 
729
{
 
730
    if (pATIHW->crtc == ATI_CRTC_MACH64) {
 
731
        int vbemode, modekey;
 
732
 
 
733
        /* Find a suitable VESA VBE mode, if one exists */
 
734
        modekey = (pScreenInfo->depth << 16) | 
 
735
            (pScreenInfo->currentMode->HDisplay);
 
736
 
 
737
        switch (modekey) {
 
738
        case (15<<16)|(640):
 
739
            vbemode = 0x110;
 
740
            break;
 
741
        case (16<<16)|(640):
 
742
            vbemode = 0x111;
 
743
            break;
 
744
#if 0
 
745
        case (24<<16)|(640):
 
746
            vbemode = 0x112;
 
747
            break;
 
748
#endif
 
749
        case (15<<16)|(800):
 
750
            vbemode = 0x113;
 
751
            break;
 
752
        case (16<<16)|(800):
 
753
            vbemode = 0x114;
 
754
            break;
 
755
#if 0
 
756
        case (24<<16)|(800):
 
757
            vbemode = 0x115;
 
758
            break;
 
759
#endif
 
760
        case (15<<16)|(1024):
 
761
            vbemode = 0x116;
 
762
            break;
 
763
        case (16<<16)|(1024):
 
764
            vbemode = 0x117;
 
765
            break;
 
766
#if 0
 
767
        case (24<<16)|(1024):
 
768
            vbemode = 0x118;
 
769
            break;
 
770
#endif
 
771
        default:
 
772
            xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, 
 
773
                       "Mode not supported for TV-Out: depth: %d HDisplay: %d\n", 
 
774
                       modekey>>16, modekey & 0xffff);
 
775
            return;
 
776
        }
 
777
 
 
778
        if (pATI->pVBE) {
 
779
 
 
780
            /* Preserve video memory contents */
 
781
            vbemode |= (1<<15);
 
782
 
 
783
            if (VBESetVBEMode(pATI->pVBE, vbemode, NULL)) {
 
784
                xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, 
 
785
                           "VBESetMode: 0x%X (width: %d, pitch: %d, depth: %d)\n",
 
786
                           vbemode, 
 
787
                           pScreenInfo->currentMode->HDisplay,     
 
788
                           pScreenInfo->displayWidth,
 
789
                           pScreenInfo->depth);
 
790
                outr(CRTC_OFF_PITCH,
 
791
                     SetBits(pScreenInfo->displayWidth>>3, CRTC_PITCH));
 
792
            } else {
 
793
                xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, "VBESetMode failed.\n");
 
794
            }
 
795
        } else {
 
796
            xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, "VBE module not loaded.\n");
 
797
        }
 
798
    } else {
 
799
        /* restore text mode with VBESetMode */
 
800
        if (pATI->pVBE) {
 
801
            if (VBESetVBEMode(pATI->pVBE, pATI->vbemode, NULL)) {
 
802
                xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, "Restoring VESA mode: 0x%x\n", 
 
803
                           pATI->vbemode);
 
804
            } else {
 
805
                xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, "VBESetMode failed.\n");
 
806
            }
 
807
        } else {
 
808
            xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, "VBE module not loaded.\n");
 
809
        }
 
810
    }
 
811
    if (xf86ServerIsExiting()) {
 
812
        if (pATI->pVBE) vbeFree(pATI->pVBE);
 
813
        if (pATI->pInt10) xf86FreeInt10(pATI->pInt10);
 
814
    }
 
815
}
 
816
 
 
817
#endif /* TV_OUT */
 
818
 
 
819
/*
 
820
 * ATIModeSet --
 
821
 *
 
822
 * This function sets a video mode.  It writes out all video state data that
 
823
 * has been previously calculated or saved.
 
824
 */
 
825
void
 
826
ATIModeSet
 
827
(
 
828
    ScrnInfoPtr pScreenInfo,
 
829
    ATIPtr      pATI,
 
830
    ATIHWPtr    pATIHW
 
831
)
 
832
{
 
833
 
 
834
#ifndef AVOID_CPIO
 
835
 
 
836
    int Index;
 
837
 
 
838
    /* Get back to bank 0 */
 
839
    (*pATIHW->SetBank)(pATI, 0);
 
840
 
 
841
#endif /* AVOID_CPIO */
 
842
 
 
843
    {
 
844
        /* Stop CRTC */
 
845
        outr(CRTC_GEN_CNTL,
 
846
            pATIHW->crtc_gen_cntl & ~(CRTC_EXT_DISP_EN | CRTC_EN));
 
847
 
 
848
        if (pATI->Chip >= ATI_CHIP_264CT)
 
849
        {
 
850
            ATIMach64PutPLLReg(PLL_VCLK_CNTL, pATIHW->pll_vclk_cntl);
 
851
            ATIMach64PutPLLReg(PLL_VCLK_POST_DIV, pATIHW->pll_vclk_post_div);
 
852
            ATIMach64PutPLLReg(PLL_VCLK0_FB_DIV, pATIHW->pll_vclk0_fb_div);
 
853
            ATIMach64PutPLLReg(PLL_VCLK1_FB_DIV, pATIHW->pll_vclk1_fb_div);
 
854
            ATIMach64PutPLLReg(PLL_VCLK2_FB_DIV, pATIHW->pll_vclk2_fb_div);
 
855
            ATIMach64PutPLLReg(PLL_VCLK3_FB_DIV, pATIHW->pll_vclk3_fb_div);
 
856
            ATIMach64PutPLLReg(PLL_XCLK_CNTL, pATIHW->pll_xclk_cntl);
 
857
            if (pATI->Chip >= ATI_CHIP_264LT)
 
858
                ATIMach64PutPLLReg(PLL_EXT_VPLL_CNTL,
 
859
                    pATIHW->pll_ext_vpll_cntl);
 
860
            ATIMach64PutPLLReg(PLL_VCLK_CNTL,
 
861
                pATIHW->pll_vclk_cntl & ~PLL_VCLK_RESET);
 
862
 
 
863
            /* Load LCD registers */
 
864
            if (pATI->LCDPanelID >= 0)
 
865
            {
 
866
                if (pATI->Chip == ATI_CHIP_264LT)
 
867
                {
 
868
                    /* Update non-shadow registers first */
 
869
                    outr(LCD_GEN_CTRL, pATIHW->lcd_gen_ctrl & ~SHADOW_RW_EN);
 
870
 
 
871
                    /* Temporarily disable stretching */
 
872
                    outr(HORZ_STRETCHING, pATIHW->horz_stretching &
 
873
                        ~(HORZ_STRETCH_MODE | HORZ_STRETCH_EN));
 
874
                    outr(VERT_STRETCHING, pATIHW->vert_stretching &
 
875
                        ~(VERT_STRETCH_RATIO1 | VERT_STRETCH_RATIO2 |
 
876
                          VERT_STRETCH_USE0 | VERT_STRETCH_EN));
 
877
                }
 
878
                else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
 
879
                            (pATI->Chip == ATI_CHIP_264XL) ||
 
880
                            (pATI->Chip == ATI_CHIP_MOBILITY)) */
 
881
                {
 
882
                    /* Update non-shadow registers first */
 
883
                    ATIMach64PutLCDReg(LCD_CONFIG_PANEL, pATIHW->config_panel);
 
884
                    ATIMach64PutLCDReg(LCD_GEN_CNTL, pATIHW->lcd_gen_ctrl &
 
885
                        ~(CRTC_RW_SELECT | SHADOW_RW_EN));
 
886
 
 
887
                    /* Temporarily disable stretching */
 
888
                    ATIMach64PutLCDReg(LCD_HORZ_STRETCHING,
 
889
                        pATIHW->horz_stretching &
 
890
                        ~(HORZ_STRETCH_MODE | HORZ_STRETCH_EN));
 
891
                    ATIMach64PutLCDReg(LCD_VERT_STRETCHING,
 
892
                        pATIHW->vert_stretching &
 
893
                        ~(VERT_STRETCH_RATIO1 | VERT_STRETCH_RATIO2 |
 
894
                          VERT_STRETCH_USE0 | VERT_STRETCH_EN));
 
895
                }
 
896
            }
 
897
        }
 
898
    }
 
899
 
 
900
    switch (pATIHW->crtc)
 
901
    {
 
902
 
 
903
#ifndef AVOID_CPIO
 
904
 
 
905
        case ATI_CRTC_VGA:
 
906
            /* Start sequencer reset */
 
907
            PutReg(SEQX, 0x00U, 0x00U);
 
908
 
 
909
            /* Set pixel clock */
 
910
            if ((pATIHW->FeedbackDivider > 0))
 
911
                ATIClockSet(pATI, pATIHW);
 
912
 
 
913
            /* Set up RAMDAC */
 
914
            if (pATI->DAC == ATI_DAC_IBMRGB514)
 
915
                ATIRGB514Set(pATI, pATIHW);
 
916
 
 
917
            /* Load VGA Wonder */
 
918
            if (pATI->CPIO_VGAWonder)
 
919
                ATIVGAWonderSet(pATI, pATIHW);
 
920
 
 
921
            /* Load VGA device */
 
922
            ATIVGASet(pATI, pATIHW);
 
923
 
 
924
            /* Load Mach64 registers */
 
925
            {
 
926
                /* Load MMIO registers */
 
927
                if (pATI->Block0Base)
 
928
                    ATIMach64Set(pATI, pATIHW);
 
929
 
 
930
                outr(CRTC_GEN_CNTL, pATIHW->crtc_gen_cntl);
 
931
                outr(CUR_CLR0, pATIHW->cur_clr0);
 
932
                outr(CUR_CLR1, pATIHW->cur_clr1);
 
933
                outr(CUR_OFFSET, pATIHW->cur_offset);
 
934
                outr(CUR_HORZ_VERT_POSN, pATIHW->cur_horz_vert_posn);
 
935
                outr(CUR_HORZ_VERT_OFF, pATIHW->cur_horz_vert_off);
 
936
                outr(BUS_CNTL, pATIHW->bus_cntl);
 
937
                outr(MEM_VGA_WP_SEL, pATIHW->mem_vga_wp_sel);
 
938
                outr(MEM_VGA_RP_SEL, pATIHW->mem_vga_rp_sel);
 
939
                outr(DAC_CNTL, pATIHW->dac_cntl);
 
940
                outr(GEN_TEST_CNTL, pATIHW->gen_test_cntl | GEN_GUI_EN);
 
941
                outr(GEN_TEST_CNTL, pATIHW->gen_test_cntl);
 
942
                outr(GEN_TEST_CNTL, pATIHW->gen_test_cntl | GEN_GUI_EN);
 
943
                outr(CONFIG_CNTL, pATIHW->config_cntl);
 
944
                if (pATI->Chip >= ATI_CHIP_264CT)
 
945
                {
 
946
                    outr(CRTC_H_TOTAL_DISP, pATIHW->crtc_h_total_disp);
 
947
                    outr(CRTC_H_SYNC_STRT_WID, pATIHW->crtc_h_sync_strt_wid);
 
948
                    outr(CRTC_V_TOTAL_DISP, pATIHW->crtc_v_total_disp);
 
949
                    outr(CRTC_V_SYNC_STRT_WID, pATIHW->crtc_v_sync_strt_wid);
 
950
                    outr(CRTC_OFF_PITCH, pATIHW->crtc_off_pitch);
 
951
                    if (pATI->Chip >= ATI_CHIP_264VTB)
 
952
                    {
 
953
                        outr(MEM_CNTL, pATIHW->mem_cntl);
 
954
                        outr(MPP_CONFIG, pATIHW->mpp_config);
 
955
                        outr(MPP_STROBE_SEQ, pATIHW->mpp_strobe_seq);
 
956
                        outr(TVO_CNTL, pATIHW->tvo_cntl);
 
957
                    }
 
958
                }
 
959
            }
 
960
 
 
961
            break;
 
962
 
 
963
#endif /* AVOID_CPIO */
 
964
 
 
965
        case ATI_CRTC_MACH64:
 
966
            /* Load Mach64 CRTC registers */
 
967
            ATIMach64Set(pATI, pATIHW);
 
968
 
 
969
#ifndef AVOID_CPIO
 
970
 
 
971
            if (pATI->VGAAdapter)
 
972
            {
 
973
                /* Oddly enough, these need to be set also, maybe others */
 
974
                PutReg(SEQX, 0x02U, pATIHW->seq[2]);
 
975
                PutReg(SEQX, 0x04U, pATIHW->seq[4]);
 
976
                PutReg(GRAX, 0x06U, pATIHW->gra[6]);
 
977
                if (pATI->CPIO_VGAWonder)
 
978
                    ATIModifyExtReg(pATI, 0xB6U, -1, 0x00U, pATIHW->b6);
 
979
            }
 
980
 
 
981
#endif /* AVOID_CPIO */
 
982
 
 
983
            break;
 
984
 
 
985
        default:
 
986
            break;
 
987
    }
 
988
 
 
989
    if (pATI->LCDPanelID >= 0)
 
990
    {
 
991
        /* Switch to shadow registers */
 
992
        if (pATI->Chip == ATI_CHIP_264LT)
 
993
            outr(LCD_GEN_CTRL, pATIHW->lcd_gen_ctrl | SHADOW_RW_EN);
 
994
        else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
 
995
                    (pATI->Chip == ATI_CHIP_264XL) ||
 
996
                    (pATI->Chip == ATI_CHIP_MOBILITY)) */
 
997
            ATIMach64PutLCDReg(LCD_GEN_CNTL,
 
998
                (pATIHW->lcd_gen_ctrl & ~CRTC_RW_SELECT) | SHADOW_RW_EN);
 
999
 
 
1000
        /* Restore shadow registers */
 
1001
        switch (pATIHW->crtc)
 
1002
        {
 
1003
 
 
1004
#ifndef AVOID_CPIO
 
1005
 
 
1006
            case ATI_CRTC_VGA:
 
1007
                for (Index = 0;
 
1008
                     Index < NumberOf(pATIHW->shadow_vga);
 
1009
                     Index++)
 
1010
                    PutReg(CRTX(pATI->CPIO_VGABase), Index,
 
1011
                        pATIHW->shadow_vga[Index]);
 
1012
                /* Fall through */
 
1013
 
 
1014
#endif /* AVOID_CPIO */
 
1015
 
 
1016
            case ATI_CRTC_MACH64:
 
1017
                outr(CRTC_H_TOTAL_DISP, pATIHW->shadow_h_total_disp);
 
1018
                outr(CRTC_H_SYNC_STRT_WID, pATIHW->shadow_h_sync_strt_wid);
 
1019
                outr(CRTC_V_TOTAL_DISP, pATIHW->shadow_v_total_disp);
 
1020
                outr(CRTC_V_SYNC_STRT_WID, pATIHW->shadow_v_sync_strt_wid);
 
1021
                break;
 
1022
 
 
1023
            default:
 
1024
                break;
 
1025
        }
 
1026
 
 
1027
        /* Restore CRTC selection & shadow state and enable stretching */
 
1028
        if (pATI->Chip == ATI_CHIP_264LT)
 
1029
        {
 
1030
            outr(LCD_GEN_CTRL, pATIHW->lcd_gen_ctrl);
 
1031
            outr(HORZ_STRETCHING, pATIHW->horz_stretching);
 
1032
            outr(VERT_STRETCHING, pATIHW->vert_stretching);
 
1033
        }
 
1034
        else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
 
1035
                    (pATI->Chip == ATI_CHIP_264XL) ||
 
1036
                    (pATI->Chip == ATI_CHIP_MOBILITY)) */
 
1037
        {
 
1038
            ATIMach64PutLCDReg(LCD_GEN_CNTL, pATIHW->lcd_gen_ctrl);
 
1039
            ATIMach64PutLCDReg(LCD_HORZ_STRETCHING, pATIHW->horz_stretching);
 
1040
            ATIMach64PutLCDReg(LCD_VERT_STRETCHING, pATIHW->vert_stretching);
 
1041
            ATIMach64PutLCDReg(LCD_EXT_VERT_STRETCH, pATIHW->ext_vert_stretch);
 
1042
            outr(LCD_INDEX, pATIHW->lcd_index);
 
1043
        }
 
1044
    }
 
1045
 
 
1046
    /*
 
1047
     * Set DSP registers.  Note that, for some reason, sequencer resets clear
 
1048
     * the DSP_CONFIG register on early integrated controllers.
 
1049
     */
 
1050
    if (pATI->Chip >= ATI_CHIP_264VTB)
 
1051
        ATIDSPSet(pATI, pATIHW);
 
1052
 
 
1053
    /* Load RAMDAC */
 
1054
    ATIDACSet(pATI, pATIHW);
 
1055
 
 
1056
    /* Reset hardware cursor caching */
 
1057
    pATI->CursorXOffset = pATI->CursorYOffset = (CARD16)(-1);
 
1058
 
 
1059
#ifdef TV_OUT
 
1060
 
 
1061
    /* Set VBE mode for TV-Out */
 
1062
    if (pATI->OptionTvOut /* && pATI->tvActive */)
 
1063
        ATISetVBEMode(pScreenInfo, pATI, pATIHW);
 
1064
 
 
1065
#endif /* TV_OUT */
 
1066
 
 
1067
#ifndef AVOID_CPIO
 
1068
 
 
1069
    /* Restore video memory */
 
1070
    ATISwap(pScreenInfo->scrnIndex, pATI, pATIHW, TRUE);
 
1071
 
 
1072
    if (pATI->VGAAdapter)
 
1073
        ATIVGASaveScreen(pATI, SCREEN_SAVER_OFF);       /* Turn on screen */
 
1074
 
 
1075
#endif /* AVOID_CPIO */
 
1076
 
 
1077
    if ((xf86GetVerbosity() > 3) && (pATIHW == &pATI->NewHW))
 
1078
    {
 
1079
        xf86ErrorFVerb(4, "\n After setting mode \"%s\":\n\n",
 
1080
            pScreenInfo->currentMode->name);
 
1081
        ATIPrintMode(pScreenInfo->currentMode);
 
1082
        ATIPrintRegisters(pATI);
 
1083
    }
 
1084
}