cir_driver.c revision 86dafe34
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#ifdef XFree86LOADER 113 114static MODULESETUPPROTO(cirSetup); 115 116static XF86ModuleVersionInfo cirVersRec = 117{ 118 "cirrus", 119 MODULEVENDORSTRING, 120 MODINFOSTRING1, 121 MODINFOSTRING2, 122 XORG_VERSION_CURRENT, 123 CIR_MAJOR_VERSION, CIR_MINOR_VERSION, CIR_PATCHLEVEL, 124 ABI_CLASS_VIDEODRV, /* This is a video driver */ 125 ABI_VIDEODRV_VERSION, 126 MOD_CLASS_VIDEODRV, 127 {0,0,0,0} 128}; 129 130/* 131 * This is the module init data. 132 * Its name has to be the driver name followed by ModuleData. 133 */ 134_X_EXPORT XF86ModuleData cirrusModuleData = { &cirVersRec, cirSetup, NULL }; 135 136static pointer 137cirSetup(pointer module, pointer opts, int *errmaj, int *errmin) 138{ 139 static Bool setupDone = FALSE; 140 141 /* This module should be loaded only once, but check to be sure. */ 142 143 if (!setupDone) { 144 setupDone = TRUE; 145 xf86AddDriver(&CIRRUS, module, 0); 146 147 return (pointer)1; 148 } 149 if (errmaj) *errmaj = LDR_ONCEONLY; 150 return NULL; 151} 152 153#endif /* XFree86LOADER */ 154 155/* Mandatory */ 156static void 157CIRIdentify(int flags) 158{ 159 xf86PrintChipsets(CIR_NAME, "driver for Cirrus chipsets", CIRChipsets); 160} 161 162static const OptionInfoRec * 163CIRAvailableOptions(int chipid, int busid) 164{ 165 int chip = chipid & 0xffff; 166 167 switch (chip) 168 { 169 case PCI_CHIP_GD5462: 170 case PCI_CHIP_GD5464: 171 case PCI_CHIP_GD5464BD: 172 case PCI_CHIP_GD5465: 173 if (lg_loaded) 174 return LgAvailableOptions(chipid); 175 else 176 return NULL; 177 178 default: 179 if (alp_loaded) 180 return AlpAvailableOptions(chipid); 181 else 182 return NULL; 183 } 184} 185 186static Bool 187CIRProbe(DriverPtr drv, int flags) 188{ 189 int i; 190 GDevPtr *devSections; 191 pciVideoPtr pPci; 192 int *usedChips; 193 int numDevSections; 194 int numUsed; 195 Bool foundScreen = FALSE; 196 ScrnInfoPtr pScrn; 197 198#ifdef CIR_DEBUG 199 ErrorF("CirProbe\n"); 200#endif 201 202 /* 203 * For PROBE_DETECT, make sure both sub-modules are loaded before 204 * calling xf86MatchPciInstances(), because the AvailableOptions() 205 * functions may be called before xf86MatchPciInstances() returns. 206 */ 207 208 if (flags & PROBE_DETECT) { 209 if (!lg_loaded) { 210 if (xf86LoadDrvSubModule(drv, "cirrus_laguna")) { 211 lg_loaded = TRUE; 212 } 213 } 214 if (!alp_loaded) { 215 if (xf86LoadDrvSubModule(drv, "cirrus_alpine")) { 216 alp_loaded = TRUE; 217 } 218 } 219 } 220 221 if ((numDevSections = xf86MatchDevice(CIR_DRIVER_NAME, 222 &devSections)) <= 0) { 223 return FALSE; 224 } 225 226#ifndef XSERVER_LIBPCIACCESS 227 if (xf86GetPciVideoInfo() == NULL) { 228 /* 229 * We won't let anything in the config file override finding no 230 * PCI video cards at all. This seems reasonable now, but we'll see. 231 */ 232 return FALSE; 233 } 234#endif 235 236 numUsed = xf86MatchPciInstances(CIR_NAME, PCI_VENDOR_CIRRUS, 237 CIRChipsets, CIRPciChipsets, devSections, 238 numDevSections, drv, &usedChips); 239 /* Free it since we don't need that list after this */ 240 xfree(devSections); 241 if (numUsed <= 0) 242 return FALSE; 243 if (flags & PROBE_DETECT) 244 foundScreen = TRUE; 245 else for (i = 0; i < numUsed; i++) { 246 /* The Laguna family of chips is so different from the Alpine 247 family that we won't share even the highest-level of 248 functions. But, the Laguna chips /are/ Cirrus chips, so 249 they should be handled in this driver (as opposed to their 250 own driver). */ 251 pPci = xf86GetPciInfoForEntity(usedChips[i]); 252 pScrn = NULL; 253 if (pPci && (PCI_DEV_DEVICE_ID(pPci) == PCI_CHIP_GD5462 || 254 PCI_DEV_DEVICE_ID(pPci) == PCI_CHIP_GD5464 || 255 PCI_DEV_DEVICE_ID(pPci) == PCI_CHIP_GD5464BD || 256 PCI_DEV_DEVICE_ID(pPci) == PCI_CHIP_GD5465)) { 257 258 if (!lg_loaded) { 259 if (!xf86LoadDrvSubModule(drv, "cirrus_laguna")) 260 continue; 261 lg_loaded = TRUE; 262 } 263 pScrn = LgProbe(usedChips[i]); 264 } else { 265 if (!alp_loaded) { 266 if (!xf86LoadDrvSubModule(drv, "cirrus_alpine")) 267 continue; 268 alp_loaded = TRUE; 269 } 270 pScrn = AlpProbe(usedChips[i]); 271 } 272 273 if (pScrn) { 274 foundScreen = TRUE; 275 /* Fill in what we can of the ScrnInfoRec */ 276 pScrn->driverVersion = CIR_VERSION; 277 pScrn->driverName = CIR_DRIVER_NAME; 278 pScrn->name = CIR_NAME; 279 pScrn->Probe = NULL; 280 } 281 } 282 xfree(usedChips); 283 284 return foundScreen; 285} 286 287/* 288 * Map the framebuffer and MMIO memory. 289 */ 290 291_X_EXPORT Bool 292CirMapMem(CirPtr pCir, int scrnIndex) 293{ 294 int mmioFlags; 295 296#ifdef CIR_DEBUG 297 ErrorF("CirMapMem\n"); 298#endif 299 300 /* 301 * Map the frame buffer. 302 */ 303 if (pCir->FbMapSize) { 304 305#ifndef XSERVER_LIBPCIACCESS 306 307 pCir->FbBase = xf86MapPciMem(scrnIndex, VIDMEM_FRAMEBUFFER, 308 pCir->PciTag, pCir->FbAddress, 309 pCir->FbMapSize); 310 if (pCir->FbBase == NULL) 311 return FALSE; 312 313#else 314 void** result = (void**)&pCir->FbBase; 315 int err = pci_device_map_range(pCir->PciInfo, 316 pCir->FbAddress, 317 pCir->FbMapSize, 318 PCI_DEV_MAP_FLAG_WRITABLE | 319 PCI_DEV_MAP_FLAG_WRITE_COMBINE, 320 result); 321 322 if (err) 323 return FALSE; 324#endif 325 } 326 327#ifdef CIR_DEBUG 328 ErrorF("CirMapMem pCir->FbBase=0x%08x\n", pCir->FbBase); 329#endif 330 331 /* 332 * Map IO registers to virtual address space 333 */ 334 if (pCir->IOAddress == 0) { 335 pCir->IOBase = NULL; /* Until we are ready to use MMIO */ 336 } else { 337 338#ifndef XSERVER_LIBPCIACCESS 339 mmioFlags = VIDMEM_MMIO; 340 /* 341 * For Alpha, we need to map SPARSE memory, since we need 342 * byte/short access. Common-level will automatically use 343 * sparse mapping for MMIO. 344 */ 345 346 pCir->IOBase = 347 xf86MapPciMem(scrnIndex, mmioFlags, pCir->PciTag, 348 pCir->IOAddress, pCir->IoMapSize); 349 if (pCir->IOBase == NULL) 350 return FALSE; 351 352#else 353 void** result = (void**)&pCir->IOBase; 354 int err = pci_device_map_range(pCir->PciInfo, 355 pCir->IOAddress, 356 pCir->IoMapSize, 357 PCI_DEV_MAP_FLAG_WRITABLE, 358 result); 359 360 if (err) 361 return FALSE; 362 363#endif 364 } 365 366#ifdef CIR_DEBUG 367 ErrorF("CirMapMem pCir->IOBase=0x%08x [length=%08x] from PCI=%08x\n", 368 pCir->IOBase, pCir->IoMapSize, pCir->IOAddress); 369 ErrorF("MMIO[GR31] = %2X\n", (int) 370 ((volatile unsigned char*) pCir->IOBase)[0x40]); 371#endif 372 373 return TRUE; 374} 375 376 377/* 378 * Unmap the framebuffer and MMIO memory. 379 */ 380 381_X_EXPORT Bool 382CirUnmapMem(CirPtr pCir, int scrnIndex) 383{ 384#ifdef CIR_DEBUG 385 ErrorF("CirUnmapMem\n"); 386#endif 387 388 if (pCir->IOBase != NULL) { 389 /* 390 * Unmap IO registers to virtual address space 391 */ 392#ifndef XSERVER_LIBPCIACCESS 393 xf86UnMapVidMem(scrnIndex, (pointer)pCir->IOBase, pCir->IoMapSize); 394#else 395 pci_device_unmap_range(pCir->PciInfo, (pointer)pCir->IOBase, pCir->IoMapSize); 396#endif 397 pCir->IOBase = NULL; 398 } 399 400#ifndef XSERVER_LIBPCIACCESS 401 xf86UnMapVidMem(scrnIndex, (pointer)pCir->FbBase, pCir->FbMapSize); 402#else 403 pci_device_unmap_range(pCir->PciInfo, (pointer)pCir->FbBase, pCir->FbMapSize); 404#endif 405 pCir->FbBase = NULL; 406 return TRUE; 407} 408 409_X_EXPORT void 410cirProbeDDC(ScrnInfoPtr pScrn, int index) 411{ 412 vbeInfoPtr pVbe; 413 414 if (xf86LoadSubModule(pScrn, "vbe")) { 415 pVbe = VBEInit(NULL,index); 416 ConfiguredMonitor = vbeDoEDID(pVbe, NULL); 417 vbeFree(pVbe); 418 } 419} 420