atividmem.c revision 0b0ce0bf
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 asymmetric 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#ifndef XSERVER_LIBPCIACCESS
88    xf86UnMapVidMem(iScreen, pATI->pBank, 0x00010000U);
89#else
90    (void) pci_device_unmap_legacy(pATI->PCIInfo, pATI->pBank, 0x00010000U);
91#endif
92
93    pATI->pBank = NULL;
94}
95
96#endif /* AVOID_CPIO */
97
98/*
99 * ATIUnmapLinear --
100 *
101 * Unmap linear aperture.
102 */
103static void
104ATIUnmapLinear
105(
106    int    iScreen,
107    ATIPtr pATI
108)
109{
110    if (pATI->pMemory)
111    {
112#ifndef XSERVER_LIBPCIACCESS
113        xf86UnMapVidMem(iScreen, pATI->pMemory, pATI->LinearSize);
114#else
115        pci_device_unmap_range(pATI->PCIInfo, pATI->pMemory, pATI->LinearSize);
116#endif
117
118#if X_BYTE_ORDER != X_LITTLE_ENDIAN
119
120        if (pATI->pMemoryLE)
121        {
122#ifndef XSERVER_LIBPCIACCESS
123            xf86UnMapVidMem(iScreen, pATI->pMemoryLE, pATI->LinearSize);
124#else
125            pci_device_unmap_range(pATI->PCIInfo, pATI->pMemoryLE, pATI->LinearSize);
126#endif
127        }
128
129#endif /* X_BYTE_ORDER */
130
131    }
132
133    pATI->pMemory = pATI->pMemoryLE = NULL;
134}
135
136/*
137 * ATIUnmapMMIO --
138 *
139 * Unmap MMIO registers.
140 */
141static void
142ATIUnmapMMIO
143(
144    int    iScreen,
145    ATIPtr pATI
146)
147{
148    if (pATI->pMMIO)
149    {
150#ifndef XSERVER_LIBPCIACCESS
151        xf86UnMapVidMem(iScreen, pATI->pMMIO, getpagesize());
152#else
153        unsigned long size;
154
155        size = PCI_REGION_SIZE(pATI->PCIInfo, 2);
156        if (!size || size > getpagesize())
157                size = getpagesize();
158        pci_device_unmap_range(pATI->PCIInfo, pATI->pMMIO, size);
159#endif
160    }
161
162    pATI->pMMIO = pATI->pBlock[0] = pATI->pBlock[1] = NULL;
163}
164
165/*
166 * ATIUnmapCursor --
167 *
168 * Unmap hardware cursor image area.
169 */
170static void
171ATIUnmapCursor
172(
173    int    iScreen,
174    ATIPtr pATI
175)
176{
177    if (pATI->pCursorPage)
178    {
179#ifndef XSERVER_LIBPCIACCESS
180        xf86UnMapVidMem(iScreen, pATI->pCursorPage, getpagesize());
181#else
182        pci_device_unmap_range(pATI->PCIInfo, pATI->pCursorPage, getpagesize());
183#endif
184    }
185
186    pATI->pCursorPage = pATI->pCursorImage = NULL;
187}
188
189/*
190 * ATIMapApertures --
191 *
192 * This function maps all apertures used by the driver.
193 *
194 * It is called three times:
195 * - to setup MMIO for an MMIO-only driver during Probe
196 * - to setup MMIO for an MMIO-only driver during PreInit
197 * - to setup MMIO (with Block0Base set) and FB (with LinearBase set)
198 */
199Bool
200ATIMapApertures
201(
202    int    iScreen,
203    ATIPtr pATI
204)
205{
206    pciVideoPtr   pVideo = pATI->PCIInfo;
207#ifndef XSERVER_LIBPCIACCESS
208    PCITAG        Tag = PCI_CFG_TAG(pVideo);
209#else
210    pciVideoPtr   Tag = pVideo;
211#endif
212    unsigned long PageSize = getpagesize();
213
214    if (pATI->Mapped)
215        return TRUE;
216
217#ifndef AVOID_CPIO
218
219    /* Map VGA aperture */
220    if (pATI->VGAAdapter)
221    {
222        /*
223         * No relocation, resizing, caching or write-combining of this
224         * aperture is supported.  Hence, the hard-coded values here...
225         */
226#ifndef XSERVER_LIBPCIACCESS
227        pATI->pBank = xf86MapDomainMemory(iScreen, VIDMEM_MMIO_32BIT,
228                                          Tag, 0x000A0000U, 0x00010000U);
229#else
230        (void) pci_device_map_legacy(Tag, 0x000A0000U, 0x00010000U,
231                                     PCI_DEV_MAP_FLAG_WRITABLE,
232                                     &pATI->pBank);
233#endif
234
235        if (!pATI->pBank)
236            return FALSE;
237
238        pATI->Mapped = TRUE;
239    }
240
241#endif /* AVOID_CPIO */
242
243    /* Map linear aperture */
244    if (pATI->LinearBase)
245    {
246
247#ifndef XSERVER_LIBPCIACCESS
248
249            pATI->pMemory = xf86MapPciMem(iScreen, VIDMEM_FRAMEBUFFER,
250                Tag, pATI->LinearBase, pATI->LinearSize);
251
252#else /* XSERVER_LIBPCIACCESS */
253
254        int mode = PCI_DEV_MAP_FLAG_WRITABLE | PCI_DEV_MAP_FLAG_WRITE_COMBINE;
255
256        int err = pci_device_map_range(pVideo,
257                                       pATI->LinearBase,
258                                       pATI->LinearSize,
259                                       mode, &pATI->pMemory);
260
261        if (err)
262        {
263            xf86DrvMsg (iScreen, X_ERROR,
264                    "Unable to map linear aperture. %s (%d)\n",
265                    strerror (err), err);
266        }
267
268#endif /* XSERVER_LIBPCIACCESS */
269
270        if (!pATI->pMemory)
271        {
272
273#ifndef AVOID_CPIO
274
275            ATIUnmapVGA(iScreen, pATI);
276
277#endif /* AVOID_CPIO */
278
279            pATI->Mapped = FALSE;
280            return FALSE;
281        }
282
283        pATI->Mapped = TRUE;
284
285#if X_BYTE_ORDER == X_LITTLE_ENDIAN
286
287        if ((pATI->CursorBase >= pATI->LinearBase) &&
288            ((pATI->CursorOffset + 0x00000400UL) <= (CARD32)pATI->LinearSize))
289            pATI->pCursorImage = (char *)pATI->pMemory + pATI->CursorOffset;
290
291        pATI->pMemoryLE = pATI->pMemory;
292
293#else /* if X_BYTE_ORDER != X_LITTLE_ENDIAN */
294
295        /*
296         * Map the little-endian aperture (used for video, etc.).  Note that
297         * caching of this area is _not_ wanted.
298         */
299        {
300
301#ifndef XSERVER_LIBPCIACCESS
302
303            pATI->pMemoryLE = xf86MapPciMem(iScreen, VIDMEM_MMIO, Tag,
304                pATI->LinearBase - 0x00800000U, pATI->LinearSize);
305
306
307#else /* XSERVER_LIBPCIACCESS */
308
309        int mode = PCI_DEV_MAP_FLAG_WRITABLE;
310
311        int err = pci_device_map_range(pVideo,
312                                       pATI->LinearBase - 0x00800000U,
313                                       pATI->LinearSize,
314                                       mode, &pATI->pMemoryLE);
315
316        if (err)
317        {
318            xf86DrvMsg (iScreen, X_ERROR,
319                    "Unable to map extended linear aperture. %s (%d)\n",
320                    strerror (err), err);
321        }
322
323#endif /* XSERVER_LIBPCIACCESS */
324
325            if (!pATI->pMemoryLE)
326            {
327                ATIUnmapLinear(iScreen, pATI);
328
329#ifndef AVOID_CPIO
330
331                ATIUnmapVGA(iScreen, pATI);
332
333#endif /* AVOID_CPIO */
334
335                pATI->Mapped = FALSE;
336                return FALSE;
337            }
338        }
339
340#endif /* X_BYTE_ORDER */
341
342    }
343
344    /* Map MMIO aperture */
345    if (pATI->Block0Base)
346    {
347        unsigned long MMIOBase = pATI->Block0Base & ~(PageSize - 1);
348
349#ifndef XSERVER_LIBPCIACCESS
350
351            pATI->pMMIO = xf86MapPciMem(iScreen, VIDMEM_MMIO,
352                Tag, MMIOBase, PageSize);
353
354#else /* XSERVER_LIBPCIACCESS */
355
356        int mode = PCI_DEV_MAP_FLAG_WRITABLE;
357
358        int err;
359        int size;
360
361        size = PCI_REGION_SIZE(pVideo, 2);
362        if (!size || size > PageSize)
363               size = PageSize;
364
365	err = pci_device_map_range(pVideo, MMIOBase,
366                                   size, mode, &pATI->pMMIO);
367
368        if (err)
369        {
370            xf86DrvMsg (iScreen, X_ERROR,
371                    "Unable to map mmio aperture. %s (%d)\n",
372                    strerror (err), err);
373        }
374
375#endif /* XSERVER_LIBPCIACCESS */
376
377        if (!pATI->pMMIO)
378        {
379
380#if X_BYTE_ORDER == X_LITTLE_ENDIAN
381
382            ATIUnmapCursor(iScreen, pATI);
383
384#endif /* X_BYTE_ORDER */
385
386            ATIUnmapLinear(iScreen, pATI);
387
388#ifndef AVOID_CPIO
389
390            ATIUnmapVGA(iScreen, pATI);
391
392#endif /* AVOID_CPIO */
393
394            pATI->Mapped = FALSE;
395            return FALSE;
396        }
397
398        pATI->Mapped = TRUE;
399
400        pATI->pBlock[0] = (char *)pATI->pMMIO +
401            (pATI->Block0Base - MMIOBase);
402
403        if (pATI->Block1Base)
404            pATI->pBlock[1] = (char *)pATI->pBlock[0] - 0x00000400U;
405
406#if X_BYTE_ORDER == X_LITTLE_ENDIAN
407
408        if (!pATI->pCursorImage)
409
410#endif /* X_BYTE_ORDER */
411
412        {
413            if ((pATI->CursorBase >= MMIOBase) &&
414                ((pATI->CursorBase + 0x00000400UL) <= (MMIOBase + PageSize)))
415                pATI->pCursorImage = (char *)pATI->pMMIO +
416                    (pATI->CursorBase - MMIOBase);
417        }
418    }
419
420    /* Map hardware cursor image area */
421    if (pATI->CursorBase && !pATI->pCursorImage)
422    {
423        unsigned long CursorBase = pATI->CursorBase & ~(PageSize - 1);
424
425#ifndef XSERVER_LIBPCIACCESS
426
427            pATI->pCursorPage = xf86MapPciMem(iScreen, VIDMEM_FRAMEBUFFER,
428                Tag, CursorBase, PageSize);
429
430#else /* XSERVER_LIBPCIACCESS */
431
432        int mode = PCI_DEV_MAP_FLAG_WRITABLE | PCI_DEV_MAP_FLAG_WRITE_COMBINE;
433
434        int err = pci_device_map_range(pVideo,
435                                       CursorBase,
436                                       PageSize,
437                                       mode, &pATI->pCursorPage);
438
439        if (err)
440        {
441            xf86DrvMsg (iScreen, X_ERROR,
442                    "Unable to map cursor aperture. %s (%d)\n",
443                    strerror (err), err);
444        }
445
446#endif /* XSERVER_LIBPCIACCESS */
447
448        if (!pATI->pCursorPage)
449        {
450            ATIUnmapCursor(iScreen, pATI);
451            ATIUnmapMMIO(iScreen, pATI);
452            ATIUnmapLinear(iScreen, pATI);
453
454#ifndef AVOID_CPIO
455
456            ATIUnmapVGA(iScreen, pATI);
457
458#endif /* AVOID_CPIO */
459
460            pATI->Mapped = FALSE;
461            return FALSE;
462        }
463
464        pATI->pCursorImage = (char *)pATI->pCursorPage +
465            (pATI->CursorBase - CursorBase);
466    }
467
468    return TRUE;
469}
470
471/*
472 * ATIUnmapApertures --
473 *
474 * This function unmaps all apertures used by the driver.
475 */
476void
477ATIUnmapApertures
478(
479    int    iScreen,
480    ATIPtr pATI
481)
482{
483    if (!pATI->Mapped)
484        return;
485    pATI->Mapped = FALSE;
486
487    /* Unmap hardware cursor image area */
488    ATIUnmapCursor(iScreen, pATI);
489
490    /* Unmap MMIO area */
491    ATIUnmapMMIO(iScreen, pATI);
492
493    /* Unmap linear aperture */
494    ATIUnmapLinear(iScreen, pATI);
495
496#ifndef AVOID_CPIO
497
498    /* Unmap VGA aperture */
499    ATIUnmapVGA(iScreen, pATI);
500
501#endif /* AVOID_CPIO */
502
503}
504