summaryrefslogtreecommitdiff
path: root/src/geode_driver.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/geode_driver.c')
-rw-r--r--src/geode_driver.c612
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 */