summaryrefslogtreecommitdiff
path: root/src/amd_driver.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/amd_driver.c')
-rw-r--r--src/amd_driver.c531
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;
+}