geode_driver.c revision f29dbc25
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 "mibank.h" 62#include "micmap.h" 63/* All drivers implementing backing store need this */ 64#include "mibstore.h" 65#include "vgaHW.h" 66#include "vbe.h" 67 68#ifdef DPMSExtension 69#include "globals.h" 70#include "opaque.h" 71#ifdef HAVE_XEXTPROTO_71 72#include <X11/extensions/dpmsconst.h> 73#else 74#define DPMS_SERVER 75#include <X11/extensions/dpms.h> 76#endif 77 78#endif /* DPMSExtension */ 79 80/* A few things all drivers should have */ 81#define GEODE_NAME "GEODE" 82#define GEODE_DRIVER_NAME "geode" 83#define GEODE_VERSION 4000 84#define GEODE_VERSION_MAJOR PACKAGE_VERSION_MAJOR 85#define GEODE_VERSION_MINOR PACKAGE_VERSION_MINOR 86#define GEODE_VERSION_PATCH PACKAGE_VERSION_PATCHLEVEL 87 88/* Forward definitions */ 89static const OptionInfoRec *AmdAvailableOptions(int chipid, int busid); 90static void AmdIdentify(int); 91 92#ifdef XSERVER_LIBPCIACCESS 93static Bool AmdPciProbe(DriverPtr, int, struct pci_device *, intptr_t); 94#else 95static Bool AmdProbe(DriverPtr, int); 96#endif 97 98#ifdef XSERVER_LIBPCIACCESS 99static const struct pci_id_match amdDeviceMatch[] = { 100 {PCI_VENDOR_ID_NS, PCI_CHIP_GEODEGX, PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, 101 0}, 102 {PCI_VENDOR_ID_AMD, PCI_CHIP_GEODELX, PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, 103 0}, 104 {0, 0, 0} 105}; 106#endif /* XSERVER_LIBPCIACCESS */ 107 108/* driver record contains the functions needed by the server after loading 109 * the driver module. 110 */ 111_X_EXPORT DriverRec AMD = { 112 GEODE_VERSION, 113 "amd", 114 AmdIdentify, 115#ifdef XSERVER_LIBPCIACCESS 116 NULL, 117#else 118 AmdProbe, 119#endif 120 AmdAvailableOptions, 121 NULL, 122 0, 123 NULL, 124#ifdef XSERVER_LIBPCIACCESS 125 amdDeviceMatch, 126 AmdPciProbe 127#endif 128}; 129 130_X_EXPORT DriverRec GEODE = { 131 GEODE_VERSION, 132 "geode", 133 AmdIdentify, 134#ifdef XSERVER_LIBPCIACCESS 135 NULL, 136#else 137 AmdProbe, 138#endif 139 AmdAvailableOptions, 140 NULL, 141 0, 142 NULL, 143#ifdef XSERVER_LIBPCIACCESS 144 amdDeviceMatch, 145 AmdPciProbe 146#endif 147}; 148 149/* Advanced Micro Devices Chip Models */ 150typedef struct _DEVICE_MODEL 151{ 152 int DeviceId; 153 int Model; 154} 155DeviceModel; 156 157DeviceModel ChipModel[] = { 158#ifdef HAVE_LX 159 {PCI_CHIP_GEODELX, LX}, 160#endif 161#ifdef HAVE_GX 162 {PCI_CHIP_GEODEGX, GX}, 163#endif 164 {-1, 0} 165}; 166 167/* Supported chipsets */ 168SymTabRec GeodeChipsets[] = { 169#ifdef HAVE_LX 170 {PCI_CHIP_GEODELX, "Geode LX"}, 171#endif 172#ifdef HAVE_GX 173 {PCI_CHIP_GEODEGX, "Geode GX"}, 174#endif 175 {-1, NULL} 176}; 177 178PciChipsets GeodePCIchipsets[] = { 179#ifdef HAVE_LX 180 {PCI_CHIP_GEODELX, PCI_CHIP_GEODELX, RES_SHARED_VGA}, 181#endif 182#ifdef HAVE_GX 183 {PCI_CHIP_GEODEGX, PCI_CHIP_GEODEGX, RES_SHARED_VGA}, 184#endif 185 {-1, -1, RES_UNDEFINED}, 186}; 187 188#ifdef HAVE_LX 189 190OptionInfoRec LX_GeodeOptions[] = { 191 {LX_OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE}, 192 {LX_OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE}, 193 {LX_OPTION_NOCOMPRESSION, "NoCompression", OPTV_BOOLEAN, {0}, FALSE}, 194 {LX_OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE}, 195 {LX_OPTION_TV_SUPPORT, "TV", OPTV_ANYSTR, {0}, FALSE}, 196 {LX_OPTION_TV_OUTPUT, "TV_Output", OPTV_ANYSTR, {0}, FALSE}, 197 {LX_OPTION_TV_OVERSCAN, "TVOverscan", OPTV_ANYSTR, {0}, FALSE}, 198 {LX_OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE}, 199 {LX_OPTION_NOPANEL, "NoPanel", OPTV_BOOLEAN, {0}, FALSE}, 200 {LX_OPTION_EXA_SCRATCH_BFRSZ, "ExaScratch", OPTV_INTEGER, {0}, FALSE}, 201 {LX_OPTION_FBSIZE, "FBSize", OPTV_INTEGER, {0}, FALSE}, 202 {LX_OPTION_PANEL_MODE, "PanelMode", OPTV_STRING, {0}, FALSE}, 203 {-1, NULL, OPTV_NONE, {0}, FALSE} 204}; 205 206#endif 207 208#ifdef HAVE_GX 209 210OptionInfoRec GX_GeodeOptions[] = { 211 {GX_OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE}, 212 {GX_OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE}, 213 {GX_OPTION_NOCOMPRESSION, "NoCompression", OPTV_BOOLEAN, {0}, FALSE}, 214 {GX_OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE}, 215 {GX_OPTION_ACCEL_METHOD, "AccelMethod", OPTV_STRING, {0}, FALSE}, 216 {GX_OPTION_TV_SUPPORT, "TV", OPTV_ANYSTR, {0}, FALSE}, 217 {GX_OPTION_TV_OUTPUT, "TV_Output", OPTV_ANYSTR, {0}, FALSE}, 218 {GX_OPTION_TV_OVERSCAN, "TVOverscan", OPTV_ANYSTR, {0}, FALSE}, 219 {GX_OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE}, 220 {GX_OPTION_NOPANEL, "NoPanel", OPTV_BOOLEAN, {0}, FALSE}, 221 {GX_OPTION_OSM_IMG_BUFS, "OSMImageBuffers", OPTV_INTEGER, {0}, FALSE}, 222 {GX_OPTION_OSM_CLR_BUFS, "OSMColorExpBuffers", OPTV_INTEGER, {0}, FALSE}, 223 {GX_OPTION_FBSIZE, "FBSize", OPTV_INTEGER, {0}, FALSE}, 224 {GX_OPTION_PANEL_GEOMETRY, "PanelGeometry", OPTV_STRING, {0}, FALSE}, 225 {-1, NULL, OPTV_NONE, {0}, FALSE} 226}; 227#endif 228 229OptionInfoRec no_GeodeOptions[] = { 230 {-1, NULL, OPTV_NONE, {0}, FALSE} 231}; 232 233#ifdef XFree86LOADER 234 235/* Module loader interface */ 236 237static MODULESETUPPROTO(AmdSetup); 238 239static XF86ModuleVersionInfo AmdVersionRec = { 240 "amd", 241 MODULEVENDORSTRING, 242 MODINFOSTRING1, 243 MODINFOSTRING2, 244 XORG_VERSION_CURRENT, 245 GEODE_VERSION_MAJOR, GEODE_VERSION_MINOR, GEODE_VERSION_PATCH, 246 ABI_CLASS_VIDEODRV, /* This is a video driver */ 247 ABI_VIDEODRV_VERSION, 248 MOD_CLASS_VIDEODRV, 249 {0, 0, 0, 0} 250}; 251 252static XF86ModuleVersionInfo GeodeVersionRec = { 253 "geode", 254 MODULEVENDORSTRING, 255 MODINFOSTRING1, 256 MODINFOSTRING2, 257 XORG_VERSION_CURRENT, 258 GEODE_VERSION_MAJOR, GEODE_VERSION_MINOR, GEODE_VERSION_PATCH, 259 ABI_CLASS_VIDEODRV, /* This is a video driver */ 260 ABI_VIDEODRV_VERSION, 261 MOD_CLASS_VIDEODRV, 262 {0, 0, 0, 0} 263}; 264 265static pointer 266GeodeSetup(pointer Module, pointer Options, int *ErrorMajor, int *ErrorMinor) 267{ 268 static Bool init = FALSE; 269 int flag = 0; 270 271#ifdef XSERVER_LIBPCIACCESS 272 flag = HaveDriverFuncs; 273#endif 274 if (init) { 275 *ErrorMajor = LDR_ONCEONLY; 276 return (pointer) NULL; 277 } 278 279 init = TRUE; 280 xf86AddDriver(&GEODE, Module, flag); 281 282 return (pointer) TRUE; 283} 284 285static pointer 286AmdSetup(pointer Module, pointer Options, int *ErrorMajor, int *ErrorMinor) 287{ 288 static Bool Initialised = FALSE; 289 290 if (!Initialised) { 291 Initialised = TRUE; 292 xf86AddDriver(&AMD, Module, 293#ifdef XSERVER_LIBPCIACCESS 294 HaveDriverFuncs 295#else 296 0 297#endif 298 ); 299 300 return (pointer) TRUE; 301 } 302 303 /*The return value must be non-NULL on success */ 304 if (ErrorMajor) 305 *ErrorMajor = LDR_ONCEONLY; 306 return NULL; 307} 308 309_X_EXPORT XF86ModuleData amdModuleData = { &AmdVersionRec, AmdSetup, NULL }; 310_X_EXPORT XF86ModuleData geodeModuleData = 311 { &GeodeVersionRec, GeodeSetup, NULL }; 312 313#endif /*End of XFree86Loader */ 314 315/*------------------------------------------------------------------------- 316 * AmdIdentify. 317 * 318 * Description : This function identify an Amdfamily version. 319 * 320 * 321 * Parameters. 322 * flags : flags may be used in PreInit* 323 * 324 * Returns : none 325 * 326 * Comments : none 327 * 328*------------------------------------------------------------------------ 329*/ 330static void 331AmdIdentify(int flags) 332{ 333 xf86PrintChipsets(GEODE_NAME, "Driver for AMD Geode Chipsets", 334 GeodeChipsets); 335} 336 337/*---------------------------------------------------------------------------- 338 * AmdAvailableOptions. 339 * 340 * Description :This function returns the geodeoptions set geodeoption 341 * 342 * Parameters. 343 * chipid :This will identify the chipset. 344 * busid :This will identify the PCI busid 345 * 346 * Returns :ptr to GeodeOptions. 347 * 348 * Comments :none 349 * 350*---------------------------------------------------------------------------- 351*/ 352static const OptionInfoRec * 353AmdAvailableOptions(int chipid, int busid) 354{ 355 switch (chipid) { 356#ifdef HAVE_LX 357 case PCI_CHIP_GEODELX: 358 return LX_GeodeOptions; 359#endif 360#ifdef HAVE_GX 361 case PCI_CHIP_GEODEGX: 362 return GX_GeodeOptions; 363#endif 364 } 365 return no_GeodeOptions; 366} 367 368#ifdef XSERVER_LIBPCIACCESS 369 370static Bool 371AmdPciProbe(DriverPtr driver, 372 int entity_num, struct pci_device *device, intptr_t match_data) 373{ 374 ScrnInfoPtr scrn = NULL; 375 int cpu_detected; 376 377 ErrorF("AmdPciProbe: Probing for supported devices!\n"); 378 379 scrn = xf86ConfigPciEntity(scrn, 0, entity_num, GeodePCIchipsets, 380 NULL, NULL, NULL, NULL, NULL); 381 382 if (scrn != NULL) { 383 scrn->driverName = GEODE_DRIVER_NAME; 384 scrn->driverVersion = GEODE_VERSION; 385 scrn->name = GEODE_NAME; 386 scrn->Probe = NULL; 387 388 switch (device->device_id) { 389#ifdef HAVE_LX 390 case PCI_CHIP_GEODELX: 391 cpu_detected = LX; 392 LXSetupChipsetFPtr(scrn); 393 break; 394#endif 395#ifdef HAVE_GX 396 case PCI_CHIP_GEODEGX: 397 cpu_detected = GX; 398 GXSetupChipsetFPtr(scrn); 399 break; 400#endif 401 default: 402 ErrorF("AmdPciProbe: unknown device ID\n"); 403 return FALSE; 404 } 405 406 DEBUGMSG(1, (0, X_INFO, "AmdPciProbe: CPUDetected %d!\n", 407 cpu_detected)); 408 } 409 return scrn != NULL; 410} 411 412#else /* XSERVER_LIBPCIACCESS */ 413 414/*---------------------------------------------------------------------------- 415 * AmdProbe. 416 * 417 * Description :This is to find that hardware is claimed by another 418 * driver if not claim the slot & allocate ScreenInfoRec. 419 * 420 * Parameters. 421 * drv :a pointer to the geode driver 422 * flags :flags may passed to check the config and probe detect 423 * 424 * Returns :TRUE on success and FALSE on failure. 425 * 426 * Comments :This should be minimal probe and it should under no 427 * circumstances change the state of the hardware.Don't do 428 * any intiallizations other than the required 429 * ScreenInforec. 430*---------------------------------------------------------------------------- 431*/ 432 433static Bool 434AmdProbe(DriverPtr drv, int flags) 435{ 436 Bool foundScreen = FALSE; 437 int numDevSections, numUsed; 438 GDevPtr *devSections = NULL; 439 int *usedChips = NULL; 440 int i; 441 void (*drvr_setup) (ScrnInfoPtr pScrni) = NULL; 442 int CPUDetected; 443 444 DEBUGMSG(1, (0, X_INFO, "AmdProbe: Probing for supported devices!\n")); 445 /* 446 * * Find the config file Device sections that match this 447 * * driver, and return if there are none. 448 */ 449 if ((numDevSections = xf86MatchDevice(GEODE_NAME, &devSections)) <= 0) { 450 DEBUGMSG(1, (0, X_INFO, "AmdProbe: failed 1!\n")); 451 return FALSE; 452 } 453 DEBUGMSG(1, (0, X_INFO, "AmdProbe: Before MatchPciInstances!\n")); 454 /* PCI BUS */ 455 if (xf86GetPciVideoInfo()) { 456 numUsed = xf86MatchPciInstances(GEODE_NAME, PCI_VENDOR_ID_NS, 457 GeodeChipsets, GeodePCIchipsets, 458 devSections, numDevSections, drv, &usedChips); 459 460 if (numUsed <= 0) 461 numUsed = xf86MatchPciInstances(GEODE_NAME, PCI_VENDOR_ID_AMD, 462 GeodeChipsets, GeodePCIchipsets, 463 devSections, numDevSections, drv, &usedChips); 464 465 DEBUGMSG(1, (0, X_INFO, "AmdProbe: MatchPCI (%d)!\n", numUsed)); 466 467 if (numUsed > 0) { 468 if (flags & PROBE_DETECT) 469 foundScreen = TRUE; 470 else { 471 /* Durango only supports one instance, */ 472 /* so take the first one */ 473 for (i = 0; i < numUsed; i++) { 474 /* Allocate a ScrnInfoRec */ 475 ScrnInfoPtr pScrni = NULL; 476 EntityInfoPtr pEnt = xf86GetEntityInfo(usedChips[i]); 477 PciChipsets *p_id; 478 479 pScrni = xf86ConfigPciEntity(pScrni, 0, usedChips[i], 480 GeodePCIchipsets, NULL, NULL, NULL, NULL, NULL); 481 for (p_id = GeodePCIchipsets; p_id->numChipset != -1; 482 p_id++) { 483 if (pEnt->chipset == p_id->numChipset) { 484 switch (pEnt->chipset) { 485#ifdef HAVE_LX 486 case PCI_CHIP_GEODELX: 487 CPUDetected = LX; 488 drvr_setup = &LXSetupChipsetFPtr; 489 break; 490#endif 491#ifdef HAVE_GX 492 case PCI_CHIP_GEODEGX: 493 CPUDetected = GX; 494 drvr_setup = &GXSetupChipsetFPtr; 495 break; 496#endif 497 default: 498 break; 499 } 500 break; 501 } 502 } 503 xfree(pEnt); 504 if (drvr_setup == NULL) 505 return FALSE; 506 507 DEBUGMSG(1, (0, X_INFO, "AmdProbe: CPUDetected %d!\n", 508 CPUDetected)); 509 510 pScrni->driverName = GEODE_DRIVER_NAME; 511 pScrni->driverVersion = GEODE_VERSION; 512 pScrni->name = GEODE_NAME; 513 pScrni->Probe = AmdProbe; 514 drvr_setup(pScrni); 515 516 foundScreen = TRUE; 517 518 } 519 } 520 } 521 } 522 523 if (usedChips) 524 xfree(usedChips); 525 if (devSections) 526 xfree(devSections); 527 DEBUGMSG(1, (0, X_INFO, "AmdProbe: result (%d)!\n", foundScreen)); 528 return foundScreen; 529} 530 531#endif /* else XSERVER_LIBPCIACCESS */ 532