geode_driver.c revision 170d5fdc
1/* 2 * Copyright (c) 2006 Avanced Micro Devices, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 * DEALINGS IN THE SOFTWARE. 21 * 22 * Neither the name of the Advanced Micro Devices, Inc. nor the names of its 23 * contributors may be used to endorse or promote products derived from this 24 * software without specific prior written permission. 25 */ 26 27/* 28 * File Contents: This is the main module configures the interfacing 29 * with the X server. The individual modules will be 30 * loaded based upon the options selected from the 31 * XF86Config. This file also has modules for finding 32 * supported modes, turning on the modes based on options. 33 * 34 * Project: Amd Xfree Frame buffer device driver. 35 * 36 */ 37 38#ifdef HAVE_CONFIG_H 39#include "config.h" 40#endif 41 42/* Includes that are used by all drivers */ 43#include "xf86.h" 44#include "xf86_OSproc.h" 45#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6 46#include "xf86Resources.h" 47#endif 48#include "compiler.h" 49#include "xf86PciInfo.h" 50#include "xf86Pci.h" 51#include "xf86cmap.h" 52 53#include "geode.h" 54 55#define RC_MAX_DEPTH 24 56 57#include "fb.h" 58 59/* Machine independent stuff */ 60#include "mipointer.h" 61#include "micmap.h" 62/* All drivers implementing backing store need this */ 63#include "mibstore.h" 64#include "vgaHW.h" 65#include "vbe.h" 66 67#ifdef DPMSExtension 68#include "globals.h" 69#include "opaque.h" 70#ifdef HAVE_XEXTPROTO_71 71#include <X11/extensions/dpmsconst.h> 72#else 73#define DPMS_SERVER 74#include <X11/extensions/dpms.h> 75#endif 76 77#endif /* DPMSExtension */ 78 79/* A few things all drivers should have */ 80#define GEODE_NAME "GEODE" 81#define GEODE_DRIVER_NAME "geode" 82#define GEODE_VERSION 4000 83#define GEODE_VERSION_MAJOR PACKAGE_VERSION_MAJOR 84#define GEODE_VERSION_MINOR PACKAGE_VERSION_MINOR 85#define GEODE_VERSION_PATCH PACKAGE_VERSION_PATCHLEVEL 86 87/* Forward definitions */ 88static const OptionInfoRec *AmdAvailableOptions(int chipid, int busid); 89static void AmdIdentify(int); 90 91#ifdef XSERVER_LIBPCIACCESS 92static Bool AmdPciProbe(DriverPtr, int, struct pci_device *, intptr_t); 93#else 94static Bool AmdProbe(DriverPtr, int); 95#endif 96 97#ifdef XSERVER_LIBPCIACCESS 98static const struct pci_id_match amdDeviceMatch[] = { 99 {PCI_VENDOR_ID_NS, PCI_CHIP_GEODEGX, PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, 100 0}, 101 {PCI_VENDOR_ID_AMD, PCI_CHIP_GEODELX, PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, 102 0}, 103 {0, 0, 0} 104}; 105#endif /* XSERVER_LIBPCIACCESS */ 106 107/* driver record contains the functions needed by the server after loading 108 * the driver module. 109 */ 110_X_EXPORT DriverRec AMD = { 111 GEODE_VERSION, 112 "amd", 113 AmdIdentify, 114#ifdef XSERVER_LIBPCIACCESS 115 NULL, 116#else 117 AmdProbe, 118#endif 119 AmdAvailableOptions, 120 NULL, 121 0, 122 NULL, 123#ifdef XSERVER_LIBPCIACCESS 124 amdDeviceMatch, 125 AmdPciProbe 126#endif 127}; 128 129_X_EXPORT DriverRec GEODE = { 130 GEODE_VERSION, 131 "geode", 132 AmdIdentify, 133#ifdef XSERVER_LIBPCIACCESS 134 NULL, 135#else 136 AmdProbe, 137#endif 138 AmdAvailableOptions, 139 NULL, 140 0, 141 NULL, 142#ifdef XSERVER_LIBPCIACCESS 143 amdDeviceMatch, 144 AmdPciProbe 145#endif 146}; 147 148/* Advanced Micro Devices Chip Models */ 149typedef struct _DEVICE_MODEL 150{ 151 int DeviceId; 152 int Model; 153} 154DeviceModel; 155 156DeviceModel ChipModel[] = { 157#ifdef HAVE_LX 158 {PCI_CHIP_GEODELX, LX}, 159#endif 160#ifdef HAVE_GX 161 {PCI_CHIP_GEODEGX, GX}, 162#endif 163 {-1, 0} 164}; 165 166/* Supported chipsets */ 167SymTabRec GeodeChipsets[] = { 168#ifdef HAVE_LX 169 {PCI_CHIP_GEODELX, "Geode LX"}, 170#endif 171#ifdef HAVE_GX 172 {PCI_CHIP_GEODEGX, "Geode GX"}, 173#endif 174 {-1, NULL} 175}; 176 177PciChipsets GeodePCIchipsets[] = { 178#ifdef HAVE_LX 179 {PCI_CHIP_GEODELX, PCI_CHIP_GEODELX, RES_SHARED_VGA}, 180#endif 181#ifdef HAVE_GX 182 {PCI_CHIP_GEODEGX, PCI_CHIP_GEODEGX, RES_SHARED_VGA}, 183#endif 184 {-1, -1, RES_UNDEFINED}, 185}; 186 187#ifdef HAVE_LX 188 189OptionInfoRec LX_GeodeOptions[] = { 190 {LX_OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE}, 191 {LX_OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE}, 192 {LX_OPTION_NOCOMPRESSION, "NoCompression", OPTV_BOOLEAN, {0}, FALSE}, 193 {LX_OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE}, 194 {LX_OPTION_TV_SUPPORT, "TV", OPTV_ANYSTR, {0}, FALSE}, 195 {LX_OPTION_TV_OUTPUT, "TV_Output", OPTV_ANYSTR, {0}, FALSE}, 196 {LX_OPTION_TV_OVERSCAN, "TVOverscan", OPTV_ANYSTR, {0}, FALSE}, 197 {LX_OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE}, 198 {LX_OPTION_NOPANEL, "NoPanel", OPTV_BOOLEAN, {0}, FALSE}, 199 {LX_OPTION_EXA_SCRATCH_BFRSZ, "ExaScratch", OPTV_INTEGER, {0}, FALSE}, 200 {LX_OPTION_FBSIZE, "FBSize", OPTV_INTEGER, {0}, FALSE}, 201 {LX_OPTION_PANEL_MODE, "PanelMode", OPTV_STRING, {0}, FALSE}, 202 {-1, NULL, OPTV_NONE, {0}, FALSE} 203}; 204 205#endif 206 207#ifdef HAVE_GX 208 209OptionInfoRec GX_GeodeOptions[] = { 210 {GX_OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE}, 211 {GX_OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE}, 212 {GX_OPTION_NOCOMPRESSION, "NoCompression", OPTV_BOOLEAN, {0}, FALSE}, 213 {GX_OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE}, 214 {GX_OPTION_ACCEL_METHOD, "AccelMethod", OPTV_STRING, {0}, FALSE}, 215 {GX_OPTION_TV_SUPPORT, "TV", OPTV_ANYSTR, {0}, FALSE}, 216 {GX_OPTION_TV_OUTPUT, "TV_Output", OPTV_ANYSTR, {0}, FALSE}, 217 {GX_OPTION_TV_OVERSCAN, "TVOverscan", OPTV_ANYSTR, {0}, FALSE}, 218 {GX_OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE}, 219 {GX_OPTION_NOPANEL, "NoPanel", OPTV_BOOLEAN, {0}, FALSE}, 220 {GX_OPTION_OSM_IMG_BUFS, "OSMImageBuffers", OPTV_INTEGER, {0}, FALSE}, 221 {GX_OPTION_OSM_CLR_BUFS, "OSMColorExpBuffers", OPTV_INTEGER, {0}, FALSE}, 222 {GX_OPTION_FBSIZE, "FBSize", OPTV_INTEGER, {0}, FALSE}, 223 {GX_OPTION_PANEL_GEOMETRY, "PanelGeometry", OPTV_STRING, {0}, FALSE}, 224 {-1, NULL, OPTV_NONE, {0}, FALSE} 225}; 226#endif 227 228OptionInfoRec no_GeodeOptions[] = { 229 {-1, NULL, OPTV_NONE, {0}, FALSE} 230}; 231 232#ifdef XFree86LOADER 233 234/* Module loader interface */ 235 236static MODULESETUPPROTO(AmdSetup); 237 238static XF86ModuleVersionInfo AmdVersionRec = { 239 "amd", 240 MODULEVENDORSTRING, 241 MODINFOSTRING1, 242 MODINFOSTRING2, 243 XORG_VERSION_CURRENT, 244 GEODE_VERSION_MAJOR, GEODE_VERSION_MINOR, GEODE_VERSION_PATCH, 245 ABI_CLASS_VIDEODRV, /* This is a video driver */ 246 ABI_VIDEODRV_VERSION, 247 MOD_CLASS_VIDEODRV, 248 {0, 0, 0, 0} 249}; 250 251static XF86ModuleVersionInfo GeodeVersionRec = { 252 "geode", 253 MODULEVENDORSTRING, 254 MODINFOSTRING1, 255 MODINFOSTRING2, 256 XORG_VERSION_CURRENT, 257 GEODE_VERSION_MAJOR, GEODE_VERSION_MINOR, GEODE_VERSION_PATCH, 258 ABI_CLASS_VIDEODRV, /* This is a video driver */ 259 ABI_VIDEODRV_VERSION, 260 MOD_CLASS_VIDEODRV, 261 {0, 0, 0, 0} 262}; 263 264static pointer 265GeodeSetup(pointer Module, pointer Options, int *ErrorMajor, int *ErrorMinor) 266{ 267 static Bool init = FALSE; 268 int flag = 0; 269 270#ifdef XSERVER_LIBPCIACCESS 271 flag = HaveDriverFuncs; 272#endif 273 if (init) { 274 *ErrorMajor = LDR_ONCEONLY; 275 return (pointer) NULL; 276 } 277 278 init = TRUE; 279 xf86AddDriver(&GEODE, Module, flag); 280 281 return (pointer) TRUE; 282} 283 284static pointer 285AmdSetup(pointer Module, pointer Options, int *ErrorMajor, int *ErrorMinor) 286{ 287 static Bool Initialised = FALSE; 288 289 if (!Initialised) { 290 Initialised = TRUE; 291 xf86AddDriver(&AMD, Module, 292#ifdef XSERVER_LIBPCIACCESS 293 HaveDriverFuncs 294#else 295 0 296#endif 297 ); 298 299 return (pointer) TRUE; 300 } 301 302 /*The return value must be non-NULL on success */ 303 if (ErrorMajor) 304 *ErrorMajor = LDR_ONCEONLY; 305 return NULL; 306} 307 308_X_EXPORT XF86ModuleData amdModuleData = { &AmdVersionRec, AmdSetup, NULL }; 309_X_EXPORT XF86ModuleData geodeModuleData = 310 { &GeodeVersionRec, GeodeSetup, NULL }; 311 312#endif /*End of XFree86Loader */ 313 314/*------------------------------------------------------------------------- 315 * AmdIdentify. 316 * 317 * Description : This function identify an Amdfamily version. 318 * 319 * 320 * Parameters. 321 * flags : flags may be used in PreInit* 322 * 323 * Returns : none 324 * 325 * Comments : none 326 * 327*------------------------------------------------------------------------ 328*/ 329static void 330AmdIdentify(int flags) 331{ 332 xf86PrintChipsets(GEODE_NAME, "Driver for AMD Geode Chipsets", 333 GeodeChipsets); 334} 335 336/*---------------------------------------------------------------------------- 337 * AmdAvailableOptions. 338 * 339 * Description :This function returns the geodeoptions set geodeoption 340 * 341 * Parameters. 342 * chipid :This will identify the chipset. 343 * busid :This will identify the PCI busid 344 * 345 * Returns :ptr to GeodeOptions. 346 * 347 * Comments :none 348 * 349*---------------------------------------------------------------------------- 350*/ 351static const OptionInfoRec * 352AmdAvailableOptions(int chipid, int busid) 353{ 354 switch (chipid) { 355#ifdef HAVE_LX 356 case PCI_CHIP_GEODELX: 357 return LX_GeodeOptions; 358#endif 359#ifdef HAVE_GX 360 case PCI_CHIP_GEODEGX: 361 return GX_GeodeOptions; 362#endif 363 } 364 return no_GeodeOptions; 365} 366 367#ifdef XSERVER_LIBPCIACCESS 368 369static Bool 370AmdPciProbe(DriverPtr driver, 371 int entity_num, struct pci_device *device, intptr_t match_data) 372{ 373 ScrnInfoPtr scrn = NULL; 374 int cpu_detected; 375 376 ErrorF("AmdPciProbe: Probing for supported devices!\n"); 377 378 scrn = xf86ConfigPciEntity(scrn, 0, entity_num, GeodePCIchipsets, 379 NULL, NULL, NULL, NULL, NULL); 380 381 if (scrn != NULL) { 382 scrn->driverName = GEODE_DRIVER_NAME; 383 scrn->driverVersion = GEODE_VERSION; 384 scrn->name = GEODE_NAME; 385 scrn->Probe = NULL; 386 387 switch (device->device_id) { 388#ifdef HAVE_LX 389 case PCI_CHIP_GEODELX: 390 cpu_detected = LX; 391 LXSetupChipsetFPtr(scrn); 392 break; 393#endif 394#ifdef HAVE_GX 395 case PCI_CHIP_GEODEGX: 396 cpu_detected = GX; 397 GXSetupChipsetFPtr(scrn); 398 break; 399#endif 400 default: 401 ErrorF("AmdPciProbe: unknown device ID\n"); 402 return FALSE; 403 } 404 405 DEBUGMSG(1, (0, X_INFO, "AmdPciProbe: CPUDetected %d!\n", 406 cpu_detected)); 407 } 408 return scrn != NULL; 409} 410 411#else /* XSERVER_LIBPCIACCESS */ 412 413/*---------------------------------------------------------------------------- 414 * AmdProbe. 415 * 416 * Description :This is to find that hardware is claimed by another 417 * driver if not claim the slot & allocate ScreenInfoRec. 418 * 419 * Parameters. 420 * drv :a pointer to the geode driver 421 * flags :flags may passed to check the config and probe detect 422 * 423 * Returns :TRUE on success and FALSE on failure. 424 * 425 * Comments :This should be minimal probe and it should under no 426 * circumstances change the state of the hardware.Don't do 427 * any intiallizations other than the required 428 * ScreenInforec. 429*---------------------------------------------------------------------------- 430*/ 431 432static Bool 433AmdProbe(DriverPtr drv, int flags) 434{ 435 Bool foundScreen = FALSE; 436 int numDevSections, numUsed; 437 GDevPtr *devSections = NULL; 438 int *usedChips = NULL; 439 int i; 440 void (*drvr_setup) (ScrnInfoPtr pScrni) = NULL; 441 int CPUDetected; 442 443 DEBUGMSG(1, (0, X_INFO, "AmdProbe: Probing for supported devices!\n")); 444 /* 445 * * Find the config file Device sections that match this 446 * * driver, and return if there are none. 447 */ 448 if ((numDevSections = xf86MatchDevice(GEODE_NAME, &devSections)) <= 0) { 449 DEBUGMSG(1, (0, X_INFO, "AmdProbe: failed 1!\n")); 450 return FALSE; 451 } 452 DEBUGMSG(1, (0, X_INFO, "AmdProbe: Before MatchPciInstances!\n")); 453 /* PCI BUS */ 454 if (xf86GetPciVideoInfo()) { 455 numUsed = xf86MatchPciInstances(GEODE_NAME, PCI_VENDOR_ID_NS, 456 GeodeChipsets, GeodePCIchipsets, 457 devSections, numDevSections, drv, &usedChips); 458 459 if (numUsed <= 0) 460 numUsed = xf86MatchPciInstances(GEODE_NAME, PCI_VENDOR_ID_AMD, 461 GeodeChipsets, GeodePCIchipsets, 462 devSections, numDevSections, drv, &usedChips); 463 464 DEBUGMSG(1, (0, X_INFO, "AmdProbe: MatchPCI (%d)!\n", numUsed)); 465 466 if (numUsed > 0) { 467 if (flags & PROBE_DETECT) 468 foundScreen = TRUE; 469 else { 470 /* Durango only supports one instance, */ 471 /* so take the first one */ 472 for (i = 0; i < numUsed; i++) { 473 /* Allocate a ScrnInfoRec */ 474 ScrnInfoPtr pScrni = NULL; 475 EntityInfoPtr pEnt = xf86GetEntityInfo(usedChips[i]); 476 PciChipsets *p_id; 477 478 pScrni = xf86ConfigPciEntity(pScrni, 0, usedChips[i], 479 GeodePCIchipsets, NULL, NULL, NULL, NULL, NULL); 480 for (p_id = GeodePCIchipsets; p_id->numChipset != -1; 481 p_id++) { 482 if (pEnt->chipset == p_id->numChipset) { 483 switch (pEnt->chipset) { 484#ifdef HAVE_LX 485 case PCI_CHIP_GEODELX: 486 CPUDetected = LX; 487 drvr_setup = &LXSetupChipsetFPtr; 488 break; 489#endif 490#ifdef HAVE_GX 491 case PCI_CHIP_GEODEGX: 492 CPUDetected = GX; 493 drvr_setup = &GXSetupChipsetFPtr; 494 break; 495#endif 496 default: 497 break; 498 } 499 break; 500 } 501 } 502 free(pEnt); 503 if (drvr_setup == NULL) 504 return FALSE; 505 506 DEBUGMSG(1, (0, X_INFO, "AmdProbe: CPUDetected %d!\n", 507 CPUDetected)); 508 509 pScrni->driverName = GEODE_DRIVER_NAME; 510 pScrni->driverVersion = GEODE_VERSION; 511 pScrni->name = GEODE_NAME; 512 pScrni->Probe = AmdProbe; 513 drvr_setup(pScrni); 514 515 foundScreen = TRUE; 516 517 } 518 } 519 } 520 } 521 522 if (usedChips) 523 free(usedChips); 524 if (devSections) 525 free(devSections); 526 DEBUGMSG(1, (0, X_INFO, "AmdProbe: result (%d)!\n", foundScreen)); 527 return foundScreen; 528} 529 530#endif /* else XSERVER_LIBPCIACCESS */ 531