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