2
* Copyright 2000 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org
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.
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.
33
#include "atimach64.h"
34
#include "atimach64io.h"
37
#include "atirgb514.h"
39
#include "atiwonder.h"
40
#include "atiwonderio.h"
53
* This function is called to copy one or all banks of a VGA plane.
67
for (iBank = 0; iBank < pATIHW->nBank; iBank++)
69
(*pATIHW->SetBank)(pATI, iBank);
70
(void)memcpy(*to, *from, 0x00010000U);
71
*saveptr = (char *)(*saveptr) + 0x00010000U;
78
* This function saves/restores video memory contents during video mode
90
pointer save, *from, *to;
91
unsigned int iPlane = 0, PlaneMask = 1;
92
CARD8 seq2, seq4, gra1, gra3, gra4, gra5, gra6, gra8;
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.
100
if (pATIHW->crtc != ATI_CRTC_VGA)
105
if (!pATIHW->frame_buffer)
113
/* Allocate the memory */
114
if (!pATIHW->frame_buffer)
116
pATIHW->frame_buffer =
117
(pointer)malloc(pATIHW->nBank * pATIHW->nPlane * 0x00010000U);
118
if (!pATIHW->frame_buffer)
120
xf86DrvMsg(iScreen, X_WARNING,
121
"Temporary frame buffer could not be allocated.\n");
130
/* Turn off screen */
131
ATIVGASaveScreen(pATI, SCREEN_SAVER_ON);
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);
142
save = pATIHW->frame_buffer;
144
/* Temporarily normalise the mode */
146
PutReg(GRAX, 0x01U, 0x00U);
148
PutReg(GRAX, 0x03U, 0x00U);
150
PutReg(GRAX, 0x06U, 0x05U);
152
PutReg(GRAX, 0x08U, 0xFFU);
156
/* Setup packed mode memory */
158
PutReg(SEQX, 0x02U, 0x0FU);
160
PutReg(SEQX, 0x04U, 0x0AU);
161
if (pATI->Chip < ATI_CHIP_264CT)
164
PutReg(GRAX, 0x05U, 0x00U);
169
PutReg(GRAX, 0x05U, 0x40U);
172
ATICopyVGAMemory(pATI, pATIHW, &save, from, to);
175
PutReg(SEQX, 0x02U, seq2);
177
PutReg(SEQX, 0x04U, seq4);
178
if (pATI->Chip < ATI_CHIP_264CT)
181
PutReg(GRAX, 0x05U, gra5);
186
PutReg(GRAX, 0x05U, gra5);
191
gra4 = GetReg(GRAX, 0x04U);
193
/* Setup planar mode memory */
195
PutReg(SEQX, 0x04U, 0x06U);
197
PutReg(GRAX, 0x05U, 0x00U);
199
for (; iPlane < pATIHW->nPlane; iPlane++)
201
PutReg(SEQX, 0x02U, PlaneMask);
202
PutReg(GRAX, 0x04U, iPlane);
203
ATICopyVGAMemory(pATI, pATIHW, &save, from, to);
207
PutReg(SEQX, 0x02U, seq2);
209
PutReg(SEQX, 0x04U, seq4);
210
PutReg(GRAX, 0x04U, gra4);
212
PutReg(GRAX, 0x05U, gra5);
215
/* Restore registers */
217
PutReg(GRAX, 0x01U, gra1);
219
PutReg(GRAX, 0x03U, gra3);
221
PutReg(GRAX, 0x06U, gra6);
223
PutReg(GRAX, 0x08U, gra8);
226
(*pATIHW->SetBank)(pATI, 0);
229
#endif /* AVOID_CPIO */
234
* This function initialises an ATIHWRec with information common to all video
235
* states generated by the driver.
240
ScrnInfoPtr pScreenInfo,
249
if (pATI->VGAAdapter)
251
/* Fill in VGA data */
252
ATIVGAPreInit(pATI, pATIHW);
254
/* Fill in VGA Wonder data */
255
if (pATI->CPIO_VGAWonder)
256
ATIVGAWonderPreInit(pATI, pATIHW);
259
#endif /* AVOID_CPIO */
262
/* Fill in Mach64 data */
263
ATIMach64PreInit(pScreenInfo, pATI, pATIHW);
265
if (pATI->Chip >= ATI_CHIP_264CT)
267
/* Ensure proper VCLK source */
268
pATIHW->pll_vclk_cntl = ATIMach64GetPLLReg(PLL_VCLK_CNTL) |
269
(PLL_VCLK_SRC_SEL | PLL_VCLK_RESET);
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);
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);
286
/* Initialise CRTC data for LCD panels */
287
if (pATI->LCDPanelID >= 0)
289
if (pATI->Chip == ATI_CHIP_264LT)
291
pATIHW->lcd_gen_ctrl = inr(LCD_GEN_CTRL);
293
else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
294
(pATI->Chip == ATI_CHIP_264XL) ||
295
(pATI->Chip == ATI_CHIP_MOBILITY)) */
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) |
306
pATIHW->lcd_gen_ctrl =
307
ATIMach64GetLCDReg(LCD_GEN_CNTL) & ~CRTC_RW_SELECT;
308
outr(LCD_INDEX, lcd_index);
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;
317
if (!pATI->OptionPanelDisplay)
320
* Use primary CRTC to drive the CRT. Turn off panel
323
pATIHW->lcd_gen_ctrl &= ~LCD_ON;
324
pATIHW->lcd_gen_ctrl |= CRT_ON;
328
/* Use primary CRTC to drive the panel */
329
pATIHW->lcd_gen_ctrl |= LCD_ON;
331
/* If requested, also force CRT on */
332
if (pATI->OptionCRTDisplay)
333
pATIHW->lcd_gen_ctrl |= CRT_ON;
337
else if (pATI->DAC == ATI_DAC_IBMRGB514)
339
ATIRGB514PreInit(pATI, pATIHW);
343
/* Set RAMDAC data */
344
ATIDACPreInit(pScreenInfo, pATI, pATIHW);
350
* This function saves the current video state.
355
ScrnInfoPtr pScreenInfo,
365
/* Get back to bank 0 */
366
(*pATIHW->SetBank)(pATI, 0);
368
#endif /* AVOID_CPIO */
370
if (pATI->Chip >= ATI_CHIP_264CT)
372
pATIHW->pll_vclk_cntl = ATIMach64GetPLLReg(PLL_VCLK_CNTL) |
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);
383
/* Save LCD registers */
384
if (pATI->LCDPanelID >= 0)
386
if (pATI->Chip == ATI_CHIP_264LT)
388
pATIHW->horz_stretching = inr(HORZ_STRETCHING);
389
pATIHW->vert_stretching = inr(VERT_STRETCHING);
390
pATIHW->lcd_gen_ctrl = inr(LCD_GEN_CTRL);
392
/* Set up to save non-shadow registers */
393
outr(LCD_GEN_CTRL, pATIHW->lcd_gen_ctrl & ~SHADOW_RW_EN);
395
else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
396
(pATI->Chip == ATI_CHIP_264XL) ||
397
(pATI->Chip == ATI_CHIP_MOBILITY)) */
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);
409
/* Set up to save non-shadow registers */
410
ATIMach64PutLCDReg(LCD_GEN_CNTL,
411
pATIHW->lcd_gen_ctrl & ~(CRTC_RW_SELECT | SHADOW_RW_EN));
418
if (pATI->VGAAdapter)
421
ATIVGASave(pATI, pATIHW);
423
/* Save VGA Wonder data */
424
if (pATI->CPIO_VGAWonder)
425
ATIVGAWonderSave(pATI, pATIHW);
428
#endif /* AVOID_CPIO */
431
/* Save Mach64 data */
432
ATIMach64Save(pATI, pATIHW);
434
if (pATI->Chip >= ATI_CHIP_264VTB)
437
ATIDSPSave(pATI, pATIHW);
439
if (pATI->LCDPanelID >= 0)
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) |
453
/* Save shadow VGA CRTC registers */
455
Index < NumberOf(pATIHW->shadow_vga);
457
pATIHW->shadow_vga[Index] =
458
GetReg(CRTX(pATI->CPIO_VGABase), Index);
460
#endif /* AVOID_CPIO */
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);
468
/* Restore CRTC selection and shadow state */
469
if (pATI->Chip == ATI_CHIP_264LT)
471
outr(LCD_GEN_CTRL, pATIHW->lcd_gen_ctrl);
473
else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
474
(pATI->Chip == ATI_CHIP_264XL) ||
475
(pATI->Chip == ATI_CHIP_MOBILITY)) */
477
ATIMach64PutLCDReg(LCD_GEN_CNTL, pATIHW->lcd_gen_ctrl);
478
outr(LCD_INDEX, pATIHW->lcd_index);
482
else if (pATI->DAC == ATI_DAC_IBMRGB514)
483
ATIRGB514Save(pATI, pATIHW);
486
/* Save RAMDAC state */
487
ATIDACSave(pATI, pATIHW);
489
if (pATIHW != &pATI->NewHW)
491
pATIHW->FeedbackDivider = 0; /* Don't programme clock */
496
/* Save video memory */
497
ATISwap(pScreenInfo->scrnIndex, pATI, pATIHW, FALSE);
499
if (pATI->VGAAdapter)
500
ATIVGASaveScreen(pATI, SCREEN_SAVER_OFF); /* Turn on screen */
502
#endif /* AVOID_CPIO */
507
* ATIModeCalculate --
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.
523
int Index, ECPClock, MaxScalerClock;
525
/* Fill in Mach64 data */
526
ATIMach64Calculate(pATI, pATIHW, pMode);
528
/* Set up LCD register values */
529
if (pATI->LCDPanelID >= 0)
531
int VDisplay = pMode->VDisplay;
533
if (pMode->Flags & V_DBLSCAN)
535
if (pMode->VScan > 1)
536
VDisplay *= pMode->VScan;
537
if (pMode->Flags & V_INTERLACE)
540
/* Ensure secondary CRTC is completely disabled */
541
pATIHW->crtc_gen_cntl &= ~(CRTC2_EN | CRTC2_PIX_WIDTH);
543
if (pATI->Chip == ATI_CHIP_264LT)
545
pATIHW->horz_stretching = inr(HORZ_STRETCHING);
547
else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
548
(pATI->Chip == ATI_CHIP_264XL) ||
549
(pATI->Chip == ATI_CHIP_MOBILITY)) */
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);
558
* Don't use vertical blending if the mode is too wide or not
559
* vertically stretched.
561
if (pATI->OptionPanelDisplay &&
562
(pMode->HDisplay <= pATI->LCDVBlendFIFOSize) &&
563
(VDisplay < pATI->LCDVertical))
564
pATIHW->ext_vert_stretch |= VERT_STRETCH_MODE;
566
outr(LCD_INDEX, lcd_index);
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))
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.
586
int HDisplay = pMode->HDisplay & ~7;
587
int nStretch = pATI->LCDHorizontal / HDisplay;
588
int Remainder = pATI->LCDHorizontal % HDisplay;
590
if ((!Remainder && ((nStretch > 2) || !pATI->OptionBlend)) ||
591
(((HDisplay * 16) / pATI->LCDHorizontal) < 7))
593
static const char StretchLoops[] = {10, 12, 13, 15, 16};
594
int horz_stretch_loop = -1, BestRemainder;
595
int Numerator = HDisplay, Denominator = pATI->LCDHorizontal;
597
ATIReduceRatio(&Numerator, &Denominator);
599
BestRemainder = (Numerator * 16) / Denominator;
600
Index = NumberOf(StretchLoops);
604
((Denominator - Numerator) * StretchLoops[Index]) %
606
if (Remainder < BestRemainder)
608
horz_stretch_loop = Index;
609
if (!(BestRemainder = Remainder))
614
* Enabling this code allows the pixel-replicated mode to
615
* be slightly wider than the panel width.
617
Remainder = Denominator - Remainder;
618
if (Remainder < BestRemainder)
620
horz_stretch_loop = Index;
621
BestRemainder = Remainder;
626
if ((horz_stretch_loop >= 0) &&
627
(!BestRemainder || !pATI->OptionBlend))
629
int horz_stretch_ratio = 0, Accumulator = 0;
630
int reuse_previous = 1;
632
Index = StretchLoops[horz_stretch_loop];
637
horz_stretch_ratio |= reuse_previous;
639
Accumulator += Denominator;
640
Accumulator -= Numerator;
641
reuse_previous <<= 1;
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) */
651
pATIHW->horz_stretching |= (HORZ_STRETCH_MODE | HORZ_STRETCH_EN) |
652
SetBits((HDisplay * (MaxBits(HORZ_STRETCH_BLEND) + 1)) /
653
pATI->LCDHorizontal, HORZ_STRETCH_BLEND);
656
if (!pATI->OptionPanelDisplay || (VDisplay >= pATI->LCDVertical))
658
pATIHW->vert_stretching = 0;
662
pATIHW->vert_stretching = (VERT_STRETCH_USE0 | VERT_STRETCH_EN) |
663
SetBits((VDisplay * (MaxBits(VERT_STRETCH_RATIO0) + 1)) /
664
pATI->LCDVertical, VERT_STRETCH_RATIO0);
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];
673
#endif /* AVOID_CPIO */
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;
681
/* Fill in clock data */
682
if (!ATIClockCalculate(iScreen, pATI, pATIHW, pMode))
685
/* Setup ECP clock divider */
686
if (pATI->Chip >= ATI_CHIP_264VT)
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;
697
MaxScalerClock = 80000; /* Conservative */
698
pATIHW->pll_vclk_cntl &= ~PLL_ECP_DIV;
700
if (pATI->OptionTvOut) {
701
/* XXX Don't do this for TVOut! */
706
ECPClock = pMode->SynthClock;
707
for (Index = 0; (ECPClock > MaxScalerClock) && (Index < 2); Index++)
709
pATIHW->pll_vclk_cntl |= SetBits(Index, PLL_ECP_DIV);
712
else if (pATI->DAC == ATI_DAC_IBMRGB514)
714
ATIRGB514Calculate(pATI, pATIHW, pMode);
725
ScrnInfoPtr pScreenInfo,
730
if (pATIHW->crtc == ATI_CRTC_MACH64) {
731
int vbemode, modekey;
733
/* Find a suitable VESA VBE mode, if one exists */
734
modekey = (pScreenInfo->depth << 16) |
735
(pScreenInfo->currentMode->HDisplay);
760
case (15<<16)|(1024):
763
case (16<<16)|(1024):
767
case (24<<16)|(1024):
772
xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
773
"Mode not supported for TV-Out: depth: %d HDisplay: %d\n",
774
modekey>>16, modekey & 0xffff);
780
/* Preserve video memory contents */
783
if (VBESetVBEMode(pATI->pVBE, vbemode, NULL)) {
784
xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
785
"VBESetMode: 0x%X (width: %d, pitch: %d, depth: %d)\n",
787
pScreenInfo->currentMode->HDisplay,
788
pScreenInfo->displayWidth,
791
SetBits(pScreenInfo->displayWidth>>3, CRTC_PITCH));
793
xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, "VBESetMode failed.\n");
796
xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, "VBE module not loaded.\n");
799
/* restore text mode with VBESetMode */
801
if (VBESetVBEMode(pATI->pVBE, pATI->vbemode, NULL)) {
802
xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, "Restoring VESA mode: 0x%x\n",
805
xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, "VBESetMode failed.\n");
808
xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, "VBE module not loaded.\n");
811
if (xf86ServerIsExiting()) {
812
if (pATI->pVBE) vbeFree(pATI->pVBE);
813
if (pATI->pInt10) xf86FreeInt10(pATI->pInt10);
822
* This function sets a video mode. It writes out all video state data that
823
* has been previously calculated or saved.
828
ScrnInfoPtr pScreenInfo,
838
/* Get back to bank 0 */
839
(*pATIHW->SetBank)(pATI, 0);
841
#endif /* AVOID_CPIO */
846
pATIHW->crtc_gen_cntl & ~(CRTC_EXT_DISP_EN | CRTC_EN));
848
if (pATI->Chip >= ATI_CHIP_264CT)
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);
863
/* Load LCD registers */
864
if (pATI->LCDPanelID >= 0)
866
if (pATI->Chip == ATI_CHIP_264LT)
868
/* Update non-shadow registers first */
869
outr(LCD_GEN_CTRL, pATIHW->lcd_gen_ctrl & ~SHADOW_RW_EN);
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));
878
else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
879
(pATI->Chip == ATI_CHIP_264XL) ||
880
(pATI->Chip == ATI_CHIP_MOBILITY)) */
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));
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));
900
switch (pATIHW->crtc)
906
/* Start sequencer reset */
907
PutReg(SEQX, 0x00U, 0x00U);
909
/* Set pixel clock */
910
if ((pATIHW->FeedbackDivider > 0))
911
ATIClockSet(pATI, pATIHW);
914
if (pATI->DAC == ATI_DAC_IBMRGB514)
915
ATIRGB514Set(pATI, pATIHW);
917
/* Load VGA Wonder */
918
if (pATI->CPIO_VGAWonder)
919
ATIVGAWonderSet(pATI, pATIHW);
921
/* Load VGA device */
922
ATIVGASet(pATI, pATIHW);
924
/* Load Mach64 registers */
926
/* Load MMIO registers */
927
if (pATI->Block0Base)
928
ATIMach64Set(pATI, pATIHW);
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)
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)
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);
963
#endif /* AVOID_CPIO */
965
case ATI_CRTC_MACH64:
966
/* Load Mach64 CRTC registers */
967
ATIMach64Set(pATI, pATIHW);
971
if (pATI->VGAAdapter)
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);
981
#endif /* AVOID_CPIO */
989
if (pATI->LCDPanelID >= 0)
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);
1000
/* Restore shadow registers */
1001
switch (pATIHW->crtc)
1008
Index < NumberOf(pATIHW->shadow_vga);
1010
PutReg(CRTX(pATI->CPIO_VGABase), Index,
1011
pATIHW->shadow_vga[Index]);
1014
#endif /* AVOID_CPIO */
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);
1027
/* Restore CRTC selection & shadow state and enable stretching */
1028
if (pATI->Chip == ATI_CHIP_264LT)
1030
outr(LCD_GEN_CTRL, pATIHW->lcd_gen_ctrl);
1031
outr(HORZ_STRETCHING, pATIHW->horz_stretching);
1032
outr(VERT_STRETCHING, pATIHW->vert_stretching);
1034
else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
1035
(pATI->Chip == ATI_CHIP_264XL) ||
1036
(pATI->Chip == ATI_CHIP_MOBILITY)) */
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);
1047
* Set DSP registers. Note that, for some reason, sequencer resets clear
1048
* the DSP_CONFIG register on early integrated controllers.
1050
if (pATI->Chip >= ATI_CHIP_264VTB)
1051
ATIDSPSet(pATI, pATIHW);
1054
ATIDACSet(pATI, pATIHW);
1056
/* Reset hardware cursor caching */
1057
pATI->CursorXOffset = pATI->CursorYOffset = (CARD16)(-1);
1061
/* Set VBE mode for TV-Out */
1062
if (pATI->OptionTvOut /* && pATI->tvActive */)
1063
ATISetVBEMode(pScreenInfo, pATI, pATIHW);
1069
/* Restore video memory */
1070
ATISwap(pScreenInfo->scrnIndex, pATI, pATIHW, TRUE);
1072
if (pATI->VGAAdapter)
1073
ATIVGASaveScreen(pATI, SCREEN_SAVER_OFF); /* Turn on screen */
1075
#endif /* AVOID_CPIO */
1077
if ((xf86GetVerbosity() > 3) && (pATIHW == &pATI->NewHW))
1079
xf86ErrorFVerb(4, "\n After setting mode \"%s\":\n\n",
1080
pScreenInfo->currentMode->name);
1081
ATIPrintMode(pScreenInfo->currentMode);
1082
ATIPrintRegisters(pATI);