cir_driver.c revision 63847c39
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/* All drivers should typically include these */ 19#include "xf86.h" 20#include "xf86_OSproc.h" 21 22#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6 23#include "xf86Resources.h" 24#endif 25/* All drivers need this */ 26 27/* Drivers that need to access the PCI config space directly need this */ 28#include "xf86Pci.h" 29 30#include "cir.h" 31#include "alp.h" 32#include "lg.h" 33 34#include "vbe.h" 35 36/* 37 * Forward definitions for the functions that make up the driver. 38 */ 39 40/* Mandatory functions */ 41 42static const OptionInfoRec * CIRAvailableOptions(int chipid, int busid); 43static void CIRIdentify(int flags); 44static Bool CIRProbe(DriverPtr drv, int flags); 45 46static Bool lg_loaded = FALSE; 47static Bool alp_loaded = FALSE; 48 49#define CIR_VERSION 4000 50#define CIR_NAME "CIRRUS" 51#define CIR_DRIVER_NAME "cirrus" 52#define CIR_MAJOR_VERSION PACKAGE_VERSION_MAJOR 53#define CIR_MINOR_VERSION PACKAGE_VERSION_MINOR 54#define CIR_PATCHLEVEL PACKAGE_VERSION_PATCHLEVEL 55 56/* 57 * This contains the functions needed by the server after loading the 58 * driver module. It must be supplied, and gets added to the driver list by 59 * the Module Setup function in the dynamic case. In the static case a 60 * reference to this is compiled in, and this requires that the name of 61 * this DriverRec be an upper-case version of the driver name. 62 */ 63 64_X_EXPORT DriverRec CIRRUS = { 65 CIR_VERSION, 66 CIR_DRIVER_NAME, 67 CIRIdentify, 68 CIRProbe, 69 CIRAvailableOptions, 70 NULL, 71 0 72}; 73 74/* Supported chipsets */ 75SymTabRec CIRChipsets[] = { 76 { PCI_CHIP_GD5430, "CLGD5430" }, 77 { PCI_CHIP_GD5434_4, "CLGD5434-4" }, 78 { PCI_CHIP_GD5434_8, "CLGD5434-8" }, 79 { PCI_CHIP_GD5436, "CLGD5436" }, 80/* { PCI_CHIP_GD5440, "CLGD5440" }, */ 81 { PCI_CHIP_GD5446, "CLGD5446" }, 82 { PCI_CHIP_GD5480, "CLGD5480" }, 83 { PCI_CHIP_GD5462, "CL-GD5462" }, 84 { PCI_CHIP_GD5464, "CL-GD5464" }, 85 { PCI_CHIP_GD5464BD, "CL-GD5464BD" }, 86 { PCI_CHIP_GD5465, "CL-GD5465" }, 87 { PCI_CHIP_GD7548, "CL-GD7548" }, 88 { PCI_CHIP_GD7555, "CL-GD7555" }, 89 { PCI_CHIP_GD7556, "CL-GD7556" }, 90 {-1, NULL } 91}; 92 93/* List of PCI chipset names */ 94_X_EXPORT PciChipsets CIRPciChipsets[] = { 95 { PCI_CHIP_GD5430, PCI_CHIP_GD5430, RES_SHARED_VGA }, 96 { PCI_CHIP_GD5434_4,PCI_CHIP_GD5434_4, RES_SHARED_VGA }, 97 { PCI_CHIP_GD5434_8,PCI_CHIP_GD5434_8, RES_SHARED_VGA }, 98 { PCI_CHIP_GD5436, PCI_CHIP_GD5436, RES_SHARED_VGA }, 99/* { PCI_CHIP_GD5440, PCI_CHIP_GD5440, RES_SHARED_VGA }, */ 100 { PCI_CHIP_GD5446, PCI_CHIP_GD5446, RES_SHARED_VGA }, 101 { PCI_CHIP_GD5480, PCI_CHIP_GD5480, RES_SHARED_VGA }, 102 { PCI_CHIP_GD5462, PCI_CHIP_GD5462, RES_SHARED_VGA }, 103 { PCI_CHIP_GD5464, PCI_CHIP_GD5464, RES_SHARED_VGA }, 104 { PCI_CHIP_GD5464BD,PCI_CHIP_GD5464BD, RES_SHARED_VGA }, 105 { PCI_CHIP_GD5465, PCI_CHIP_GD5465, RES_SHARED_VGA }, 106 { PCI_CHIP_GD7548, PCI_CHIP_GD7548, RES_SHARED_VGA }, 107 { PCI_CHIP_GD7555, PCI_CHIP_GD7555, RES_SHARED_VGA }, 108 { PCI_CHIP_GD7556, PCI_CHIP_GD7556, 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 if (numUsed <= 0) { 241 free(devSections); 242 return FALSE; 243 } 244 if (flags & PROBE_DETECT) 245 foundScreen = TRUE; 246 else for (i = 0; i < numUsed; i++) { 247 /* The Laguna family of chips is so different from the Alpine 248 family that we won't share even the highest-level of 249 functions. But, the Laguna chips /are/ Cirrus chips, so 250 they should be handled in this driver (as opposed to their 251 own driver). */ 252 pPci = xf86GetPciInfoForEntity(usedChips[i]); 253 254#ifdef XSERVER_LIBPCIACCESS 255 if (pci_device_has_kernel_driver(pPci)) { 256 xf86DrvMsg(0, X_ERROR, 257 "cirrus: The PCI device 0x%x at %2.2d@%2.2d:%2.2d:%1.1d has a kernel module claiming it.\n", 258 pPci->device_id, pPci->bus, pPci->domain, pPci->dev, pPci->func); 259 xf86DrvMsg(0, X_ERROR, 260 "cirrus: This driver cannot operate until it has been unloaded.\n"); 261#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 13 262 xf86UnclaimPciSlot(pPci); 263#else 264 xf86UnclaimPciSlot(pPci, devSections[0]); 265#endif 266 free(devSections); 267 return FALSE; 268 } 269#endif 270 pScrn = NULL; 271 if (pPci && (PCI_DEV_DEVICE_ID(pPci) == PCI_CHIP_GD5462 || 272 PCI_DEV_DEVICE_ID(pPci) == PCI_CHIP_GD5464 || 273 PCI_DEV_DEVICE_ID(pPci) == PCI_CHIP_GD5464BD || 274 PCI_DEV_DEVICE_ID(pPci) == PCI_CHIP_GD5465)) { 275 276 if (!lg_loaded) { 277 if (!xf86LoadDrvSubModule(drv, "cirrus_laguna")) 278 continue; 279 lg_loaded = TRUE; 280 } 281 pScrn = LgProbe(usedChips[i]); 282 } else { 283 if (!alp_loaded) { 284 if (!xf86LoadDrvSubModule(drv, "cirrus_alpine")) 285 continue; 286 alp_loaded = TRUE; 287 } 288 pScrn = AlpProbe(usedChips[i]); 289 } 290 291 if (pScrn) { 292 foundScreen = TRUE; 293 /* Fill in what we can of the ScrnInfoRec */ 294 pScrn->driverVersion = CIR_VERSION; 295 pScrn->driverName = CIR_DRIVER_NAME; 296 pScrn->name = CIR_NAME; 297 pScrn->Probe = NULL; 298 } 299 } 300 free(devSections); 301 free(usedChips); 302 303 return foundScreen; 304} 305 306/* 307 * Map the framebuffer and MMIO memory. 308 */ 309 310_X_EXPORT Bool 311CirMapMem(CirPtr pCir, int scrnIndex) 312{ 313 int mmioFlags; 314 315#ifdef CIR_DEBUG 316 ErrorF("CirMapMem\n"); 317#endif 318 319 /* 320 * Map the frame buffer. 321 */ 322 if (pCir->FbMapSize) { 323 324#ifndef XSERVER_LIBPCIACCESS 325 326 pCir->FbBase = xf86MapPciMem(scrnIndex, VIDMEM_FRAMEBUFFER, 327 pCir->PciTag, pCir->FbAddress, 328 pCir->FbMapSize); 329 if (pCir->FbBase == NULL) 330 return FALSE; 331 332#else 333 void** result = (void**)&pCir->FbBase; 334 int err = pci_device_map_range(pCir->PciInfo, 335 pCir->FbAddress, 336 pCir->FbMapSize, 337 PCI_DEV_MAP_FLAG_WRITABLE | 338 PCI_DEV_MAP_FLAG_WRITE_COMBINE, 339 result); 340 341 if (err) 342 return FALSE; 343#endif 344 } 345 346#ifdef CIR_DEBUG 347 ErrorF("CirMapMem pCir->FbBase=0x%08x\n", pCir->FbBase); 348#endif 349 350 /* 351 * Map IO registers to virtual address space 352 */ 353 if (pCir->IOAddress == 0) { 354 pCir->IOBase = NULL; /* Until we are ready to use MMIO */ 355 } else { 356 357#ifndef XSERVER_LIBPCIACCESS 358 mmioFlags = VIDMEM_MMIO; 359 /* 360 * For Alpha, we need to map SPARSE memory, since we need 361 * byte/short access. Common-level will automatically use 362 * sparse mapping for MMIO. 363 */ 364 365 pCir->IOBase = 366 xf86MapPciMem(scrnIndex, mmioFlags, pCir->PciTag, 367 pCir->IOAddress, pCir->IoMapSize); 368 if (pCir->IOBase == NULL) 369 return FALSE; 370 371#else 372 void** result = (void**)&pCir->IOBase; 373 int err = pci_device_map_range(pCir->PciInfo, 374 pCir->IOAddress, 375 pCir->IoMapSize, 376 PCI_DEV_MAP_FLAG_WRITABLE, 377 result); 378 379 if (err) 380 return FALSE; 381 382#endif 383 } 384 385#ifdef CIR_DEBUG 386 ErrorF("CirMapMem pCir->IOBase=0x%08x [length=%08x] from PCI=%08x\n", 387 pCir->IOBase, pCir->IoMapSize, pCir->IOAddress); 388 ErrorF("MMIO[GR31] = %2X\n", (int) 389 ((volatile unsigned char*) pCir->IOBase)[0x40]); 390#endif 391 392 return TRUE; 393} 394 395 396/* 397 * Unmap the framebuffer and MMIO memory. 398 */ 399 400_X_EXPORT Bool 401CirUnmapMem(CirPtr pCir, int scrnIndex) 402{ 403#ifdef CIR_DEBUG 404 ErrorF("CirUnmapMem\n"); 405#endif 406 407 if (pCir->IOBase != NULL) { 408 /* 409 * Unmap IO registers to virtual address space 410 */ 411#ifndef XSERVER_LIBPCIACCESS 412 xf86UnMapVidMem(scrnIndex, (pointer)pCir->IOBase, pCir->IoMapSize); 413#else 414 pci_device_unmap_range(pCir->PciInfo, (pointer)pCir->IOBase, pCir->IoMapSize); 415#endif 416 pCir->IOBase = NULL; 417 } 418 419#ifndef XSERVER_LIBPCIACCESS 420 xf86UnMapVidMem(scrnIndex, (pointer)pCir->FbBase, pCir->FbMapSize); 421#else 422 pci_device_unmap_range(pCir->PciInfo, (pointer)pCir->FbBase, pCir->FbMapSize); 423#endif 424 pCir->FbBase = NULL; 425 return TRUE; 426} 427 428_X_EXPORT void 429cirProbeDDC(ScrnInfoPtr pScrn, int index) 430{ 431 vbeInfoPtr pVbe; 432 433 if (xf86LoadSubModule(pScrn, "vbe")) { 434 pVbe = VBEInit(NULL,index); 435 ConfiguredMonitor = vbeDoEDID(pVbe, NULL); 436 vbeFree(pVbe); 437 } 438} 439