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