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 authors 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 46#define CIR_VERSION 4000 47#define CIR_NAME "CIRRUS" 48#define CIR_DRIVER_NAME "cirrus" 49#define CIR_MAJOR_VERSION PACKAGE_VERSION_MAJOR 50#define CIR_MINOR_VERSION PACKAGE_VERSION_MINOR 51#define CIR_PATCHLEVEL PACKAGE_VERSION_PATCHLEVEL 52 53/* 54 * This contains the functions needed by the server after loading the 55 * driver module. It must be supplied, and gets added to the driver list by 56 * the Module Setup function in the dynamic case. In the static case a 57 * reference to this is compiled in, and this requires that the name of 58 * this DriverRec be an upper-case version of the driver name. 59 */ 60 61_X_EXPORT DriverRec CIRRUS = { 62 CIR_VERSION, 63 CIR_DRIVER_NAME, 64 CIRIdentify, 65 CIRProbe, 66 CIRAvailableOptions, 67 NULL, 68 0 69}; 70 71/* Supported chipsets */ 72SymTabRec CIRChipsets[] = { 73 { PCI_CHIP_GD5430, "CLGD5430" }, 74 { PCI_CHIP_GD5434_4, "CLGD5434-4" }, 75 { PCI_CHIP_GD5434_8, "CLGD5434-8" }, 76 { PCI_CHIP_GD5436, "CLGD5436" }, 77/* { PCI_CHIP_GD5440, "CLGD5440" }, */ 78 { PCI_CHIP_GD5446, "CLGD5446" }, 79 { PCI_CHIP_GD5480, "CLGD5480" }, 80 { PCI_CHIP_GD5462, "CL-GD5462" }, 81 { PCI_CHIP_GD5464, "CL-GD5464" }, 82 { PCI_CHIP_GD5464BD, "CL-GD5464BD" }, 83 { PCI_CHIP_GD5465, "CL-GD5465" }, 84 { PCI_CHIP_GD7548, "CL-GD7548" }, 85 { PCI_CHIP_GD7555, "CL-GD7555" }, 86 { PCI_CHIP_GD7556, "CL-GD7556" }, 87 {-1, NULL } 88}; 89 90/* List of PCI chipset names */ 91_X_EXPORT PciChipsets CIRPciChipsets[] = { 92 { PCI_CHIP_GD5430, PCI_CHIP_GD5430, RES_SHARED_VGA }, 93 { PCI_CHIP_GD5434_4,PCI_CHIP_GD5434_4, RES_SHARED_VGA }, 94 { PCI_CHIP_GD5434_8,PCI_CHIP_GD5434_8, RES_SHARED_VGA }, 95 { PCI_CHIP_GD5436, PCI_CHIP_GD5436, RES_SHARED_VGA }, 96/* { PCI_CHIP_GD5440, PCI_CHIP_GD5440, RES_SHARED_VGA }, */ 97 { PCI_CHIP_GD5446, PCI_CHIP_GD5446, RES_SHARED_VGA }, 98 { PCI_CHIP_GD5480, PCI_CHIP_GD5480, RES_SHARED_VGA }, 99 { PCI_CHIP_GD5462, PCI_CHIP_GD5462, RES_SHARED_VGA }, 100 { PCI_CHIP_GD5464, PCI_CHIP_GD5464, RES_SHARED_VGA }, 101 { PCI_CHIP_GD5464BD,PCI_CHIP_GD5464BD, RES_SHARED_VGA }, 102 { PCI_CHIP_GD5465, PCI_CHIP_GD5465, RES_SHARED_VGA }, 103 { PCI_CHIP_GD7548, PCI_CHIP_GD7548, RES_SHARED_VGA }, 104 { PCI_CHIP_GD7555, PCI_CHIP_GD7555, RES_SHARED_VGA }, 105 { PCI_CHIP_GD7556, PCI_CHIP_GD7556, RES_SHARED_VGA }, 106 { -1, -1, RES_UNDEFINED} 107}; 108 109#ifdef XFree86LOADER 110 111static MODULESETUPPROTO(cirSetup); 112 113static XF86ModuleVersionInfo cirVersRec = 114{ 115 "cirrus", 116 MODULEVENDORSTRING, 117 MODINFOSTRING1, 118 MODINFOSTRING2, 119 XORG_VERSION_CURRENT, 120 CIR_MAJOR_VERSION, CIR_MINOR_VERSION, CIR_PATCHLEVEL, 121 ABI_CLASS_VIDEODRV, /* This is a video driver */ 122 ABI_VIDEODRV_VERSION, 123 MOD_CLASS_VIDEODRV, 124 {0,0,0,0} 125}; 126 127/* 128 * This is the module init data. 129 * Its name has to be the driver name followed by ModuleData. 130 */ 131_X_EXPORT XF86ModuleData cirrusModuleData = { &cirVersRec, cirSetup, NULL }; 132 133static pointer 134cirSetup(pointer module, pointer opts, int *errmaj, int *errmin) 135{ 136 static Bool setupDone = FALSE; 137 138 /* This module should be loaded only once, but check to be sure. */ 139 140 if (!setupDone) { 141 setupDone = TRUE; 142 xf86AddDriver(&CIRRUS, module, 0); 143 144 return (pointer)1; 145 } 146 if (errmaj) *errmaj = LDR_ONCEONLY; 147 return NULL; 148} 149 150#endif /* XFree86LOADER */ 151 152/* Mandatory */ 153static void 154CIRIdentify(int flags) 155{ 156 xf86PrintChipsets(CIR_NAME, "driver for Cirrus chipsets", CIRChipsets); 157} 158 159static const OptionInfoRec * 160CIRAvailableOptions(int chipid, int busid) 161{ 162 int chip = chipid & 0xffff; 163 164 switch (chip) 165 { 166 case PCI_CHIP_GD5462: 167 case PCI_CHIP_GD5464: 168 case PCI_CHIP_GD5464BD: 169 case PCI_CHIP_GD5465: 170 return LgAvailableOptions(chipid); 171 172 default: 173 return AlpAvailableOptions(chipid); 174 } 175} 176 177static Bool 178CIRProbe(DriverPtr drv, int flags) 179{ 180 int i; 181 GDevPtr *devSections; 182 pciVideoPtr pPci; 183 int *usedChips; 184 int numDevSections; 185 int numUsed; 186 Bool foundScreen = FALSE; 187 ScrnInfoPtr pScrn; 188 189#ifdef CIR_DEBUG 190 ErrorF("CirProbe\n"); 191#endif 192 193 if ((numDevSections = xf86MatchDevice(CIR_DRIVER_NAME, 194 &devSections)) <= 0) { 195 return FALSE; 196 } 197 198#ifndef XSERVER_LIBPCIACCESS 199 if (xf86GetPciVideoInfo() == NULL) { 200 /* 201 * We won't let anything in the config file override finding no 202 * PCI video cards at all. This seems reasonable now, but we'll see. 203 */ 204 return FALSE; 205 } 206#endif 207 208 numUsed = xf86MatchPciInstances(CIR_NAME, PCI_VENDOR_CIRRUS, 209 CIRChipsets, CIRPciChipsets, devSections, 210 numDevSections, drv, &usedChips); 211 /* Free it since we don't need that list after this */ 212 if (numUsed <= 0) { 213 free(devSections); 214 return FALSE; 215 } 216 if (flags & PROBE_DETECT) 217 foundScreen = TRUE; 218 else for (i = 0; i < numUsed; i++) { 219 /* The Laguna family of chips is so different from the Alpine 220 family that we won't share even the highest-level of 221 functions. But, the Laguna chips /are/ Cirrus chips, so 222 they should be handled in this driver (as opposed to their 223 own driver). */ 224 pPci = xf86GetPciInfoForEntity(usedChips[i]); 225 226#ifdef XSERVER_LIBPCIACCESS 227 if (pci_device_has_kernel_driver(pPci)) { 228 xf86DrvMsg(0, X_ERROR, 229 "cirrus: The PCI device 0x%x at %2.2d@%2.2d:%2.2d:%1.1d has a kernel module claiming it.\n", 230 pPci->device_id, pPci->bus, pPci->domain, pPci->dev, pPci->func); 231 xf86DrvMsg(0, X_ERROR, 232 "cirrus: This driver cannot operate until it has been unloaded.\n"); 233#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 13 234 xf86UnclaimPciSlot(pPci); 235#else 236 xf86UnclaimPciSlot(pPci, devSections[0]); 237#endif 238 free(devSections); 239 return FALSE; 240 } 241#endif 242 pScrn = NULL; 243 if (pPci && (PCI_DEV_DEVICE_ID(pPci) == PCI_CHIP_GD5462 || 244 PCI_DEV_DEVICE_ID(pPci) == PCI_CHIP_GD5464 || 245 PCI_DEV_DEVICE_ID(pPci) == PCI_CHIP_GD5464BD || 246 PCI_DEV_DEVICE_ID(pPci) == PCI_CHIP_GD5465)) { 247 pScrn = LgProbe(usedChips[i]); 248 } else { 249 pScrn = AlpProbe(usedChips[i]); 250 } 251 252 if (pScrn) { 253 foundScreen = TRUE; 254 /* Fill in what we can of the ScrnInfoRec */ 255 pScrn->driverVersion = CIR_VERSION; 256 pScrn->driverName = CIR_DRIVER_NAME; 257 pScrn->name = CIR_NAME; 258 pScrn->Probe = NULL; 259 } 260 } 261 free(devSections); 262 free(usedChips); 263 264 return foundScreen; 265} 266 267/* 268 * Map the framebuffer and MMIO memory. 269 */ 270 271_X_EXPORT Bool 272CirMapMem(CirPtr pCir, int scrnIndex) 273{ 274#ifdef CIR_DEBUG 275 ErrorF("CirMapMem\n"); 276#endif 277 278 /* 279 * Map the frame buffer. 280 */ 281 if (pCir->FbMapSize) { 282 283#ifndef XSERVER_LIBPCIACCESS 284 285 pCir->FbBase = xf86MapPciMem(scrnIndex, VIDMEM_FRAMEBUFFER, 286 pCir->PciTag, pCir->FbAddress, 287 pCir->FbMapSize); 288 if (pCir->FbBase == NULL) 289 return FALSE; 290 291#else 292 void** result = (void**)&pCir->FbBase; 293 int err = pci_device_map_range(pCir->PciInfo, 294 pCir->FbAddress, 295 pCir->FbMapSize, 296 PCI_DEV_MAP_FLAG_WRITABLE | 297 PCI_DEV_MAP_FLAG_WRITE_COMBINE, 298 result); 299 300 if (err) 301 return FALSE; 302#endif 303 } 304 305#ifdef CIR_DEBUG 306 ErrorF("CirMapMem pCir->FbBase=0x%08x\n", pCir->FbBase); 307#endif 308 309 /* 310 * Map IO registers to virtual address space 311 */ 312 if (pCir->IOAddress == 0) { 313 pCir->IOBase = NULL; /* Until we are ready to use MMIO */ 314 } else { 315 316#ifndef XSERVER_LIBPCIACCESS 317 /* 318 * For Alpha, we need to map SPARSE memory, since we need 319 * byte/short access. Common-level will automatically use 320 * sparse mapping for MMIO. 321 */ 322 323 pCir->IOBase = 324 xf86MapPciMem(scrnIndex, VIDMEM_MMIO, pCir->PciTag, 325 pCir->IOAddress, pCir->IoMapSize); 326 if (pCir->IOBase == NULL) 327 return FALSE; 328 329#else 330 void** result = (void**)&pCir->IOBase; 331 int err = pci_device_map_range(pCir->PciInfo, 332 pCir->IOAddress, 333 pCir->IoMapSize, 334 PCI_DEV_MAP_FLAG_WRITABLE, 335 result); 336 337 if (err) 338 return FALSE; 339 340#endif 341 } 342 343#ifdef CIR_DEBUG 344 ErrorF("CirMapMem pCir->IOBase=0x%08x [length=%08x] from PCI=%08x\n", 345 pCir->IOBase, pCir->IoMapSize, pCir->IOAddress); 346 ErrorF("MMIO[GR31] = %2X\n", (int) 347 ((volatile unsigned char*) pCir->IOBase)[0x40]); 348#endif 349 350 return TRUE; 351} 352 353 354/* 355 * Unmap the framebuffer and MMIO memory. 356 */ 357 358_X_EXPORT Bool 359CirUnmapMem(CirPtr pCir, int scrnIndex) 360{ 361#ifdef CIR_DEBUG 362 ErrorF("CirUnmapMem\n"); 363#endif 364 365 if (pCir->IOBase != NULL) { 366 /* 367 * Unmap IO registers to virtual address space 368 */ 369#ifndef XSERVER_LIBPCIACCESS 370 xf86UnMapVidMem(scrnIndex, (pointer)pCir->IOBase, pCir->IoMapSize); 371#else 372 pci_device_unmap_range(pCir->PciInfo, (pointer)pCir->IOBase, pCir->IoMapSize); 373#endif 374 pCir->IOBase = NULL; 375 } 376 377#ifndef XSERVER_LIBPCIACCESS 378 xf86UnMapVidMem(scrnIndex, (pointer)pCir->FbBase, pCir->FbMapSize); 379#else 380 pci_device_unmap_range(pCir->PciInfo, (pointer)pCir->FbBase, pCir->FbMapSize); 381#endif 382 pCir->FbBase = NULL; 383 return TRUE; 384} 385 386_X_EXPORT void 387cirProbeDDC(ScrnInfoPtr pScrn, int index) 388{ 389 vbeInfoPtr pVbe; 390 391 if (xf86LoadSubModule(pScrn, "vbe")) { 392 pVbe = VBEInit(NULL,index); 393 ConfiguredMonitor = vbeDoEDID(pVbe, NULL); 394 vbeFree(pVbe); 395 } 396} 397