Home | History | Annotate | Line # | Download | only in src
      1 /*
      2  * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi (at) 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 */
     32 const 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 */
     45 const 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 */
     58 const 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  */
     77 static void
     78 ATIUnmapVGA
     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  */
    103 static void
    104 ATIUnmapLinear
    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  */
    141 static void
    142 ATIUnmapMMIO
    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  */
    170 static void
    171 ATIUnmapCursor
    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  */
    199 Bool
    200 ATIMapApertures
    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  */
    476 void
    477 ATIUnmapApertures
    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