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