cir_driver.c revision 1ae1b5e8
1/* 2 * Driver for CL-GD5480. 3 * Itai Nahshon. 4 * 5 * Support for the CL-GD7548: David Monniaux 6 * 7 * This is mainly a cut & paste from the MGA driver. 8 * Original autors and contributors list include: 9 * Radoslaw Kapitan, Andrew Vanderstock, Dirk Hohndel, 10 * David Dawes, Andrew E. Mileski, Leonard N. Zubkoff, 11 * Guy DESBIEF 12 */ 13 14#ifdef HAVE_CONFIG_H 15#include "config.h" 16#endif 17 18/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/cirrus/cir_driver.c,v 1.67 2001/05/15 10:19:37 eich Exp $ */ 19 20/* All drivers should typically include these */ 21#include "xf86.h" 22#include "xf86_OSproc.h" 23 24#include "xf86Resources.h" 25 26/* All drivers need this */ 27 28/* Drivers for PCI hardware need this */ 29#include "xf86PciInfo.h" 30 31/* Drivers that need to access the PCI config space directly need this */ 32#include "xf86Pci.h" 33 34#include "cir.h" 35#include "alp.h" 36#include "lg.h" 37 38#include "vbe.h" 39 40/* 41 * Forward definitions for the functions that make up the driver. 42 */ 43 44/* Mandatory functions */ 45 46static const OptionInfoRec * CIRAvailableOptions(int chipid, int busid); 47static void CIRIdentify(int flags); 48static Bool CIRProbe(DriverPtr drv, int flags); 49 50static Bool lg_loaded = FALSE; 51static Bool alp_loaded = FALSE; 52 53#define CIR_VERSION 4000 54#define CIR_NAME "CIRRUS" 55#define CIR_DRIVER_NAME "cirrus" 56#define CIR_MAJOR_VERSION PACKAGE_VERSION_MAJOR 57#define CIR_MINOR_VERSION PACKAGE_VERSION_MINOR 58#define CIR_PATCHLEVEL PACKAGE_VERSION_PATCHLEVEL 59 60/* 61 * This contains the functions needed by the server after loading the 62 * driver module. It must be supplied, and gets added to the driver list by 63 * the Module Setup function in the dynamic case. In the static case a 64 * reference to this is compiled in, and this requires that the name of 65 * this DriverRec be an upper-case version of the driver name. 66 */ 67 68_X_EXPORT DriverRec CIRRUS = { 69 CIR_VERSION, 70 CIR_DRIVER_NAME, 71 CIRIdentify, 72 CIRProbe, 73 CIRAvailableOptions, 74 NULL, 75 0 76}; 77 78/* Supported chipsets */ 79SymTabRec CIRChipsets[] = { 80 { PCI_CHIP_GD5430, "CLGD5430" }, 81 { PCI_CHIP_GD5434_4, "CLGD5434-4" }, 82 { PCI_CHIP_GD5434_8, "CLGD5434-8" }, 83 { PCI_CHIP_GD5436, "CLGD5436" }, 84/* { PCI_CHIP_GD5440, "CLGD5440" }, */ 85 { PCI_CHIP_GD5446, "CLGD5446" }, 86 { PCI_CHIP_GD5480, "CLGD5480" }, 87 { PCI_CHIP_GD5462, "CL-GD5462" }, 88 { PCI_CHIP_GD5464, "CL-GD5464" }, 89 { PCI_CHIP_GD5464BD, "CL-GD5464BD" }, 90 { PCI_CHIP_GD5465, "CL-GD5465" }, 91 { PCI_CHIP_GD7548, "CL-GD7548" }, 92 {-1, NULL } 93}; 94 95/* List of PCI chipset names */ 96_X_EXPORT PciChipsets CIRPciChipsets[] = { 97 { PCI_CHIP_GD5430, PCI_CHIP_GD5430, RES_SHARED_VGA }, 98 { PCI_CHIP_GD5434_4,PCI_CHIP_GD5434_4, RES_SHARED_VGA }, 99 { PCI_CHIP_GD5434_8,PCI_CHIP_GD5434_8, RES_SHARED_VGA }, 100 { PCI_CHIP_GD5436, PCI_CHIP_GD5436, RES_SHARED_VGA }, 101/* { PCI_CHIP_GD5440, PCI_CHIP_GD5440, RES_SHARED_VGA }, */ 102 { PCI_CHIP_GD5446, PCI_CHIP_GD5446, RES_SHARED_VGA }, 103 { PCI_CHIP_GD5480, PCI_CHIP_GD5480, RES_SHARED_VGA }, 104 { PCI_CHIP_GD5462, PCI_CHIP_GD5462, RES_SHARED_VGA }, 105 { PCI_CHIP_GD5464, PCI_CHIP_GD5464, RES_SHARED_VGA }, 106 { PCI_CHIP_GD5464BD,PCI_CHIP_GD5464BD, RES_SHARED_VGA }, 107 { PCI_CHIP_GD5465, PCI_CHIP_GD5465, RES_SHARED_VGA }, 108 { PCI_CHIP_GD7548, PCI_CHIP_GD7548, RES_SHARED_VGA }, 109 { -1, -1, RES_UNDEFINED} 110}; 111 112/* 113 * List of symbols from other modules that this module references. This 114 * list is used to tell the loader that it is OK for symbols here to be 115 * unresolved providing that it hasn't been told that they haven't been 116 * told that they are essential via a call to xf86LoaderReqSymbols() or 117 * xf86LoaderReqSymLists(). The purpose of this is to avoid warnings about 118 * unresolved symbols that are not required. 119 */ 120 121static const char *alpSymbols[] = { 122 "AlpAvailableOptions", 123 "AlpProbe", 124 NULL 125}; 126static const char *lgSymbols[] = { 127 "LgAvailableOptions", 128 "LgProbe", 129 NULL 130}; 131 132static const char *vbeSymbols[] = { 133 "VBEInit", 134 "vbeDoEDID", 135 "vbeFree", 136 NULL 137}; 138 139#ifdef XFree86LOADER 140 141static MODULESETUPPROTO(cirSetup); 142 143static XF86ModuleVersionInfo cirVersRec = 144{ 145 "cirrus", 146 MODULEVENDORSTRING, 147 MODINFOSTRING1, 148 MODINFOSTRING2, 149 XORG_VERSION_CURRENT, 150 CIR_MAJOR_VERSION, CIR_MINOR_VERSION, CIR_PATCHLEVEL, 151 ABI_CLASS_VIDEODRV, /* This is a video driver */ 152 ABI_VIDEODRV_VERSION, 153 MOD_CLASS_VIDEODRV, 154 {0,0,0,0} 155}; 156 157/* 158 * This is the module init data. 159 * Its name has to be the driver name followed by ModuleData. 160 */ 161_X_EXPORT XF86ModuleData cirrusModuleData = { &cirVersRec, cirSetup, NULL }; 162 163static pointer 164cirSetup(pointer module, pointer opts, int *errmaj, int *errmin) 165{ 166 static Bool setupDone = FALSE; 167 168 /* This module should be loaded only once, but check to be sure. */ 169 170 if (!setupDone) { 171 setupDone = TRUE; 172 xf86AddDriver(&CIRRUS, module, 0); 173 174 LoaderRefSymLists(alpSymbols, lgSymbols, vbeSymbols, NULL); 175 return (pointer)1; 176 } 177 if (errmaj) *errmaj = LDR_ONCEONLY; 178 return NULL; 179} 180 181#endif /* XFree86LOADER */ 182 183/* Mandatory */ 184static void 185CIRIdentify(int flags) 186{ 187 xf86PrintChipsets(CIR_NAME, "driver for Cirrus chipsets", CIRChipsets); 188} 189 190static const OptionInfoRec * 191CIRAvailableOptions(int chipid, int busid) 192{ 193 int chip = chipid & 0xffff; 194 195 switch (chip) 196 { 197 case PCI_CHIP_GD5462: 198 case PCI_CHIP_GD5464: 199 case PCI_CHIP_GD5464BD: 200 case PCI_CHIP_GD5465: 201 if (lg_loaded) 202 return LgAvailableOptions(chipid); 203 else 204 return NULL; 205 206 default: 207 if (alp_loaded) 208 return AlpAvailableOptions(chipid); 209 else 210 return NULL; 211 } 212} 213 214static Bool 215CIRProbe(DriverPtr drv, int flags) 216{ 217 int i; 218 GDevPtr *devSections; 219 pciVideoPtr pPci; 220 int *usedChips; 221 int numDevSections; 222 int numUsed; 223 Bool foundScreen = FALSE; 224 ScrnInfoPtr pScrn; 225 226#ifdef CIR_DEBUG 227 ErrorF("CirProbe\n"); 228#endif 229 230 /* 231 * For PROBE_DETECT, make sure both sub-modules are loaded before 232 * calling xf86MatchPciInstances(), because the AvailableOptions() 233 * functions may be called before xf86MatchPciInstances() returns. 234 */ 235 236 if (flags & PROBE_DETECT) { 237 if (!lg_loaded) { 238 if (xf86LoadDrvSubModule(drv, "cirrus_laguna")) { 239 xf86LoaderReqSymLists(lgSymbols, NULL); 240 lg_loaded = TRUE; 241 } 242 } 243 if (!alp_loaded) { 244 if (xf86LoadDrvSubModule(drv, "cirrus_alpine")) { 245 xf86LoaderReqSymLists(alpSymbols, NULL); 246 alp_loaded = TRUE; 247 } 248 } 249 } 250 251 if ((numDevSections = xf86MatchDevice(CIR_DRIVER_NAME, 252 &devSections)) <= 0) { 253 return FALSE; 254 } 255 256#ifndef XSERVER_LIBPCIACCESS 257 if (xf86GetPciVideoInfo() == NULL) { 258 /* 259 * We won't let anything in the config file override finding no 260 * PCI video cards at all. This seems reasonable now, but we'll see. 261 */ 262 return FALSE; 263 } 264#endif 265 266 numUsed = xf86MatchPciInstances(CIR_NAME, PCI_VENDOR_CIRRUS, 267 CIRChipsets, CIRPciChipsets, devSections, 268 numDevSections, drv, &usedChips); 269 /* Free it since we don't need that list after this */ 270 xfree(devSections); 271 if (numUsed <= 0) 272 return FALSE; 273 if (flags & PROBE_DETECT) 274 foundScreen = TRUE; 275 else for (i = 0; i < numUsed; i++) { 276 /* The Laguna family of chips is so different from the Alpine 277 family that we won't share even the highest-level of 278 functions. But, the Laguna chips /are/ Cirrus chips, so 279 they should be handled in this driver (as opposed to their 280 own driver). */ 281 pPci = xf86GetPciInfoForEntity(usedChips[i]); 282 pScrn = NULL; 283 if (pPci && (PCI_DEV_DEVICE_ID(pPci) == PCI_CHIP_GD5462 || 284 PCI_DEV_DEVICE_ID(pPci) == PCI_CHIP_GD5464 || 285 PCI_DEV_DEVICE_ID(pPci) == PCI_CHIP_GD5464BD || 286 PCI_DEV_DEVICE_ID(pPci) == PCI_CHIP_GD5465)) { 287 288 if (!lg_loaded) { 289 if (!xf86LoadDrvSubModule(drv, "cirrus_laguna")) 290 continue; 291 xf86LoaderReqSymLists(lgSymbols, NULL); 292 lg_loaded = TRUE; 293 } 294 pScrn = LgProbe(usedChips[i]); 295 } else { 296 if (!alp_loaded) { 297 if (!xf86LoadDrvSubModule(drv, "cirrus_alpine")) 298 continue; 299 xf86LoaderReqSymLists(alpSymbols, NULL); 300 alp_loaded = TRUE; 301 } 302 pScrn = AlpProbe(usedChips[i]); 303 } 304 305 if (pScrn) { 306 foundScreen = TRUE; 307 /* Fill in what we can of the ScrnInfoRec */ 308 pScrn->driverVersion = CIR_VERSION; 309 pScrn->driverName = CIR_DRIVER_NAME; 310 pScrn->name = CIR_NAME; 311 pScrn->Probe = NULL; 312 } 313 } 314 xfree(usedChips); 315 316 return foundScreen; 317} 318 319/* 320 * Map the framebuffer and MMIO memory. 321 */ 322 323_X_EXPORT Bool 324CirMapMem(CirPtr pCir, int scrnIndex) 325{ 326 int mmioFlags; 327 328#ifdef CIR_DEBUG 329 ErrorF("CirMapMem\n"); 330#endif 331 332 /* 333 * Map the frame buffer. 334 */ 335 if (pCir->FbMapSize) { 336 337#ifndef XSERVER_LIBPCIACCESS 338 339 pCir->FbBase = xf86MapPciMem(scrnIndex, VIDMEM_FRAMEBUFFER, 340 pCir->PciTag, pCir->FbAddress, 341 pCir->FbMapSize); 342 if (pCir->FbBase == NULL) 343 return FALSE; 344 345#else 346 void** result = (void**)&pCir->FbBase; 347 int err = pci_device_map_range(pCir->PciInfo, 348 pCir->FbAddress, 349 pCir->FbMapSize, 350 PCI_DEV_MAP_FLAG_WRITABLE | 351 PCI_DEV_MAP_FLAG_WRITE_COMBINE, 352 result); 353 354 if (err) 355 return FALSE; 356#endif 357 } 358 359#ifdef CIR_DEBUG 360 ErrorF("CirMapMem pCir->FbBase=0x%08x\n", pCir->FbBase); 361#endif 362 363 /* 364 * Map IO registers to virtual address space 365 */ 366 if (pCir->IOAddress == 0) { 367 pCir->IOBase = NULL; /* Until we are ready to use MMIO */ 368 } else { 369 370#ifndef XSERVER_LIBPCIACCESS 371 mmioFlags = VIDMEM_MMIO; 372 /* 373 * For Alpha, we need to map SPARSE memory, since we need 374 * byte/short access. Common-level will automatically use 375 * sparse mapping for MMIO. 376 */ 377 378 pCir->IOBase = 379 xf86MapPciMem(scrnIndex, mmioFlags, pCir->PciTag, 380 pCir->IOAddress, pCir->IoMapSize); 381 if (pCir->IOBase == NULL) 382 return FALSE; 383 384#else 385 void** result = (void**)&pCir->IOBase; 386 int err = pci_device_map_range(pCir->PciInfo, 387 pCir->IOAddress, 388 pCir->IoMapSize, 389 PCI_DEV_MAP_FLAG_WRITABLE, 390 result); 391 392 if (err) 393 return FALSE; 394 395#endif 396 } 397 398#ifdef CIR_DEBUG 399 ErrorF("CirMapMem pCir->IOBase=0x%08x [length=%08x] from PCI=%08x\n", 400 pCir->IOBase, pCir->IoMapSize, pCir->IOAddress); 401 ErrorF("MMIO[GR31] = %2X\n", (int) 402 ((volatile unsigned char*) pCir->IOBase)[0x40]); 403#endif 404 405 return TRUE; 406} 407 408 409/* 410 * Unmap the framebuffer and MMIO memory. 411 */ 412 413_X_EXPORT Bool 414CirUnmapMem(CirPtr pCir, int scrnIndex) 415{ 416#ifdef CIR_DEBUG 417 ErrorF("CirUnmapMem\n"); 418#endif 419 420 if (pCir->IOBase != NULL) { 421 /* 422 * Unmap IO registers to virtual address space 423 */ 424#ifndef XSERVER_LIBPCIACCESS 425 xf86UnMapVidMem(scrnIndex, (pointer)pCir->IOBase, pCir->IoMapSize); 426#else 427 pci_device_unmap_range(pCir->PciInfo, (pointer)pCir->IOBase, pCir->IoMapSize); 428#endif 429 pCir->IOBase = NULL; 430 } 431 432#ifndef XSERVER_LIBPCIACCESS 433 xf86UnMapVidMem(scrnIndex, (pointer)pCir->FbBase, pCir->FbMapSize); 434#else 435 pci_device_unmap_range(pCir->PciInfo, (pointer)pCir->FbBase, pCir->FbMapSize); 436#endif 437 pCir->FbBase = NULL; 438 return TRUE; 439} 440 441_X_EXPORT void 442cirProbeDDC(ScrnInfoPtr pScrn, int index) 443{ 444 vbeInfoPtr pVbe; 445 446 if (xf86LoadSubModule(pScrn, "vbe")) { 447 xf86LoaderReqSymLists(vbeSymbols,NULL); 448 pVbe = VBEInit(NULL,index); 449 ConfiguredMonitor = vbeDoEDID(pVbe, NULL); 450 vbeFree(pVbe); 451 } 452} 453