1 /*
2  * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario,
3  *                      Precision Insight, Inc., Cedar Park, Texas, and
4  *                      VA Linux Systems Inc., Fremont, California.
5  *
6  * All Rights Reserved.
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining
9  * a copy of this software and associated documentation files (the
10  * "Software"), to deal in the Software without restriction, including
11  * without limitation on the rights to use, copy, modify, merge,
12  * publish, distribute, sublicense, and/or sell copies of the Software,
13  * and to permit persons to whom the Software is furnished to do so,
14  * subject to the following conditions:
15  *
16  * The above copyright notice and this permission notice (including the
17  * next paragraph) shall be included in all copies or substantial
18  * portions of the Software.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23  * NON-INFRINGEMENT.  IN NO EVENT SHALL ATI, PRECISION INSIGHT, VA LINUX
24  * SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
25  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
26  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27  * OTHER DEALINGS IN THE SOFTWARE.
28  */
29 
30 #ifdef HAVE_CONFIG_H
31 #include "config.h"
32 #endif
33 
34 /*
35  * Authors:
36  *   Rickard E. Faith <faith@valinux.com>
37  *   Kevin E. Martin <martin@valinux.com>
38  *   Gareth Hughes <gareth@valinux.com>
39  *
40  * Credits:
41  *
42  *   Thanks to Alan Hourihane <alanh@fairlite.demon..co.uk> and SuSE for
43  *   providing source code to their 3.3.x Rage 128 driver.  Portions of
44  *   this file are based on the initialization code for that driver.
45  *
46  * References:
47  *
48  *   RAGE 128 VR/ RAGE 128 GL Register Reference Manual (Technical
49  *   Reference Manual P/N RRG-G04100-C Rev. 0.04), ATI Technologies: April
50  *   1999.
51  *
52  *   RAGE 128 Software Development Manual (Technical Reference Manual P/N
53  *   SDK-G04000 Rev. 0.01), ATI Technologies: June 1999.
54  *
55  * This server does not yet support these XFree86 4.0 features:
56  *   DDC1 & DDC2
57  *   shadowfb
58  *   overlay planes
59  *
60  * Modified by Marc Aurele La France <tsi@xfree86.org> for ATI driver merge.
61  *
62  * Dualhead support - Alex Deucher <agd5f@yahoo.com>
63  */
64 
65 #include <string.h>
66 #include <stdio.h>
67 
68 				/* Driver data structures */
69 #include "r128.h"
70 #include "r128_probe.h"
71 #include "r128_reg.h"
72 #include "r128_version.h"
73 
74 #ifdef R128DRI
75 #define _XF86DRI_SERVER_
76 #include "r128_dri.h"
77 #include "r128_common.h"
78 #include "r128_sarea.h"
79 #endif
80 
81 				/* colormap initialization */
82 #include "micmap.h"
83 
84 				/* X and server generic header files */
85 #include "xf86.h"
86 #include "xf86_OSproc.h"
87 #include "xf86RandR12.h"
88 #if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6
89 #include "xf86RAC.h"
90 #include "xf86Resources.h"
91 #endif
92 #include "xf86cmap.h"
93 #include "xf86xv.h"
94 #include "vbe.h"
95 
96 				/* fbdevhw & vgahw */
97 #ifdef WITH_VGAHW
98 #include "vgaHW.h"
99 #endif
100 #include "fbdevhw.h"
101 #include "dixstruct.h"
102 
103 				/* DPMS support. */
104 #ifdef HAVE_XEXTPROTO_71
105 #include <X11/extensions/dpmsconst.h>
106 #else
107 #define DPMS_SERVER
108 #include <X11/extensions/dpms.h>
109 #endif
110 
111 
112 static Bool R128CloseScreen(CLOSE_SCREEN_ARGS_DECL);
113 static Bool R128SaveScreen(ScreenPtr pScreen, int mode);
114 static void R128Save(ScrnInfoPtr pScrn);
115 static void R128Restore(ScrnInfoPtr pScrn);
116 
117 typedef enum {
118   OPTION_NOACCEL,
119   OPTION_FBDEV,
120   OPTION_DAC_6BIT,
121   OPTION_VGA_ACCESS,
122   OPTION_SHOW_CACHE,
123   OPTION_SW_CURSOR,
124   OPTION_VIDEO_KEY,
125   OPTION_PANEL_WIDTH,
126   OPTION_PANEL_HEIGHT,
127   OPTION_PROG_FP_REGS,
128 #ifdef R128DRI
129   OPTION_XV_DMA,
130   OPTION_IS_PCI,
131   OPTION_CCE_PIO,
132   OPTION_NO_SECURITY,
133   OPTION_USEC_TIMEOUT,
134   OPTION_AGP_MODE,
135   OPTION_AGP_SIZE,
136   OPTION_RING_SIZE,
137   OPTION_BUFFER_SIZE,
138   OPTION_PAGE_FLIP,
139 #endif
140   OPTION_ACCELMETHOD,
141   OPTION_RENDERACCEL
142 } R128Opts;
143 
144 static const OptionInfoRec R128Options[] = {
145 { OPTION_NOACCEL,      "NoAccel",          OPTV_BOOLEAN, {0}, FALSE },
146 { OPTION_FBDEV,        "UseFBDev",         OPTV_BOOLEAN, {0}, FALSE },
147 { OPTION_DAC_6BIT,     "Dac6Bit",          OPTV_BOOLEAN, {0}, FALSE },
148 { OPTION_VGA_ACCESS,   "VGAAccess",        OPTV_BOOLEAN, {0}, TRUE  },
149 { OPTION_SHOW_CACHE,   "ShowCache",        OPTV_BOOLEAN, {0}, FALSE },
150 { OPTION_SW_CURSOR,    "SWcursor",         OPTV_BOOLEAN, {0}, FALSE },
151 { OPTION_VIDEO_KEY,    "VideoKey",         OPTV_INTEGER, {0}, FALSE },
152 { OPTION_PANEL_WIDTH,  "PanelWidth",       OPTV_INTEGER, {0}, FALSE },
153 { OPTION_PANEL_HEIGHT, "PanelHeight",      OPTV_INTEGER, {0}, FALSE },
154 { OPTION_PROG_FP_REGS, "ProgramFPRegs",    OPTV_BOOLEAN, {0}, FALSE },
155 #ifdef R128DRI
156   { OPTION_XV_DMA,       "DMAForXv",         OPTV_BOOLEAN, {0}, FALSE },
157   { OPTION_IS_PCI,       "ForcePCIMode",     OPTV_BOOLEAN, {0}, FALSE },
158   { OPTION_CCE_PIO,      "CCEPIOMode",       OPTV_BOOLEAN, {0}, FALSE },
159   { OPTION_NO_SECURITY,  "CCENoSecurity",    OPTV_BOOLEAN, {0}, FALSE },
160   { OPTION_USEC_TIMEOUT, "CCEusecTimeout",   OPTV_INTEGER, {0}, FALSE },
161   { OPTION_AGP_MODE,     "AGPMode",          OPTV_INTEGER, {0}, FALSE },
162   { OPTION_AGP_SIZE,     "AGPSize",          OPTV_INTEGER, {0}, FALSE },
163   { OPTION_RING_SIZE,    "RingSize",         OPTV_INTEGER, {0}, FALSE },
164   { OPTION_BUFFER_SIZE,  "BufferSize",       OPTV_INTEGER, {0}, FALSE },
165   { OPTION_PAGE_FLIP,    "EnablePageFlip",   OPTV_BOOLEAN, {0}, FALSE },
166 #endif
167   { OPTION_ACCELMETHOD,  "AccelMethod",      OPTV_STRING,  {0}, FALSE },
168   { OPTION_RENDERACCEL,  "RenderAccel",      OPTV_BOOLEAN, {0}, FALSE },
169   { -1,                  NULL,               OPTV_NONE,    {0}, FALSE }
170 };
171 
R128OptionsWeak(void)172 const OptionInfoRec *R128OptionsWeak(void) { return R128Options; }
173 
174 R128RAMRec R128RAM[] = {        /* Memory Specifications
175 				   From RAGE 128 Software Development
176 				   Manual (Technical Reference Manual P/N
177 				   SDK-G04000 Rev 0.01), page 3-21.  */
178     { 4, 4, 3, 3, 1, 3, 1, 16, 12, "128-bit SDR SGRAM 1:1" },
179     { 4, 8, 3, 3, 1, 3, 1, 17, 13, "64-bit SDR SGRAM 1:1" },
180     { 4, 4, 1, 2, 1, 2, 1, 16, 12, "64-bit SDR SGRAM 2:1" },
181     { 4, 4, 3, 3, 2, 3, 1, 16, 12, "64-bit DDR SGRAM" },
182 };
183 
184 extern _X_EXPORT int gR128EntityIndex;
185 
getR128EntityIndex(void)186 int getR128EntityIndex(void)
187 {
188     return gR128EntityIndex;
189 }
190 
R128EntPriv(ScrnInfoPtr pScrn)191 R128EntPtr R128EntPriv(ScrnInfoPtr pScrn)
192 {
193     DevUnion     *pPriv;
194     R128InfoPtr  info   = R128PTR(pScrn);
195     pPriv = xf86GetEntityPrivate(info->pEnt->index,
196                                  getR128EntityIndex());
197     return pPriv->ptr;
198 }
199 
200 /* Allocate our private R128InfoRec. */
R128GetRec(ScrnInfoPtr pScrn)201 static Bool R128GetRec(ScrnInfoPtr pScrn)
202 {
203     if (pScrn->driverPrivate) return TRUE;
204 
205     pScrn->driverPrivate = xnfcalloc(sizeof(R128InfoRec), 1);
206     return TRUE;
207 }
208 
209 /* Free our private R128InfoRec. */
R128FreeRec(ScrnInfoPtr pScrn)210 static void R128FreeRec(ScrnInfoPtr pScrn)
211 {
212     if (!pScrn || !pScrn->driverPrivate) return;
213     free(pScrn->driverPrivate);
214     pScrn->driverPrivate = NULL;
215 }
216 
217 /* Memory map the MMIO region.  Used during pre-init and by R128MapMem,
218    below. */
R128MapMMIO(ScrnInfoPtr pScrn)219 static Bool R128MapMMIO(ScrnInfoPtr pScrn)
220 {
221     R128InfoPtr info          = R128PTR(pScrn);
222 
223     if (info->FBDev) {
224 	info->MMIO = fbdevHWMapMMIO(pScrn);
225     } else {
226 #ifndef XSERVER_LIBPCIACCESS
227 	info->MMIO = xf86MapPciMem(pScrn->scrnIndex,
228 				   VIDMEM_MMIO | VIDMEM_READSIDEEFFECT,
229 				   info->PciTag,
230 				   info->MMIOAddr,
231 				   R128_MMIOSIZE);
232         if (!info->MMIO) return FALSE;
233 #else
234 	int err = pci_device_map_range(info->PciInfo,
235 				       info->MMIOAddr,
236 				       R128_MMIOSIZE,
237 				       PCI_DEV_MAP_FLAG_WRITABLE,
238 				       &info->MMIO);
239 
240 	if (err) {
241 	    xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
242                         "Unable to map MMIO aperture. %s (%d)\n",
243                         strerror (err), err);
244 	    return FALSE;
245 	}
246 #endif
247     }
248 
249     return TRUE;
250 }
251 
252 /* Unmap the MMIO region.  Used during pre-init and by R128UnmapMem,
253    below. */
R128UnmapMMIO(ScrnInfoPtr pScrn)254 static Bool R128UnmapMMIO(ScrnInfoPtr pScrn)
255 {
256     R128InfoPtr info          = R128PTR(pScrn);
257 
258     if (info->FBDev)
259 	fbdevHWUnmapMMIO(pScrn);
260     else {
261 #ifndef XSERVER_LIBPCIACCESS
262 	xf86UnMapVidMem(pScrn->scrnIndex, info->MMIO, R128_MMIOSIZE);
263 #else
264 	pci_device_unmap_range(info->PciInfo, info->MMIO, R128_MMIOSIZE);
265 #endif
266     }
267     info->MMIO = NULL;
268     return TRUE;
269 }
270 
271 /* Memory map the frame buffer.  Used by R128MapMem, below. */
R128MapFB(ScrnInfoPtr pScrn)272 static Bool R128MapFB(ScrnInfoPtr pScrn)
273 {
274     R128InfoPtr info          = R128PTR(pScrn);
275 
276     if (info->FBDev) {
277 	info->FB = fbdevHWMapVidmem(pScrn);
278     } else {
279 #ifndef XSERVER_LIBPCIACCESS
280 	info->FB = xf86MapPciMem(pScrn->scrnIndex,
281 				 VIDMEM_FRAMEBUFFER,
282 				 info->PciTag,
283 				 info->LinearAddr,
284 				 info->FbMapSize);
285 #else
286 	int err = pci_device_map_range(info->PciInfo,
287 				       info->LinearAddr,
288 				       info->FbMapSize,
289 				       PCI_DEV_MAP_FLAG_WRITABLE |
290 				       PCI_DEV_MAP_FLAG_WRITE_COMBINE,
291 				       &info->FB);
292 
293 	if (err) {
294 	    xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
295                         "Unable to map FB aperture. %s (%d)\n",
296                         strerror (err), err);
297 	    return FALSE;
298 	}
299 #endif
300     }
301 
302     if (!info->FB) return FALSE;
303     return TRUE;
304 }
305 
306 /* Unmap the frame buffer.  Used by R128UnmapMem, below. */
R128UnmapFB(ScrnInfoPtr pScrn)307 static Bool R128UnmapFB(ScrnInfoPtr pScrn)
308 {
309     R128InfoPtr info          = R128PTR(pScrn);
310 
311     if (info->FBDev)
312 	fbdevHWUnmapVidmem(pScrn);
313     else
314 #ifndef XSERVER_LIBPCIACCESS
315 	xf86UnMapVidMem(pScrn->scrnIndex, info->FB, info->FbMapSize);
316 #else
317 	pci_device_unmap_range(info->PciInfo, info->FB, info->FbMapSize);
318 #endif
319     info->FB = NULL;
320     return TRUE;
321 }
322 
323 /* Memory map the MMIO region and the frame buffer. */
R128MapMem(ScrnInfoPtr pScrn)324 static Bool R128MapMem(ScrnInfoPtr pScrn)
325 {
326     if (!R128MapMMIO(pScrn)) return FALSE;
327     if (!R128MapFB(pScrn)) {
328 	R128UnmapMMIO(pScrn);
329 	return FALSE;
330     }
331     return TRUE;
332 }
333 
334 /* Unmap the MMIO region and the frame buffer. */
R128UnmapMem(ScrnInfoPtr pScrn)335 static Bool R128UnmapMem(ScrnInfoPtr pScrn)
336 {
337     if (!R128UnmapMMIO(pScrn) || !R128UnmapFB(pScrn)) return FALSE;
338     return TRUE;
339 }
340 
341 /* Read PLL information */
R128INPLL(ScrnInfoPtr pScrn,int addr)342 unsigned R128INPLL(ScrnInfoPtr pScrn, int addr)
343 {
344     R128InfoPtr   info      = R128PTR(pScrn);
345     unsigned char *R128MMIO = info->MMIO;
346 
347     OUTREG8(R128_CLOCK_CNTL_INDEX, addr & 0x3f);
348     return INREG(R128_CLOCK_CNTL_DATA);
349 }
350 
351 #if 0
352 /* Read PAL information (only used for debugging). */
353 static int R128INPAL(int idx)
354 {
355     R128InfoPtr   info      = R128PTR(pScrn);
356     unsigned char *R128MMIO = info->MMIO;
357 
358     OUTREG(R128_PALETTE_INDEX, idx << 16);
359     return INREG(R128_PALETTE_DATA);
360 }
361 #endif
362 
363 /* Wait for vertical sync. */
R128WaitForVerticalSync(ScrnInfoPtr pScrn)364 void R128WaitForVerticalSync(ScrnInfoPtr pScrn)
365 {
366     R128InfoPtr   info      = R128PTR(pScrn);
367     unsigned char *R128MMIO = info->MMIO;
368     int           i;
369 
370     OUTREG(R128_GEN_INT_STATUS, R128_VSYNC_INT_AK);
371     for (i = 0; i < R128_TIMEOUT; i++) {
372 	if (INREG(R128_GEN_INT_STATUS) & R128_VSYNC_INT) break;
373     }
374 }
375 
376 /* Compute log base 2 of val. */
R128MinBits(int val)377 int R128MinBits(int val)
378 {
379     int bits;
380 
381     if (!val) return 1;
382     for (bits = 0; val; val >>= 1, ++bits);
383     return bits;
384 }
385 
386 /* Finds the first output using a given crtc. */
R128FirstOutput(xf86CrtcPtr crtc)387 xf86OutputPtr R128FirstOutput(xf86CrtcPtr crtc)
388 {
389     ScrnInfoPtr pScrn = crtc->scrn;
390     xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
391     xf86OutputPtr output = xf86_config->output[0];
392     int o;
393 
394     for (o = 0; o < xf86_config->num_output; o++) {
395         output = xf86_config->output[o];
396         if (output->crtc == crtc) break;
397     }
398 
399     return output;
400 }
401 
402 /* Read the Video BIOS block. */
R128GetBIOSParameters(ScrnInfoPtr pScrn,xf86Int10InfoPtr pInt10)403 static Bool R128GetBIOSParameters(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
404 {
405     R128InfoPtr info = R128PTR(pScrn);
406 
407 #ifdef XSERVER_LIBPCIACCESS
408     int size = info->PciInfo->rom_size > R128_VBIOS_SIZE ? info->PciInfo->rom_size : R128_VBIOS_SIZE;
409     info->VBIOS = malloc(size);
410 #else
411     info->VBIOS = malloc(R128_VBIOS_SIZE);
412 #endif
413 
414     if (!info->VBIOS) {
415 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
416 		   "Cannot allocate space for hold Video BIOS!\n");
417 	return FALSE;
418     }
419 
420     if (pInt10) {
421 	info->BIOSAddr = pInt10->BIOSseg << 4;
422 	(void)memcpy(info->VBIOS, xf86int10Addr(pInt10, info->BIOSAddr),
423 		     R128_VBIOS_SIZE);
424     } else {
425 #ifdef XSERVER_LIBPCIACCESS
426 	if (pci_device_read_rom(info->PciInfo, info->VBIOS)) {
427 	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
428 		       "Failed to read PCI ROM!\n");
429 	}
430 #else
431 	xf86ReadPciBIOS(0, info->PciTag, 0, info->VBIOS, R128_VBIOS_SIZE);
432 	if (info->VBIOS[0] != 0x55 || info->VBIOS[1] != 0xaa) {
433 	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
434 		       "Video BIOS not detected in PCI space!\n");
435 	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
436 		       "Attempting to read Video BIOS from legacy ISA space!\n");
437 	    info->BIOSAddr = 0x000c0000;
438 	    xf86ReadDomainMemory(info->PciTag, info->BIOSAddr, R128_VBIOS_SIZE, info->VBIOS);
439 	}
440 #endif
441     }
442     if (info->VBIOS[0] != 0x55 || info->VBIOS[1] != 0xaa) {
443 	info->BIOSAddr = 0x00000000;
444 	free(info->VBIOS);
445 	info->VBIOS = NULL;
446 	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
447 		   "Video BIOS not found!\n");
448     }
449 
450     return TRUE;
451 }
452 
453 /* Read the FP parameters if an LVDS panel is expected. */
R128GetPanelInfoFromBIOS(xf86OutputPtr output)454 void R128GetPanelInfoFromBIOS(xf86OutputPtr output)
455 {
456     ScrnInfoPtr pScrn = output->scrn;
457     R128InfoPtr info  = R128PTR(pScrn);
458     R128OutputPrivatePtr r128_output = output->driver_private;
459     int FPHeader = 0;
460     int i;
461 
462     r128_output->PanelPwrDly = 200;
463     xf86GetOptValInteger(info->Options, OPTION_PANEL_WIDTH,  &(r128_output->PanelXRes));
464     xf86GetOptValInteger(info->Options, OPTION_PANEL_HEIGHT, &(r128_output->PanelYRes));
465 
466     if (!info->VBIOS) return;
467     info->FPBIOSstart = 0;
468 
469     /* FIXME: There should be direct access to the start of the FP info
470      * tables, but until we find out where that offset is stored, we
471      * must search for the ATI signature string: "M3      ".
472      */
473     for (i = 4; i < R128_VBIOS_SIZE - 8; i++) {
474         if (R128_BIOS8(i)     == 'M' &&
475             R128_BIOS8(i + 1) == '3' &&
476             R128_BIOS8(i + 2) == ' ' &&
477             R128_BIOS8(i + 3) == ' ' &&
478             R128_BIOS8(i + 4) == ' ' &&
479             R128_BIOS8(i + 5) == ' ' &&
480             R128_BIOS8(i + 6) == ' ' &&
481             R128_BIOS8(i + 7) == ' ') {
482             FPHeader = i - 2;
483             break;
484         }
485     }
486 
487     if (!FPHeader) return;
488 
489     /* Assume that only one panel is attached and supported */
490     for (i = FPHeader + 20; i < FPHeader + 84; i += 2) {
491         if (R128_BIOS16(i) != 0) {
492             info->FPBIOSstart = R128_BIOS16(i);
493             break;
494         }
495     }
496 
497     if (!info->FPBIOSstart) return;
498 
499     if (!r128_output->PanelXRes)
500         r128_output->PanelXRes = R128_BIOS16(info->FPBIOSstart + 25);
501     if (!r128_output->PanelYRes)
502         r128_output->PanelYRes = R128_BIOS16(info->FPBIOSstart + 27);
503     xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel size: %dx%d\n",
504                r128_output->PanelXRes, r128_output->PanelYRes);
505 
506     r128_output->PanelPwrDly = R128_BIOS8(info->FPBIOSstart + 56);
507 
508     if (!r128_output->PanelXRes || !r128_output->PanelYRes) {
509         info->HasPanelRegs = FALSE;
510         xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
511 		   "Can't determine panel dimensions, and none specified.\n"
512 		   "\tDisabling programming of FP registers.\n");
513     }
514 
515     xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel ID: ");
516     for (i = 1; i <= 24; i++)
517         ErrorF("%c", R128_BIOS8(info->FPBIOSstart + i));
518 
519     ErrorF("\n");
520 
521     xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel Type: ");
522     i = R128_BIOS16(info->FPBIOSstart + 29);
523     if (i & 1) ErrorF("Color, ");
524     else       ErrorF("Monochrome, ");
525     if (i & 2) ErrorF("Dual(split), ");
526     else       ErrorF("Single, ");
527 
528     switch ((i >> 2) & 0x3f) {
529     case 0:  ErrorF("STN");        break;
530     case 1:  ErrorF("TFT");        break;
531     case 2:  ErrorF("Active STN"); break;
532     case 3:  ErrorF("EL");         break;
533     case 4:  ErrorF("Plasma");     break;
534     default: ErrorF("UNKNOWN");    break;
535     }
536 
537     ErrorF("\n");
538 
539     if (R128_BIOS8(info->FPBIOSstart + 61) & 1) {
540         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel Interface: LVDS\n");
541     } else {
542         /* FIXME: Add Non-LVDS flat pael support */
543         xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
544                    "Non-LVDS panel interface detected!  "
545                    "This support is untested and may not "
546                    "function properly\n");
547     }
548 }
549 
550 /* Read PLL parameters from BIOS block.  Default to typical values if there
551    is no BIOS. */
R128GetPLLParameters(ScrnInfoPtr pScrn)552 static Bool R128GetPLLParameters(ScrnInfoPtr pScrn)
553 {
554     R128InfoPtr   info = R128PTR(pScrn);
555     R128PLLPtr    pll  = &info->pll;
556 
557 #if defined(__powerpc__) || defined(__alpha__)
558     /* there is no bios under Linux PowerPC but Open Firmware
559        does set up the PLL registers properly and we can use
560        those to calculate xclk and find the reference divider */
561 
562     unsigned x_mpll_ref_fb_div;
563     unsigned xclk_cntl;
564     unsigned Nx, M;
565     unsigned PostDivSet[] = {0, 1, 2, 4, 8, 3, 6, 12};
566 
567     /* Assume REF clock is 2950 (in units of 10khz) */
568     /* and that all pllclk must be between 125 Mhz and 250Mhz */
569     pll->reference_freq = 2950;
570     pll->min_pll_freq   = 12500;
571     pll->max_pll_freq   = 25000;
572 
573     x_mpll_ref_fb_div = INPLL(pScrn, R128_X_MPLL_REF_FB_DIV);
574     xclk_cntl = INPLL(pScrn, R128_XCLK_CNTL) & 0x7;
575     pll->reference_div =
576 	INPLL(pScrn,R128_PPLL_REF_DIV) & R128_PPLL_REF_DIV_MASK;
577 
578     Nx = (x_mpll_ref_fb_div & 0x00FF00) >> 8;
579     M =  (x_mpll_ref_fb_div & 0x0000FF);
580 
581     pll->xclk =  R128Div((2 * Nx * pll->reference_freq),
582 			 (M * PostDivSet[xclk_cntl]));
583 
584 #else /* !defined(__powerpc__) */
585 
586     if (!info->VBIOS) {
587 	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
588 		   "Video BIOS not detected, using default PLL parameters!\n");
589 				/* These probably aren't going to work for
590 				   the card you are using.  Specifically,
591 				   reference freq can be 29.50MHz,
592 				   28.63MHz, or 14.32MHz.  YMMV. */
593 	pll->reference_freq = 2950;
594 	pll->reference_div  = 65;
595 	pll->min_pll_freq   = 12500;
596 	pll->max_pll_freq   = 25000;
597 	pll->xclk           = 10300;
598     } else {
599 	uint16_t bios_header    = R128_BIOS16(0x48);
600 	uint16_t pll_info_block = R128_BIOS16(bios_header + 0x30);
601     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
602                         "Header at 0x%04x; PLL Information at 0x%04x\n",
603                         bios_header, pll_info_block));
604 
605 	pll->reference_freq = R128_BIOS16(pll_info_block + 0x0e);
606 	pll->reference_div  = R128_BIOS16(pll_info_block + 0x10);
607 	pll->min_pll_freq   = R128_BIOS32(pll_info_block + 0x12);
608 	pll->max_pll_freq   = R128_BIOS32(pll_info_block + 0x16);
609 	pll->xclk           = R128_BIOS16(pll_info_block + 0x08);
610     }
611 #endif /* __powerpc__ */
612 
613     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
614 	       "PLL parameters: rf=%d rd=%d min=%d max=%d; xclk=%d\n",
615 	       pll->reference_freq,
616 	       pll->reference_div,
617 	       pll->min_pll_freq,
618 	       pll->max_pll_freq,
619 	       pll->xclk);
620 
621     return TRUE;
622 }
623 
624 /* This is called by R128PreInit to set up the default visual. */
R128PreInitVisual(ScrnInfoPtr pScrn)625 static Bool R128PreInitVisual(ScrnInfoPtr pScrn)
626 {
627     if (!xf86SetDepthBpp(pScrn, 0, 0, 0, (Support24bppFb
628 					  | Support32bppFb
629 					  | SupportConvert32to24
630 					  )))
631 	return FALSE;
632 
633     switch (pScrn->depth) {
634     case 8:
635     case 15:
636     case 16:
637     case 24:
638 	break;
639     default:
640 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
641 		   "Given depth (%d) is not supported by %s driver\n",
642 		   pScrn->depth, R128_DRIVER_NAME);
643 	return FALSE;
644     }
645 
646     xf86PrintDepthBpp(pScrn);
647 
648     if (!xf86SetDefaultVisual(pScrn, -1)) return FALSE;
649 
650     if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
651 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
652 		   "Default visual (%s) is not supported at depth %d\n",
653 		   xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
654 	return FALSE;
655     }
656     return TRUE;
657 
658 }
659 
660 /* This is called by R128PreInit to handle all color weight issues. */
R128PreInitWeight(ScrnInfoPtr pScrn)661 static Bool R128PreInitWeight(ScrnInfoPtr pScrn)
662 {
663     R128InfoPtr info          = R128PTR(pScrn);
664     rgb defaultWeight = { 0, 0, 0 };
665 
666     /*
667      * Save flag for 6 bit DAC to use for setting CRTC registers.
668      * Otherwise use an 8 bit DAC, even if xf86SetWeight sets
669      * pScrn->rgbBits to some value other than 8.
670      */
671     if (pScrn->depth <= 8) {
672         if (info->dac6bits) {
673             pScrn->rgbBits = 6;
674         } else {
675             pScrn->rgbBits = 8;
676         }
677     } else {
678         info->dac6bits = FALSE;
679         pScrn->rgbBits = 8;
680     }
681 
682     if (pScrn->depth > 8) {
683         if (!xf86SetWeight(pScrn, defaultWeight, defaultWeight)) return FALSE;
684     }
685 
686     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
687                "Using %d bits per RGB (%d bit DAC)\n",
688                pScrn->rgbBits, info->dac6bits ? 6 : 8);
689 
690     return TRUE;
691 }
692 
693 /* This is called by R128PreInit to handle config file overrides for things
694    like chipset and memory regions.  Also determine memory size and type.
695    If memory type ever needs an override, put it in this routine. */
R128PreInitConfig(ScrnInfoPtr pScrn)696 static Bool R128PreInitConfig(ScrnInfoPtr pScrn)
697 {
698     R128InfoPtr   info      = R128PTR(pScrn);
699     R128EntPtr    pR128Ent  = R128EntPriv(pScrn);
700     unsigned char *R128MMIO = info->MMIO;
701     EntityInfoPtr pEnt      = info->pEnt;
702     GDevPtr       dev       = pEnt->device;
703     int           offset    = 0;        /* RAM Type */
704     MessageType   from;
705 
706 				/* Chipset */
707     from = X_PROBED;
708     if (dev->chipset && *dev->chipset) {
709 	info->Chipset  = xf86StringToToken(R128Chipsets, dev->chipset);
710 	from           = X_CONFIG;
711     } else if (dev->chipID >= 0) {
712 	info->Chipset  = dev->chipID;
713 	from           = X_CONFIG;
714     } else {
715 	info->Chipset = PCI_DEV_DEVICE_ID(info->PciInfo);
716     }
717     pScrn->chipset = (char *)xf86TokenToString(R128Chipsets, info->Chipset);
718 
719     if (!pScrn->chipset) {
720 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
721 		   "ChipID 0x%04x is not recognized\n", info->Chipset);
722 	return FALSE;
723     }
724 
725     if (info->Chipset < 0) {
726 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
727 		   "Chipset \"%s\" is not recognized\n", pScrn->chipset);
728 	return FALSE;
729     }
730 
731     xf86DrvMsg(pScrn->scrnIndex, from,
732 	       "Chipset: \"%s\" (ChipID = 0x%04x)\n",
733 	       pScrn->chipset,
734 	       info->Chipset);
735 
736 				/* Framebuffer */
737 
738     from             = X_PROBED;
739     info->LinearAddr = PCI_REGION_BASE(info->PciInfo, 0, REGION_MEM) & 0xfc000000;
740     pScrn->memPhysBase = info->LinearAddr;
741     if (dev->MemBase) {
742 	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
743 		   "Linear address override, using 0x%08lx instead of 0x%08lx\n",
744 		   dev->MemBase,
745 		   info->LinearAddr);
746 	info->LinearAddr = dev->MemBase;
747 	from             = X_CONFIG;
748     } else if (!info->LinearAddr) {
749 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
750 		   "No valid linear framebuffer address\n");
751 	return FALSE;
752     }
753     xf86DrvMsg(pScrn->scrnIndex, from,
754 	       "Linear framebuffer at 0x%08lx\n", info->LinearAddr);
755 
756 				/* MMIO registers */
757     from             = X_PROBED;
758     info->MMIOAddr   = PCI_REGION_BASE(info->PciInfo, 2, REGION_MEM) & 0xffffff00;
759     if (dev->IOBase) {
760 	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
761 		   "MMIO address override, using 0x%08lx instead of 0x%08lx\n",
762 		   dev->IOBase,
763 		   info->MMIOAddr);
764 	info->MMIOAddr = dev->IOBase;
765 	from           = X_CONFIG;
766     } else if (!info->MMIOAddr) {
767 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid MMIO address\n");
768 	return FALSE;
769     }
770     xf86DrvMsg(pScrn->scrnIndex, from,
771 	       "MMIO registers at 0x%08lx\n", info->MMIOAddr);
772 
773 #ifndef XSERVER_LIBPCIACCESS
774 				/* BIOS */
775     from              = X_PROBED;
776     info->BIOSAddr    = info->PciInfo->biosBase & 0xfffe0000;
777     if (info->BIOSAddr) {
778 	xf86DrvMsg(pScrn->scrnIndex, from,
779 		   "BIOS at 0x%08lx\n", info->BIOSAddr);
780     }
781 #endif
782 
783 				/* Flat panel (part 1) */
784     if (xf86GetOptValBool(info->Options, OPTION_PROG_FP_REGS,
785 			  &info->HasPanelRegs)) {
786 	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
787 		   "Turned flat panel register programming %s\n",
788 		   info->HasPanelRegs ? "on" : "off");
789 	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
790 		   "\n\nWARNING: Forcing the driver to use/not use the flat panel registers\nmight damage your flat panel.  Use at your *OWN* *RISK*.\n\n");
791     } else {
792         info->isDFP = FALSE;
793         info->isPro2 = FALSE;
794         pR128Ent->HasCRTC2 = FALSE;
795 	switch (info->Chipset) {
796 	/* R128 Pro and Pro2 can have DFP, we will deal with it.
797 	   No support for dual-head/xinerama yet.
798            M3 can also have DFP, no support for now */
799 	case PCI_CHIP_RAGE128TF:
800 	case PCI_CHIP_RAGE128TL:
801 	case PCI_CHIP_RAGE128TR:
802 	/* FIXME: RAGE128 TS/TT/TU are assumed to be PRO2 as all 6 chips came
803 	 *        out at the same time, so are of the same family likely.
804 	 *        This requires confirmation however to be fully correct.
805 	 *        Mike A. Harris <mharris@redhat.com>
806 	 */
807 	case PCI_CHIP_RAGE128TS:
808 	case PCI_CHIP_RAGE128TT:
809 	case PCI_CHIP_RAGE128TU: info->isPro2 = TRUE;
810 	/* FIXME: RAGE128 P[ABCEGHIJKLMNOQSTUVWX] are assumed to have DFP
811 	 *        capability, as the comment at the top suggests.
812 	 *        This requires confirmation however to be fully correct.
813 	 *        Mike A. Harris <mharris@redhat.com>
814 	 */
815 	case PCI_CHIP_RAGE128PA:
816 	case PCI_CHIP_RAGE128PB:
817 	case PCI_CHIP_RAGE128PC:
818 	case PCI_CHIP_RAGE128PE:
819 	case PCI_CHIP_RAGE128PG:
820 	case PCI_CHIP_RAGE128PH:
821 	case PCI_CHIP_RAGE128PI:
822 	case PCI_CHIP_RAGE128PJ:
823 	case PCI_CHIP_RAGE128PK:
824 	case PCI_CHIP_RAGE128PL:
825 	case PCI_CHIP_RAGE128PM:
826 	case PCI_CHIP_RAGE128PN:
827 	case PCI_CHIP_RAGE128PO:
828 	case PCI_CHIP_RAGE128PQ:
829 	case PCI_CHIP_RAGE128PS:
830 	case PCI_CHIP_RAGE128PT:
831 	case PCI_CHIP_RAGE128PU:
832 	case PCI_CHIP_RAGE128PV:
833 	case PCI_CHIP_RAGE128PW:
834 	case PCI_CHIP_RAGE128PX:
835 
836 	case PCI_CHIP_RAGE128PD:
837 	case PCI_CHIP_RAGE128PF:
838 	case PCI_CHIP_RAGE128PP:
839 	case PCI_CHIP_RAGE128PR: info->isDFP = TRUE; break;
840 
841 	case PCI_CHIP_RAGE128LE:
842 	case PCI_CHIP_RAGE128LF:
843 	case PCI_CHIP_RAGE128MF:
844 	case PCI_CHIP_RAGE128ML:
845 			info->HasPanelRegs = TRUE;
846 			/* which chips support dualhead? */
847 			pR128Ent->HasCRTC2 = TRUE;
848 			break;
849 	case PCI_CHIP_RAGE128RE:
850 	case PCI_CHIP_RAGE128RF:
851 	case PCI_CHIP_RAGE128RG:
852 	case PCI_CHIP_RAGE128RK:
853 	case PCI_CHIP_RAGE128RL:
854 	case PCI_CHIP_RAGE128SM:
855 	/* FIXME: RAGE128 S[EFGHKLN] are assumed to be like the SM above as
856 	 *        all of them are listed as "Rage 128 4x" in ATI docs.
857 	 *        This requires confirmation however to be fully correct.
858 	 *        Mike A. Harris <mharris@redhat.com>
859 	 */
860 	case PCI_CHIP_RAGE128SE:
861 	case PCI_CHIP_RAGE128SF:
862 	case PCI_CHIP_RAGE128SG:
863 	case PCI_CHIP_RAGE128SH:
864 	case PCI_CHIP_RAGE128SK:
865 	case PCI_CHIP_RAGE128SL:
866 	case PCI_CHIP_RAGE128SN:
867 	default:                 info->HasPanelRegs = FALSE; break;
868 	}
869     }
870 
871 				/* Read registers used to determine options */
872     from                      = X_PROBED;
873     if (!R128MapMMIO(pScrn)) return FALSE;
874     R128MMIO                  = info->MMIO;
875 
876     if (info->FBDev)
877 	pScrn->videoRam       = fbdevHWGetVidmem(pScrn) / 1024;
878     else
879 	pScrn->videoRam       = INREG(R128_CONFIG_MEMSIZE) / 1024;
880 
881     info->MemCntl             = INREG(R128_MEM_CNTL);
882     info->BusCntl             = INREG(R128_BUS_CNTL);
883 
884 				/* RAM */
885     switch (info->MemCntl & 0x3) {
886     case 0:                     /* SDR SGRAM 1:1 */
887 	switch (info->Chipset) {
888 	case PCI_CHIP_RAGE128TF:
889 	case PCI_CHIP_RAGE128TL:
890 	case PCI_CHIP_RAGE128TR:
891 	case PCI_CHIP_RAGE128LE:
892 	case PCI_CHIP_RAGE128LF:
893 	case PCI_CHIP_RAGE128MF:
894 	case PCI_CHIP_RAGE128ML:
895 	case PCI_CHIP_RAGE128RE:
896 	case PCI_CHIP_RAGE128RF:
897 	case PCI_CHIP_RAGE128RG: offset = 0; break; /* 128-bit SDR SGRAM 1:1 */
898 	case PCI_CHIP_RAGE128RK:
899 	case PCI_CHIP_RAGE128RL:
900 	case PCI_CHIP_RAGE128SM:
901 	default:                 offset = 1; break; /*  64-bit SDR SGRAM 1:1 */
902 	}
903 	break;
904     case 1:                      offset = 2; break; /*  64-bit SDR SGRAM 2:1 */
905     case 2:                      offset = 3; break; /*  64-bit DDR SGRAM     */
906     default:                     offset = 1; break; /*  64-bit SDR SGRAM 1:1 */
907     }
908     info->ram = &R128RAM[offset];
909 
910     if (dev->videoRam) {
911 	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
912 		   "Video RAM override, using %d kB instead of %d kB\n",
913 		   dev->videoRam,
914 		   pScrn->videoRam);
915 	from             = X_CONFIG;
916 	pScrn->videoRam  = dev->videoRam;
917     }
918 
919     xf86DrvMsg(pScrn->scrnIndex, from,
920 	       "VideoRAM: %d kByte (%s)\n", pScrn->videoRam, info->ram->name);
921 
922     pScrn->videoRam  &= ~1023;
923     info->FbMapSize  = pScrn->videoRam * 1024;
924 
925 #ifdef R128DRI
926     /* AGP/PCI */
927     if (!info->IsPCI) {
928 	switch (info->Chipset) {
929 	case PCI_CHIP_RAGE128LE:
930 	case PCI_CHIP_RAGE128RE:
931 	case PCI_CHIP_RAGE128RK:
932 	case PCI_CHIP_RAGE128PD:
933 	case PCI_CHIP_RAGE128PR:
934 	case PCI_CHIP_RAGE128PP: info->IsPCI = TRUE;  break;
935 	case PCI_CHIP_RAGE128LF:
936 	case PCI_CHIP_RAGE128MF:
937 	case PCI_CHIP_RAGE128ML:
938 	case PCI_CHIP_RAGE128PF:
939 	case PCI_CHIP_RAGE128RF:
940 	case PCI_CHIP_RAGE128RG:
941 	case PCI_CHIP_RAGE128RL:
942 	case PCI_CHIP_RAGE128SM:
943 	case PCI_CHIP_RAGE128TF:
944 	case PCI_CHIP_RAGE128TL:
945 	case PCI_CHIP_RAGE128TR:
946 	/* FIXME: Rage 128 S[EFGHKLN], T[STU], P[ABCEGHIJKLMNOQSTUVWX] are
947 	 * believed to be AGP, but need confirmation. <mharris@redhat.com>
948 	 */
949 	case PCI_CHIP_RAGE128PA:
950 	case PCI_CHIP_RAGE128PB:
951 	case PCI_CHIP_RAGE128PC:
952 	case PCI_CHIP_RAGE128PE:
953 	case PCI_CHIP_RAGE128PG:
954 	case PCI_CHIP_RAGE128PH:
955 	case PCI_CHIP_RAGE128PI:
956 	case PCI_CHIP_RAGE128PJ:
957 	case PCI_CHIP_RAGE128PK:
958 	case PCI_CHIP_RAGE128PL:
959 	case PCI_CHIP_RAGE128PM:
960 	case PCI_CHIP_RAGE128PN:
961 	case PCI_CHIP_RAGE128PO:
962 	case PCI_CHIP_RAGE128PQ:
963 	case PCI_CHIP_RAGE128PS:
964 	case PCI_CHIP_RAGE128PT:
965 	case PCI_CHIP_RAGE128PU:
966 	case PCI_CHIP_RAGE128PV:
967 	case PCI_CHIP_RAGE128PW:
968 	case PCI_CHIP_RAGE128PX:
969 	case PCI_CHIP_RAGE128TS:
970 	case PCI_CHIP_RAGE128TT:
971 	case PCI_CHIP_RAGE128TU:
972 	case PCI_CHIP_RAGE128SE:
973 	case PCI_CHIP_RAGE128SF:
974 	case PCI_CHIP_RAGE128SG:
975 	case PCI_CHIP_RAGE128SH:
976 	case PCI_CHIP_RAGE128SK:
977 	case PCI_CHIP_RAGE128SL:
978 	case PCI_CHIP_RAGE128SN:
979 	default:                 info->IsPCI = FALSE; break;
980 	}
981     }
982 #endif
983 
984     return TRUE;
985 }
986 
R128PreInitDDC(ScrnInfoPtr pScrn,xf86Int10InfoPtr pInt10)987 static Bool R128PreInitDDC(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
988 {
989 #if !defined(__powerpc__) && !defined(__alpha__) && !defined(__sparc__)
990     R128InfoPtr   info = R128PTR(pScrn);
991     vbeInfoPtr pVbe;
992 #endif
993 
994     if (!xf86LoadSubModule(pScrn, "ddc")) return FALSE;
995     if (!xf86LoadSubModule(pScrn, "i2c")) return FALSE;
996 
997 #if defined(__powerpc__) || defined(__alpha__) || defined(__sparc__)
998     /* Int10 is broken on PPC and some Alphas */
999     return TRUE;
1000 #else
1001     if (xf86LoadSubModule(pScrn, "vbe")) {
1002 	pVbe = VBEInit(pInt10,info->pEnt->index);
1003 	if (!pVbe) return FALSE;
1004         xf86SetDDCproperties(pScrn,xf86PrintEDID(vbeDoEDID(pVbe,NULL)));
1005 	vbeFree(pVbe);
1006 	return TRUE;
1007     } else
1008 	return FALSE;
1009 #endif
1010 }
1011 
1012 /* This is called by R128PreInit to initialize gamma correction. */
R128PreInitGamma(ScrnInfoPtr pScrn)1013 static Bool R128PreInitGamma(ScrnInfoPtr pScrn)
1014 {
1015     Gamma zeros = { 0.0, 0.0, 0.0 };
1016 
1017     if (!xf86SetGamma(pScrn, zeros)) return FALSE;
1018     return TRUE;
1019 }
1020 
1021 /* This is called by R128PreInit to initialize the hardware cursor. */
R128PreInitCursor(ScrnInfoPtr pScrn)1022 static Bool R128PreInitCursor(ScrnInfoPtr pScrn)
1023 {
1024     R128InfoPtr   info = R128PTR(pScrn);
1025 
1026     if (!info->swCursor) {
1027 	if (!xf86LoadSubModule(pScrn, "ramdac")) return FALSE;
1028     }
1029     return TRUE;
1030 }
1031 
R128PreInitInt10(ScrnInfoPtr pScrn,xf86Int10InfoPtr * ppInt10)1032 static Bool R128PreInitInt10(ScrnInfoPtr pScrn, xf86Int10InfoPtr *ppInt10)
1033 {
1034     R128InfoPtr   info = R128PTR(pScrn);
1035 #if !defined(__powerpc__) && !defined(__alpha__)
1036     /* int10 is broken on some Alphas and powerpc */
1037     if (xf86LoadSubModule(pScrn, "int10")) {
1038 	xf86DrvMsg(pScrn->scrnIndex,X_INFO,"initializing int10\n");
1039 	*ppInt10 = xf86InitInt10(info->pEnt->index);
1040     }
1041 #endif
1042     return TRUE;
1043 }
1044 
1045 #ifdef R128DRI
R128PreInitDRI(ScrnInfoPtr pScrn)1046 static Bool R128PreInitDRI(ScrnInfoPtr pScrn)
1047 {
1048     R128InfoPtr   info = R128PTR(pScrn);
1049 
1050     info->agpMode        = R128_DEFAULT_AGP_MODE;
1051     info->agpSize        = R128_DEFAULT_AGP_SIZE;
1052     info->ringSize       = R128_DEFAULT_RING_SIZE;
1053     info->bufSize        = R128_DEFAULT_BUFFER_SIZE;
1054     info->agpTexSize     = R128_DEFAULT_AGP_TEX_SIZE;
1055 
1056     info->CCEusecTimeout = R128_DEFAULT_CCE_TIMEOUT;
1057 
1058     if (!info->IsPCI) {
1059 	if (xf86GetOptValInteger(info->Options,
1060 				 OPTION_AGP_MODE, &(info->agpMode))) {
1061 	    if (info->agpMode < 1 || info->agpMode > R128_AGP_MAX_MODE) {
1062 		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1063 			   "Illegal AGP Mode: %d\n", info->agpMode);
1064 		return FALSE;
1065 	    }
1066 	    xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
1067 		       "Using AGP %dx mode\n", info->agpMode);
1068 	}
1069 
1070 	if (xf86GetOptValInteger(info->Options,
1071 				 OPTION_AGP_SIZE, (int *)&(info->agpSize))) {
1072 	    switch (info->agpSize) {
1073 	    case 4:
1074 	    case 8:
1075 	    case 16:
1076 	    case 32:
1077 	    case 64:
1078 	    case 128:
1079 	    case 256:
1080 		break;
1081 	    default:
1082 		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1083 			   "Illegal AGP size: %d MB\n", info->agpSize);
1084 		return FALSE;
1085 	    }
1086 	}
1087 
1088 	if (xf86GetOptValInteger(info->Options,
1089 				 OPTION_RING_SIZE, &(info->ringSize))) {
1090 	    if (info->ringSize < 1 || info->ringSize >= (int)info->agpSize) {
1091 		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1092 			   "Illegal ring buffer size: %d MB\n",
1093 			   info->ringSize);
1094 		return FALSE;
1095 	    }
1096 	}
1097 
1098 	if (xf86GetOptValInteger(info->Options,
1099 				 OPTION_BUFFER_SIZE, &(info->bufSize))) {
1100 	    if (info->bufSize < 1 || info->bufSize >= (int)info->agpSize) {
1101 		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1102 			   "Illegal vertex/indirect buffers size: %d MB\n",
1103 			   info->bufSize);
1104 		return FALSE;
1105 	    }
1106 	    if (info->bufSize > 2) {
1107 		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1108 			   "Illegal vertex/indirect buffers size: %d MB\n",
1109 			   info->bufSize);
1110 		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1111 			   "Clamping vertex/indirect buffers size to 2 MB\n");
1112 		info->bufSize = 2;
1113 	    }
1114 	}
1115 
1116 	if (info->ringSize + info->bufSize + info->agpTexSize >
1117 	    (int)info->agpSize) {
1118 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1119 		       "Buffers are too big for requested AGP space\n");
1120 	    return FALSE;
1121 	}
1122 
1123 	info->agpTexSize = info->agpSize - (info->ringSize + info->bufSize);
1124     }
1125 
1126     if (xf86GetOptValInteger(info->Options, OPTION_USEC_TIMEOUT,
1127 			     &(info->CCEusecTimeout))) {
1128 	/* This option checked by the R128 DRM kernel module */
1129     }
1130 
1131     if (!xf86LoadSubModule(pScrn, "shadowfb")) {
1132 	info->allowPageFlip = 0;
1133 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1134 		   "Couldn't load shadowfb module:\n");
1135     } else {
1136 	info->allowPageFlip = xf86ReturnOptValBool(info->Options,
1137 						   OPTION_PAGE_FLIP,
1138 						   FALSE);
1139     }
1140 
1141     xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Page flipping %sabled\n",
1142 	       info->allowPageFlip ? "en" : "dis");
1143 
1144     return TRUE;
1145 }
1146 #endif
1147 
R128PreInitControllers(ScrnInfoPtr pScrn,xf86Int10InfoPtr pInt10)1148 static Bool R128PreInitControllers(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
1149 {
1150     xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
1151     int found = 0;
1152     int i;
1153 
1154     if (!R128GetBIOSParameters(pScrn, pInt10))
1155         return FALSE;
1156 
1157     if (!R128GetPLLParameters(pScrn))
1158         return FALSE;
1159 
1160     if (!R128AllocateControllers(pScrn))
1161         return FALSE;
1162 
1163     if (!R128SetupConnectors(pScrn))
1164         return FALSE;
1165 
1166     for (i = 0; i < config->num_output; i++) {
1167         xf86OutputPtr output = config->output[i];
1168 
1169         output->status = (*output->funcs->detect) (output);
1170         if (output->status == XF86OutputStatusConnected)
1171             found++;
1172     }
1173     return !!found;
1174 }
1175 
1176 static void
r128UMSOption(ScrnInfoPtr pScrn)1177 r128UMSOption(ScrnInfoPtr pScrn)
1178 {
1179     R128InfoPtr      info = R128PTR(pScrn);
1180 
1181     info->dac6bits = xf86ReturnOptValBool(info->Options,
1182                                             OPTION_DAC_6BIT, FALSE);
1183 
1184 #ifdef __powerpc__
1185     if (xf86ReturnOptValBool(info->Options, OPTION_FBDEV, TRUE))
1186 #else
1187     if (xf86ReturnOptValBool(info->Options, OPTION_FBDEV, FALSE))
1188 #endif
1189     {
1190         info->FBDev = TRUE;
1191         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
1192                     "Using framebuffer device.\n");
1193     }
1194 
1195     /* By default, don't access VGA IOs on PowerPC or SPARC. */
1196 #if defined(__powerpc__) || defined(__sparc__) || !defined(WITH_VGAHW)
1197     info->VGAAccess = FALSE;
1198 #else
1199     info->VGAAccess = TRUE;
1200 #endif
1201 
1202 #ifdef WITH_VGAHW
1203     xf86GetOptValBool(info->Options, OPTION_VGA_ACCESS,
1204                         &info->VGAAccess);
1205     if (info->VGAAccess) {
1206        if (!xf86LoadSubModule(pScrn, "vgahw"))
1207            info->VGAAccess = FALSE;
1208         else {
1209             if (!vgaHWGetHWRec(pScrn))
1210                info->VGAAccess = FALSE;
1211        }
1212 
1213        if (!info->VGAAccess) {
1214            xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1215                        "Loading VGA module failed, trying to "
1216                        "run without it.\n");
1217        }
1218     } else
1219            xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1220                        "VGAAccess option set to FALSE, VGA "
1221                        "module load skipped.\n");
1222     if (info->VGAAccess) {
1223         vgaHWSetStdFuncs(VGAHWPTR(pScrn));
1224         vgaHWGetIOBase(VGAHWPTR(pScrn));
1225     }
1226 #else
1227     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1228                 "VGAHW support not compiled, VGA "
1229                 "module load skipped.\n");
1230 #endif
1231 
1232     if (xf86ReturnOptValBool(info->Options,
1233                                 OPTION_SHOW_CACHE, FALSE)) {
1234         info->showCache = TRUE;
1235         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
1236                     "ShowCache enabled.\n");
1237     }
1238 
1239     if (xf86ReturnOptValBool(info->Options,
1240                                 OPTION_SW_CURSOR, FALSE)) {
1241         info->swCursor = TRUE;
1242         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
1243                     "Software cursor requested.\n");
1244     }
1245 
1246     if(xf86GetOptValInteger(info->Options,
1247                             OPTION_VIDEO_KEY, &info->videoKey)) {
1248         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
1249                     "Video key set to 0x%x.\n", info->videoKey);
1250     } else {
1251         info->videoKey = 0x1E;
1252     }
1253 
1254 #ifdef R128DRI
1255     /* DMA for Xv */
1256     info->DMAForXv = xf86ReturnOptValBool(info->Options,
1257                                             OPTION_XV_DMA, FALSE);
1258     if (info->DMAForXv) {
1259         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
1260                    "Will try to use DMA for Xv image transfers.\n");
1261     }
1262 
1263     /* Force PCI Mode */
1264     info->IsPCI = xf86ReturnOptValBool(info->Options,
1265                                         OPTION_IS_PCI, FALSE);
1266     if (info->IsPCI) {
1267         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
1268                     "Forced into PCI only mode.\n");
1269     }
1270 
1271     if (xf86ReturnOptValBool(info->Options, OPTION_CCE_PIO, FALSE)) {
1272         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
1273                     "Forcing CCE into PIO mode.\n");
1274         info->CCEMode = R128_DEFAULT_CCE_PIO_MODE;
1275     } else {
1276         info->CCEMode = R128_DEFAULT_CCE_BM_MODE;
1277     }
1278 
1279     if (xf86ReturnOptValBool(info->Options, OPTION_NO_SECURITY, FALSE)) {
1280         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
1281                     "WARNING!!! CCE Security checks disabled!!!\n");
1282         info->CCESecure = FALSE;
1283     } else {
1284         info->CCESecure = TRUE;
1285     }
1286 
1287 
1288 #endif
1289 }
1290 
1291 static void
r128AcquireOption(ScrnInfoPtr pScrn)1292 r128AcquireOption(ScrnInfoPtr pScrn)
1293 {
1294     R128InfoPtr      info = R128PTR(pScrn);
1295 #ifdef USE_EXA
1296     char *optstr;
1297 #endif
1298 
1299     if (xf86ReturnOptValBool(info->Options, OPTION_NOACCEL, FALSE)) {
1300         info->noAccel = TRUE;
1301     }
1302 
1303 #ifdef USE_EXA
1304     if (!info->noAccel) {
1305         optstr = (char *) xf86GetOptValString(info->Options,
1306                                                 OPTION_ACCELMETHOD);
1307         if (optstr) {
1308             xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1309                         "AccelMethod option found.\n");
1310             if (xf86NameCmp(optstr, "EXA") == 0) {
1311                 info->useEXA = TRUE;
1312                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1313                             "AccelMethod is set to EXA, turning "
1314                             "EXA on.\n");
1315             }
1316         }
1317 
1318 #ifdef RENDER
1319         info->RenderAccel = xf86ReturnOptValBool(info->Options,
1320                                                     OPTION_RENDERACCEL,
1321                                                     TRUE);
1322         if (info->RenderAccel)
1323             xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1324                         "Acceleration of RENDER operations will be "
1325                         "enabled upon successful loading of DRI and "
1326                         "EXA.\n");
1327 #endif
1328     }
1329 #endif
1330 
1331     r128UMSOption(pScrn);
1332 }
1333 
R128CRTCResize(ScrnInfoPtr pScrn,int width,int height)1334 static Bool R128CRTCResize(ScrnInfoPtr pScrn, int width, int height)
1335 {
1336     pScrn->virtualX = width;
1337     pScrn->virtualY = height;
1338     return TRUE;
1339 }
1340 
1341 static const xf86CrtcConfigFuncsRec R128CRTCResizeFuncs = {
1342     R128CRTCResize
1343 };
1344 
R128LegacyMS(ScrnInfoPtr pScrn)1345 static Bool R128LegacyMS(ScrnInfoPtr pScrn)
1346 {
1347     R128InfoPtr      info = R128PTR(pScrn);
1348     xf86Int10InfoPtr pInt10 = NULL;
1349     Bool ret = FALSE;
1350 
1351     if (info->FBDev) {
1352         /* check for linux framebuffer device */
1353         if (!xf86LoadSubModule(pScrn, "fbdevhw")) goto exit;
1354         if (!fbdevHWInit(pScrn, info->PciInfo, NULL)) goto exit;
1355         pScrn->SwitchMode    = fbdevHWSwitchModeWeak();
1356         pScrn->AdjustFrame   = fbdevHWAdjustFrameWeak();
1357         pScrn->ValidMode     = fbdevHWValidModeWeak();
1358     } else {
1359         if (!R128PreInitInt10(pScrn, &pInt10)) goto exit;
1360     }
1361 
1362     if (!R128PreInitConfig(pScrn)) goto freeInt10;
1363 
1364     xf86CrtcSetSizeRange(pScrn, 320, 200, 4096, 4096);
1365 
1366     if (!R128PreInitCursor(pScrn)) goto freeInt10;
1367 
1368     /* Don't fail on this one */
1369     info->DDC = R128PreInitDDC(pScrn, pInt10);
1370 
1371     if (!R128PreInitControllers(pScrn, pInt10)) goto freeInt10;
1372 
1373 #ifdef R128DRI
1374     if (!R128PreInitDRI(pScrn)) goto freeInt10;
1375 #endif
1376 
1377     ret = TRUE;
1378 freeInt10:
1379     /* Free int10 info */
1380     if (pInt10) {
1381         xf86FreeInt10(pInt10);
1382     }
1383 
1384 exit:
1385     return ret;
1386 }
1387 
1388 static void
R128PreInitAccel(ScrnInfoPtr pScrn)1389 R128PreInitAccel(ScrnInfoPtr pScrn)
1390 {
1391     R128InfoPtr      info = R128PTR(pScrn);
1392 #ifdef USE_EXA
1393     int errmaj, errmin;
1394 #endif
1395 
1396     if (!info->noAccel) {
1397         if (info->useEXA) {
1398 #ifdef USE_EXA
1399             info->exaReq.majorversion = EXA_VERSION_MAJOR;
1400             info->exaReq.minorversion = EXA_VERSION_MINOR;
1401 
1402             xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1403                         "Loading EXA module...\n");
1404             if (LoadSubModule(pScrn->module, "exa", NULL, NULL, NULL,
1405                                 &info->exaReq, &errmaj, &errmin)) {
1406                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1407                             "Loading EXA module.\n");
1408             } else {
1409                 LoaderErrorMsg(NULL, "exa", errmaj, errmin);
1410             }
1411 #endif
1412         }
1413 
1414         if ((!info->useEXA) ||
1415             ((info->useEXA) && (!info->accelOn))) {
1416 #ifdef HAVE_XAA_H
1417             if (xf86LoadSubModule(pScrn, "xaa")) {
1418                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1419                             "Loading XAA module.\n");
1420             }
1421 #endif
1422         }
1423     }
1424 }
1425 
1426 /* R128PreInit is called once at server startup. */
R128PreInit(ScrnInfoPtr pScrn,int flags)1427 Bool R128PreInit(ScrnInfoPtr pScrn, int flags)
1428 {
1429     R128InfoPtr      info;
1430 
1431     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1432                         "%s\n", __func__));
1433 
1434     if (flags & PROBE_DETECT) {
1435         return TRUE;
1436     }
1437 
1438     pScrn->monitor = pScrn->confScreen->monitor;
1439 
1440     if (!R128PreInitVisual(pScrn)) {
1441         return FALSE;
1442     }
1443 
1444     if (!R128PreInitGamma(pScrn)) {
1445         return FALSE;
1446     }
1447 
1448     if (pScrn->numEntities != 1) return FALSE;
1449 
1450     if (!R128GetRec(pScrn)) return FALSE;
1451 
1452     info                = R128PTR(pScrn);
1453     info->SwitchingMode = FALSE;
1454     info->MMIO          = NULL;
1455 
1456     info->pEnt          = xf86GetEntityInfo(pScrn->entityList[0]);
1457     if (info->pEnt->location.type != BUS_PCI) goto fail;
1458 
1459     info->PciInfo       = xf86GetPciInfoForEntity(info->pEnt->index);
1460 
1461     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1462 	       "PCI bus %d card %d func %d\n",
1463 	       PCI_DEV_BUS(info->PciInfo),
1464 	       PCI_DEV_DEV(info->PciInfo),
1465 	       PCI_DEV_FUNC(info->PciInfo));
1466 
1467 #ifndef XSERVER_LIBPCIACCESS
1468     info->PciTag        = pciTag(PCI_DEV_BUS(info->PciInfo),
1469 				PCI_DEV_DEV(info->PciInfo),
1470 				PCI_DEV_FUNC(info->PciInfo));
1471 
1472     if (xf86RegisterResources(info->pEnt->index, 0, ResNone)) goto fail;
1473     if (xf86SetOperatingState(resVga, info->pEnt->index, ResUnusedOpr)) goto fail;
1474 
1475     pScrn->racMemFlags  = RAC_FB | RAC_COLORMAP | RAC_VIEWPORT | RAC_CURSOR;
1476 #endif
1477 
1478     info->fifo_slots  = 0;
1479     info->pix24bpp    = xf86GetBppFromDepth(pScrn, pScrn->depth);
1480     info->CurrentLayout.bitsPerPixel = pScrn->bitsPerPixel;
1481     info->CurrentLayout.depth        = pScrn->depth;
1482     info->CurrentLayout.pixel_bytes  = pScrn->bitsPerPixel / 8;
1483     info->CurrentLayout.pixel_code   = (pScrn->bitsPerPixel != 16
1484                                        ? pScrn->bitsPerPixel
1485                                        : pScrn->depth);
1486 
1487     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1488            "Pixel depth = %d bits stored in %d byte%s (%d bpp pixmaps)\n",
1489            pScrn->depth,
1490            info->CurrentLayout.pixel_bytes,
1491            info->CurrentLayout.pixel_bytes > 1 ? "s" : "",
1492            info->pix24bpp);
1493 
1494 				/* We can't do this until we have a
1495 				   pScrn->display. */
1496     xf86CollectOptions(pScrn, NULL);
1497     if (!(info->Options = malloc(sizeof(R128Options))))    goto fail;
1498     memcpy(info->Options, R128Options, sizeof(R128Options));
1499     xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, info->Options);
1500 
1501     info->noAccel = FALSE;
1502     info->accelOn = FALSE;
1503 
1504     info->useEXA = FALSE;
1505 #ifdef USE_EXA
1506 #ifndef HAVE_XAA_H
1507     info->useEXA = TRUE;
1508 #endif
1509 #endif
1510 
1511     info->swCursor = FALSE;
1512 
1513     r128AcquireOption(pScrn);
1514 
1515     if (!R128PreInitWeight(pScrn))    goto fail;
1516 
1517     /* Allocate an xf86CrtcConfig */
1518     xf86CrtcConfigInit(pScrn, &R128CRTCResizeFuncs);
1519 
1520     R128LegacyMS(pScrn);
1521 
1522     if (!xf86InitialConfiguration(pScrn, TRUE)) {
1523         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n");
1524         goto fail;
1525     }
1526     pScrn->displayWidth = (pScrn->virtualX + 63) & ~63;
1527 
1528     /* Set display resolution */
1529     xf86SetDpi(pScrn, 0, 0);
1530 
1531     /* Get ScreenInit function */
1532     if (!xf86LoadSubModule(pScrn, "fb")) return FALSE;
1533 
1534     R128PreInitAccel(pScrn);
1535 
1536     info->CurrentLayout.displayWidth = pScrn->displayWidth;
1537 
1538     if (!xf86RandR12PreInit(pScrn)) {
1539         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "RandR initialization failure\n");
1540         goto fail;
1541     }
1542 
1543     if (pScrn->modes == NULL) {
1544         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n");
1545         goto fail;
1546     }
1547 
1548 				/* Free the video bios (if applicable) */
1549     if (info->VBIOS) {
1550 	free(info->VBIOS);
1551 	info->VBIOS = NULL;
1552     }
1553 
1554     if (info->MMIO) R128UnmapMMIO(pScrn);
1555     info->MMIO = NULL;
1556 
1557     return TRUE;
1558 
1559   fail:
1560 				/* Pre-init failed. */
1561 
1562 				/* Free the video bios (if applicable) */
1563     if (info->VBIOS) {
1564 	free(info->VBIOS);
1565 	info->VBIOS = NULL;
1566     }
1567 
1568 #ifdef WITH_VGAHW
1569     if (info->VGAAccess)
1570            vgaHWFreeHWRec(pScrn);
1571 #endif
1572 
1573     if (info->MMIO) R128UnmapMMIO(pScrn);
1574     info->MMIO = NULL;
1575 
1576     R128FreeRec(pScrn);
1577     return FALSE;
1578 }
1579 
1580 /* Load a palette. */
R128LoadPalette(ScrnInfoPtr pScrn,int numColors,int * indices,LOCO * colors,VisualPtr pVisual)1581 static void R128LoadPalette(ScrnInfoPtr pScrn, int numColors,
1582 			    int *indices, LOCO *colors, VisualPtr pVisual)
1583 {
1584     R128InfoPtr   info      = R128PTR(pScrn);
1585     xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
1586     int i, j;
1587     int c, index;
1588     uint16_t lut_r[256], lut_g[256], lut_b[256];
1589 
1590     for (c = 0; c < xf86_config->num_crtc; c++) {
1591         xf86CrtcPtr crtc = xf86_config->crtc[c];
1592         R128CrtcPrivatePtr r128_crtc = crtc->driver_private;
1593 
1594         for (i = 0 ; i < 256; i++) {
1595             lut_r[i] = r128_crtc->lut_r[i] << 8;
1596             lut_g[i] = r128_crtc->lut_g[i] << 8;
1597             lut_b[i] = r128_crtc->lut_b[i] << 8;
1598         }
1599 
1600         switch (info->CurrentLayout.depth) {
1601         case 15:
1602             for (i = 0; i < numColors; i++) {
1603                 index = indices[i];
1604                 for (j = 0; j < 8; j++) {
1605                     lut_r[index * 8 + j] = colors[index].red << 8;
1606                     lut_g[index * 8 + j] = colors[index].green << 8;
1607                     lut_b[index * 8 + j] = colors[index].blue << 8;
1608                 }
1609             }
1610         case 16:
1611             for (i = 0; i < numColors; i++) {
1612                 index = indices[i];
1613 
1614                 /* XXX: The old version of R128LoadPalette did not do this and
1615                  * the old version of RADEONLoadPalette has a comment asking why.
1616                  */
1617                 if (i <= 31) {
1618                     for (j = 0; j < 8; j++) {
1619                         lut_r[index * 8 + j] = colors[index].red << 8;
1620                         lut_b[index * 8 + j] = colors[index].blue << 8;
1621                     }
1622                 }
1623 
1624                 for (j = 0; j < 4; j++) {
1625                     lut_g[index * 4 + j] = colors[index].green << 8;
1626                 }
1627             }
1628         default:
1629             for (i = 0; i < numColors; i++) {
1630                 index = indices[i];
1631                 lut_r[index] = colors[index].red << 8;
1632                 lut_g[index] = colors[index].green << 8;
1633                 lut_b[index] = colors[index].blue << 8;
1634             }
1635             break;
1636         }
1637 
1638         /* Make the change through RandR */
1639 #ifdef RANDR_12_INTERFACE
1640         if (crtc->randr_crtc)
1641             RRCrtcGammaSet(crtc->randr_crtc, lut_r, lut_g, lut_b);
1642         else
1643 #endif
1644         crtc->funcs->gamma_set(crtc, lut_r, lut_g, lut_b, 256);
1645     }
1646 }
1647 
1648 static void
R128BlockHandler(BLOCKHANDLER_ARGS_DECL)1649 R128BlockHandler(BLOCKHANDLER_ARGS_DECL)
1650 {
1651     SCREEN_PTR(arg);
1652     ScrnInfoPtr pScrn   = xf86ScreenToScrn(pScreen);
1653     R128InfoPtr info    = R128PTR(pScrn);
1654 
1655 #ifdef R128DRI
1656     if (info->directRenderingEnabled)
1657         FLUSH_RING();
1658 #endif
1659 
1660     pScreen->BlockHandler = info->BlockHandler;
1661     (*pScreen->BlockHandler) (BLOCKHANDLER_ARGS);
1662     pScreen->BlockHandler = R128BlockHandler;
1663 
1664     if(info->VideoTimerCallback) {
1665         (*info->VideoTimerCallback)(pScrn, currentTime.milliseconds);
1666     }
1667 }
1668 
1669 /* Called at the start of each server generation. */
R128ScreenInit(SCREEN_INIT_ARGS_DECL)1670 Bool R128ScreenInit(SCREEN_INIT_ARGS_DECL)
1671 {
1672     ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
1673     R128InfoPtr info   = R128PTR(pScrn);
1674     BoxRec      MemBox;
1675     int width_bytes = (pScrn->displayWidth *
1676                         info->CurrentLayout.pixel_bytes);
1677     int scanlines;
1678     int total = info->FbMapSize;
1679     FBAreaPtr fbarea = NULL;
1680 #ifdef R128DRI
1681     int cpp = info->CurrentLayout.pixel_bytes;
1682     int x1 = 0, x2 = 0, y1 = 0, y2 = 0;
1683 #ifdef USE_EXA
1684     ExaOffscreenArea*     osArea = NULL;
1685 #endif /* USE_EXA */
1686 #endif /* R128DRI */
1687 
1688     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1689                         "%s %lx %lx\n",
1690                         __func__,
1691                         pScrn->memPhysBase, pScrn->fbOffset));
1692 
1693 #ifdef R128DRI
1694 				/* Turn off the CCE for now. */
1695     info->CCEInUse     = FALSE;
1696     info->indirectBuffer = NULL;
1697 #endif
1698 
1699     if (!R128MapMem(pScrn)) return FALSE;
1700     pScrn->fbOffset    = 0;
1701     //if(info->IsSecondary) pScrn->fbOffset = pScrn->videoRam * 1024;
1702 #ifdef R128DRI
1703     info->fbX          = 0;
1704     info->fbY          = 0;
1705     info->frontOffset  = 0;
1706     info->frontPitch   = pScrn->displayWidth;
1707 #endif
1708 
1709     info->PaletteSavedOnVT = FALSE;
1710 
1711     R128Save(pScrn);
1712 
1713 				/* Visual setup */
1714     miClearVisualTypes();
1715     if (!miSetVisualTypes(pScrn->depth,
1716 			  miGetDefaultVisualMask(pScrn->depth),
1717 			  pScrn->rgbBits,
1718 			  pScrn->defaultVisual)) return FALSE;
1719     miSetPixmapDepths ();
1720 
1721 #ifdef R128DRI
1722 				/* Setup DRI after visuals have been
1723 				   established, but before fbScreenInit is
1724 				   called. */
1725     {
1726 	/* FIXME: When we move to dynamic allocation of back and depth
1727 	   buffers, we will want to revisit the following check for 3
1728 	   times the virtual size of the screen below. */
1729 	int maxy        = info->FbMapSize / width_bytes;
1730 
1731         if (info->noAccel) {
1732 	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1733 		       "Acceleration disabled, not initializing the DRI\n");
1734 	    info->directRenderingEnabled = FALSE;
1735 	} else if (maxy <= pScrn->virtualY * 3) {
1736 	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1737 		       "Static buffer allocation failed -- "
1738 		       "need at least %d kB video memory\n",
1739 		       (pScrn->displayWidth * pScrn->virtualY *
1740 			info->CurrentLayout.pixel_bytes * 3 + 1023) / 1024);
1741 	    info->directRenderingEnabled = FALSE;
1742 	} else {
1743             info->directRenderingEnabled = R128DRIScreenInit(pScreen);
1744 	}
1745     }
1746 #endif
1747 
1748     if (!fbScreenInit (pScreen, info->FB,
1749 		       pScrn->virtualX, pScrn->virtualY,
1750 		       pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth,
1751 		       pScrn->bitsPerPixel))
1752 	return FALSE;
1753 
1754     xf86SetBlackWhitePixels(pScreen);
1755 
1756     if (pScrn->bitsPerPixel > 8) {
1757 	VisualPtr visual;
1758 
1759 	visual = pScreen->visuals + pScreen->numVisuals;
1760 	while (--visual >= pScreen->visuals) {
1761 	    if ((visual->class | DynamicClass) == DirectColor) {
1762 		visual->offsetRed   = pScrn->offset.red;
1763 		visual->offsetGreen = pScrn->offset.green;
1764 		visual->offsetBlue  = pScrn->offset.blue;
1765 		visual->redMask     = pScrn->mask.red;
1766 		visual->greenMask   = pScrn->mask.green;
1767 		visual->blueMask    = pScrn->mask.blue;
1768 	    }
1769 	}
1770     }
1771 
1772     /* must be after RGB order fixed */
1773     fbPictureInit (pScreen, 0, 0);
1774 
1775 				/* Memory manager setup */
1776 #ifdef R128DRI
1777     if (info->directRenderingEnabled) {
1778 	int bufferSize = pScrn->virtualY * width_bytes;
1779 	int l;
1780 
1781 	switch (info->CCEMode) {
1782 	case R128_DEFAULT_CCE_PIO_MODE:
1783 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CCE in PIO mode\n");
1784 	    break;
1785 	case R128_DEFAULT_CCE_BM_MODE:
1786 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CCE in BM mode\n");
1787 	    break;
1788 	default:
1789 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CCE in UNKNOWN mode\n");
1790 	    break;
1791 	}
1792 
1793 	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1794 		   "Using %d MB AGP aperture\n", info->agpSize);
1795 	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1796 		   "Using %d MB for the ring buffer\n", info->ringSize);
1797 	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1798 		   "Using %d MB for vertex/indirect buffers\n", info->bufSize);
1799 	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1800 		   "Using %d MB for AGP textures\n", info->agpTexSize);
1801 
1802 	/* Try for front, back, depth, and two framebuffers worth of
1803 	 * pixmap cache.  Should be enough for a fullscreen background
1804 	 * image plus some leftovers.
1805 	 */
1806 	info->textureSize = info->FbMapSize - 5 * bufferSize;
1807 
1808 	/* If that gives us less than half the available memory, let's
1809 	 * be greedy and grab some more.  Sorry, I care more about 3D
1810 	 * performance than playing nicely, and you'll get around a full
1811 	 * framebuffer's worth of pixmap cache anyway.
1812 	 */
1813 	if (info->textureSize < (int)info->FbMapSize / 2) {
1814 	    info->textureSize = info->FbMapSize - 4 * bufferSize;
1815 	}
1816 
1817 	if (info->textureSize > 0) {
1818 	    l = R128MinBits((info->textureSize-1) / R128_NR_TEX_REGIONS);
1819 	    if (l < R128_LOG_TEX_GRANULARITY) l = R128_LOG_TEX_GRANULARITY;
1820 
1821 	    /* Round the texture size up to the nearest whole number of
1822 	     * texture regions.  Again, be greedy about this, don't
1823 	     * round down.
1824 	     */
1825 	    info->log2TexGran = l;
1826 	    info->textureSize = (info->textureSize >> l) << l;
1827 	} else {
1828 	    info->textureSize = 0;
1829 	}
1830 
1831 	/* Set a minimum usable local texture heap size.  This will fit
1832 	 * two 256x256x32bpp textures.
1833 	 */
1834 	if (info->textureSize < 512 * 1024) {
1835 	    info->textureOffset = 0;
1836 	    info->textureSize = 0;
1837 	}
1838 
1839         total = info->FbMapSize - info->textureSize;
1840     }
1841 #endif /* R128DRI */
1842 
1843     scanlines = total / width_bytes;
1844     if (scanlines > 8191) scanlines = 8191;
1845 
1846 #ifdef R128DRI
1847     if (info->directRenderingEnabled)
1848         /*
1849          * Recalculate the texture offset and size to accomodate any
1850          * rounding to a whole number of scanlines.
1851          */
1852         info->textureOffset = scanlines * width_bytes;
1853 #endif /* R128DRI */
1854 
1855     MemBox.x1 = 0;
1856     MemBox.y1 = 0;
1857     MemBox.x2 = pScrn->displayWidth;
1858     MemBox.y2 = scanlines;
1859 
1860 	if (!info->useEXA) {
1861 	    if (!xf86InitFBManager(pScreen, &MemBox)) {
1862 	        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1863 		           "Memory manager initialization to (%d,%d) (%d,%d) failed\n",
1864 		           MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2);
1865 	        return FALSE;
1866 	    } else {
1867 	        int width, height;
1868 
1869 	        xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1870 		           "Memory manager initialized to (%d,%d) (%d,%d)\n",
1871 		           MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2);
1872 	        if ((fbarea = xf86AllocateOffscreenArea(pScreen,
1873 						        pScrn->displayWidth,
1874 						        2, 0, NULL, NULL, NULL))) {
1875 		    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1876 			       "Reserved area from (%d,%d) to (%d,%d)\n",
1877 			       fbarea->box.x1, fbarea->box.y1,
1878 			       fbarea->box.x2, fbarea->box.y2);
1879 	        } else {
1880 		    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unable to reserve area\n");
1881 	        }
1882 	        if (xf86QueryLargestOffscreenArea(pScreen, &width,
1883 						  &height, 0, 0, 0)) {
1884 		    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1885 			       "Largest offscreen area available: %d x %d\n",
1886 				width, height);
1887 	        }
1888 
1889             if (!info->noAccel) {
1890                 if (R128XAAAccelInit(pScreen)) {
1891                     info->accelOn = TRUE;
1892                     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1893                                 "XAA acceleration enabled.\n");
1894                 } else {
1895                     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1896                                 "Acceleration disabled.\n");
1897                 }
1898             }
1899         }
1900     }
1901 #ifdef USE_EXA
1902     else {
1903         xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1904                     "Filling in EXA memory info\n");
1905 
1906 
1907         /*
1908          * Don't give EXA the true full memory size, because
1909          * the textureSize sized chunk on the end is handled
1910          * by DRI.
1911          */
1912         if (R128EXAInit(pScreen, total)) {
1913             info->accelOn = TRUE;
1914             xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1915                         "EXA Acceleration enabled.\n");
1916         } else {
1917             xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1918                         "EXA Acceleration initialization "
1919                         "failed.\n");
1920             xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1921                         "Acceleration disabled.\n");
1922         }
1923     }
1924 #endif
1925 
1926 #ifdef R128DRI
1927     if (info->directRenderingEnabled) {
1928 				/* Allocate the shared back buffer */
1929 	if(!info->useEXA) {
1930 	    fbarea = xf86AllocateOffscreenArea(pScreen,
1931 					       pScrn->virtualX,
1932 					       pScrn->virtualY,
1933 					       32, NULL, NULL, NULL);
1934 
1935 	    if (fbarea) {
1936 		x1 = fbarea->box.x1;
1937 		x2 = fbarea->box.x2;
1938 		y1 = fbarea->box.y1;
1939 		y2 = fbarea->box.y2;
1940 	    }
1941 	}
1942 #ifdef USE_EXA
1943 	else {
1944 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1945 		       "Actually trying an EXA allocation...\n");
1946 	    osArea = exaOffscreenAlloc(pScreen,
1947 				       pScrn->virtualY * width_bytes,
1948 				       32, TRUE, NULL, NULL);
1949 
1950 	    if (osArea) {
1951 		x1 = osArea->offset % width_bytes;
1952 		x2 = (osArea->offset + osArea->size) % width_bytes;
1953 		y1 = osArea->offset / width_bytes;
1954 		y2 = (osArea->offset + osArea->size) / width_bytes;
1955 
1956 		xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Went swimmingly...\n");
1957 	    }
1958 	}
1959 #endif
1960 
1961 	if ((!info->useEXA && fbarea) || (info->useEXA && osArea)) {
1962 	    /* info->backOffset = y1 * width_bytes + x1 * cpp; */
1963 	    info->backOffset = R128_ALIGN(y1 * width_bytes + x1 * cpp, 16);
1964 	    info->backX = info->backOffset % width_bytes;
1965 	    info->backY = info->backOffset / width_bytes;
1966 	    info->backPitch = pScrn->displayWidth;
1967 
1968 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1969 		       "Reserved back buffer from (%d,%d) to (%d,%d) offset: %x\n",
1970 		       x1, y1,
1971 		       x2, y2, info->backOffset);
1972 	} else {
1973 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unable to reserve back buffer\n");
1974 	    info->backX = -1;
1975 	    info->backY = -1;
1976 	    info->backOffset = -1;
1977 	    info->backPitch = -1;
1978 	}
1979 
1980 				/* Allocate the shared depth buffer */
1981 	if(!info->useEXA) {
1982 	    fbarea = xf86AllocateOffscreenArea(pScreen,
1983 					       pScrn->virtualX,
1984 					       pScrn->virtualY + 1,
1985 					       32, NULL, NULL, NULL);
1986 	    if (fbarea) {
1987 		x1 = fbarea->box.x1;
1988 		x2 = fbarea->box.x2;
1989 		y1 = fbarea->box.y1;
1990 		y2 = fbarea->box.y2;
1991 	    }
1992 	}
1993 #ifdef USE_EXA
1994 	else {
1995 	    osArea = exaOffscreenAlloc(pScreen,
1996 				       (pScrn->virtualY + 1) * width_bytes,
1997 				       32, TRUE, NULL, NULL);
1998 
1999 	    if (osArea) {
2000 		x1 = osArea->offset % width_bytes;
2001 		x2 = (osArea->offset + osArea->size) % width_bytes;
2002 		y1 = osArea->offset / width_bytes;
2003 		y2 = (osArea->offset + osArea->size) / width_bytes;
2004 	    }
2005 	}
2006 #endif
2007 
2008 	if ((!info->useEXA && fbarea) || (info->useEXA && osArea)) {
2009 	    /* info->depthOffset = y1 * width_bytes + x1 * cpp; */
2010 	    info->depthOffset = R128_ALIGN(y1 * width_bytes + x1 * cpp, 16);
2011 	    info->depthX = info->depthOffset % width_bytes;
2012 	    info->depthY = info->depthOffset / width_bytes;
2013 	    info->depthPitch = pScrn->displayWidth;
2014 	    info->spanOffset = (y2 - 1) * width_bytes + x1 * cpp;
2015 
2016 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2017 		       "Reserved depth buffer from (%d,%d) to (%d,%d) offset: %x\n",
2018 		       x1, y1,
2019 		       x2, y2, info->depthOffset);
2020 
2021 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2022 		       "Reserved depth span from (%d,%d) offset 0x%x\n",
2023 		       x1, y2 - 1, info->spanOffset);
2024 	} else {
2025 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unable to reserve depth buffer\n");
2026 	    info->depthX = -1;
2027 	    info->depthY = -1;
2028 	    info->depthOffset = -1;
2029 	    info->depthPitch = -1;
2030 	    info->spanOffset = -1;
2031 	}
2032 
2033 	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2034 		   "Reserved %d kb for textures at offset 0x%x\n",
2035 		   info->textureSize/1024, info->textureOffset);
2036     }
2037 #endif /* R128DRI */
2038 
2039     pScrn->vtSema = TRUE;
2040     /* xf86CrtcRotate accesses pScrn->pScreen */
2041     pScrn->pScreen = pScreen;
2042 
2043     if (info->FBDev) {
2044 	if (!fbdevHWModeInit(pScrn, pScrn->currentMode)) return FALSE;
2045     } else {
2046 	if (!xf86SetDesiredModes(pScrn)) return FALSE;
2047     }
2048 
2049     R128SaveScreen(pScreen, SCREEN_SAVER_ON);
2050     //pScrn->AdjustFrame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0));
2051 
2052 				/* DGA setup */
2053 #ifdef XFreeXDGA
2054     xf86DiDGAInit(pScreen, info->LinearAddr + pScrn->fbOffset);
2055 #endif
2056 
2057 				/* Backing store setup */
2058     xf86SetBackingStore(pScreen);
2059 
2060 				/* Set Silken Mouse */
2061     xf86SetSilkenMouse(pScreen);
2062 
2063 				/* Cursor setup */
2064     miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
2065 
2066 				/* Hardware cursor setup */
2067     if (!info->swCursor) {
2068 	if (R128CursorInit(pScreen)) {
2069 	    int width, height;
2070 
2071 	    if (xf86QueryLargestOffscreenArea(pScreen, &width, &height,
2072 					      0, 0, 0)) {
2073 		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2074 			   "Largest offscreen area available: %d x %d\n",
2075 			   width, height);
2076 	    }
2077 	} else {
2078 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2079 		       "Hardware cursor initialization failed\n");
2080 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using software cursor\n");
2081 	}
2082     } else {
2083 	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using software cursor\n");
2084     }
2085 
2086     /* DPMS setup - FIXME: also for mirror mode in non-fbdev case? - Michel */
2087     if (info->FBDev)
2088 	xf86DPMSInit(pScreen, fbdevHWDPMSSetWeak(), 0);
2089     else
2090         xf86DPMSInit(pScreen, xf86DPMSSet, 0);
2091 
2092     R128InitVideo(pScreen);
2093 
2094 				/* Provide SaveScreen */
2095     pScreen->SaveScreen  = R128SaveScreen;
2096 
2097 				/* Wrap CloseScreen */
2098     info->CloseScreen    = pScreen->CloseScreen;
2099     pScreen->CloseScreen = R128CloseScreen;
2100 
2101 				/* Note unused options */
2102     if (serverGeneration == 1)
2103 	xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
2104 
2105 #ifdef R128DRI
2106 				/* DRI finalization */
2107     if (info->directRenderingEnabled) {
2108 				/* Now that mi, fb, drm and others have
2109 				   done their thing, complete the DRI
2110 				   setup. */
2111 	info->directRenderingEnabled = R128DRIFinishScreenInit(pScreen);
2112     }
2113     if (info->directRenderingEnabled) {
2114 	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering enabled\n");
2115     } else {
2116 	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
2117 		   "Direct rendering disabled\n");
2118     }
2119 #endif
2120 
2121     info->BlockHandler = pScreen->BlockHandler;
2122     pScreen->BlockHandler = R128BlockHandler;
2123 
2124     if (!xf86CrtcScreenInit(pScreen)) return FALSE;
2125 
2126 				/* Colormap setup */
2127     if (!miCreateDefColormap(pScreen)) return FALSE;
2128     if (!xf86HandleColormaps(pScreen, 256, info->dac6bits ? 6 : 8,
2129 			     (info->FBDev ? fbdevHWLoadPaletteWeak() :
2130 			     R128LoadPalette), NULL,
2131 			     CMAP_PALETTED_TRUECOLOR
2132 			     | CMAP_RELOAD_ON_MODE_SWITCH
2133 #if 0 /* This option messes up text mode! (eich@suse.de) */
2134 			     | CMAP_LOAD_EVEN_IF_OFFSCREEN
2135 #endif
2136 			     )) return FALSE;
2137 
2138     return TRUE;
2139 }
2140 
2141 /* Write common registers (initialized to 0). */
R128RestoreCommonRegisters(ScrnInfoPtr pScrn,R128SavePtr restore)2142 void R128RestoreCommonRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
2143 {
2144     R128InfoPtr   info      = R128PTR(pScrn);
2145     unsigned char *R128MMIO = info->MMIO;
2146 
2147     OUTREG(R128_FP_GEN_CNTL, restore->fp_gen_cntl | R128_FP_BLANK_DIS);
2148 
2149     OUTREG(R128_OVR_CLR,              restore->ovr_clr);
2150     OUTREG(R128_OVR_WID_LEFT_RIGHT,   restore->ovr_wid_left_right);
2151     OUTREG(R128_OVR_WID_TOP_BOTTOM,   restore->ovr_wid_top_bottom);
2152     OUTREG(R128_OV0_SCALE_CNTL,       restore->ov0_scale_cntl);
2153     OUTREG(R128_MPP_TB_CONFIG,        restore->mpp_tb_config );
2154     OUTREG(R128_MPP_GP_CONFIG,        restore->mpp_gp_config );
2155     OUTREG(R128_SUBPIC_CNTL,          restore->subpic_cntl);
2156     OUTREG(R128_VIPH_CONTROL,         restore->viph_control);
2157     OUTREG(R128_I2C_CNTL_1,           restore->i2c_cntl_1);
2158     OUTREG(R128_GEN_INT_CNTL,         restore->gen_int_cntl);
2159     OUTREG(R128_CAP0_TRIG_CNTL,       restore->cap0_trig_cntl);
2160     OUTREG(R128_CAP1_TRIG_CNTL,       restore->cap1_trig_cntl);
2161     OUTREG(R128_BUS_CNTL,             restore->bus_cntl);
2162     OUTREG(R128_CONFIG_CNTL,          restore->config_cntl);
2163 }
2164 
2165 /* Write RMX registers */
R128RestoreRMXRegisters(ScrnInfoPtr pScrn,R128SavePtr restore)2166 void R128RestoreRMXRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
2167 {
2168     R128InfoPtr   info      = R128PTR(pScrn);
2169     unsigned char *R128MMIO = info->MMIO;
2170 
2171     OUTREG(R128_FP_HORZ_STRETCH,      restore->fp_horz_stretch);
2172     OUTREG(R128_FP_VERT_STRETCH,      restore->fp_vert_stretch);
2173     OUTREG(R128_FP_CRTC_H_TOTAL_DISP, restore->fp_crtc_h_total_disp);
2174     OUTREG(R128_FP_CRTC_V_TOTAL_DISP, restore->fp_crtc_v_total_disp);
2175     OUTREG(R128_FP_H_SYNC_STRT_WID,   restore->fp_h_sync_strt_wid);
2176     OUTREG(R128_FP_V_SYNC_STRT_WID,   restore->fp_v_sync_strt_wid);
2177 }
2178 
2179 /* Write flat panel registers */
R128RestoreFPRegisters(ScrnInfoPtr pScrn,R128SavePtr restore)2180 void R128RestoreFPRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
2181 {
2182     R128InfoPtr   info      = R128PTR(pScrn);
2183     unsigned char *R128MMIO = info->MMIO;
2184 
2185     OUTREG(R128_TMDS_CRC,              restore->tmds_crc);
2186     OUTREG(R128_TMDS_TRANSMITTER_CNTL, restore->tmds_transmitter_cntl);
2187     OUTREG(R128_FP_PANEL_CNTL,         restore->fp_panel_cntl);
2188     OUTREG(R128_FP_GEN_CNTL, restore->fp_gen_cntl & ~(uint32_t)R128_FP_BLANK_DIS);
2189 }
2190 
2191 /* Write LVDS registers */
R128RestoreLVDSRegisters(ScrnInfoPtr pScrn,R128SavePtr restore)2192 void R128RestoreLVDSRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
2193 {
2194     R128InfoPtr   info      = R128PTR(pScrn);
2195     R128EntPtr    pR128Ent  = R128EntPriv(pScrn);
2196     unsigned char *R128MMIO = info->MMIO;
2197     uint32_t      tmp;
2198 
2199     xf86OutputPtr output = R128FirstOutput(pR128Ent->pCrtc[0]);
2200     R128OutputPrivatePtr r128_output = output->driver_private;
2201 
2202     tmp = INREG(R128_LVDS_GEN_CNTL);
2203     if ((tmp & (R128_LVDS_ON | R128_LVDS_BLON)) ==
2204 	(restore->lvds_gen_cntl & (R128_LVDS_ON | R128_LVDS_BLON))) {
2205 	OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl);
2206     } else {
2207 	if (restore->lvds_gen_cntl & (R128_LVDS_ON | R128_LVDS_BLON)) {
2208 	    OUTREG(R128_LVDS_GEN_CNTL,
2209 		   restore->lvds_gen_cntl & (uint32_t)~R128_LVDS_BLON);
2210 	    usleep(r128_output->PanelPwrDly * 1000);
2211 	    OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl);
2212 	} else {
2213 	    OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl | R128_LVDS_BLON);
2214 	    usleep(r128_output->PanelPwrDly * 1000);
2215 	    OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl);
2216 	}
2217     }
2218 }
2219 
2220 /* Write DDA registers. */
R128RestoreDDARegisters(ScrnInfoPtr pScrn,R128SavePtr restore)2221 void R128RestoreDDARegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
2222 {
2223     R128InfoPtr   info      = R128PTR(pScrn);
2224     unsigned char *R128MMIO = info->MMIO;
2225 
2226     OUTREG(R128_DDA_CONFIG, restore->dda_config);
2227     OUTREG(R128_DDA_ON_OFF, restore->dda_on_off);
2228 }
2229 
2230 /* Write DDA registers. */
R128RestoreDDA2Registers(ScrnInfoPtr pScrn,R128SavePtr restore)2231 void R128RestoreDDA2Registers(ScrnInfoPtr pScrn, R128SavePtr restore)
2232 {
2233     R128InfoPtr   info      = R128PTR(pScrn);
2234     unsigned char *R128MMIO = info->MMIO;
2235 
2236     OUTREG(R128_DDA2_CONFIG, restore->dda2_config);
2237     OUTREG(R128_DDA2_ON_OFF, restore->dda2_on_off);
2238 }
2239 
2240 /* Read common registers. */
R128SaveCommonRegisters(ScrnInfoPtr pScrn,R128SavePtr save)2241 static void R128SaveCommonRegisters(ScrnInfoPtr pScrn, R128SavePtr save)
2242 {
2243     R128InfoPtr   info      = R128PTR(pScrn);
2244     unsigned char *R128MMIO = info->MMIO;
2245 
2246     save->ovr_clr            = INREG(R128_OVR_CLR);
2247     save->ovr_wid_left_right = INREG(R128_OVR_WID_LEFT_RIGHT);
2248     save->ovr_wid_top_bottom = INREG(R128_OVR_WID_TOP_BOTTOM);
2249     save->ov0_scale_cntl     = INREG(R128_OV0_SCALE_CNTL);
2250     save->mpp_tb_config      = INREG(R128_MPP_TB_CONFIG);
2251     save->mpp_gp_config      = INREG(R128_MPP_GP_CONFIG);
2252     save->subpic_cntl        = INREG(R128_SUBPIC_CNTL);
2253     save->viph_control       = INREG(R128_VIPH_CONTROL);
2254     save->i2c_cntl_1         = INREG(R128_I2C_CNTL_1);
2255     save->gen_int_cntl       = INREG(R128_GEN_INT_CNTL);
2256     save->cap0_trig_cntl     = INREG(R128_CAP0_TRIG_CNTL);
2257     save->cap1_trig_cntl     = INREG(R128_CAP1_TRIG_CNTL);
2258     save->bus_cntl           = INREG(R128_BUS_CNTL);
2259     save->config_cntl        = INREG(R128_CONFIG_CNTL);
2260 }
2261 
2262 /* Read CRTC registers. */
R128SaveCrtcRegisters(ScrnInfoPtr pScrn,R128SavePtr save)2263 static void R128SaveCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr save)
2264 {
2265     R128InfoPtr   info      = R128PTR(pScrn);
2266     unsigned char *R128MMIO = info->MMIO;
2267 
2268     save->crtc_gen_cntl        = INREG(R128_CRTC_GEN_CNTL);
2269     save->crtc_ext_cntl        = INREG(R128_CRTC_EXT_CNTL);
2270     save->dac_cntl             = INREG(R128_DAC_CNTL);
2271     save->crtc_h_total_disp    = INREG(R128_CRTC_H_TOTAL_DISP);
2272     save->crtc_h_sync_strt_wid = INREG(R128_CRTC_H_SYNC_STRT_WID);
2273     save->crtc_v_total_disp    = INREG(R128_CRTC_V_TOTAL_DISP);
2274     save->crtc_v_sync_strt_wid = INREG(R128_CRTC_V_SYNC_STRT_WID);
2275     save->crtc_offset          = INREG(R128_CRTC_OFFSET);
2276     save->crtc_offset_cntl     = INREG(R128_CRTC_OFFSET_CNTL);
2277     save->crtc_pitch           = INREG(R128_CRTC_PITCH);
2278 }
2279 
2280 /* Read flat panel registers */
R128SaveFPRegisters(ScrnInfoPtr pScrn,R128SavePtr save)2281 static void R128SaveFPRegisters(ScrnInfoPtr pScrn, R128SavePtr save)
2282 {
2283     R128InfoPtr   info      = R128PTR(pScrn);
2284     unsigned char *R128MMIO = info->MMIO;
2285 
2286     save->fp_crtc_h_total_disp = INREG(R128_FP_CRTC_H_TOTAL_DISP);
2287     save->fp_crtc_v_total_disp = INREG(R128_FP_CRTC_V_TOTAL_DISP);
2288     save->fp_gen_cntl          = INREG(R128_FP_GEN_CNTL);
2289     save->fp_h_sync_strt_wid   = INREG(R128_FP_H_SYNC_STRT_WID);
2290     save->fp_horz_stretch      = INREG(R128_FP_HORZ_STRETCH);
2291     save->fp_panel_cntl        = INREG(R128_FP_PANEL_CNTL);
2292     save->fp_v_sync_strt_wid   = INREG(R128_FP_V_SYNC_STRT_WID);
2293     save->fp_vert_stretch      = INREG(R128_FP_VERT_STRETCH);
2294     save->lvds_gen_cntl        = INREG(R128_LVDS_GEN_CNTL);
2295     save->tmds_crc             = INREG(R128_TMDS_CRC);
2296     save->tmds_transmitter_cntl = INREG(R128_TMDS_TRANSMITTER_CNTL);
2297 }
2298 
2299 /* Read CRTC2 registers. */
R128SaveCrtc2Registers(ScrnInfoPtr pScrn,R128SavePtr save)2300 static void R128SaveCrtc2Registers(ScrnInfoPtr pScrn, R128SavePtr save)
2301 {
2302     R128InfoPtr info        = R128PTR(pScrn);
2303     unsigned char *R128MMIO = info->MMIO;
2304 
2305     save->crtc2_gen_cntl        = INREG(R128_CRTC2_GEN_CNTL);
2306     save->crtc2_h_total_disp    = INREG(R128_CRTC2_H_TOTAL_DISP);
2307     save->crtc2_h_sync_strt_wid = INREG(R128_CRTC2_H_SYNC_STRT_WID);
2308     save->crtc2_v_total_disp    = INREG(R128_CRTC2_V_TOTAL_DISP);
2309     save->crtc2_v_sync_strt_wid = INREG(R128_CRTC2_V_SYNC_STRT_WID);
2310     save->crtc2_offset          = INREG(R128_CRTC2_OFFSET);
2311     save->crtc2_offset_cntl     = INREG(R128_CRTC2_OFFSET_CNTL);
2312     save->crtc2_pitch           = INREG(R128_CRTC2_PITCH);
2313 }
2314 
2315 /* Read PLL registers. */
R128SavePLLRegisters(ScrnInfoPtr pScrn,R128SavePtr save)2316 static void R128SavePLLRegisters(ScrnInfoPtr pScrn, R128SavePtr save)
2317 {
2318     save->ppll_ref_div         = INPLL(pScrn, R128_PPLL_REF_DIV);
2319     save->ppll_div_3           = INPLL(pScrn, R128_PPLL_DIV_3);
2320     save->ppll_div_0           = INPLL(pScrn, R128_PPLL_DIV_0);
2321     save->htotal_cntl          = INPLL(pScrn, R128_HTOTAL_CNTL);
2322 
2323     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2324                         "Read: 0x%08x 0x%08x 0x%08x\n",
2325                         save->ppll_ref_div,
2326                         save->ppll_div_3,
2327                         save->htotal_cntl));
2328     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2329                         "Read: rd=%d, fd=%d, pd=%d\n",
2330                         save->ppll_ref_div & R128_PPLL_REF_DIV_MASK,
2331                         save->ppll_div_3 & R128_PPLL_FB3_DIV_MASK,
2332                         (save->ppll_div_3 &
2333                                 R128_PPLL_POST3_DIV_MASK) >> 16));
2334 }
2335 
2336 /* Read PLL2 registers. */
R128SavePLL2Registers(ScrnInfoPtr pScrn,R128SavePtr save)2337 static void R128SavePLL2Registers(ScrnInfoPtr pScrn, R128SavePtr save)
2338 {
2339     save->p2pll_ref_div        = INPLL(pScrn, R128_P2PLL_REF_DIV);
2340     save->p2pll_div_0          = INPLL(pScrn, R128_P2PLL_DIV_0);
2341     save->htotal_cntl2         = INPLL(pScrn, R128_HTOTAL2_CNTL);
2342 
2343     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2344                         "Read: 0x%08x 0x%08x 0x%08x\n",
2345                         save->p2pll_ref_div,
2346                         save->p2pll_div_0,
2347                         save->htotal_cntl2));
2348     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2349                         "Read: rd=%d, fd=%d, pd=%d\n",
2350                         save->p2pll_ref_div & R128_P2PLL_REF_DIV_MASK,
2351                         save->p2pll_div_0 & R128_P2PLL_FB0_DIV_MASK,
2352                         (save->p2pll_div_0 &
2353                                 R128_P2PLL_POST0_DIV_MASK) >> 16));
2354 }
2355 
2356 /* Read DDA registers. */
R128SaveDDARegisters(ScrnInfoPtr pScrn,R128SavePtr save)2357 static void R128SaveDDARegisters(ScrnInfoPtr pScrn, R128SavePtr save)
2358 {
2359     R128InfoPtr   info      = R128PTR(pScrn);
2360     unsigned char *R128MMIO = info->MMIO;
2361 
2362     save->dda_config           = INREG(R128_DDA_CONFIG);
2363     save->dda_on_off           = INREG(R128_DDA_ON_OFF);
2364 }
2365 
2366 /* Read DDA2 registers. */
R128SaveDDA2Registers(ScrnInfoPtr pScrn,R128SavePtr save)2367 static void R128SaveDDA2Registers(ScrnInfoPtr pScrn, R128SavePtr save)
2368 {
2369     R128InfoPtr   info      = R128PTR(pScrn);
2370     unsigned char *R128MMIO = info->MMIO;
2371 
2372     save->dda2_config           = INREG(R128_DDA2_CONFIG);
2373     save->dda2_on_off           = INREG(R128_DDA2_ON_OFF);
2374 }
2375 
2376 /* Read palette data. */
R128SavePalette(ScrnInfoPtr pScrn,R128SavePtr save)2377 static void R128SavePalette(ScrnInfoPtr pScrn, R128SavePtr save)
2378 {
2379     R128InfoPtr   info      = R128PTR(pScrn);
2380     unsigned char *R128MMIO = info->MMIO;
2381     int           i;
2382 
2383     PAL_SELECT(1);
2384     INPAL_START(0);
2385     for (i = 0; i < 256; i++) save->palette2[i] = INPAL_NEXT();
2386     PAL_SELECT(0);
2387     INPAL_START(0);
2388     for (i = 0; i < 256; i++) save->palette[i] = INPAL_NEXT();
2389     save->palette_valid = TRUE;
2390 }
2391 
2392 /* Save state that defines current video mode. */
R128SaveMode(ScrnInfoPtr pScrn,R128SavePtr save)2393 static void R128SaveMode(ScrnInfoPtr pScrn, R128SavePtr save)
2394 {
2395     R128InfoPtr   info      = R128PTR(pScrn);
2396     R128EntPtr    pR128Ent  = R128EntPriv(pScrn);
2397 
2398     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2399                         "%s(%p)\n", __func__, save));
2400 
2401     R128SaveCommonRegisters(pScrn, save);
2402     R128SaveCrtcRegisters(pScrn, save);
2403     R128SavePLLRegisters(pScrn, save);
2404     R128SaveDDARegisters(pScrn, save);
2405     if (pR128Ent->HasCRTC2) {
2406         R128SaveCrtc2Registers(pScrn, save);
2407         R128SavePLL2Registers(pScrn, save);
2408         R128SaveDDA2Registers(pScrn, save);
2409     }
2410     if (info->HasPanelRegs) {
2411         R128SaveFPRegisters(pScrn, save);
2412     }
2413     R128SavePalette(pScrn, save);
2414 
2415     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2416                         "%s returns %p\n", __func__, save));
2417 }
2418 
2419 /* Save everything needed to restore the original VC state. */
R128Save(ScrnInfoPtr pScrn)2420 static void R128Save(ScrnInfoPtr pScrn)
2421 {
2422     R128InfoPtr   info      = R128PTR(pScrn);
2423     unsigned char *R128MMIO = info->MMIO;
2424     R128SavePtr   save      = &info->SavedReg;
2425 
2426     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2427                         "%s\n", __func__));
2428     if (info->FBDev) {
2429 	fbdevHWSave(pScrn);
2430 	return;
2431     }
2432 
2433 #ifdef WITH_VGAHW
2434     if (info->VGAAccess) {
2435         vgaHWPtr hwp = VGAHWPTR(pScrn);
2436 
2437         vgaHWUnlock(hwp);
2438 # if defined(__powerpc__)
2439         /* temporary hack to prevent crashing on PowerMacs when trying to
2440          * read VGA fonts and colormap, will find a better solution
2441          * in the future. TODO: Check if there's actually some VGA stuff
2442          * setup in the card at all !!
2443          */
2444         vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_MODE); /* Save mode only */
2445 # else
2446         /* Save mode * & fonts & cmap */
2447         vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_MODE | VGA_SR_FONTS);
2448 # endif
2449         vgaHWLock(hwp);
2450     }
2451 #endif
2452 
2453     save->dp_datatype      = INREG(R128_DP_DATATYPE);
2454     save->gen_reset_cntl   = INREG(R128_GEN_RESET_CNTL);
2455     save->clock_cntl_index = INREG(R128_CLOCK_CNTL_INDEX);
2456     save->amcgpio_en_reg   = INREG(R128_AMCGPIO_EN_REG);
2457     save->amcgpio_mask     = INREG(R128_AMCGPIO_MASK);
2458 
2459     R128SaveMode(pScrn, save);
2460 }
2461 
2462 /* Restore the original (text) mode. */
R128Restore(ScrnInfoPtr pScrn)2463 static void R128Restore(ScrnInfoPtr pScrn)
2464 {
2465     R128InfoPtr   info      = R128PTR(pScrn);
2466     R128EntPtr    pR128Ent  = R128EntPriv(pScrn);
2467     unsigned char *R128MMIO = info->MMIO;
2468     R128SavePtr   restore   = &info->SavedReg;
2469 
2470     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2471                         "%s\n", __func__));
2472     if (info->FBDev) {
2473 	fbdevHWRestore(pScrn);
2474 	return;
2475     }
2476 
2477     R128Blank(pScrn);
2478 
2479     OUTREG(R128_AMCGPIO_MASK,     restore->amcgpio_mask);
2480     OUTREG(R128_AMCGPIO_EN_REG,   restore->amcgpio_en_reg);
2481     OUTREG(R128_CLOCK_CNTL_INDEX, restore->clock_cntl_index);
2482     OUTREG(R128_GEN_RESET_CNTL,   restore->gen_reset_cntl);
2483     OUTREG(R128_DP_DATATYPE,      restore->dp_datatype);
2484 
2485     R128RestoreCommonRegisters(pScrn, restore);
2486     if (pR128Ent->HasCRTC2) {
2487         R128RestoreDDA2Registers(pScrn, restore);
2488         R128RestoreCrtc2Registers(pScrn, restore);
2489         R128RestorePLL2Registers(pScrn, restore);
2490     }
2491     R128RestoreDDARegisters(pScrn, restore);
2492     R128RestoreCrtcRegisters(pScrn, restore);
2493     R128RestorePLLRegisters(pScrn, restore);
2494     R128RestoreDACRegisters(pScrn, restore);
2495     R128RestoreRMXRegisters(pScrn, restore);
2496     R128RestoreFPRegisters(pScrn, restore);
2497     R128RestoreLVDSRegisters(pScrn, restore);
2498 
2499 #ifdef WITH_VGAHW
2500     if (info->VGAAccess) {
2501         vgaHWPtr hwp = VGAHWPTR(pScrn);
2502         vgaHWUnlock(hwp);
2503 # if defined(__powerpc__)
2504         /* Temporary hack to prevent crashing on PowerMacs when trying to
2505          * write VGA fonts, will find a better solution in the future
2506          */
2507         vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE );
2508 # else
2509         vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE | VGA_SR_FONTS );
2510 # endif
2511         vgaHWLock(hwp);
2512     }
2513 #endif
2514 
2515     R128WaitForVerticalSync(pScrn);
2516     R128Unblank(pScrn);
2517 }
2518 
2519 /* Define common registers for requested video mode. */
R128InitCommonRegisters(R128SavePtr save,R128InfoPtr info)2520 void R128InitCommonRegisters(R128SavePtr save, R128InfoPtr info)
2521 {
2522     save->ovr_clr            = 0;
2523     save->ovr_wid_left_right = 0;
2524     save->ovr_wid_top_bottom = 0;
2525     save->ov0_scale_cntl     = 0;
2526     save->mpp_tb_config      = 0;
2527     save->mpp_gp_config      = 0;
2528     save->subpic_cntl        = 0;
2529     save->viph_control       = 0;
2530     save->i2c_cntl_1         = 0;
2531 #ifdef R128DRI
2532     save->gen_int_cntl       = info->gen_int_cntl;
2533 #else
2534     save->gen_int_cntl       = 0;
2535 #endif
2536     save->cap0_trig_cntl     = 0;
2537     save->cap1_trig_cntl     = 0;
2538     save->bus_cntl           = info->BusCntl;
2539     /*
2540      * If bursts are enabled, turn on discards and aborts
2541      */
2542     if (save->bus_cntl & (R128_BUS_WRT_BURST|R128_BUS_READ_BURST))
2543 	save->bus_cntl |= R128_BUS_RD_DISCARD_EN | R128_BUS_RD_ABORT_EN;
2544 }
2545 
2546 /* Define RMX registers for the requested video mode. */
R128InitRMXRegisters(R128SavePtr orig,R128SavePtr save,xf86OutputPtr output,DisplayModePtr mode)2547 void R128InitRMXRegisters(R128SavePtr orig, R128SavePtr save,
2548                           xf86OutputPtr output, DisplayModePtr mode)
2549 {
2550     R128OutputPrivatePtr r128_output = output->driver_private;
2551 
2552     int   xres = mode->CrtcHDisplay;
2553     int   yres = mode->CrtcVDisplay;
2554     float Hratio, Vratio;
2555 
2556     save->fp_crtc_h_total_disp = save->crtc_h_total_disp;
2557     save->fp_crtc_v_total_disp = save->crtc_v_total_disp;
2558     save->fp_h_sync_strt_wid   = save->crtc_h_sync_strt_wid;
2559     save->fp_v_sync_strt_wid   = save->crtc_v_sync_strt_wid;
2560 
2561     if (r128_output->MonType != MT_DFP && r128_output->MonType != MT_LCD)
2562         return;
2563 
2564     if (r128_output->PanelXRes == 0 || r128_output->PanelYRes == 0) {
2565         xres = r128_output->PanelXRes;
2566         yres = r128_output->PanelYRes;
2567 
2568         Hratio = 1.0;
2569         Vratio = 1.0;
2570     } else {
2571         if (xres > r128_output->PanelXRes) xres = r128_output->PanelXRes;
2572         if (yres > r128_output->PanelYRes) yres = r128_output->PanelYRes;
2573 
2574         Hratio = (float)xres/(float)r128_output->PanelXRes;
2575         Vratio = (float)yres/(float)r128_output->PanelYRes;
2576     }
2577 
2578     save->fp_horz_stretch =
2579 	(((((int)(Hratio * R128_HORZ_STRETCH_RATIO_MAX + 0.5))
2580 	   & R128_HORZ_STRETCH_RATIO_MASK) << R128_HORZ_STRETCH_RATIO_SHIFT) |
2581        (orig->fp_horz_stretch & (R128_HORZ_PANEL_SIZE |
2582                                  R128_HORZ_FP_LOOP_STRETCH |
2583                                  R128_HORZ_STRETCH_RESERVED)));
2584     save->fp_horz_stretch &= ~R128_HORZ_AUTO_RATIO_FIX_EN;
2585     save->fp_horz_stretch &= ~R128_AUTO_HORZ_RATIO;
2586     if (xres == r128_output->PanelXRes)
2587          save->fp_horz_stretch &= ~(R128_HORZ_STRETCH_BLEND | R128_HORZ_STRETCH_ENABLE);
2588     else
2589          save->fp_horz_stretch |=  (R128_HORZ_STRETCH_BLEND | R128_HORZ_STRETCH_ENABLE);
2590 
2591     save->fp_vert_stretch =
2592 	(((((int)(Vratio * R128_VERT_STRETCH_RATIO_MAX + 0.5))
2593 	   & R128_VERT_STRETCH_RATIO_MASK) << R128_VERT_STRETCH_RATIO_SHIFT) |
2594 	 (orig->fp_vert_stretch & (R128_VERT_PANEL_SIZE |
2595 				   R128_VERT_STRETCH_RESERVED)));
2596     save->fp_vert_stretch &= ~R128_VERT_AUTO_RATIO_EN;
2597     if (yres == r128_output->PanelYRes)
2598         save->fp_vert_stretch &= ~(R128_VERT_STRETCH_ENABLE | R128_VERT_STRETCH_BLEND);
2599     else
2600         save->fp_vert_stretch |=  (R128_VERT_STRETCH_ENABLE | R128_VERT_STRETCH_BLEND);
2601 }
2602 
2603 /* Define flat panel registers for the requested video mode. */
R128InitFPRegisters(R128SavePtr orig,R128SavePtr save,xf86OutputPtr output)2604 void R128InitFPRegisters(R128SavePtr orig, R128SavePtr save, xf86OutputPtr output)
2605 {
2606     xf86CrtcPtr crtc = output->crtc;
2607     R128CrtcPrivatePtr r128_crtc = crtc->driver_private;
2608 
2609     /* WARNING: Be careful about turning on the flat panel */
2610     save->fp_gen_cntl            = orig->fp_gen_cntl;
2611     save->fp_panel_cntl          = orig->fp_panel_cntl;
2612     save->tmds_transmitter_cntl  = orig->tmds_transmitter_cntl;
2613     save->tmds_crc               = orig->tmds_crc;
2614 
2615     if (r128_crtc->crtc_id)
2616         save->fp_gen_cntl       |=   R128_FP_SEL_CRTC2;
2617     else
2618         save->fp_gen_cntl       &=  ~R128_FP_SEL_CRTC2;
2619 
2620     save->fp_gen_cntl           &= ~(R128_FP_CRTC_USE_SHADOW_VEND |
2621                                      R128_FP_CRTC_USE_SHADOW_ROWCUR |
2622                                      R128_FP_CRTC_HORZ_DIV2_EN |
2623                                      R128_FP_CRTC_HOR_CRT_DIV2_DIS |
2624                                      R128_FP_CRT_SYNC_SEL |
2625                                      R128_FP_USE_SHADOW_EN);
2626 
2627     save->fp_gen_cntl           |=  (R128_FP_CRTC_DONT_SHADOW_VPAR |
2628                                      R128_FP_CRTC_DONT_SHADOW_HEND);
2629 
2630     save->fp_panel_cntl         |=  (R128_FP_DIGON | R128_FP_BLON);
2631     save->tmds_transmitter_cntl &=  ~R128_TMDS_PLLRST;
2632     save->tmds_transmitter_cntl |=   R128_TMDS_PLLEN;
2633 }
2634 
2635 /* Define LVDS registers for the requested video mode. */
R128InitLVDSRegisters(R128SavePtr orig,R128SavePtr save,xf86OutputPtr output)2636 void R128InitLVDSRegisters(R128SavePtr orig, R128SavePtr save, xf86OutputPtr output)
2637 {
2638     xf86CrtcPtr crtc = output->crtc;
2639     R128CrtcPrivatePtr r128_crtc = crtc->driver_private;
2640 
2641     save->lvds_gen_cntl      =  orig->lvds_gen_cntl;
2642 
2643     if (r128_crtc->crtc_id)
2644         save->lvds_gen_cntl |=  R128_LVDS_SEL_CRTC2;
2645     else
2646         save->lvds_gen_cntl &= ~R128_LVDS_SEL_CRTC2;
2647 }
2648 
2649 #if 0
2650 /* Define initial palette for requested video mode.  This doesn't do
2651    anything for XFree86 4.0. */
2652 static void R128InitPalette(R128SavePtr save)
2653 {
2654     save->palette_valid = FALSE;
2655 }
2656 #endif
2657 
R128SaveScreen(ScreenPtr pScreen,int mode)2658 static Bool R128SaveScreen(ScreenPtr pScreen, int mode)
2659 {
2660     ScrnInfoPtr   pScrn = xf86ScreenToScrn(pScreen);
2661     Bool unblank;
2662 
2663     unblank = xf86IsUnblank(mode);
2664     if (unblank)
2665 	SetTimeSinceLastInputEvent();
2666 
2667     if ((pScrn != NULL) && pScrn->vtSema) {
2668 	if (unblank)
2669 		R128Unblank(pScrn);
2670 	else
2671 		R128Blank(pScrn);
2672     }
2673     return TRUE;
2674 }
2675 
2676 /*
2677  * SwitchMode() doesn't work right on crtc2 on some laptops.
2678  * The workaround is to switch the mode, then switch to another VT, then
2679  * switch back. --AGD
2680  */
R128SwitchMode(SWITCH_MODE_ARGS_DECL)2681 Bool R128SwitchMode(SWITCH_MODE_ARGS_DECL)
2682 {
2683     SCRN_INFO_PTR(arg);
2684     R128InfoPtr info        = R128PTR(pScrn);
2685     Bool ret;
2686 
2687     info->SwitchingMode = TRUE;
2688     ret = xf86SetSingleMode(pScrn, mode, RR_Rotate_0);
2689     info->SwitchingMode = FALSE;
2690     return ret;
2691 }
2692 
R128DoValidMode(xf86OutputPtr output,DisplayModePtr mode,int flags)2693 ModeStatus R128DoValidMode(xf86OutputPtr output, DisplayModePtr mode, int flags)
2694 {
2695     ScrnInfoPtr pScrn = output->scrn;
2696     R128InfoPtr info  = R128PTR(pScrn);
2697     R128OutputPrivatePtr r128_output = output->driver_private;
2698     int i, j;
2699 
2700     if (r128_output->MonType == MT_CRT)
2701         return MODE_OK;
2702 
2703     if (r128_output->MonType == MT_DFP || r128_output->MonType == MT_LCD) {
2704 	if (mode->Flags & V_INTERLACE) return MODE_NO_INTERLACE;
2705 	if (mode->Flags & V_DBLSCAN)   return MODE_NO_DBLESCAN;
2706     }
2707 
2708     if (r128_output->MonType == MT_LCD && info->VBIOS) {
2709 	for (i = info->FPBIOSstart + 64; R128_BIOS16(i) != 0; i += 2) {
2710 	    j = R128_BIOS16(i);
2711 
2712 	    if (mode->CrtcHDisplay == R128_BIOS16(j) &&
2713 		mode->CrtcVDisplay == R128_BIOS16(j + 2)) {
2714 		if ((flags & MODECHECK_FINAL) == MODECHECK_FINAL) {
2715 		    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2716 			       "Modifying mode according to VBIOS: %ix%i [pclk %.1f MHz] for FP to: ",
2717 			       mode->CrtcHDisplay, mode->CrtcVDisplay,
2718 			       (float)mode->Clock / 1000);
2719 
2720 		    /* Assume we are using expanded mode */
2721 		    if (R128_BIOS16(j + 5)) j  = R128_BIOS16(j + 5);
2722 		    else                    j += 9;
2723 
2724 		    mode->Clock = (uint32_t)R128_BIOS16(j) * 10;
2725 
2726 		    mode->HDisplay   = mode->CrtcHDisplay   =
2727 			((R128_BIOS16(j + 10) & 0x01ff) + 1) * 8;
2728 		    mode->HSyncStart = mode->CrtcHSyncStart =
2729 			((R128_BIOS16(j + 12) & 0x01ff) + 1) * 8;
2730 		    mode->HSyncEnd   = mode->CrtcHSyncEnd   =
2731 			mode->CrtcHSyncStart + (R128_BIOS8(j + 14) & 0x1f);
2732 		    mode->HTotal     = mode->CrtcHTotal     =
2733 			((R128_BIOS16(j + 8)  & 0x01ff) + 1) * 8;
2734 
2735 		    mode->VDisplay   = mode->CrtcVDisplay   =
2736 			(R128_BIOS16(j + 17) & 0x07ff) + 1;
2737 		    mode->VSyncStart = mode->CrtcVSyncStart =
2738 			(R128_BIOS16(j + 19) & 0x07ff) + 1;
2739 		    mode->VSyncEnd   = mode->CrtcVSyncEnd   =
2740 			mode->CrtcVSyncStart + ((R128_BIOS16(j + 19) >> 11) & 0x1f);
2741 		    mode->VTotal     = mode->CrtcVTotal     =
2742 			(R128_BIOS16(j + 15) & 0x07ff) + 1;
2743 		    xf86ErrorF("%ix%i [pclk %.1f MHz]\n",
2744 			       mode->CrtcHDisplay,mode->CrtcVDisplay,
2745 			       (float)mode->Clock/ 1000);
2746 		}
2747 		return MODE_OK;
2748 	    }
2749 	}
2750 	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 5,
2751 		       "Mode rejected for FP %ix%i [pclk: %.1f] "
2752 		       "(not listed in VBIOS)\n",
2753 		       mode->CrtcHDisplay, mode->CrtcVDisplay,
2754 		       (float)mode->Clock / 1000);
2755 	return MODE_NOMODE;
2756     }
2757 
2758     return MODE_OK;
2759 }
2760 
2761 /* Used to disallow modes that are not supported by the hardware. */
R128ValidMode(SCRN_ARG_TYPE arg,DisplayModePtr mode,Bool verbose,int flags)2762 ModeStatus R128ValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode,
2763                                    Bool verbose, int flags)
2764 {
2765     SCRN_INFO_PTR(arg);
2766     R128EntPtr  pR128Ent = R128EntPriv(pScrn);
2767     xf86OutputPtr output = R128FirstOutput(pR128Ent->pCrtc[0]);
2768 
2769     return R128DoValidMode(output, mode, flags);
2770 }
2771 
2772 /* Adjust viewport into virtual desktop such that (0,0) in viewport space
2773    is (x,y) in virtual space. */
R128AdjustFrame(ADJUST_FRAME_ARGS_DECL)2774 void R128AdjustFrame(ADJUST_FRAME_ARGS_DECL)
2775 {
2776     SCRN_INFO_PTR(arg);
2777     R128InfoPtr   info      = R128PTR(pScrn);
2778     unsigned char *R128MMIO = info->MMIO;
2779     int           Base;
2780 
2781     if(info->showCache && y && pScrn->vtSema)
2782         y += pScrn->virtualY - 1;
2783 
2784     Base = y * info->CurrentLayout.displayWidth + x;
2785 
2786     switch (info->CurrentLayout.pixel_code) {
2787     case 15:
2788     case 16: Base *= 2; break;
2789     case 24: Base *= 3; break;
2790     case 32: Base *= 4; break;
2791     }
2792 
2793     Base &= ~7;                 /* 3 lower bits are always 0 */
2794 
2795     if (info->CurrentLayout.pixel_code == 24)
2796 	Base += 8 * (Base % 3); /* Must be multiple of 8 and 3 */
2797 
2798     OUTREG(R128_CRTC_OFFSET, Base);
2799 }
2800 
2801 /* Called when VT switching back to the X server.  Reinitialize the video
2802    mode. */
R128EnterVT(VT_FUNC_ARGS_DECL)2803 Bool R128EnterVT(VT_FUNC_ARGS_DECL)
2804 {
2805     SCRN_INFO_PTR(arg);
2806     R128InfoPtr info  = R128PTR(pScrn);
2807 
2808     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2809                         "%s\n", __func__));
2810 
2811     pScrn->vtSema = TRUE;
2812     if (info->FBDev) {
2813         if (!fbdevHWEnterVT(VT_FUNC_ARGS)) return FALSE;
2814     } else {
2815         if (!xf86SetDesiredModes(pScrn)) return FALSE;
2816     }
2817 
2818     //if (!R128ModeInit(pScrn, pScrn->currentMode)) return FALSE;
2819 
2820     if (info->accelOn)
2821 	R128EngineInit(pScrn);
2822 
2823 #ifdef R128DRI
2824     if (info->directRenderingEnabled) {
2825 	if (info->irq) {
2826 	    /* Need to make sure interrupts are enabled */
2827 	    unsigned char *R128MMIO = info->MMIO;
2828 	    OUTREG(R128_GEN_INT_CNTL, info->gen_int_cntl);
2829 	}
2830 	R128CCE_START(pScrn, info);
2831 	DRIUnlock(pScrn->pScreen);
2832     }
2833 #endif
2834 
2835     info->PaletteSavedOnVT = FALSE;
2836     //pScrn->AdjustFrame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0));
2837 
2838     return TRUE;
2839 }
2840 
2841 /* Called when VT switching away from the X server.  Restore the original
2842    text mode. */
R128LeaveVT(VT_FUNC_ARGS_DECL)2843 void R128LeaveVT(VT_FUNC_ARGS_DECL)
2844 {
2845     SCRN_INFO_PTR(arg);
2846     R128InfoPtr info  = R128PTR(pScrn);
2847     R128SavePtr save  = &info->ModeReg;
2848 
2849     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2850                         "%s\n", __func__));
2851 #ifdef R128DRI
2852     if (info->directRenderingEnabled) {
2853 	DRILock(pScrn->pScreen, 0);
2854 	R128CCE_STOP(pScrn, info);
2855     }
2856 #ifdef USE_EXA
2857     if (info->useEXA)
2858         info->state_2d.composite_setup = FALSE;
2859 #endif
2860 #endif
2861     R128SavePalette(pScrn, save);
2862     info->PaletteSavedOnVT = TRUE;
2863     if (info->FBDev)
2864         fbdevHWLeaveVT(VT_FUNC_ARGS);
2865     else
2866         R128Restore(pScrn);
2867 }
2868 
2869 
2870 /* Called at the end of each server generation.  Restore the original text
2871    mode, unmap video memory, and unwrap and call the saved CloseScreen
2872    function.  */
R128CloseScreen(CLOSE_SCREEN_ARGS_DECL)2873 static Bool R128CloseScreen(CLOSE_SCREEN_ARGS_DECL)
2874 {
2875     ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
2876     R128InfoPtr info  = R128PTR(pScrn);
2877 
2878     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2879                         "%s\n", __func__));
2880 
2881 #ifdef R128DRI
2882 				/* Disable direct rendering */
2883     if (info->directRenderingEnabled) {
2884 	R128DRICloseScreen(pScreen);
2885 	info->directRenderingEnabled = FALSE;
2886     }
2887 #endif
2888 
2889     if (pScrn->vtSema) {
2890 	R128Restore(pScrn);
2891 	R128UnmapMem(pScrn);
2892     }
2893 
2894 #ifdef USE_EXA
2895         if (info->useEXA) {
2896 	    exaDriverFini(pScreen);
2897 	    free(info->ExaDriver);
2898 	} else
2899 #endif
2900 #ifdef HAVE_XAA_H
2901 	{
2902             if (info->accel)             XAADestroyInfoRec(info->accel);
2903 	    info->accel                  = NULL;
2904         }
2905 #endif
2906 
2907     if (info->scratch_save)      free(info->scratch_save);
2908     info->scratch_save           = NULL;
2909 
2910     if (info->adaptor) {
2911         free(info->adaptor->pPortPrivates[0].ptr);
2912 	xf86XVFreeVideoAdaptorRec(info->adaptor);
2913 	info->adaptor = NULL;
2914     }
2915 
2916     pScrn->vtSema = FALSE;
2917 
2918     pScreen->BlockHandler = info->BlockHandler;
2919     pScreen->CloseScreen = info->CloseScreen;
2920     return (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS);
2921 }
2922 
R128FreeScreen(FREE_SCREEN_ARGS_DECL)2923 void R128FreeScreen(FREE_SCREEN_ARGS_DECL)
2924 {
2925     SCRN_INFO_PTR(arg);
2926     R128InfoPtr   info      = R128PTR(pScrn);
2927 
2928     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2929                         "%s\n", __func__));
2930     if (info == NULL)
2931 	return;
2932 #ifdef WITH_VGAHW
2933     if (info->VGAAccess && xf86LoaderCheckSymbol("vgaHWFreeHWRec"))
2934 	vgaHWFreeHWRec(pScrn);
2935 #endif
2936     R128FreeRec(pScrn);
2937 }
2938