diff options
Diffstat (limited to 'src/amd_driver.c')
-rw-r--r-- | src/amd_driver.c | 531 |
1 files changed, 531 insertions, 0 deletions
diff --git a/src/amd_driver.c b/src/amd_driver.c new file mode 100644 index 0000000..20f1729 --- /dev/null +++ b/src/amd_driver.c @@ -0,0 +1,531 @@ +/* + * Copyright (c) 2006 Advanced 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. + * + */ + +/* Includes that are used by all drivers */ +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" +#include "xf86Resources.h" +#include "compiler.h" +#include "xf86PciInfo.h" +#include "xf86Pci.h" +#include "xf86cmap.h" + +#include "amd.h" +#include "build_num.h" + +#define RC_MAX_DEPTH 24 + +/* Frame buffer stuff */ +#if CFB +/* + * If using cfb, cfb.h is required. Select the others for the bpp values + * the driver supports. + */ +#define PSZ 8 /* needed for cfb.h */ +#include "cfb.h" +#undef PSZ +#include "cfb16.h" +#include "cfb24.h" +#include "cfb32.h" +#else +#include "fb.h" +#endif + +#include "shadowfb.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 "extensions/xf86dgastr.h" +#endif /* XFreeXDGA */ + +#ifdef DPMSExtension +#include "globals.h" +#include "opaque.h" +#define DPMS_SERVER +#include "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); +static Bool AmdProbe(DriverPtr, int); +static int CPUDetected; + +/* driver record contains the functions needed by the server after loading + * the driver module. + */ +DriverRec AMD = { + AMD_VERSION_CURRENT, + AMD_DRIVER_NAME, + AmdIdentify, + AmdProbe, + AmdAvailableOptions, + NULL, + 0 +}; + +/* 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_TV_ENCODER, "TV_Encoder", OPTV_ANYSTR, {0}, FALSE}, + {LX_OPTION_TV_BUS_FMT, "TV_Bus_Fmt", OPTV_ANYSTR, {0}, FALSE}, + {LX_OPTION_TV_FLAGS, "TV_Flags", OPTV_ANYSTR, {0}, FALSE}, + {LX_OPTION_TV_601_FLAGS, "TV_601_Flags", OPTV_ANYSTR, {0}, FALSE}, + {LX_OPTION_TV_VSYNC_SELECT, "TV_Vsync_Select", OPTV_ANYSTR, {0}, FALSE}, + {LX_OPTION_TV_CONVERSION, "TV_Conversion", OPTV_ANYSTR, {0}, FALSE}, + {LX_OPTION_TV_OVERSCAN, "TV_Overscan", OPTV_ANYSTR, {0}, FALSE}, + {LX_OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE}, + {LX_OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE}, + {LX_OPTION_FLATPANEL, "FlatPanel", OPTV_BOOLEAN, {0}, FALSE}, + {LX_OPTION_CRTENABLE, "CrtEnable", OPTV_BOOLEAN, {0}, FALSE}, + {LX_OPTION_COLOR_KEY, "ColorKey", OPTV_INTEGER, {0}, FALSE}, + {LX_OPTION_OSM_IMG_BUFS, "OSMImageBuffers", OPTV_INTEGER, {0}, FALSE}, + {LX_OPTION_OSM_CLR_BUFS, "OSMColorExpBuffers", OPTV_INTEGER, {0}, FALSE}, + {LX_OPTION_CUSTOM_MODE, "CustomMode", OPTV_BOOLEAN, {0}, FALSE}, + {LX_OPTION_FP_DEST_GEOM, "FPDestGeom", OPTV_ANYSTR, {0}, FALSE}, + {LX_OPTION_FP_ACTIVE_GEOM, "FPActiveGeom", OPTV_ANYSTR, {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_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE}, + {GX_OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE}, + {GX_OPTION_FLATPANEL, "FlatPanel", 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_CUSTOM_MODE, "CustomMode", OPTV_BOOLEAN, {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 +}; + +#if CFB +const char *amdCfbSymbols[] = { + "cfbScreenInit", + "cfb16ScreenInit", + "cfb24ScreenInit", + "cfb32ScreenInit", + NULL +}; +#else +const char *amdFbSymbols[] = { + "fbScreenInit", + "fbPictureInit", + NULL +}; +#endif + +const char *amdXaaSymbols[] = { + "XAADestroyInfoRec", + "XAACreateInfoRec", + "XAAInit", + "XAAScreenIndex", + NULL +}; + +const char *amdExaSymbols[] = { + "exaGetVersion", + "exaDriverInit", + "exaDriverFini", + "exaOffscreenAlloc", + "exaOffscreenFree", + NULL +}; + +const char *amdRamdacSymbols[] = { + "xf86InitCursor", + "xf86CreateCursorInfoRec", + "xf86DestroyCursorInfoRec", + NULL +}; + +const char *amdShadowSymbols[] = { + "ShadowFBInit", + NULL +}; + +#ifdef XFree86LOADER + +/* Module loader interface */ + +static MODULESETUPPROTO(AmdSetup); + +static XF86ModuleVersionInfo AmdVersionRec = { + "amd", + MODULEVENDORSTRING, + MODINFOSTRING1, + MODINFOSTRING2, + XF86_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} +}; + +/* + * This data is accessed by the loader. The name must be the module name + * followed by "ModuleInit". + */ +XF86ModuleData amdModuleData = { &AmdVersionRec, AmdSetup, NULL }; + +/*------------------------------------------------------------------------- + * AmdSetup. + * + * Description :This function sets up the driver in X list and load the + * module symbols through xf86loader routines.. + * + * Parameters. + * Module :Pointer to the geode module + * options :Driver module options. + * ErrorMajor:Major no + * ErrorMinor:Minor no. + * + * Returns :NULL on success + * + * Comments :Module setup is done by this function + * + *------------------------------------------------------------------------- +*/ +static pointer +AmdSetup(pointer Module, pointer Options, int *ErrorMajor, int *ErrorMinor) +{ + static Bool Initialised = FALSE; + + if (!Initialised) { + Initialised = TRUE; + xf86AddDriver(&AMD, Module, 0); + /* Tell the loader about symbols from other modules that this + * module might refer to. + */ + LoaderRefSymLists(amdVgahwSymbols, amdVbeSymbols, +#if CFB + amdCfbSymbols, +#else + amdFbSymbols, +#endif + amdXaaSymbols, + amdInt10Symbols, amdRamdacSymbols, amdShadowSymbols, NULL); + return (pointer) TRUE; + } + + /*The return value must be non-NULL on success */ + if (ErrorMajor) + *ErrorMajor = LDR_ONCEONLY; + return 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; +} + +/*---------------------------------------------------------------------------- + * 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); + + 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: + return FALSE; + } + break; + } + } + xfree(pEnt); + 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; +} |