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