First import
[xorg_rtime.git] / xorg-server-1.4 / hw / kdrive / ati / ati.c
blobc4f67e171f7bf85091509f2d84592e2561aacc11
1 /*
2 * Copyright © 2003 Eric Anholt
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of Eric Anholt not be used in
9 * advertising or publicity pertaining to distribution of the software without
10 * specific, written prior permission. Eric Anholt makes no
11 * representations about the suitability of this software for any purpose. It
12 * is provided "as is" without express or implied warranty.
14 * ERIC ANHOLT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL ERIC ANHOLT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 * PERFORMANCE OF THIS SOFTWARE.
23 #ifdef HAVE_CONFIG_H
24 #include <kdrive-config.h>
25 #endif
26 #include "ati.h"
27 #include "ati_reg.h"
28 #if defined(USE_DRI) && defined(GLXEXT)
29 #include "ati_sarea.h"
30 #endif
32 static Bool ATIIsAGP(ATICardInfo *atic);
34 #define CAP_SERIESMASK 0xf
35 #define CAP_R128 0x1 /* If it's a Rage 128 */
36 #define CAP_R100 0x2 /* If it's an r100 series radeon. */
37 #define CAP_R200 0x3 /* If it's an r200 series radeon. */
38 #define CAP_R300 0x4 /* If it's an r300 series radeon. */
40 #define CAP_FEATURESMASK 0xf0
41 #define CAP_NOAGP 0x10 /* If it's a PCI-only card. */
43 struct pci_id_entry ati_pci_ids[] = {
44 {0x1002, 0x4136, 0x2, "ATI Radeon RS100"},
45 {0x1002, 0x4137, 0x2, "ATI Radeon RS200"},
46 {0x1002, 0x4237, 0x2, "ATI Radeon RS250"},
47 {0x1002, 0x4144, 0x4, "ATI Radeon R300 AD"},
48 {0x1002, 0x4145, 0x4, "ATI Radeon R300 AE"},
49 {0x1002, 0x4146, 0x4, "ATI Radeon R300 AF"},
50 {0x1002, 0x4147, 0x4, "ATI Radeon R300 AG"},
51 {0x1002, 0x4148, 0x4, "ATI Radeon R350 AH"},
52 {0x1002, 0x4149, 0x4, "ATI Radeon R350 AI"},
53 {0x1002, 0x414a, 0x4, "ATI Radeon R350 AJ"},
54 {0x1002, 0x414b, 0x4, "ATI Radeon R350 AK"},
55 {0x1002, 0x4150, 0x4, "ATI Radeon RV350 AP"},
56 {0x1002, 0x4151, 0x4, "ATI Radeon RV350 AQ"},
57 {0x1002, 0x4152, 0x4, "ATI Radeon RV350 AR"},
58 {0x1002, 0x4153, 0x4, "ATI Radeon RV350 AS"},
59 {0x1002, 0x4154, 0x4, "ATI Radeon RV350 AT"},
60 {0x1002, 0x4156, 0x4, "ATI Radeon RV350 AV"},
61 {0x1002, 0x4242, 0x3, "ATI Radeon R200 BB"},
62 {0x1002, 0x4243, 0x3, "ATI Radeon R200 BC"},
63 {0x1002, 0x4336, 0x2, "ATI Radeon RS100"},
64 {0x1002, 0x4337, 0x2, "ATI Radeon RS200"},
65 {0x1002, 0x4437, 0x2, "ATI Radeon RS250"},
66 {0x1002, 0x4964, 0x2, "ATI Radeon RV250 Id"},
67 {0x1002, 0x4965, 0x2, "ATI Radeon RV250 Ie"},
68 {0x1002, 0x4966, 0x2, "ATI Radeon RV250 If"},
69 {0x1002, 0x4967, 0x2, "ATI Radeon R250 Ig"},
70 {0x1002, 0x4c45, 0x11, "ATI Rage 128 LE"},
71 {0x1002, 0x4c46, 0x1, "ATI Rage 128 LF"},
72 {0x1002, 0x4c57, 0x2, "ATI Radeon Mobiliy M7 RV200 LW (7500)"},
73 {0x1002, 0x4c58, 0x2, "ATI Radeon Mobiliy M7 RV200 LX (7500)"},
74 {0x1002, 0x4c59, 0x2, "ATI Radeon Mobility M6 LY"},
75 {0x1002, 0x4c5a, 0x2, "ATI Radeon Mobility M6 LZ"},
76 {0x1002, 0x4c64, 0x3, "ATI Radeon RV250 Ld"},
77 {0x1002, 0x4c65, 0x3, "ATI Radeon RV250 Le"},
78 {0x1002, 0x4c66, 0x3, "ATI Radeon Mobility M9 RV250 Lf"},
79 {0x1002, 0x4c67, 0x3, "ATI Radeon RV250 Lg"},
80 {0x1002, 0x4d46, 0x1, "ATI Rage 128 MF"},
81 {0x1002, 0x4d46, 0x1, "ATI Rage 128 ML"},
82 {0x1002, 0x4e44, 0x4, "ATI Radeon R300 ND"},
83 {0x1002, 0x4e45, 0x4, "ATI Radeon R300 NE"},
84 {0x1002, 0x4e46, 0x4, "ATI Radeon R300 NF"},
85 {0x1002, 0x4e47, 0x4, "ATI Radeon R300 NG"},
86 {0x1002, 0x4e48, 0x4, "ATI Radeon R350 NH"},
87 {0x1002, 0x4e49, 0x4, "ATI Radeon R350 NI"},
88 {0x1002, 0x4e4a, 0x4, "ATI Radeon R350 NJ"},
89 {0x1002, 0x4e4b, 0x4, "ATI Radeon R350 NK"},
90 {0x1002, 0x4e50, 0x4, "ATI Radeon Mobility RV350 NP"},
91 {0x1002, 0x4e51, 0x4, "ATI Radeon Mobility RV350 NQ"},
92 {0x1002, 0x4e52, 0x4, "ATI Radeon Mobility RV350 NR"},
93 {0x1002, 0x4e53, 0x4, "ATI Radeon Mobility RV350 NS"},
94 {0x1002, 0x4e54, 0x4, "ATI Radeon Mobility RV350 NT"},
95 {0x1002, 0x4e56, 0x4, "ATI Radeon Mobility RV350 NV"},
96 {0x1002, 0x5041, 0x1, "ATI Rage 128 PA"},
97 {0x1002, 0x5042, 0x1, "ATI Rage 128 PB"},
98 {0x1002, 0x5043, 0x1, "ATI Rage 128 PC"},
99 {0x1002, 0x5044, 0x11, "ATI Rage 128 PD"},
100 {0x1002, 0x5045, 0x1, "ATI Rage 128 PE"},
101 {0x1002, 0x5046, 0x1, "ATI Rage 128 PF"},
102 {0x1002, 0x5047, 0x1, "ATI Rage 128 PG"},
103 {0x1002, 0x5048, 0x1, "ATI Rage 128 PH"},
104 {0x1002, 0x5049, 0x1, "ATI Rage 128 PI"},
105 {0x1002, 0x504a, 0x1, "ATI Rage 128 PJ"},
106 {0x1002, 0x504b, 0x1, "ATI Rage 128 PK"},
107 {0x1002, 0x504c, 0x1, "ATI Rage 128 PL"},
108 {0x1002, 0x504d, 0x1, "ATI Rage 128 PM"},
109 {0x1002, 0x504e, 0x1, "ATI Rage 128 PN"},
110 {0x1002, 0x504f, 0x1, "ATI Rage 128 PO"},
111 {0x1002, 0x5050, 0x11, "ATI Rage 128 PP"},
112 {0x1002, 0x5051, 0x1, "ATI Rage 128 PQ"},
113 {0x1002, 0x5052, 0x11, "ATI Rage 128 PR"},
114 {0x1002, 0x5053, 0x1, "ATI Rage 128 PS"},
115 {0x1002, 0x5054, 0x1, "ATI Rage 128 PT"},
116 {0x1002, 0x5055, 0x1, "ATI Rage 128 PU"},
117 {0x1002, 0x5056, 0x1, "ATI Rage 128 PV"},
118 {0x1002, 0x5057, 0x1, "ATI Rage 128 PW"},
119 {0x1002, 0x5058, 0x1, "ATI Rage 128 PX"},
120 {0x1002, 0x5144, 0x2, "ATI Radeon R100 QD"},
121 {0x1002, 0x5145, 0x2, "ATI Radeon R100 QE"},
122 {0x1002, 0x5146, 0x2, "ATI Radeon R100 QF"},
123 {0x1002, 0x5147, 0x2, "ATI Radeon R100 QG"},
124 {0x1002, 0x5148, 0x3, "ATI Radeon R200 QH"},
125 {0x1002, 0x514c, 0x3, "ATI Radeon R200 QL"},
126 {0x1002, 0x514d, 0x3, "ATI Radeon R200 QM"},
127 {0x1002, 0x5157, 0x2, "ATI Radeon RV200 QW (7500)"},
128 {0x1002, 0x5158, 0x2, "ATI Radeon RV200 QX (7500)"},
129 {0x1002, 0x5159, 0x2, "ATI Radeon RV100 QY"},
130 {0x1002, 0x515a, 0x2, "ATI Radeon RV100 QZ"},
131 {0x1002, 0x5245, 0x11, "ATI Rage 128 RE"},
132 {0x1002, 0x5246, 0x1, "ATI Rage 128 RF"},
133 {0x1002, 0x5247, 0x1, "ATI Rage 128 RG"},
134 {0x1002, 0x524b, 0x11, "ATI Rage 128 RK"},
135 {0x1002, 0x524c, 0x1, "ATI Rage 128 RL"},
136 {0x1002, 0x5345, 0x1, "ATI Rage 128 SE"},
137 {0x1002, 0x5346, 0x1, "ATI Rage 128 SF"},
138 {0x1002, 0x5347, 0x1, "ATI Rage 128 SG"},
139 {0x1002, 0x5348, 0x1, "ATI Rage 128 SH"},
140 {0x1002, 0x534b, 0x1, "ATI Rage 128 SK"},
141 {0x1002, 0x534c, 0x1, "ATI Rage 128 SL"},
142 {0x1002, 0x534d, 0x1, "ATI Rage 128 SM"},
143 {0x1002, 0x534e, 0x1, "ATI Rage 128 SN"},
144 {0x1002, 0x5446, 0x1, "ATI Rage 128 TF"},
145 {0x1002, 0x544c, 0x1, "ATI Rage 128 TL"},
146 {0x1002, 0x5452, 0x1, "ATI Rage 128 TR"},
147 {0x1002, 0x5453, 0x1, "ATI Rage 128 TS"},
148 {0x1002, 0x5454, 0x1, "ATI Rage 128 TT"},
149 {0x1002, 0x5455, 0x1, "ATI Rage 128 TU"},
150 {0x1002, 0x5834, 0x3, "ATI Radeon RS300"},
151 {0x1002, 0x5835, 0x3, "ATI Radeon RS300 Mobility"},
152 {0x1002, 0x5941, 0x3, "ATI Radeon RV280 (9200)"},
153 {0x1002, 0x5961, 0x3, "ATI Radeon RV280 (9200 SE)"},
154 {0x1002, 0x5964, 0x3, "ATI Radeon RV280 (9200 SE)"},
155 {0x1002, 0x5c60, 0x3, "ATI Radeon RV280"},
156 {0x1002, 0x5c61, 0x3, "ATI Radeon RV280 Mobility"},
157 {0x1002, 0x5c62, 0x3, "ATI Radeon RV280"},
158 {0x1002, 0x5c63, 0x3, "ATI Radeon RV280 Mobility"},
159 {0x1002, 0x5c64, 0x3, "ATI Radeon RV280"},
160 {0, 0, 0, NULL}
163 static char *
164 make_busid(KdCardAttr *attr)
166 char *busid;
168 busid = xalloc(20);
169 if (busid == NULL)
170 return NULL;
171 snprintf(busid, 20, "pci:%04x:%02x:%02x.%d", attr->domain, attr->bus,
172 attr->slot, attr->func);
173 return busid;
176 static Bool
177 ATICardInit(KdCardInfo *card)
179 ATICardInfo *atic;
180 int i;
181 Bool initialized = FALSE;
183 atic = xcalloc(sizeof(ATICardInfo), 1);
184 if (atic == NULL)
185 return FALSE;
187 #ifdef KDRIVEFBDEV
188 if (!initialized && fbdevInitialize(card, &atic->backend_priv.fbdev)) {
189 atic->use_fbdev = TRUE;
190 initialized = TRUE;
191 atic->backend_funcs.cardfini = fbdevCardFini;
192 atic->backend_funcs.scrfini = fbdevScreenFini;
193 atic->backend_funcs.initScreen = fbdevInitScreen;
194 atic->backend_funcs.finishInitScreen = fbdevFinishInitScreen;
195 atic->backend_funcs.createRes = fbdevCreateResources;
196 atic->backend_funcs.preserve = fbdevPreserve;
197 atic->backend_funcs.restore = fbdevRestore;
198 atic->backend_funcs.dpms = fbdevDPMS;
199 atic->backend_funcs.enable = fbdevEnable;
200 atic->backend_funcs.disable = fbdevDisable;
201 atic->backend_funcs.getColors = fbdevGetColors;
202 atic->backend_funcs.putColors = fbdevPutColors;
203 #ifdef RANDR
204 atic->backend_funcs.randrSetConfig = fbdevRandRSetConfig;
205 #endif
207 #endif
208 #ifdef KDRIVEVESA
209 if (!initialized && vesaInitialize(card, &atic->backend_priv.vesa)) {
210 atic->use_vesa = TRUE;
211 initialized = TRUE;
212 atic->backend_funcs.cardfini = vesaCardFini;
213 atic->backend_funcs.scrfini = vesaScreenFini;
214 atic->backend_funcs.initScreen = vesaInitScreen;
215 atic->backend_funcs.finishInitScreen = vesaFinishInitScreen;
216 atic->backend_funcs.createRes = vesaCreateResources;
217 atic->backend_funcs.preserve = vesaPreserve;
218 atic->backend_funcs.restore = vesaRestore;
219 atic->backend_funcs.dpms = vesaDPMS;
220 atic->backend_funcs.enable = vesaEnable;
221 atic->backend_funcs.disable = vesaDisable;
222 atic->backend_funcs.getColors = vesaGetColors;
223 atic->backend_funcs.putColors = vesaPutColors;
224 #ifdef RANDR
225 atic->backend_funcs.randrSetConfig = vesaRandRSetConfig;
226 #endif
228 #endif
230 if (!initialized || !ATIMapReg(card, atic)) {
231 xfree(atic);
232 return FALSE;
235 atic->busid = make_busid(&card->attr);
236 if (atic->busid == NULL) {
237 xfree(atic);
238 return FALSE;
241 #ifdef USE_DRI
242 /* We demand identification by busid, not driver name */
243 atic->drmFd = drmOpen(NULL, atic->busid);
244 if (atic->drmFd < 0)
245 ErrorF("Failed to open DRM, DRI disabled.\n");
246 #endif /* USE_DRI */
248 card->driver = atic;
250 for (i = 0; ati_pci_ids[i].name != NULL; i++) {
251 if (ati_pci_ids[i].device == card->attr.deviceID) {
252 atic->pci_id = &ati_pci_ids[i];
253 break;
257 if ((atic->pci_id->caps & CAP_SERIESMASK) != CAP_R128)
258 atic->is_radeon = TRUE;
259 if ((atic->pci_id->caps & CAP_SERIESMASK) == CAP_R100)
260 atic->is_r100 = TRUE;
261 if ((atic->pci_id->caps & CAP_SERIESMASK) == CAP_R200)
262 atic->is_r200 = TRUE;
263 if ((atic->pci_id->caps & CAP_SERIESMASK) == CAP_R300)
264 atic->is_r300 = TRUE;
266 atic->is_agp = ATIIsAGP(atic);
268 ErrorF("Using ATI card: %s (%s) at %s\n", atic->pci_id->name,
269 atic->is_agp ? "AGP" : "PCI", atic->busid);
271 return TRUE;
274 static void
275 ATICardFini(KdCardInfo *card)
277 ATICardInfo *atic = (ATICardInfo *)card->driver;
279 ATIUnmapReg(card, atic);
280 atic->backend_funcs.cardfini(card);
284 * Once screen->off_screen_base is set, this function
285 * allocates the remaining memory appropriately
288 static void
289 ATISetOffscreen (KdScreenInfo *screen)
291 ATICardInfo(screen);
292 #if defined(USE_DRI) && defined(GLXEXT)
293 ATIScreenInfo *atis = (ATIScreenInfo *)screen->driver;
294 int l;
295 #endif
296 int screen_size;
297 char *mmio = atic->reg_base;
299 /* check (and adjust) pitch */
300 if (mmio)
302 int byteStride = screen->fb[0].byteStride;
303 int bitStride;
304 int pixelStride;
305 int bpp = screen->fb[0].bitsPerPixel;
308 * Ensure frame buffer is correctly aligned
310 if (byteStride & 0x3f)
312 byteStride = (byteStride + 0x3f) & ~0x3f;
313 bitStride = byteStride * 8;
314 pixelStride = bitStride / bpp;
316 screen->fb[0].byteStride = byteStride;
317 screen->fb[0].pixelStride = pixelStride;
321 screen_size = screen->fb[0].byteStride * screen->height;
323 screen->off_screen_base = screen_size;
325 #if defined(USE_DRI) && defined(GLXEXT)
326 /* Reserve a static area for the back buffer the same size as the
327 * visible screen. XXX: This would be better initialized in ati_dri.c
328 * when GLX is set up, but the offscreen memory manager's allocations
329 * don't last through VT switches, while the kernel's understanding of
330 * offscreen locations does.
332 atis->frontOffset = 0;
333 atis->frontPitch = screen->fb[0].byteStride;
335 if (screen->off_screen_base + screen_size <= screen->memory_size) {
336 atis->backOffset = screen->off_screen_base;
337 atis->backPitch = screen->fb[0].byteStride;
338 screen->off_screen_base += screen_size;
341 /* Reserve the depth span for Rage 128 */
342 if (!atic->is_radeon && screen->off_screen_base +
343 screen->fb[0].byteStride <= screen->memory_size) {
344 atis->spanOffset = screen->off_screen_base;
345 screen->off_screen_base += screen->fb[0].byteStride;
348 /* Reserve the static depth buffer, which happens to be the same
349 * bitsPerPixel as the screen.
351 if (screen->off_screen_base + screen_size <= screen->memory_size) {
352 atis->depthOffset = screen->off_screen_base;
353 atis->depthPitch = screen->fb[0].byteStride;
354 screen->off_screen_base += screen_size;
357 /* Reserve approx. half of remaining offscreen memory for local
358 * textures. Round down to a whole number of texture regions.
360 atis->textureSize = (screen->memory_size - screen->off_screen_base) / 2;
361 l = ATILog2(atis->textureSize / ATI_NR_TEX_REGIONS);
362 if (l < ATI_LOG_TEX_GRANULARITY)
363 l = ATI_LOG_TEX_GRANULARITY;
364 atis->textureSize = (atis->textureSize >> l) << l;
365 if (atis->textureSize >= 512 * 1024) {
366 atis->textureOffset = screen->off_screen_base;
367 screen->off_screen_base += atis->textureSize;
368 } else {
369 /* Minimum texture size is for 2 256x256x32bpp textures */
370 atis->textureSize = 0;
372 #endif /* USE_DRI && GLXEXT */
375 static void
376 ATISetPitch (KdScreenInfo *screen)
378 ATICardInfo(screen);
379 #if defined(USE_DRI) && defined(GLXEXT)
380 ATIScreenInfo *atis = (ATIScreenInfo *)screen->driver;
381 int l;
382 #endif
383 char *mmio = atic->reg_base;
385 /* check (and adjust) pitch for radeon */
386 if (mmio)
388 int byteStride = screen->fb[0].byteStride;
389 int bitStride;
390 int pixelStride;
391 int bpp = screen->fb[0].bitsPerPixel;
392 CARD32 crtc_pitch;
393 CARD32 crtc2_pitch;
394 #if 0
395 CARD32 crtc_ext_cntl;
396 CARD32 dac_cntl;
397 #endif
398 bitStride = byteStride * 8;
399 pixelStride = bitStride / bpp;
401 crtc_pitch = (pixelStride >> 3);
402 crtc_pitch |= crtc_pitch << 16;
403 crtc2_pitch = (pixelStride >> 3);
404 crtc2_pitch |= crtc2_pitch << 16;
405 #if 0
406 crtc_ext_cntl = MMIO_IN32 (mmio, ATI_REG_CRTC_EXT_CNTL);
407 dac_cntl = MMIO_IN32 (mmio, ATI_REG_DAC_CNTL);
408 /* Turn off the screen */
409 MMIO_OUT32 (mmio, ATI_REG_CRTC_EXT_CNTL,
410 crtc_ext_cntl |
411 ATI_CRTC_VSYNC_DIS |
412 ATI_CRTC_HSYNC_DIS |
413 ATI_CRTC_DISPLAY_DIS);
414 MMIO_OUT32 (mmio, ATI_REG_DAC_CNTL,
415 dac_cntl |
416 ATI_DAC_RANGE_CNTL |
417 ATI_DAC_BLANKING);
418 #endif
419 MMIO_OUT32 (mmio, ATI_REG_CRTC_PITCH, crtc_pitch);
420 MMIO_OUT32 (mmio, ATI_REG_CRTC2_PITCH, crtc2_pitch);
421 #if 0
422 /* Turn the screen back on */
423 MMIO_OUT32 (mmio, ATI_REG_CRTC_EXT_CNTL,
424 crtc_ext_cntl);
425 MMIO_OUT32 (mmio, ATI_REG_DAC_CNTL,
426 dac_cntl);
427 #endif
431 static Bool
432 ATIScreenInit(KdScreenInfo *screen)
434 ATIScreenInfo *atis;
435 ATICardInfo(screen);
436 Bool success = FALSE;
438 atis = xcalloc(sizeof(ATIScreenInfo), 1);
439 if (atis == NULL)
440 return FALSE;
442 atis->atic = atic;
443 atis->screen = screen;
444 screen->driver = atis;
446 if (screen->fb[0].depth == 0)
447 screen->fb[0].depth = 16;
448 #ifdef KDRIVEFBDEV
449 if (atic->use_fbdev) {
450 success = fbdevScreenInitialize(screen,
451 &atis->backend_priv.fbdev);
453 #endif
454 #ifdef KDRIVEVESA
455 if (atic->use_vesa) {
456 success = vesaScreenInitialize(screen,
457 &atis->backend_priv.vesa);
459 #endif
461 if (!success) {
462 screen->driver = NULL;
463 xfree(atis);
464 return FALSE;
467 ATISetOffscreen (screen);
469 return TRUE;
472 #ifdef RANDR
473 static Bool
474 ATIRandRSetConfig (ScreenPtr pScreen,
475 Rotation randr,
476 int rate,
477 RRScreenSizePtr pSize)
479 KdScreenPriv(pScreen);
480 KdScreenInfo *screen = pScreenPriv->screen;
481 ATICardInfo *atic = screen->card->driver;
482 Bool ret;
484 ATIDrawDisable (pScreen);
485 ret = atic->backend_funcs.randrSetConfig(pScreen, randr, rate, pSize);
486 ATISetOffscreen (screen);
487 ATISetPitch (screen);
489 * Set frame buffer mapping
491 (*pScreen->ModifyPixmapHeader) (fbGetScreenPixmap (pScreen),
492 pScreen->width,
493 pScreen->height,
494 screen->fb[0].depth,
495 screen->fb[0].bitsPerPixel,
496 screen->fb[0].byteStride,
497 screen->fb[0].frameBuffer);
499 ATIDrawEnable (pScreen);
500 return ret;
503 static Bool
504 ATIRandRInit (ScreenPtr pScreen)
506 rrScrPrivPtr pScrPriv;
508 pScrPriv = rrGetScrPriv(pScreen);
509 pScrPriv->rrSetConfig = ATIRandRSetConfig;
510 return TRUE;
512 #endif
514 static void
515 ATIScreenFini(KdScreenInfo *screen)
517 ATIScreenInfo *atis = (ATIScreenInfo *)screen->driver;
518 ATICardInfo *atic = screen->card->driver;
520 #ifdef XV
521 ATIFiniVideo(screen->pScreen);
522 #endif
524 atic->backend_funcs.scrfini(screen);
525 xfree(atis);
526 screen->driver = 0;
529 Bool
530 ATIMapReg(KdCardInfo *card, ATICardInfo *atic)
532 atic->reg_base = (char *)KdMapDevice(ATI_REG_BASE(card),
533 ATI_REG_SIZE(card));
535 if (atic->reg_base == NULL)
536 return FALSE;
538 KdSetMappedMode(ATI_REG_BASE(card), ATI_REG_SIZE(card),
539 KD_MAPPED_MODE_REGISTERS);
541 return TRUE;
544 void
545 ATIUnmapReg(KdCardInfo *card, ATICardInfo *atic)
547 if (atic->reg_base) {
548 KdResetMappedMode(ATI_REG_BASE(card), ATI_REG_SIZE(card),
549 KD_MAPPED_MODE_REGISTERS);
550 KdUnmapDevice((void *)atic->reg_base, ATI_REG_SIZE(card));
551 atic->reg_base = 0;
555 static Bool
556 ATIInitScreen(ScreenPtr pScreen)
558 KdScreenPriv(pScreen);
559 ATICardInfo(pScreenPriv);
561 #ifdef XV
562 ATIInitVideo(pScreen);
563 #endif
564 return atic->backend_funcs.initScreen(pScreen);
567 static Bool
568 ATIFinishInitScreen(ScreenPtr pScreen)
570 KdScreenPriv(pScreen);
571 ATICardInfo(pScreenPriv);
573 if (!atic->backend_funcs.finishInitScreen(pScreen))
574 return FALSE;
575 #ifdef RANDR
576 if (!ATIRandRInit (pScreen))
577 return FALSE;
578 #endif
579 return TRUE;
582 static Bool
583 ATICreateResources(ScreenPtr pScreen)
585 KdScreenPriv(pScreen);
586 ATICardInfo(pScreenPriv);
588 return atic->backend_funcs.createRes(pScreen);
591 static void
592 ATIPreserve(KdCardInfo *card)
594 ATICardInfo *atic = card->driver;
595 char *mmio = atic->reg_base;
597 atic->backend_funcs.preserve(card);
598 if (atic->is_radeon && mmio)
600 atic->crtc_pitch = MMIO_IN32(mmio, ATI_REG_CRTC_PITCH);
601 atic->crtc2_pitch = MMIO_IN32(mmio, ATI_REG_CRTC2_PITCH);
606 static void
607 ATIRestore(KdCardInfo *card)
609 ATICardInfo *atic = card->driver;
610 char *mmio = atic->reg_base;
612 if (mmio)
614 MMIO_OUT32(mmio, ATI_REG_CRTC_PITCH, atic->crtc_pitch);
615 MMIO_OUT32(mmio, ATI_REG_CRTC2_PITCH, atic->crtc2_pitch);
617 ATIUnmapReg(card, atic);
619 atic->backend_funcs.restore(card);
622 static Bool
623 ATIDPMS(ScreenPtr pScreen, int mode)
625 KdScreenPriv(pScreen);
626 ATICardInfo(pScreenPriv);
628 return atic->backend_funcs.dpms(pScreen, mode);
631 static Bool
632 ATIEnable(ScreenPtr pScreen)
634 KdScreenPriv(pScreen);
635 ATICardInfo(pScreenPriv);
637 if (!atic->backend_funcs.enable(pScreen))
638 return FALSE;
640 if ((atic->reg_base == NULL) && !ATIMapReg(pScreenPriv->screen->card,
641 atic))
642 return FALSE;
644 ATISetOffscreen (pScreenPriv->screen);
646 ATISetPitch (pScreenPriv->screen);
648 return TRUE;
651 static void
652 ATIDisable(ScreenPtr pScreen)
654 KdScreenPriv(pScreen);
655 #if defined(USE_DRI) && defined(GLXEXT)
656 ATIScreenInfo(pScreenPriv);
657 #endif /* USE_DRI && GLXEXT */
658 ATICardInfo(pScreenPriv);
660 ATIUnmapReg(pScreenPriv->card, atic);
662 atic->backend_funcs.disable(pScreen);
665 static void
666 ATIGetColors(ScreenPtr pScreen, int fb, int n, xColorItem *pdefs)
668 KdScreenPriv(pScreen);
669 ATICardInfo(pScreenPriv);
671 atic->backend_funcs.getColors(pScreen, fb, n, pdefs);
674 static void
675 ATIPutColors(ScreenPtr pScreen, int fb, int n, xColorItem *pdefs)
677 KdScreenPriv(pScreen);
678 ATICardInfo(pScreenPriv);
680 atic->backend_funcs.putColors(pScreen, fb, n, pdefs);
683 /* Compute log base 2 of val. */
685 ATILog2(int val)
687 int bits;
689 for (bits = 0; val != 0; val >>= 1, ++bits)
691 return bits - 1;
694 static Bool
695 ATIIsAGP(ATICardInfo *atic)
697 char *mmio = atic->reg_base;
698 CARD32 cap_ptr, cap_id;
700 if (mmio == NULL)
701 return FALSE;
703 if (MMIO_IN32(mmio, ATI_REG_PCI_CFG_STATUS) & ATI_CAP_LIST) {
704 cap_ptr = MMIO_IN32(mmio, ATI_REG_PCI_CFG_CAPABILITIES_PTR) &
705 ATI_CAP_PTR_MASK;
706 while (cap_ptr != ATI_CAP_ID_NULL) {
707 cap_id = MMIO_IN32(mmio, ATI_PCI_CFG_OFFSET + cap_ptr);
708 if ((cap_id & 0xff) == ATI_CAP_ID_AGP)
709 return TRUE;
710 cap_ptr = (cap_id >> 8) & ATI_CAP_PTR_MASK;
714 return FALSE;
717 /* This function is required to work around a hardware bug in some (all?)
718 * revisions of the R300. This workaround should be called after every
719 * CLOCK_CNTL_INDEX register access. If not, register reads afterward
720 * may not be correct.
722 void R300CGWorkaround(ATIScreenInfo *atis) {
723 ATICardInfo *atic = atis->atic;
724 char *mmio = atic->reg_base;
725 CARD32 save;
727 save = MMIO_IN32(mmio, ATI_REG_CLOCK_CNTL_INDEX);
728 MMIO_OUT32(mmio, ATI_REG_CLOCK_CNTL_INDEX, save & ~(0x3f |
729 ATI_PLL_WR_EN));
730 MMIO_IN32(mmio, ATI_REG_CLOCK_CNTL_INDEX);
731 MMIO_OUT32(mmio, ATI_REG_CLOCK_CNTL_INDEX, save);
734 KdCardFuncs ATIFuncs = {
735 ATICardInit, /* cardinit */
736 ATIScreenInit, /* scrinit */
737 ATIInitScreen, /* initScreen */
738 ATIFinishInitScreen, /* finishInitScreen */
739 ATICreateResources, /* createRes */
740 ATIPreserve, /* preserve */
741 ATIEnable, /* enable */
742 ATIDPMS, /* dpms */
743 ATIDisable, /* disable */
744 ATIRestore, /* restore */
745 ATIScreenFini, /* scrfini */
746 ATICardFini, /* cardfini */
748 ATICursorInit, /* initCursor */
749 ATICursorEnable, /* enableCursor */
750 ATICursorDisable, /* disableCursor */
751 ATICursorFini, /* finiCursor */
752 ATIRecolorCursor, /* recolorCursor */
754 ATIDrawInit, /* initAccel */
755 ATIDrawEnable, /* enableAccel */
756 ATIDrawDisable, /* disableAccel */
757 ATIDrawFini, /* finiAccel */
759 ATIGetColors, /* getColors */
760 ATIPutColors, /* putColors */