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