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.
24 #include <kdrive-config.h>
28 #if defined(USE_DRI) && defined(GLXEXT)
29 #include "ati_sarea.h"
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"},
164 make_busid(KdCardAttr
*attr
)
171 snprintf(busid
, 20, "pci:%04x:%02x:%02x.%d", attr
->domain
, attr
->bus
,
172 attr
->slot
, attr
->func
);
177 ATICardInit(KdCardInfo
*card
)
181 Bool initialized
= FALSE
;
183 atic
= xcalloc(sizeof(ATICardInfo
), 1);
188 if (!initialized
&& fbdevInitialize(card
, &atic
->backend_priv
.fbdev
)) {
189 atic
->use_fbdev
= 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
;
204 atic
->backend_funcs
.randrSetConfig
= fbdevRandRSetConfig
;
209 if (!initialized
&& vesaInitialize(card
, &atic
->backend_priv
.vesa
)) {
210 atic
->use_vesa
= 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
;
225 atic
->backend_funcs
.randrSetConfig
= vesaRandRSetConfig
;
230 if (!initialized
|| !ATIMapReg(card
, atic
)) {
235 atic
->busid
= make_busid(&card
->attr
);
236 if (atic
->busid
== NULL
) {
242 /* We demand identification by busid, not driver name */
243 atic
->drmFd
= drmOpen(NULL
, atic
->busid
);
245 ErrorF("Failed to open DRM, DRI disabled.\n");
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
];
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
);
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
289 ATISetOffscreen (KdScreenInfo
*screen
)
292 #if defined(USE_DRI) && defined(GLXEXT)
293 ATIScreenInfo
*atis
= (ATIScreenInfo
*)screen
->driver
;
297 char *mmio
= atic
->reg_base
;
299 /* check (and adjust) pitch */
302 int byteStride
= screen
->fb
[0].byteStride
;
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
;
369 /* Minimum texture size is for 2 256x256x32bpp textures */
370 atis
->textureSize
= 0;
372 #endif /* USE_DRI && GLXEXT */
376 ATISetPitch (KdScreenInfo
*screen
)
379 #if defined(USE_DRI) && defined(GLXEXT)
380 ATIScreenInfo
*atis
= (ATIScreenInfo
*)screen
->driver
;
383 char *mmio
= atic
->reg_base
;
385 /* check (and adjust) pitch for radeon */
388 int byteStride
= screen
->fb
[0].byteStride
;
391 int bpp
= screen
->fb
[0].bitsPerPixel
;
395 CARD32 crtc_ext_cntl
;
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;
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
,
413 ATI_CRTC_DISPLAY_DIS
);
414 MMIO_OUT32 (mmio
, ATI_REG_DAC_CNTL
,
419 MMIO_OUT32 (mmio
, ATI_REG_CRTC_PITCH
, crtc_pitch
);
420 MMIO_OUT32 (mmio
, ATI_REG_CRTC2_PITCH
, crtc2_pitch
);
422 /* Turn the screen back on */
423 MMIO_OUT32 (mmio
, ATI_REG_CRTC_EXT_CNTL
,
425 MMIO_OUT32 (mmio
, ATI_REG_DAC_CNTL
,
432 ATIScreenInit(KdScreenInfo
*screen
)
436 Bool success
= FALSE
;
438 atis
= xcalloc(sizeof(ATIScreenInfo
), 1);
443 atis
->screen
= screen
;
444 screen
->driver
= atis
;
446 if (screen
->fb
[0].depth
== 0)
447 screen
->fb
[0].depth
= 16;
449 if (atic
->use_fbdev
) {
450 success
= fbdevScreenInitialize(screen
,
451 &atis
->backend_priv
.fbdev
);
455 if (atic
->use_vesa
) {
456 success
= vesaScreenInitialize(screen
,
457 &atis
->backend_priv
.vesa
);
462 screen
->driver
= NULL
;
467 ATISetOffscreen (screen
);
474 ATIRandRSetConfig (ScreenPtr pScreen
,
477 RRScreenSizePtr pSize
)
479 KdScreenPriv(pScreen
);
480 KdScreenInfo
*screen
= pScreenPriv
->screen
;
481 ATICardInfo
*atic
= screen
->card
->driver
;
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
),
495 screen
->fb
[0].bitsPerPixel
,
496 screen
->fb
[0].byteStride
,
497 screen
->fb
[0].frameBuffer
);
499 ATIDrawEnable (pScreen
);
504 ATIRandRInit (ScreenPtr pScreen
)
506 rrScrPrivPtr pScrPriv
;
508 pScrPriv
= rrGetScrPriv(pScreen
);
509 pScrPriv
->rrSetConfig
= ATIRandRSetConfig
;
515 ATIScreenFini(KdScreenInfo
*screen
)
517 ATIScreenInfo
*atis
= (ATIScreenInfo
*)screen
->driver
;
518 ATICardInfo
*atic
= screen
->card
->driver
;
521 ATIFiniVideo(screen
->pScreen
);
524 atic
->backend_funcs
.scrfini(screen
);
530 ATIMapReg(KdCardInfo
*card
, ATICardInfo
*atic
)
532 atic
->reg_base
= (char *)KdMapDevice(ATI_REG_BASE(card
),
535 if (atic
->reg_base
== NULL
)
538 KdSetMappedMode(ATI_REG_BASE(card
), ATI_REG_SIZE(card
),
539 KD_MAPPED_MODE_REGISTERS
);
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
));
556 ATIInitScreen(ScreenPtr pScreen
)
558 KdScreenPriv(pScreen
);
559 ATICardInfo(pScreenPriv
);
562 ATIInitVideo(pScreen
);
564 return atic
->backend_funcs
.initScreen(pScreen
);
568 ATIFinishInitScreen(ScreenPtr pScreen
)
570 KdScreenPriv(pScreen
);
571 ATICardInfo(pScreenPriv
);
573 if (!atic
->backend_funcs
.finishInitScreen(pScreen
))
576 if (!ATIRandRInit (pScreen
))
583 ATICreateResources(ScreenPtr pScreen
)
585 KdScreenPriv(pScreen
);
586 ATICardInfo(pScreenPriv
);
588 return atic
->backend_funcs
.createRes(pScreen
);
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
);
607 ATIRestore(KdCardInfo
*card
)
609 ATICardInfo
*atic
= card
->driver
;
610 char *mmio
= atic
->reg_base
;
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
);
623 ATIDPMS(ScreenPtr pScreen
, int mode
)
625 KdScreenPriv(pScreen
);
626 ATICardInfo(pScreenPriv
);
628 return atic
->backend_funcs
.dpms(pScreen
, mode
);
632 ATIEnable(ScreenPtr pScreen
)
634 KdScreenPriv(pScreen
);
635 ATICardInfo(pScreenPriv
);
637 if (!atic
->backend_funcs
.enable(pScreen
))
640 if ((atic
->reg_base
== NULL
) && !ATIMapReg(pScreenPriv
->screen
->card
,
644 ATISetOffscreen (pScreenPriv
->screen
);
646 ATISetPitch (pScreenPriv
->screen
);
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
);
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
);
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. */
689 for (bits
= 0; val
!= 0; val
>>= 1, ++bits
)
695 ATIIsAGP(ATICardInfo
*atic
)
697 char *mmio
= atic
->reg_base
;
698 CARD32 cap_ptr
, cap_id
;
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
) &
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
)
710 cap_ptr
= (cap_id
>> 8) & ATI_CAP_PTR_MASK
;
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
;
727 save
= MMIO_IN32(mmio
, ATI_REG_CLOCK_CNTL_INDEX
);
728 MMIO_OUT32(mmio
, ATI_REG_CLOCK_CNTL_INDEX
, save
& ~(0x3f |
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 */
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 */