diff options
Diffstat (limited to 'src/geode_driver.c')
-rw-r--r-- | src/geode_driver.c | 612 |
1 files changed, 612 insertions, 0 deletions
diff --git a/src/geode_driver.c b/src/geode_driver.c new file mode 100644 index 0000000..303f865 --- /dev/null +++ b/src/geode_driver.c @@ -0,0 +1,612 @@ +/* + * Copyright (c) 2006 Avanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Neither the name of the Advanced Micro Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + */ + +/* + * File Contents: This is the main module configures the interfacing + * with the X server. The individual modules will be + * loaded based upon the options selected from the + * XF86Config. This file also has modules for finding + * supported modes, turning on the modes based on options. + * + * Project: Amd Xfree Frame buffer device driver. + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/* Includes that are used by all drivers */ +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86Resources.h" +#include "compiler.h" +#include "xf86PciInfo.h" +#include "xf86Pci.h" +#include "xf86cmap.h" + +#include "geode.h" +#include "build_num.h" + +#define RC_MAX_DEPTH 24 + +#include "fb.h" + +/* Machine independent stuff */ +#include "mipointer.h" +#include "mibank.h" +#include "micmap.h" +/* All drivers implementing backing store need this */ +#include "mibstore.h" +#include "vgaHW.h" +#include "vbe.h" + +/* Check for some extensions */ +#ifdef XFreeXDGA +#define _XF86_DGA_SERVER_ +#include <X11/extensions/xf86dgastr.h> +#endif /* XFreeXDGA */ + +#ifdef DPMSExtension +#include "globals.h" +#include "opaque.h" +#define DPMS_SERVER +#include <X11/extensions/dpms.h> +#endif /* DPMSExtension */ + +/* A few things all drivers should have */ +#define AMD_NAME "AMD" +#define AMD_DRIVER_NAME "amd" +#define _id(n,m) n##m +#define _cat(n,m) _id(n,m) +#define AMD_VERSION_CURRENT ((_cat(0x,_MAJOR) << 24) | \ + (_cat(0x,_MINOR) << 16) | (_cat(0x,_BL) << 8) \ + | _cat(0x,_BLREV)) + +/* Forward definitions */ +static const OptionInfoRec *AmdAvailableOptions(int chipid, int busid); +static void AmdIdentify(int); + +#ifdef XSERVER_LIBPCIACCESS +static Bool AmdPciProbe(DriverPtr, int, struct pci_device *, intptr_t); +#else +static Bool AmdProbe(DriverPtr, int); +#endif + +#ifdef XSERVER_LIBPCIACCESS +static const struct pci_id_match amdDeviceMatch[] = { + {PCI_VENDOR_ID_NS, PCI_CHIP_REDCLOUD, PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, + 0}, + {PCI_VENDOR_ID_AMD, PCI_CHIP_GEODELX, PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, + 0}, + {0, 0, 0} +}; +#endif /* XSERVER_LIBPCIACCESS */ + +/* driver record contains the functions needed by the server after loading + * the driver module. + */ +_X_EXPORT DriverRec AMD = { + AMD_VERSION_CURRENT, + "amd", + AmdIdentify, +#ifdef XSERVER_LIBPCIACCESS + NULL, +#else + AmdProbe, +#endif + AmdAvailableOptions, + NULL, + 0, + NULL, +#ifdef XSERVER_LIBPCIACCESS + amdDeviceMatch, + AmdPciProbe +#endif +}; + +_X_EXPORT DriverRec GEODE = { + AMD_VERSION_CURRENT, + "geode", + AmdIdentify, +#ifdef XSERVER_LIBPCIACCESS + NULL, +#else + AmdProbe, +#endif + AmdAvailableOptions, + NULL, + 0, + NULL, +#ifdef XSERVER_LIBPCIACCESS + amdDeviceMatch, + AmdPciProbe +#endif +}; + +/* Advanced Micro Devices Chip Models */ +typedef struct _DEVICE_MODEL +{ + int DeviceId; + int Model; +} +DeviceModel; + +DeviceModel ChipModel[] = { +#ifdef HAVE_LX + {PCI_CHIP_GEODELX, LX}, +#endif +#ifdef HAVE_GX + {PCI_CHIP_REDCLOUD, GX2}, +#endif + {-1, 0} +}; + +/* Supported chipsets */ +SymTabRec GeodeChipsets[] = { +#ifdef HAVE_LX + {PCI_CHIP_GEODELX, "GeodeLX"}, +#endif +#ifdef HAVE_GX + {PCI_CHIP_REDCLOUD, "REDCLOUD"}, +#endif + {-1, NULL} +}; + +PciChipsets GeodePCIchipsets[] = { +#ifdef HAVE_LX + {PCI_CHIP_GEODELX, PCI_CHIP_GEODELX, RES_SHARED_VGA}, +#endif +#ifdef HAVE_GX + {PCI_CHIP_REDCLOUD, PCI_CHIP_REDCLOUD, RES_SHARED_VGA}, +#endif + {-1, -1, RES_UNDEFINED}, +}; + +#ifdef HAVE_LX +void LXSetupChipsetFPtr(ScrnInfoPtr pScrni); + +OptionInfoRec LX_GeodeOptions[] = { + {LX_OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE}, + {LX_OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE}, + {LX_OPTION_NOCOMPRESSION, "NoCompression", OPTV_BOOLEAN, {0}, FALSE}, + {LX_OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE}, + {LX_OPTION_ACCEL_METHOD, "AccelMethod", OPTV_STRING, {0}, FALSE}, + {LX_OPTION_TV_SUPPORT, "TV", OPTV_ANYSTR, {0}, FALSE}, + {LX_OPTION_TV_OUTPUT, "TV_Output", OPTV_ANYSTR, {0}, FALSE}, + {LX_OPTION_TV_OVERSCAN, "TVOverscan", OPTV_ANYSTR, {0}, FALSE}, + {LX_OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE}, + {LX_OPTION_NOPANEL, "NoPanel", OPTV_BOOLEAN, {0}, FALSE}, + {LX_OPTION_COLOR_KEY, "ColorKey", OPTV_INTEGER, {0}, FALSE}, + {LX_OPTION_EXA_SCRATCH_BFRSZ, "ExaScratch", OPTV_INTEGER, {0}, FALSE}, + {LX_OPTION_FBSIZE, "FBSize", OPTV_INTEGER, {0}, FALSE}, + {LX_OPTION_PANEL_GEOMETRY, "PanelGeometry", OPTV_STRING, {0}, FALSE}, + {-1, NULL, OPTV_NONE, {0}, FALSE} +}; + +#endif + +#ifdef HAVE_GX +void GXSetupChipsetFPtr(ScrnInfoPtr pScrni); + +OptionInfoRec GX_GeodeOptions[] = { + {GX_OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE}, + {GX_OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE}, + {GX_OPTION_NOCOMPRESSION, "NoCompression", OPTV_BOOLEAN, {0}, FALSE}, + {GX_OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE}, + {GX_OPTION_ACCEL_METHOD, "AccelMethod", OPTV_STRING, {0}, FALSE}, + {GX_OPTION_TV_SUPPORT, "TV", OPTV_ANYSTR, {0}, FALSE}, + {GX_OPTION_TV_OUTPUT, "TV_Output", OPTV_ANYSTR, {0}, FALSE}, + {GX_OPTION_TV_OVERSCAN, "TVOverscan", OPTV_ANYSTR, {0}, FALSE}, + {GX_OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE}, + {GX_OPTION_NOPANEL, "NoPanel", OPTV_BOOLEAN, {0}, FALSE}, + {GX_OPTION_COLOR_KEY, "ColorKey", OPTV_INTEGER, {0}, FALSE}, + {GX_OPTION_OSM_IMG_BUFS, "OSMImageBuffers", OPTV_INTEGER, {0}, FALSE}, + {GX_OPTION_OSM_CLR_BUFS, "OSMColorExpBuffers", OPTV_INTEGER, {0}, FALSE}, + {GX_OPTION_FBSIZE, "FBSize", OPTV_INTEGER, {0}, FALSE}, + {GX_OPTION_PANEL_GEOMETRY, "PanelGeometry", OPTV_STRING, {0}, FALSE}, + {-1, NULL, OPTV_NONE, {0}, FALSE} +}; +#endif + +OptionInfoRec no_GeodeOptions[] = { + {-1, NULL, OPTV_NONE, {0}, FALSE} +}; + +/* List of symbols from other modules that this module references.The purpose +* is that to avoid unresolved symbol warnings +*/ +const char *amdVgahwSymbols[] = { + "vgaHWGetHWRec", + "vgaHWUnlock", + "vgaHWInit", + "vgaHWSave", + "vgaHWRestore", + "vgaHWProtect", + "vgaHWGetIOBase", + "vgaHWMapMem", + "vgaHWLock", + "vgaHWFreeHWRec", + "vgaHWSaveScreen", + NULL +}; + +const char *amdVbeSymbols[] = { + "VBEInit", + "vbeDoEDID", + "vbeFree", + NULL +}; + +const char *amdInt10Symbols[] = { + "xf86ExecX86int10", + "xf86InitInt10", + "xf86Int10AllocPages", + "xf86Int10Addr", + NULL +}; + +const char *amdFbSymbols[] = { + "fbScreenInit", + "fbPictureInit", + NULL +}; + +const char *amdXaaSymbols[] = { + "XAADestroyInfoRec", + "XAACreateInfoRec", + "XAAInit", + "XAAScreenIndex", + NULL +}; + +const char *amdExaSymbols[] = { + "exaGetVersion", + "exaDriverInit", + "exaDriverFini", + "exaOffscreenAlloc", + "exaOffscreenFree", + NULL +}; + +const char *amdRamdacSymbols[] = { + "xf86InitCursor", + "xf86CreateCursorInfoRec", + "xf86DestroyCursorInfoRec", + NULL +}; + +#ifdef XFree86LOADER + +/* Module loader interface */ + +static MODULESETUPPROTO(AmdSetup); + +static XF86ModuleVersionInfo AmdVersionRec = { + "amd", + MODULEVENDORSTRING, + MODINFOSTRING1, + MODINFOSTRING2, + XORG_VERSION_CURRENT, + GET_MODULE_MAJOR_VERSION(AMD_VERSION_CURRENT), + GET_MODULE_MINOR_VERSION(AMD_VERSION_CURRENT), + (GET_MODULE_PATCHLEVEL(AMD_VERSION_CURRENT) >> 8) * 100 + + (GET_MODULE_PATCHLEVEL(AMD_VERSION_CURRENT) & 0xff), + ABI_CLASS_VIDEODRV, /* This is a video driver */ + ABI_VIDEODRV_VERSION, + MOD_CLASS_VIDEODRV, + {0, 0, 0, 0} +}; + +static XF86ModuleVersionInfo GeodeVersionRec = { + "geode", + MODULEVENDORSTRING, + MODINFOSTRING1, + MODINFOSTRING2, + XORG_VERSION_CURRENT, + GET_MODULE_MAJOR_VERSION(AMD_VERSION_CURRENT), + GET_MODULE_MINOR_VERSION(AMD_VERSION_CURRENT), + (GET_MODULE_PATCHLEVEL(AMD_VERSION_CURRENT) >> 8) * 100 + + (GET_MODULE_PATCHLEVEL(AMD_VERSION_CURRENT) & 0xff), + ABI_CLASS_VIDEODRV, /* This is a video driver */ + ABI_VIDEODRV_VERSION, + MOD_CLASS_VIDEODRV, + {0, 0, 0, 0} +}; + +static pointer +GeodeSetup(pointer Module, pointer Options, int *ErrorMajor, int *ErrorMinor) +{ + static Bool init = FALSE; + int flag = 0; + +#ifdef XSERVER_LIBPCIACCESS + flag = HaveDriverFuncs; +#endif + if (init) { + *ErrorMajor = LDR_ONCEONLY; + return (pointer) NULL; + } + + init = TRUE; + xf86AddDriver(&GEODE, Module, flag); + + LoaderRefSymLists(amdVgahwSymbols, amdVbeSymbols, + amdFbSymbols, amdXaaSymbols, amdInt10Symbols, amdRamdacSymbols, NULL); + + return (pointer) TRUE; +} + +static pointer +AmdSetup(pointer Module, pointer Options, int *ErrorMajor, int *ErrorMinor) +{ + static Bool Initialised = FALSE; + + if (!Initialised) { + Initialised = TRUE; + xf86AddDriver(&AMD, Module, +#ifdef XSERVER_LIBPCIACCESS + HaveDriverFuncs +#else + 0 +#endif + ); + + /* Tell the loader about symbols from other modules that this + * module might refer to. + */ + LoaderRefSymLists(amdVgahwSymbols, amdVbeSymbols, + amdFbSymbols, amdXaaSymbols, + amdInt10Symbols, amdRamdacSymbols, NULL); + return (pointer) TRUE; + } + + /*The return value must be non-NULL on success */ + if (ErrorMajor) + *ErrorMajor = LDR_ONCEONLY; + return NULL; +} + +_X_EXPORT XF86ModuleData amdModuleData = { &AmdVersionRec, AmdSetup, NULL }; +_X_EXPORT XF86ModuleData geodeModuleData = + { &GeodeVersionRec, GeodeSetup, NULL }; + +#endif /*End of XFree86Loader */ + +/*------------------------------------------------------------------------- + * AmdIdentify. + * + * Description : This function identify an Amdfamily version. + * + * + * Parameters. + * flags : flags may be used in PreInit* + * + * Returns : none + * + * Comments : none + * +*------------------------------------------------------------------------ +*/ +static void +AmdIdentify(int flags) +{ + xf86PrintChipsets(AMD_NAME, AMD_VERSION " for chipsets ", GeodeChipsets); +} + +/*---------------------------------------------------------------------------- + * AmdAvailableOptions. + * + * Description :This function returns the geodeoptions set geodeoption + * + * Parameters. + * chipid :This will identify the chipset. + * busid :This will identify the PCI busid + * + * Returns :ptr to GeodeOptions. + * + * Comments :none + * +*---------------------------------------------------------------------------- +*/ +static const OptionInfoRec * +AmdAvailableOptions(int chipid, int busid) +{ + switch (chipid) { +#ifdef HAVE_LX + case PCI_CHIP_GEODELX: + return LX_GeodeOptions; +#endif +#ifdef HAVE_GX + case PCI_CHIP_REDCLOUD: + return GX_GeodeOptions; +#endif + } + return no_GeodeOptions; +} + +#ifdef XSERVER_LIBPCIACCESS + +static Bool +AmdPciProbe(DriverPtr driver, + int entity_num, struct pci_device *device, intptr_t match_data) +{ + ScrnInfoPtr scrn = NULL; + int cpu_detected; + + ErrorF("AmdPciProbe: Probing for supported devices!\n"); + + scrn = xf86ConfigPciEntity(scrn, 0, entity_num, GeodePCIchipsets, + NULL, NULL, NULL, NULL, NULL); + + if (scrn != NULL) { + scrn->driverName = AMD_DRIVER_NAME; + scrn->name = AMD_NAME; + scrn->Probe = NULL; + + switch (device->device_id) { +#ifdef HAVE_LX + case PCI_CHIP_GEODELX: + cpu_detected = LX; + LXSetupChipsetFPtr(scrn); + break; +#endif +#ifdef HAVE_GX + case PCI_CHIP_REDCLOUD: + cpu_detected = GX2; + GXSetupChipsetFPtr(scrn); + break; +#endif + default: + ErrorF("AmdPciProbe: unknown device ID\n"); + return FALSE; + } + + DEBUGMSG(1, (0, X_INFO, "AmdPciProbe: CPUDetected %d!\n", + cpu_detected)); + } + return scrn != NULL; +} + +#else /* XSERVER_LIBPCIACCESS */ + +/*---------------------------------------------------------------------------- + * AmdProbe. + * + * Description :This is to find that hardware is claimed by another + * driver if not claim the slot & allocate ScreenInfoRec. + * + * Parameters. + * drv :a pointer to the geode driver + * flags :flags may passed to check the config and probe detect + * + * Returns :TRUE on success and FALSE on failure. + * + * Comments :This should ne minimal probe and it should under no + * circumstances change the state of the hardware.Don't do + * any intiallizations other than the required + * ScreenInforec. +*---------------------------------------------------------------------------- +*/ + +static Bool +AmdProbe(DriverPtr drv, int flags) +{ + Bool foundScreen = FALSE; + int numDevSections, numUsed; + GDevPtr *devSections = NULL; + int *usedChips = NULL; + int i; + void (*drvr_setup) (ScrnInfoPtr pScrni) = NULL; + int CPUDetected; + + DEBUGMSG(1, (0, X_INFO, "AmdProbe: Probing for supported devices!\n")); + /* + * * Find the config file Device sections that match this + * * driver, and return if there are none. + */ + if ((numDevSections = xf86MatchDevice(AMD_NAME, &devSections)) <= 0) { + DEBUGMSG(1, (0, X_INFO, "AmdProbe: failed 1!\n")); + return FALSE; + } + DEBUGMSG(1, (0, X_INFO, "AmdProbe: Before MatchPciInstances!\n")); + /* PCI BUS */ + if (xf86GetPciVideoInfo()) { + numUsed = xf86MatchPciInstances(AMD_NAME, PCI_VENDOR_ID_NS, + GeodeChipsets, GeodePCIchipsets, + devSections, numDevSections, drv, &usedChips); + + if (numUsed <= 0) + numUsed = xf86MatchPciInstances(AMD_NAME, PCI_VENDOR_ID_AMD, + GeodeChipsets, GeodePCIchipsets, + devSections, numDevSections, drv, &usedChips); + + DEBUGMSG(1, (0, X_INFO, "AmdProbe: MatchPCI (%d)!\n", numUsed)); + + if (numUsed > 0) { + if (flags & PROBE_DETECT) + foundScreen = TRUE; + else { + /* Durango only supports one instance, */ + /* so take the first one */ + for (i = 0; i < numUsed; i++) { + /* Allocate a ScrnInfoRec */ + ScrnInfoPtr pScrni = xf86AllocateScreen(drv, 0); + + EntityInfoPtr pEnt = xf86GetEntityInfo(usedChips[i]); + PciChipsets *p_id; + + for (p_id = GeodePCIchipsets; p_id->numChipset != -1; + p_id++) { + if (pEnt->chipset == p_id->numChipset) { + switch (pEnt->chipset) { +#ifdef HAVE_LX + case PCI_CHIP_GEODELX: + CPUDetected = LX; + drvr_setup = &LXSetupChipsetFPtr; + break; +#endif +#ifdef HAVE_GX + case PCI_CHIP_REDCLOUD: + CPUDetected = GX2; + drvr_setup = &GXSetupChipsetFPtr; + break; +#endif + default: + break; + } + break; + } + } + xfree(pEnt); + if (drvr_setup == NULL) + return FALSE; + + DEBUGMSG(1, (0, X_INFO, "AmdProbe: CPUDetected %d!\n", + CPUDetected)); + + pScrni->driverName = AMD_DRIVER_NAME; + pScrni->name = AMD_NAME; + pScrni->Probe = AmdProbe; + drvr_setup(pScrni); + + foundScreen = TRUE; + xf86ConfigActivePciEntity(pScrni, usedChips[i], + GeodePCIchipsets, NULL, NULL, NULL, NULL, NULL); + } + } + } + } + + if (usedChips) + xfree(usedChips); + if (devSections) + xfree(devSections); + DEBUGMSG(1, (0, X_INFO, "AmdProbe: result (%d)!\n", foundScreen)); + return foundScreen; +} + +#endif /* else XSERVER_LIBPCIACCESS */ |