atividmem.c revision 32b578d3
1/*
2 * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that copyright
7 * notice and this permission notice appear in supporting documentation, and
8 * that the name of Marc Aurele La France not be used in advertising or
9 * publicity pertaining to distribution of the software without specific,
10 * written prior permission.  Marc Aurele La France makes no representations
11 * about the suitability of this software for any purpose.  It is provided
12 * "as-is" without express or implied warranty.
13 *
14 * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.  IN NO
16 * EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 * PERFORMANCE OF THIS SOFTWARE.
21 */
22
23#ifdef HAVE_CONFIG_H
24#include "config.h"
25#endif
26
27#include "ati.h"
28#include "atistruct.h"
29#include "atividmem.h"
30
31/* Memory types for 68800's and 88800GX's */
32const char *ATIMemoryTypeNames_Mach[] =
33{
34    "DRAM (256Kx4)",
35    "VRAM (256Kx4, x8, x16)",
36    "VRAM (256Kx16 with short shift register)",
37    "DRAM (256Kx16)",
38    "Graphics DRAM (256Kx16)",
39    "Enhanced VRAM (256Kx4, x8, x16)",
40    "Enhanced VRAM (256Kx16 with short shift register)",
41    "Unknown video memory type"
42};
43
44/* Memory types for 88800CX's */
45const char *ATIMemoryTypeNames_88800CX[] =
46{
47    "DRAM (256Kx4, x8, x16)",
48    "EDO DRAM (256Kx4, x8, x16)",
49    "Unknown video memory type",
50    "DRAM (256Kx16 with assymetric RAS/CAS)",
51    "Unknown video memory type",
52    "Unknown video memory type",
53    "Unknown video memory type",
54    "Unknown video memory type"
55};
56
57/* Memory types for 264xT's */
58const char *ATIMemoryTypeNames_264xT[] =
59{
60    "Disabled video memory",
61    "DRAM",
62    "EDO DRAM",
63    "Pseudo-EDO DRAM",
64    "SDRAM (1:1)",
65    "SGRAM (1:1)",
66    "SGRAM (2:1) 32-bit",
67    "Unknown video memory type"
68};
69
70#ifndef AVOID_CPIO
71
72/*
73 * ATIUnmapVGA --
74 *
75 * Unmap VGA aperture.
76 */
77static void
78ATIUnmapVGA
79(
80    int    iScreen,
81    ATIPtr pATI
82)
83{
84    if (!pATI->pBank)
85        return;
86
87    xf86UnMapVidMem(iScreen, pATI->pBank, 0x00010000U);
88
89    pATI->pBank = NULL;
90}
91
92#endif /* AVOID_CPIO */
93
94/*
95 * ATIUnmapLinear --
96 *
97 * Unmap linear aperture.
98 */
99static void
100ATIUnmapLinear
101(
102    int    iScreen,
103    ATIPtr pATI
104)
105{
106    if (pATI->pMemory)
107    {
108#ifndef XSERVER_LIBPCIACCESS
109        xf86UnMapVidMem(iScreen, pATI->pMemory, pATI->LinearSize);
110#else
111        pci_device_unmap_range(pATI->PCIInfo, pATI->pMemory, pATI->LinearSize);
112#endif
113
114#if X_BYTE_ORDER != X_LITTLE_ENDIAN
115
116        if (pATI->pMemoryLE)
117        {
118#ifndef XSERVER_LIBPCIACCESS
119            xf86UnMapVidMem(iScreen, pATI->pMemoryLE, pATI->LinearSize);
120#else
121            pci_device_unmap_range(pATI->PCIInfo, pATI->pMemoryLE, pATI->LinearSize);
122#endif
123        }
124
125#endif /* X_BYTE_ORDER */
126
127    }
128
129    pATI->pMemory = pATI->pMemoryLE = NULL;
130}
131
132/*
133 * ATIUnmapMMIO --
134 *
135 * Unmap MMIO registers.
136 */
137static void
138ATIUnmapMMIO
139(
140    int    iScreen,
141    ATIPtr pATI
142)
143{
144    if (pATI->pMMIO)
145    {
146#ifndef XSERVER_LIBPCIACCESS
147        xf86UnMapVidMem(iScreen, pATI->pMMIO, getpagesize());
148#else
149        unsigned long size;
150
151        size = PCI_REGION_SIZE(pATI->PCIInfo, 2);
152        if (!size || size > getpagesize())
153                size = getpagesize();
154        pci_device_unmap_range(pATI->PCIInfo, pATI->pMMIO, size);
155#endif
156    }
157
158    pATI->pMMIO = pATI->pBlock[0] = pATI->pBlock[1] = NULL;
159}
160
161/*
162 * ATIUnmapCursor --
163 *
164 * Unmap hardware cursor image area.
165 */
166static void
167ATIUnmapCursor
168(
169    int    iScreen,
170    ATIPtr pATI
171)
172{
173    if (pATI->pCursorPage)
174    {
175#ifndef XSERVER_LIBPCIACCESS
176        xf86UnMapVidMem(iScreen, pATI->pCursorPage, getpagesize());
177#else
178        pci_device_unmap_range(pATI->PCIInfo, pATI->pCursorPage, getpagesize());
179#endif
180    }
181
182    pATI->pCursorPage = pATI->pCursorImage = NULL;
183}
184
185/*
186 * ATIMapApertures --
187 *
188 * This function maps all apertures used by the driver.
189 *
190 * It is called three times:
191 * - to setup MMIO for an MMIO-only driver during Probe
192 * - to setup MMIO for an MMIO-only driver during PreInit
193 * - to setup MMIO (with Block0Base set) and FB (with LinearBase set)
194 */
195Bool
196ATIMapApertures
197(
198    int    iScreen,
199    ATIPtr pATI
200)
201{
202    pciVideoPtr   pVideo = pATI->PCIInfo;
203#ifndef XSERVER_LIBPCIACCESS
204    PCITAG        Tag = PCI_CFG_TAG(pVideo);
205#else
206    pciVideoPtr   Tag = pVideo;
207#endif
208    unsigned long PageSize = getpagesize();
209
210    if (pATI->Mapped)
211        return TRUE;
212
213#ifndef AVOID_CPIO
214
215    /* Map VGA aperture */
216    if (pATI->VGAAdapter)
217    {
218        /*
219         * No relocation, resizing, caching or write-combining of this
220         * aperture is supported.  Hence, the hard-coded values here...
221         */
222            pATI->pBank = xf86MapDomainMemory(iScreen, VIDMEM_MMIO_32BIT,
223                Tag, 0x000A0000U, 0x00010000U);
224
225        if (!pATI->pBank)
226            return FALSE;
227
228        pATI->Mapped = TRUE;
229    }
230
231#endif /* AVOID_CPIO */
232
233    /* Map linear aperture */
234    if (pATI->LinearBase)
235    {
236
237#ifndef XSERVER_LIBPCIACCESS
238
239            pATI->pMemory = xf86MapPciMem(iScreen, VIDMEM_FRAMEBUFFER,
240                Tag, pATI->LinearBase, pATI->LinearSize);
241
242#else /* XSERVER_LIBPCIACCESS */
243
244        int mode = PCI_DEV_MAP_FLAG_WRITABLE | PCI_DEV_MAP_FLAG_WRITE_COMBINE;
245
246        int err = pci_device_map_range(pVideo,
247                                       pATI->LinearBase,
248                                       pATI->LinearSize,
249                                       mode, &pATI->pMemory);
250
251        if (err)
252        {
253            xf86DrvMsg (iScreen, X_ERROR,
254                    "Unable to map linear aperture. %s (%d)\n",
255                    strerror (err), err);
256        }
257
258#endif /* XSERVER_LIBPCIACCESS */
259
260        if (!pATI->pMemory)
261        {
262
263#ifndef AVOID_CPIO
264
265            ATIUnmapVGA(iScreen, pATI);
266
267#endif /* AVOID_CPIO */
268
269            pATI->Mapped = FALSE;
270            return FALSE;
271        }
272
273        pATI->Mapped = TRUE;
274
275#if X_BYTE_ORDER == X_LITTLE_ENDIAN
276
277        if ((pATI->CursorBase >= pATI->LinearBase) &&
278            ((pATI->CursorOffset + 0x00000400UL) <= (CARD32)pATI->LinearSize))
279            pATI->pCursorImage = (char *)pATI->pMemory + pATI->CursorOffset;
280
281        pATI->pMemoryLE = pATI->pMemory;
282
283#else /* if X_BYTE_ORDER != X_LITTLE_ENDIAN */
284
285        /*
286         * Map the little-endian aperture (used for video, etc.).  Note that
287         * caching of this area is _not_ wanted.
288         */
289        {
290
291#ifndef XSERVER_LIBPCIACCESS
292
293            pATI->pMemoryLE = xf86MapPciMem(iScreen, VIDMEM_MMIO, Tag,
294                pATI->LinearBase - 0x00800000U, pATI->LinearSize);
295
296
297#else /* XSERVER_LIBPCIACCESS */
298
299        int mode = PCI_DEV_MAP_FLAG_WRITABLE;
300
301        int err = pci_device_map_range(pVideo,
302                                       pATI->LinearBase - 0x00800000U,
303                                       pATI->LinearSize,
304                                       mode, &pATI->pMemoryLE);
305
306        if (err)
307        {
308            xf86DrvMsg (iScreen, X_ERROR,
309                    "Unable to map extended linear aperture. %s (%d)\n",
310                    strerror (err), err);
311        }
312
313#endif /* XSERVER_LIBPCIACCESS */
314
315            if (!pATI->pMemoryLE)
316            {
317                ATIUnmapLinear(iScreen, pATI);
318
319#ifndef AVOID_CPIO
320
321                ATIUnmapVGA(iScreen, pATI);
322
323#endif /* AVOID_CPIO */
324
325                pATI->Mapped = FALSE;
326                return FALSE;
327            }
328        }
329
330#endif /* X_BYTE_ORDER */
331
332    }
333
334    /* Map MMIO aperture */
335    if (pATI->Block0Base)
336    {
337        unsigned long MMIOBase = pATI->Block0Base & ~(PageSize - 1);
338
339#ifndef XSERVER_LIBPCIACCESS
340
341            pATI->pMMIO = xf86MapPciMem(iScreen, VIDMEM_MMIO,
342                Tag, MMIOBase, PageSize);
343
344#else /* XSERVER_LIBPCIACCESS */
345
346        int mode = PCI_DEV_MAP_FLAG_WRITABLE;
347
348        int err;
349        int size;
350
351        size = PCI_REGION_SIZE(pVideo, 2);
352        if (!size || size > PageSize)
353               size = PageSize;
354
355	err = pci_device_map_range(pVideo, MMIOBase,
356                                   size, mode, &pATI->pMMIO);
357
358        if (err)
359        {
360            xf86DrvMsg (iScreen, X_ERROR,
361                    "Unable to map mmio aperture. %s (%d)\n",
362                    strerror (err), err);
363        }
364
365#endif /* XSERVER_LIBPCIACCESS */
366
367        if (!pATI->pMMIO)
368        {
369
370#if X_BYTE_ORDER == X_LITTLE_ENDIAN
371
372            ATIUnmapCursor(iScreen, pATI);
373
374#endif /* X_BYTE_ORDER */
375
376            ATIUnmapLinear(iScreen, pATI);
377
378#ifndef AVOID_CPIO
379
380            ATIUnmapVGA(iScreen, pATI);
381
382#endif /* AVOID_CPIO */
383
384            pATI->Mapped = FALSE;
385            return FALSE;
386        }
387
388        pATI->Mapped = TRUE;
389
390        pATI->pBlock[0] = (char *)pATI->pMMIO +
391            (pATI->Block0Base - MMIOBase);
392
393        if (pATI->Block1Base)
394            pATI->pBlock[1] = (char *)pATI->pBlock[0] - 0x00000400U;
395
396#if X_BYTE_ORDER == X_LITTLE_ENDIAN
397
398        if (!pATI->pCursorImage)
399
400#endif /* X_BYTE_ORDER */
401
402        {
403            if ((pATI->CursorBase >= MMIOBase) &&
404                ((pATI->CursorBase + 0x00000400UL) <= (MMIOBase + PageSize)))
405                pATI->pCursorImage = (char *)pATI->pMMIO +
406                    (pATI->CursorBase - MMIOBase);
407        }
408    }
409
410    /* Map hardware cursor image area */
411    if (pATI->CursorBase && !pATI->pCursorImage)
412    {
413        unsigned long CursorBase = pATI->CursorBase & ~(PageSize - 1);
414
415#ifndef XSERVER_LIBPCIACCESS
416
417            pATI->pCursorPage = xf86MapPciMem(iScreen, VIDMEM_FRAMEBUFFER,
418                Tag, CursorBase, PageSize);
419
420#else /* XSERVER_LIBPCIACCESS */
421
422        int mode = PCI_DEV_MAP_FLAG_WRITABLE | PCI_DEV_MAP_FLAG_WRITE_COMBINE;
423
424        int err = pci_device_map_range(pVideo,
425                                       CursorBase,
426                                       PageSize,
427                                       mode, &pATI->pCursorPage);
428
429        if (err)
430        {
431            xf86DrvMsg (iScreen, X_ERROR,
432                    "Unable to map cursor aperture. %s (%d)\n",
433                    strerror (err), err);
434        }
435
436#endif /* XSERVER_LIBPCIACCESS */
437
438        if (!pATI->pCursorPage)
439        {
440            ATIUnmapCursor(iScreen, pATI);
441            ATIUnmapMMIO(iScreen, pATI);
442            ATIUnmapLinear(iScreen, pATI);
443
444#ifndef AVOID_CPIO
445
446            ATIUnmapVGA(iScreen, pATI);
447
448#endif /* AVOID_CPIO */
449
450            pATI->Mapped = FALSE;
451            return FALSE;
452        }
453
454        pATI->pCursorImage = (char *)pATI->pCursorPage +
455            (pATI->CursorBase - CursorBase);
456    }
457
458    return TRUE;
459}
460
461/*
462 * ATIUnmapApertures --
463 *
464 * This function unmaps all apertures used by the driver.
465 */
466void
467ATIUnmapApertures
468(
469    int    iScreen,
470    ATIPtr pATI
471)
472{
473    if (!pATI->Mapped)
474        return;
475    pATI->Mapped = FALSE;
476
477    /* Unmap hardware cursor image area */
478    ATIUnmapCursor(iScreen, pATI);
479
480    /* Unmap MMIO area */
481    ATIUnmapMMIO(iScreen, pATI);
482
483    /* Unmap linear aperture */
484    ATIUnmapLinear(iScreen, pATI);
485
486#ifndef AVOID_CPIO
487
488    /* Unmap VGA aperture */
489    ATIUnmapVGA(iScreen, pATI);
490
491#endif /* AVOID_CPIO */
492
493}
494