aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/hw
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2012-07-09 08:17:19 +0200
committermarha <marha@users.sourceforge.net>2012-07-09 08:17:19 +0200
commit98fa64178af8ad608e19391053b40b0772466c64 (patch)
tree841e3eebe0277bdf98441dd45224c039e069d3b8 /xorg-server/hw
parent405ae9defaaa03d4d305b6264a744107c3dd460d (diff)
parentc29d91cfd8df084f16d0d2dfa82c3a86f7719a73 (diff)
downloadvcxsrv-98fa64178af8ad608e19391053b40b0772466c64.tar.gz
vcxsrv-98fa64178af8ad608e19391053b40b0772466c64.tar.bz2
vcxsrv-98fa64178af8ad608e19391053b40b0772466c64.zip
Merge remote-tracking branch 'origin/released'
Conflicts: xorg-server/dix/dispatch.c xorg-server/include/misc.h
Diffstat (limited to 'xorg-server/hw')
-rw-r--r--xorg-server/hw/xfree86/common/Makefile.am8
-rw-r--r--xorg-server/hw/xfree86/common/xf86.h8
-rw-r--r--xorg-server/hw/xfree86/common/xf86AutoConfig.c9
-rw-r--r--xorg-server/hw/xfree86/common/xf86Bus.c22
-rw-r--r--xorg-server/hw/xfree86/common/xf86Bus.h1
-rw-r--r--xorg-server/hw/xfree86/common/xf86Config.c15
-rw-r--r--xorg-server/hw/xfree86/common/xf86Globals.c11
-rw-r--r--xorg-server/hw/xfree86/common/xf86Helper.c111
-rw-r--r--xorg-server/hw/xfree86/common/xf86Init.c42
-rw-r--r--xorg-server/hw/xfree86/common/xf86Priv.h2
-rw-r--r--xorg-server/hw/xfree86/common/xf86Privstr.h2
-rw-r--r--xorg-server/hw/xfree86/common/xf86fbBus.c4
-rw-r--r--xorg-server/hw/xfree86/common/xf86pciBus.c41
-rw-r--r--xorg-server/hw/xfree86/common/xf86pciBus.h10
-rw-r--r--xorg-server/hw/xfree86/common/xf86platformBus.c489
-rw-r--r--xorg-server/hw/xfree86/common/xf86platformBus.h64
-rw-r--r--xorg-server/hw/xfree86/common/xf86str.h12
-rw-r--r--xorg-server/hw/xfree86/modes/xf86EdidModes.c13
-rw-r--r--xorg-server/hw/xfree86/os-support/linux/Makefile.am2
-rw-r--r--xorg-server/hw/xfree86/os-support/linux/lnx_platform.c179
-rw-r--r--xorg-server/hw/xfree86/os-support/shared/platform_noop.c23
-rw-r--r--xorg-server/hw/xfree86/os-support/xf86_OSproc.h6
-rw-r--r--xorg-server/hw/xfree86/ramdac/xf86Cursor.c31
23 files changed, 1036 insertions, 69 deletions
diff --git a/xorg-server/hw/xfree86/common/Makefile.am b/xorg-server/hw/xfree86/common/Makefile.am
index 27921777d..65d98e694 100644
--- a/xorg-server/hw/xfree86/common/Makefile.am
+++ b/xorg-server/hw/xfree86/common/Makefile.am
@@ -22,9 +22,13 @@ if DGA
DGASOURCES = xf86DGA.c
endif
+if XORG_BUS_PLATFORM
+PLATSOURCES = xf86platformBus.c
+endif
+
RANDRSOURCES = xf86RandR.c
-BUSSOURCES = xf86fbBus.c xf86noBus.c $(PCI_SOURCES) $(SBUS_SOURCES)
+BUSSOURCES = xf86fbBus.c xf86noBus.c $(PCI_SOURCES) $(SBUS_SOURCES) $(PLATSOURCES)
MODEDEFSOURCES = $(srcdir)/vesamodes $(srcdir)/extramodes
@@ -56,7 +60,7 @@ sdk_HEADERS = compiler.h fourcc.h xf86.h xf86Module.h xf86Opt.h \
xf86PciInfo.h xf86Priv.h xf86Privstr.h \
xf86cmap.h xf86fbman.h xf86str.h xf86Xinput.h xisb.h \
$(XVSDKINCS) $(XF86VMODE_SDK) xorgVersion.h \
- xf86sbusBus.h xf86VGAarbiter.h xf86Optionstr.h
+ xf86sbusBus.h xf86VGAarbiter.h xf86Optionstr.h xf86platformBus.h
DISTCLEANFILES = xf86Build.h
CLEANFILES = $(BUILT_SOURCES)
diff --git a/xorg-server/hw/xfree86/common/xf86.h b/xorg-server/hw/xfree86/common/xf86.h
index 129660d81..61169857f 100644
--- a/xorg-server/hw/xfree86/common/xf86.h
+++ b/xorg-server/hw/xfree86/common/xf86.h
@@ -71,6 +71,11 @@ extern _X_EXPORT Bool fbSlotClaimed;
#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
extern _X_EXPORT Bool sbusSlotClaimed;
#endif
+
+#if defined(XSERVER_PLATFORM_BUS)
+extern _X_EXPORT int platformSlotClaimed;
+#endif
+
extern _X_EXPORT confDRIRec xf86ConfigDRI;
extern _X_EXPORT Bool xf86DRI2Enabled(void);
@@ -460,4 +465,7 @@ extern _X_EXPORT ScreenPtr xf86ScrnToScreen(ScrnInfoPtr pScrn);
#define XF86_SCRN_INTERFACE 1 /* define for drivers to use in api compat */
+/* flags passed to xf86 allocate screen */
+#define XF86_ALLOCATE_GPU_SCREEN 1
+
#endif /* _XF86_H */
diff --git a/xorg-server/hw/xfree86/common/xf86AutoConfig.c b/xorg-server/hw/xfree86/common/xf86AutoConfig.c
index d0eb0affb..271ce86b6 100644
--- a/xorg-server/hw/xfree86/common/xf86AutoConfig.c
+++ b/xorg-server/hw/xfree86/common/xf86AutoConfig.c
@@ -198,10 +198,13 @@ listPossibleVideoDrivers(char *matches[], int nmatches)
}
i = 0;
+#ifdef XSERVER_PLATFORM_BUS
+ i = xf86PlatformMatchDriver(matches, nmatches);
+#endif
#ifdef sun
/* Check for driver type based on /dev/fb type and if valid, use
it instead of PCI bus probe results */
- if (xf86Info.consoleFd >= 0) {
+ if (xf86Info.consoleFd >= 0 && (i < (nmatches - 1))) {
struct vis_identifier visid;
const char *cp;
extern char xf86SolarisFbDev[PATH_MAX];
@@ -251,6 +254,7 @@ listPossibleVideoDrivers(char *matches[], int nmatches)
}
#endif
#ifdef __sparc__
+ if (i < (nmatches - 1))
{
char *sbusDriver = sparcDriverName();
@@ -259,7 +263,8 @@ listPossibleVideoDrivers(char *matches[], int nmatches)
}
#endif
#ifdef XSERVER_LIBPCIACCESS
- i = xf86PciMatchDriver(matches, nmatches);
+ if (i < (nmatches - 1))
+ i = xf86PciMatchDriver(matches, nmatches);
#endif
/* Fallback to platform default hardware */
if (i < (nmatches - 1)) {
diff --git a/xorg-server/hw/xfree86/common/xf86Bus.c b/xorg-server/hw/xfree86/common/xf86Bus.c
index 6c86f5e26..6de8409fc 100644
--- a/xorg-server/hw/xfree86/common/xf86Bus.c
+++ b/xorg-server/hw/xfree86/common/xf86Bus.c
@@ -77,8 +77,14 @@ xf86CallDriverProbe(DriverPtr drv, Bool detect_only)
{
Bool foundScreen = FALSE;
+#ifdef XSERVER_PLATFORM_BUS
+ if (drv->platformProbe != NULL) {
+ foundScreen = xf86platformProbeDev(drv);
+ }
+#endif
+
#ifdef XSERVER_LIBPCIACCESS
- if (drv->PciProbe != NULL) {
+ if (!foundScreen && (drv->PciProbe != NULL)) {
if (xf86DoConfigure && xf86DoConfigurePass1) {
assert(detect_only);
foundScreen = xf86PciAddMatchingDev(drv);
@@ -183,6 +189,10 @@ xf86BusConfig(void)
}
}
+ /* bind GPU conf screen to protocol screen 0 */
+ for (i = 0; i < xf86NumGPUScreens; i++)
+ xf86GPUScreens[i]->confScreen = xf86Screens[0]->confScreen;
+
/* If no screens left, return now. */
if (xf86NumScreens == 0) {
xf86Msg(X_ERROR,
@@ -202,6 +212,9 @@ xf86BusConfig(void)
void
xf86BusProbe(void)
{
+#ifdef XSERVER_PLATFORM_BUS
+ xf86platformProbe();
+#endif
#ifdef XSERVER_LIBPCIACCESS
xf86PciProbe();
#endif
@@ -238,6 +251,8 @@ StringToBusType(const char *busID, const char **retID)
ret = BUS_PCI;
if (!xf86NameCmp(p, "sbus"))
ret = BUS_SBUS;
+ if (!xf86NameCmp(p, "platform"))
+ ret = BUS_PLATFORM;
if (ret != BUS_NONE)
if (retID)
*retID = busID + strlen(p) + 1;
@@ -270,6 +285,8 @@ xf86IsEntityPrimary(int entityIndex)
return pEnt->bus.id.pci == primaryBus.id.pci;
case BUS_SBUS:
return pEnt->bus.id.sbus.fbNum == primaryBus.id.sbus.fbNum;
+ case BUS_PLATFORM:
+ return pEnt->bus.id.plat == primaryBus.id.plat;
default:
return FALSE;
}
@@ -541,6 +558,9 @@ xf86PostProbe(void)
#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
sbusSlotClaimed ||
#endif
+#ifdef XSERVER_PLATFORM_BUS
+ platformSlotClaimed ||
+#endif
#ifdef XSERVER_LIBPCIACCESS
pciSlotClaimed
#else
diff --git a/xorg-server/hw/xfree86/common/xf86Bus.h b/xorg-server/hw/xfree86/common/xf86Bus.h
index abf2efd1a..e83ba780a 100644
--- a/xorg-server/hw/xfree86/common/xf86Bus.h
+++ b/xorg-server/hw/xfree86/common/xf86Bus.h
@@ -42,6 +42,7 @@
#if defined(__sparc__) || defined(__sparc)
#include "xf86sbusBus.h"
#endif
+#include "xf86platformBus.h"
typedef struct {
DriverPtr driver;
diff --git a/xorg-server/hw/xfree86/common/xf86Config.c b/xorg-server/hw/xfree86/common/xf86Config.c
index 3ec40fe9b..6b806a372 100644
--- a/xorg-server/hw/xfree86/common/xf86Config.c
+++ b/xorg-server/hw/xfree86/common/xf86Config.c
@@ -712,7 +712,8 @@ typedef enum {
FLAG_AUTO_ENABLE_DEVICES,
FLAG_GLX_VISUALS,
FLAG_DRI2,
- FLAG_USE_SIGIO
+ FLAG_USE_SIGIO,
+ FLAG_AUTO_ADD_GPU,
} FlagValues;
/**
@@ -770,6 +771,8 @@ static OptionInfoRec FlagOptions[] = {
{0}, FALSE},
{FLAG_USE_SIGIO, "UseSIGIO", OPTV_BOOLEAN,
{0}, FALSE},
+ {FLAG_AUTO_ADD_GPU, "AutoAddGPU", OPTV_BOOLEAN,
+ {0}, FALSE},
{-1, NULL, OPTV_NONE,
{0}, FALSE},
};
@@ -862,6 +865,16 @@ configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts)
xf86Msg(from, "%sutomatically enabling devices\n",
xf86Info.autoEnableDevices ? "A" : "Not a");
+ if (xf86IsOptionSet(FlagOptions, FLAG_AUTO_ADD_GPU)) {
+ xf86GetOptValBool(FlagOptions, FLAG_AUTO_ADD_GPU,
+ &xf86Info.autoAddGPU);
+ from = X_CONFIG;
+ }
+ else {
+ from = X_DEFAULT;
+ }
+ xf86Msg(from, "%sutomatically adding GPU devices\n",
+ xf86Info.autoAddGPU ? "A" : "Not a");
/*
* Set things up based on the config file information. Some of these
* settings may be overridden later when the command line options are
diff --git a/xorg-server/hw/xfree86/common/xf86Globals.c b/xorg-server/hw/xfree86/common/xf86Globals.c
index 0071004eb..7df7a80c4 100644
--- a/xorg-server/hw/xfree86/common/xf86Globals.c
+++ b/xorg-server/hw/xfree86/common/xf86Globals.c
@@ -51,6 +51,7 @@ DevPrivateKeyRec xf86CreateRootWindowKeyRec;
DevPrivateKeyRec xf86ScreenKeyRec;
ScrnInfoPtr *xf86Screens = NULL; /* List of ScrnInfos */
+ScrnInfoPtr *xf86GPUScreens = NULL; /* List of ScrnInfos */
const unsigned char byte_reversed[256] = {
0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
@@ -125,11 +126,16 @@ xf86InfoRec xf86Info = {
#if defined(CONFIG_HAL) || defined(CONFIG_UDEV) || defined(CONFIG_WSCONS)
.forceInputDevices = FALSE,
.autoAddDevices = TRUE,
- .autoEnableDevices = TRUE
+ .autoEnableDevices = TRUE,
#else
.forceInputDevices = TRUE,
.autoAddDevices = FALSE,
- .autoEnableDevices = FALSE
+ .autoEnableDevices = FALSE,
+#endif
+#if defined(CONFIG_UDEV_KMS)
+ .autoAddGPU = TRUE,
+#else
+ .autoAddGPU = FALSE,
#endif
};
@@ -153,6 +159,7 @@ int xf86NumDrivers = 0;
InputDriverPtr *xf86InputDriverList = NULL;
int xf86NumInputDrivers = 0;
int xf86NumScreens = 0;
+int xf86NumGPUScreens = 0;
const char *xf86VisualNames[] = {
"StaticGray",
diff --git a/xorg-server/hw/xfree86/common/xf86Helper.c b/xorg-server/hw/xfree86/common/xf86Helper.c
index 5ef1dabfb..f681a8577 100644
--- a/xorg-server/hw/xfree86/common/xf86Helper.c
+++ b/xorg-server/hw/xfree86/common/xf86Helper.c
@@ -167,29 +167,43 @@ ScrnInfoPtr
xf86AllocateScreen(DriverPtr drv, int flags)
{
int i;
+ ScrnInfoPtr pScrn;
- if (xf86Screens == NULL)
- xf86NumScreens = 0;
-
- i = xf86NumScreens++;
- xf86Screens = xnfrealloc(xf86Screens, xf86NumScreens * sizeof(ScrnInfoPtr));
- xf86Screens[i] = xnfcalloc(sizeof(ScrnInfoRec), 1);
- xf86Screens[i]->scrnIndex = i; /* Changes when a screen is removed */
- xf86Screens[i]->origIndex = i; /* This never changes */
- xf86Screens[i]->privates = xnfcalloc(sizeof(DevUnion),
- xf86ScrnInfoPrivateCount);
+ if (flags & XF86_ALLOCATE_GPU_SCREEN) {
+ if (xf86GPUScreens == NULL)
+ xf86NumGPUScreens = 0;
+ i = xf86NumGPUScreens++;
+ xf86GPUScreens = xnfrealloc(xf86GPUScreens, xf86NumGPUScreens * sizeof(ScrnInfoPtr));
+ xf86GPUScreens[i] = xnfcalloc(sizeof(ScrnInfoRec), 1);
+ pScrn = xf86GPUScreens[i];
+ pScrn->scrnIndex = i + GPU_SCREEN_OFFSET; /* Changes when a screen is removed */
+ pScrn->is_gpu = TRUE;
+ } else {
+ if (xf86Screens == NULL)
+ xf86NumScreens = 0;
+
+ i = xf86NumScreens++;
+ xf86Screens = xnfrealloc(xf86Screens, xf86NumScreens * sizeof(ScrnInfoPtr));
+ xf86Screens[i] = xnfcalloc(sizeof(ScrnInfoRec), 1);
+ pScrn = xf86Screens[i];
+
+ pScrn->scrnIndex = i; /* Changes when a screen is removed */
+ }
+
+ pScrn->origIndex = pScrn->scrnIndex; /* This never changes */
+ pScrn->privates = xnfcalloc(sizeof(DevUnion), xf86ScrnInfoPrivateCount);
/*
* EnableDisableFBAccess now gets initialized in InitOutput()
- * xf86Screens[i]->EnableDisableFBAccess = xf86EnableDisableFBAccess;
+ * pScrn->EnableDisableFBAccess = xf86EnableDisableFBAccess;
*/
- xf86Screens[i]->drv = drv;
+ pScrn->drv = drv;
drv->refCount++;
- xf86Screens[i]->module = DuplicateModule(drv->module, NULL);
+ pScrn->module = DuplicateModule(drv->module, NULL);
- xf86Screens[i]->DriverFunc = drv->driverFunc;
+ pScrn->DriverFunc = drv->driverFunc;
- return xf86Screens[i];
+ return pScrn;
}
/*
@@ -202,10 +216,17 @@ xf86DeleteScreen(ScrnInfoPtr pScrn)
{
int i;
int scrnIndex;
-
- /* First check if the screen is valid */
- if (xf86NumScreens == 0 || xf86Screens == NULL)
- return;
+ Bool is_gpu = FALSE;
+ if (pScrn->is_gpu) {
+ /* First check if the screen is valid */
+ if (xf86NumGPUScreens == 0 || xf86GPUScreens == NULL)
+ return;
+ is_gpu = TRUE;
+ } else {
+ /* First check if the screen is valid */
+ if (xf86NumScreens == 0 || xf86Screens == NULL)
+ return;
+ }
if (!pScrn)
return;
@@ -237,12 +258,23 @@ xf86DeleteScreen(ScrnInfoPtr pScrn)
/* Move the other entries down, updating their scrnIndex fields */
- xf86NumScreens--;
+ if (is_gpu) {
+ xf86NumGPUScreens--;
+ scrnIndex -= GPU_SCREEN_OFFSET;
+ for (i = scrnIndex; i < xf86NumGPUScreens; i++) {
+ xf86GPUScreens[i] = xf86GPUScreens[i + 1];
+ xf86GPUScreens[i]->scrnIndex = i + GPU_SCREEN_OFFSET;
+ /* Also need to take care of the screen layout settings */
+ }
+ }
+ else {
+ xf86NumScreens--;
- for (i = scrnIndex; i < xf86NumScreens; i++) {
- xf86Screens[i] = xf86Screens[i + 1];
- xf86Screens[i]->scrnIndex = i;
- /* Also need to take care of the screen layout settings */
+ for (i = scrnIndex; i < xf86NumScreens; i++) {
+ xf86Screens[i] = xf86Screens[i + 1];
+ xf86Screens[i]->scrnIndex = i;
+ /* Also need to take care of the screen layout settings */
+ }
}
}
@@ -266,6 +298,14 @@ xf86AllocateScrnInfoPrivateIndex(void)
memset(&nprivs[idx], 0, sizeof(DevUnion));
pScr->privates = nprivs;
}
+ for (i = 0; i < xf86NumGPUScreens; i++) {
+ pScr = xf86GPUScreens[i];
+ nprivs = xnfrealloc(pScr->privates,
+ xf86ScrnInfoPrivateCount * sizeof(DevUnion));
+ /* Zero the new private */
+ memset(&nprivs[idx], 0, sizeof(DevUnion));
+ pScr->privates = nprivs;
+ }
return idx;
}
@@ -1058,6 +1098,11 @@ xf86VDrvMsgVerb(int scrnIndex, MessageType type, int verb, const char *format,
xf86Screens[scrnIndex]->name)
LogHdrMessageVerb(type, verb, format, args, "%s(%d): ",
xf86Screens[scrnIndex]->name, scrnIndex);
+ else if (scrnIndex >= GPU_SCREEN_OFFSET &&
+ scrnIndex < GPU_SCREEN_OFFSET + xf86NumGPUScreens &&
+ xf86GPUScreens[scrnIndex - GPU_SCREEN_OFFSET]->name)
+ LogHdrMessageVerb(type, verb, format, args, "%s(G%d): ",
+ xf86GPUScreens[scrnIndex - GPU_SCREEN_OFFSET]->name, scrnIndex - GPU_SCREEN_OFFSET);
else
LogVMessageVerb(type, verb, format, args);
}
@@ -1833,13 +1878,23 @@ xf86MotionHistoryAllocate(InputInfoPtr pInfo)
ScrnInfoPtr
xf86ScreenToScrn(ScreenPtr pScreen)
{
- assert(pScreen->myNum < xf86NumScreens);
- return xf86Screens[pScreen->myNum];
+ if (pScreen->isGPU) {
+ assert(pScreen->myNum - GPU_SCREEN_OFFSET < xf86NumGPUScreens);
+ return xf86GPUScreens[pScreen->myNum - GPU_SCREEN_OFFSET];
+ } else {
+ assert(pScreen->myNum < xf86NumScreens);
+ return xf86Screens[pScreen->myNum];
+ }
}
ScreenPtr
xf86ScrnToScreen(ScrnInfoPtr pScrn)
{
- assert(pScrn->scrnIndex < screenInfo.numScreens);
- return screenInfo.screens[pScrn->scrnIndex];
+ if (pScrn->is_gpu) {
+ assert(pScrn->scrnIndex - GPU_SCREEN_OFFSET < screenInfo.numGPUScreens);
+ return screenInfo.gpuscreens[pScrn->scrnIndex - GPU_SCREEN_OFFSET];
+ } else {
+ assert(pScrn->scrnIndex < screenInfo.numScreens);
+ return screenInfo.screens[pScrn->scrnIndex];
+ }
}
diff --git a/xorg-server/hw/xfree86/common/xf86Init.c b/xorg-server/hw/xfree86/common/xf86Init.c
index 1f5a382b7..aa17a58fd 100644
--- a/xorg-server/hw/xfree86/common/xf86Init.c
+++ b/xorg-server/hw/xfree86/common/xf86Init.c
@@ -593,6 +593,18 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
if (!xf86Screens[i]->configured)
xf86DeleteScreen(xf86Screens[i--]);
+ for (i = 0; i < xf86NumGPUScreens; i++) {
+ xf86VGAarbiterScrnInit(xf86GPUScreens[i]);
+ xf86VGAarbiterLock(xf86GPUScreens[i]);
+ if (xf86GPUScreens[i]->PreInit &&
+ xf86GPUScreens[i]->PreInit(xf86GPUScreens[i], 0))
+ xf86GPUScreens[i]->configured = TRUE;
+ xf86VGAarbiterUnlock(xf86GPUScreens[i]);
+ }
+ for (i = 0; i < xf86NumGPUScreens; i++)
+ if (!xf86GPUScreens[i]->configured)
+ xf86DeleteScreen(xf86GPUScreens[i--]);
+
/*
* If no screens left, return now.
*/
@@ -818,6 +830,36 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
!dixRegisterPrivateKey(&xf86CreateRootWindowKeyRec, PRIVATE_SCREEN, 0))
FatalError("Cannot register DDX private keys");
+ for (i = 0; i < xf86NumGPUScreens; i++) {
+ ScrnInfoPtr pScrn = xf86GPUScreens[i];
+ xf86VGAarbiterLock(pScrn);
+
+ /*
+ * Almost everything uses these defaults, and many of those that
+ * don't, will wrap them.
+ */
+ pScrn->EnableDisableFBAccess = xf86EnableDisableFBAccess;
+#ifdef XFreeXDGA
+ pScrn->SetDGAMode = xf86SetDGAMode;
+#endif
+ pScrn->DPMSSet = NULL;
+ pScrn->LoadPalette = NULL;
+ pScrn->SetOverscan = NULL;
+ pScrn->DriverFunc = NULL;
+ pScrn->pScreen = NULL;
+ scr_index = AddGPUScreen(pScrn->ScreenInit, argc, argv);
+ xf86VGAarbiterUnlock(pScrn);
+ if (scr_index == i) {
+ dixSetPrivate(&screenInfo.gpuscreens[scr_index]->devPrivates,
+ xf86ScreenKey, xf86GPUScreens[i]);
+ pScrn->pScreen = screenInfo.gpuscreens[scr_index];
+ /* The driver should set this, but make sure it is set anyway */
+ pScrn->vtSema = TRUE;
+ } else {
+ FatalError("AddScreen/ScreenInit failed for gpu driver %d %d\n", i, scr_index);
+ }
+ }
+
for (i = 0; i < xf86NumScreens; i++) {
xf86VGAarbiterLock(xf86Screens[i]);
/*
diff --git a/xorg-server/hw/xfree86/common/xf86Priv.h b/xorg-server/hw/xfree86/common/xf86Priv.h
index 42a3b30f0..c9f2e7eb8 100644
--- a/xorg-server/hw/xfree86/common/xf86Priv.h
+++ b/xorg-server/hw/xfree86/common/xf86Priv.h
@@ -95,6 +95,8 @@ extern _X_EXPORT Bool xorgHWAccess;
extern _X_EXPORT RootWinPropPtr *xf86RegisteredPropertiesTable;
+extern ScrnInfoPtr *xf86GPUScreens; /* List of pointers to ScrnInfoRecs */
+extern int xf86NumGPUScreens;
#ifndef DEFAULT_VERBOSE
#define DEFAULT_VERBOSE 0
#endif
diff --git a/xorg-server/hw/xfree86/common/xf86Privstr.h b/xorg-server/hw/xfree86/common/xf86Privstr.h
index e78cd407d..e20be03a9 100644
--- a/xorg-server/hw/xfree86/common/xf86Privstr.h
+++ b/xorg-server/hw/xfree86/common/xf86Privstr.h
@@ -110,6 +110,8 @@ typedef struct {
Bool dri2;
MessageType dri2From;
+
+ Bool autoAddGPU;
} xf86InfoRec, *xf86InfoPtr;
#ifdef DPMSExtension
diff --git a/xorg-server/hw/xfree86/common/xf86fbBus.c b/xorg-server/hw/xfree86/common/xf86fbBus.c
index 1e5162332..303b9c2f5 100644
--- a/xorg-server/hw/xfree86/common/xf86fbBus.c
+++ b/xorg-server/hw/xfree86/common/xf86fbBus.c
@@ -54,6 +54,10 @@ xf86ClaimFbSlot(DriverPtr drvp, int chipset, GDevPtr dev, Bool active)
EntityPtr p;
int num;
+#ifdef XSERVER_PLATFORM_BUS
+ if (platformSlotClaimed)
+ return -1;
+#endif
#ifdef XSERVER_LIBPCIACCESS
if (pciSlotClaimed)
return -1;
diff --git a/xorg-server/hw/xfree86/common/xf86pciBus.c b/xorg-server/hw/xfree86/common/xf86pciBus.c
index d758260b6..a2c18ebf2 100644
--- a/xorg-server/hw/xfree86/common/xf86pciBus.c
+++ b/xorg-server/hw/xfree86/common/xf86pciBus.c
@@ -110,7 +110,7 @@ xf86PciProbe(void)
xf86PciVideoInfo[num - 1] = info;
pci_device_probe(info);
- if (pci_device_is_boot_vga(info)) {
+ if (primaryBus.type == BUS_NONE && pci_device_is_boot_vga(info)) {
primaryBus.type = BUS_PCI;
primaryBus.id.pci = info;
}
@@ -352,7 +352,15 @@ xf86ComparePciBusString(const char *busID, int bus, int device, int func)
Bool
xf86IsPrimaryPci(struct pci_device *pPci)
{
- return ((primaryBus.type == BUS_PCI) && (pPci == primaryBus.id.pci));
+ if (primaryBus.type == BUS_PCI)
+ return pPci == primaryBus.id.pci;
+#ifdef XSERVER_PLATFORM_BUS
+ if (primaryBus.type == BUS_PLATFORM)
+ if (primaryBus.id.plat->pdev)
+ if (MATCH_PCI_DEVICES(primaryBus.id.plat->pdev, pPci))
+ return TRUE;
+#endif
+ return FALSE;
}
/*
@@ -367,7 +375,15 @@ xf86GetPciInfoForEntity(int entityIndex)
return NULL;
p = xf86Entities[entityIndex];
- return (p->bus.type == BUS_PCI) ? p->bus.id.pci : NULL;
+ switch (p->bus.type) {
+ case BUS_PCI:
+ return p->bus.id.pci;
+ case BUS_PLATFORM:
+ return p->bus.id.plat->pdev;
+ default:
+ break;
+ }
+ return NULL;
}
/*
@@ -400,6 +416,13 @@ xf86CheckPciSlot(const struct pci_device *d)
if ((p->bus.type == BUS_PCI) && (p->bus.id.pci == d)) {
return FALSE;
}
+#ifdef XSERVER_PLATFORM_BUS
+ if ((p->bus.type == BUS_PLATFORM) && (p->bus.id.plat->pdev)) {
+ struct pci_device *ud = p->bus.id.plat->pdev;
+ if (MATCH_PCI_DEVICES(ud, d))
+ return FALSE;
+ }
+#endif
}
return TRUE;
}
@@ -1065,8 +1088,8 @@ xf86ConfigActivePciEntity(ScrnInfoPtr pScrn, int entityIndex,
return TRUE;
}
-static int
-videoPtrToDriverList(struct pci_device *dev,
+int
+xf86VideoPtrToDriverList(struct pci_device *dev,
char *returnList[], int returnListMax)
{
int i;
@@ -1249,8 +1272,8 @@ xchomp(char *line)
* don't export their PCI ID's properly. If distros don't end up using this
* feature it can and should be removed because the symbol-based resolution
* scheme should be the primary one */
-static void
-matchDriverFromFiles(char **matches, uint16_t match_vendor, uint16_t match_chip)
+void
+xf86MatchDriverFromFiles(char **matches, uint16_t match_vendor, uint16_t match_chip)
{
DIR *idsdir;
FILE *fp;
@@ -1379,7 +1402,7 @@ xf86PciMatchDriver(char *matches[], int nmatches)
pci_iterator_destroy(iter);
#ifdef __linux__
if (info)
- matchDriverFromFiles(matches, info->vendor_id, info->device_id);
+ xf86MatchDriverFromFiles(matches, info->vendor_id, info->device_id);
#endif
for (i = 0; (i < nmatches) && (matches[i]); i++) {
@@ -1387,7 +1410,7 @@ xf86PciMatchDriver(char *matches[], int nmatches)
}
if ((info != NULL) && (i < nmatches)) {
- i += videoPtrToDriverList(info, &(matches[i]), nmatches - i);
+ i += xf86VideoPtrToDriverList(info, &(matches[i]), nmatches - i);
}
return i;
diff --git a/xorg-server/hw/xfree86/common/xf86pciBus.h b/xorg-server/hw/xfree86/common/xf86pciBus.h
index 56ec6e9e7..4972c3688 100644
--- a/xorg-server/hw/xfree86/common/xf86pciBus.h
+++ b/xorg-server/hw/xfree86/common/xf86pciBus.h
@@ -42,4 +42,14 @@ Bool xf86PciConfigure(void *busData, struct pci_device *pDev);
void xf86PciConfigureNewDev(void *busData, struct pci_device *pVideo,
GDevRec * GDev, int *chipset);
+#define MATCH_PCI_DEVICES(x, y) (((x)->domain == (y)->domain) && \
+ ((x)->bus == (y)->bus) && \
+ ((x)->func == (y)->func) && \
+ ((x)->dev == (y)->dev))
+
+void
+xf86MatchDriverFromFiles(char **matches, uint16_t match_vendor, uint16_t match_chip);
+int
+xf86VideoPtrToDriverList(struct pci_device *dev,
+ char *returnList[], int returnListMax);
#endif /* _XF86_PCI_BUS_H */
diff --git a/xorg-server/hw/xfree86/common/xf86platformBus.c b/xorg-server/hw/xfree86/common/xf86platformBus.c
new file mode 100644
index 000000000..3bfb22e83
--- /dev/null
+++ b/xorg-server/hw/xfree86/common/xf86platformBus.c
@@ -0,0 +1,489 @@
+/*
+ * Copyright © 2012 Red Hat.
+ *
+ * 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.
+ *
+ * Author: Dave Airlie <airlied@redhat.com>
+ */
+
+/*
+ * This file contains the interfaces to the bus-specific code
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#ifdef XSERVER_PLATFORM_BUS
+#include <errno.h>
+
+#include <pciaccess.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include "os.h"
+#include "hotplug.h"
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86Priv.h"
+#include "xf86str.h"
+#include "xf86Bus.h"
+#include "Pci.h"
+#include "xf86platformBus.h"
+
+int platformSlotClaimed;
+
+int xf86_num_platform_devices;
+
+static struct xf86_platform_device *xf86_platform_devices;
+
+int
+xf86_add_platform_device(struct OdevAttributes *attribs)
+{
+ xf86_platform_devices = xnfrealloc(xf86_platform_devices,
+ (sizeof(struct xf86_platform_device)
+ * (xf86_num_platform_devices + 1)));
+
+ xf86_platform_devices[xf86_num_platform_devices].attribs = attribs;
+ xf86_platform_devices[xf86_num_platform_devices].pdev = NULL;
+
+ xf86_num_platform_devices++;
+ return 0;
+}
+
+int
+xf86_remove_platform_device(int dev_index)
+{
+ int j;
+
+ config_odev_free_attribute_list(xf86_platform_devices[dev_index].attribs);
+
+ for (j = dev_index; j < xf86_num_platform_devices - 1; j++)
+ memcpy(&xf86_platform_devices[j], &xf86_platform_devices[j + 1], sizeof(struct xf86_platform_device));
+ xf86_num_platform_devices--;
+ return 0;
+}
+
+Bool
+xf86_add_platform_device_attrib(int index, int attrib_id, char *attrib_name)
+{
+ struct xf86_platform_device *device = &xf86_platform_devices[index];
+
+ return config_odev_add_attribute(device->attribs, attrib_id, attrib_name);
+}
+
+char *
+xf86_get_platform_attrib(int index, int attrib_id)
+{
+ struct xf86_platform_device *device = &xf86_platform_devices[index];
+ struct OdevAttribute *oa;
+
+ xorg_list_for_each_entry(oa, &device->attribs->list, member) {
+ if (oa->attrib_id == attrib_id)
+ return oa->attrib_name;
+ }
+ return NULL;
+}
+
+char *
+xf86_get_platform_device_attrib(struct xf86_platform_device *device, int attrib_id)
+{
+ struct OdevAttribute *oa;
+
+ xorg_list_for_each_entry(oa, &device->attribs->list, member) {
+ if (oa->attrib_id == attrib_id)
+ return oa->attrib_name;
+ }
+ return NULL;
+}
+
+
+/*
+ * xf86IsPrimaryPlatform() -- return TRUE if primary device
+ * is a platform device and it matches this one.
+ */
+
+static Bool
+xf86IsPrimaryPlatform(struct xf86_platform_device *plat)
+{
+ return ((primaryBus.type == BUS_PLATFORM) && (plat == primaryBus.id.plat));
+}
+
+static void
+platform_find_pci_info(struct xf86_platform_device *pd, char *busid)
+{
+ struct pci_slot_match devmatch;
+ struct pci_device *info;
+ struct pci_device_iterator *iter;
+ int ret;
+
+ ret = sscanf(busid, "pci:%04x:%02x:%02x.%u",
+ &devmatch.domain, &devmatch.bus, &devmatch.dev,
+ &devmatch.func);
+ if (ret != 4)
+ return;
+
+ iter = pci_slot_match_iterator_create(&devmatch);
+ info = pci_device_next(iter);
+ if (info) {
+ pd->pdev = info;
+ pci_device_probe(info);
+ if (pci_device_is_boot_vga(info)) {
+ primaryBus.type = BUS_PLATFORM;
+ primaryBus.id.plat = pd;
+ }
+ }
+ pci_iterator_destroy(iter);
+
+}
+
+static Bool
+xf86_check_platform_slot(const struct xf86_platform_device *pd)
+{
+ int i;
+
+ for (i = 0; i < xf86NumEntities; i++) {
+ const EntityPtr u = xf86Entities[i];
+
+ if (pd->pdev && u->bus.type == BUS_PCI)
+ return !MATCH_PCI_DEVICES(pd->pdev, u->bus.id.pci);
+ if ((u->bus.type == BUS_PLATFORM) && (pd == u->bus.id.plat)) {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+/**
+ * @return The numbers of found devices that match with the current system
+ * drivers.
+ */
+int
+xf86PlatformMatchDriver(char *matches[], int nmatches)
+{
+ int i, j = 0;
+ struct pci_device *info = NULL;
+ int pass = 0;
+
+ for (pass = 0; pass < 2; pass++) {
+ for (i = 0; i < xf86_num_platform_devices; i++) {
+
+ if (xf86IsPrimaryPlatform(&xf86_platform_devices[i]) && (pass == 1))
+ continue;
+ else if (!xf86IsPrimaryPlatform(&xf86_platform_devices[i]) && (pass == 0))
+ continue;
+
+ info = xf86_platform_devices[i].pdev;
+#ifdef __linux__
+ if (info)
+ xf86MatchDriverFromFiles(matches, info->vendor_id, info->device_id);
+#endif
+
+ for (j = 0; (j < nmatches) && (matches[j]); j++) {
+ /* find end of matches list */
+ }
+
+ if ((info != NULL) && (j < nmatches)) {
+ j += xf86VideoPtrToDriverList(info, &(matches[j]), nmatches - j);
+ }
+ }
+ }
+ return j;
+}
+
+int
+xf86platformProbe(void)
+{
+ int i;
+ Bool pci = TRUE;
+
+ if (!xf86scanpci()) {
+ pci = FALSE;
+ }
+
+ config_odev_probe(&xf86PlatformDeviceProbe);
+ for (i = 0; i < xf86_num_platform_devices; i++) {
+ char *busid = xf86_get_platform_attrib(i, ODEV_ATTRIB_BUSID);
+
+ if (pci && (strncmp(busid, "pci:", 4) == 0)) {
+ platform_find_pci_info(&xf86_platform_devices[i], busid);
+ }
+ }
+ return 0;
+}
+
+static int
+xf86ClaimPlatformSlot(struct xf86_platform_device * d, DriverPtr drvp,
+ int chipset, GDevPtr dev, Bool active)
+{
+ EntityPtr p = NULL;
+ int num;
+
+ if (xf86_check_platform_slot(d)) {
+ num = xf86AllocateEntity();
+ p = xf86Entities[num];
+ p->driver = drvp;
+ p->chipset = chipset;
+ p->bus.type = BUS_PLATFORM;
+ p->bus.id.plat = d;
+ p->active = active;
+ p->inUse = FALSE;
+ if (dev)
+ xf86AddDevToEntity(num, dev);
+
+ platformSlotClaimed++;
+ return num;
+ }
+ else
+ return -1;
+}
+
+static int
+xf86UnclaimPlatformSlot(struct xf86_platform_device *d, GDevPtr dev)
+{
+ int i;
+
+ for (i = 0; i < xf86NumEntities; i++) {
+ const EntityPtr p = xf86Entities[i];
+
+ if ((p->bus.type == BUS_PLATFORM) && (p->bus.id.plat == d)) {
+ if (dev)
+ xf86RemoveDevFromEntity(i, dev);
+ platformSlotClaimed--;
+ p->bus.type = BUS_NONE;
+ return 0;
+ }
+ }
+ return 0;
+}
+
+
+#define END_OF_MATCHES(m) \
+ (((m).vendor_id == 0) && ((m).device_id == 0) && ((m).subvendor_id == 0))
+
+static Bool doPlatformProbe(struct xf86_platform_device *dev, DriverPtr drvp,
+ GDevPtr gdev, int flags, intptr_t match_data)
+{
+ Bool foundScreen = FALSE;
+ int entity;
+
+ if (gdev->screen == 0 && !xf86_check_platform_slot(dev))
+ return FALSE;
+
+ entity = xf86ClaimPlatformSlot(dev, drvp, 0,
+ gdev, gdev->active);
+
+ if ((entity == -1) && (gdev->screen > 0)) {
+ unsigned nent;
+
+ for (nent = 0; nent < xf86NumEntities; nent++) {
+ EntityPtr pEnt = xf86Entities[nent];
+
+ if (pEnt->bus.type != BUS_PLATFORM)
+ continue;
+ if (pEnt->bus.id.plat == dev) {
+ entity = nent;
+ xf86AddDevToEntity(nent, gdev);
+ break;
+ }
+ }
+ }
+ if (entity != -1) {
+ if (drvp->platformProbe(drvp, entity, flags, dev, match_data))
+ foundScreen = TRUE;
+ else
+ xf86UnclaimPlatformSlot(dev, gdev);
+ }
+ return foundScreen;
+}
+
+static Bool
+probeSingleDevice(struct xf86_platform_device *dev, DriverPtr drvp, GDevPtr gdev, int flags)
+{
+ int k;
+ Bool foundScreen = FALSE;
+ struct pci_device *pPci;
+ const struct pci_id_match *const devices = drvp->supported_devices;
+
+ if (dev->pdev && devices) {
+ int device_id = dev->pdev->device_id;
+ pPci = dev->pdev;
+ for (k = 0; !END_OF_MATCHES(devices[k]); k++) {
+ if (PCI_ID_COMPARE(devices[k].vendor_id, pPci->vendor_id)
+ && PCI_ID_COMPARE(devices[k].device_id, device_id)
+ && ((devices[k].device_class_mask & pPci->device_class)
+ == devices[k].device_class)) {
+ foundScreen = doPlatformProbe(dev, drvp, gdev, flags, devices[k].match_data);
+ if (foundScreen)
+ break;
+ }
+ }
+ }
+ else if (dev->pdev && !devices)
+ return FALSE;
+ else
+ foundScreen = doPlatformProbe(dev, drvp, gdev, flags, 0);
+ return foundScreen;
+}
+
+int
+xf86platformProbeDev(DriverPtr drvp)
+{
+ Bool foundScreen = FALSE;
+ GDevPtr *devList;
+ const unsigned numDevs = xf86MatchDevice(drvp->driverName, &devList);
+ int i, j;
+
+ /* find the main device or any device specificed in xorg.conf */
+ for (i = 0; i < numDevs; i++) {
+ for (j = 0; j < xf86_num_platform_devices; j++) {
+ if (devList[i]->busID && *devList[i]->busID) {
+ if (xf86PlatformDeviceCheckBusID(&xf86_platform_devices[j], devList[i]->busID))
+ break;
+ }
+ else {
+ if (xf86_platform_devices[j].pdev) {
+ if (xf86IsPrimaryPlatform(&xf86_platform_devices[j]))
+ break;
+ }
+ }
+ }
+
+ if (j == xf86_num_platform_devices)
+ continue;
+
+ foundScreen = probeSingleDevice(&xf86_platform_devices[j], drvp, devList[i], 0);
+ if (!foundScreen)
+ continue;
+ }
+
+ /* if autoaddgpu devices is enabled then go find a few more and add them as GPU screens */
+ if (xf86Info.autoAddGPU && numDevs) {
+ for (j = 0; j < xf86_num_platform_devices; j++) {
+ probeSingleDevice(&xf86_platform_devices[j], drvp, devList[0], PLATFORM_PROBE_GPU_SCREEN);
+ }
+ }
+
+ return foundScreen;
+}
+
+int
+xf86platformAddDevice(int index)
+{
+ int i, old_screens, scr_index;
+ DriverPtr drvp = NULL;
+ int entity;
+ screenLayoutPtr layout;
+ static char *hotplug_driver_name = "modesetting";
+
+ /* force load the driver for now */
+ xf86LoadOneModule(hotplug_driver_name, NULL);
+
+ for (i = 0; i < xf86NumDrivers; i++) {
+ if (!xf86DriverList[i])
+ continue;
+
+ if (!strcmp(xf86DriverList[i]->driverName, hotplug_driver_name)) {
+ drvp = xf86DriverList[i];
+ break;
+ }
+ }
+ if (i == xf86NumDrivers)
+ return -1;
+
+ old_screens = xf86NumGPUScreens;
+ entity = xf86ClaimPlatformSlot(&xf86_platform_devices[index],
+ drvp, 0, 0, 0);
+ if (!drvp->platformProbe(drvp, entity, PLATFORM_PROBE_GPU_SCREEN, &xf86_platform_devices[index], 0)) {
+ xf86UnclaimPlatformSlot(&xf86_platform_devices[index], NULL);
+ }
+ if (old_screens == xf86NumGPUScreens)
+ return -1;
+ i = old_screens;
+
+ for (layout = xf86ConfigLayout.screens; layout->screen != NULL;
+ layout++) {
+ xf86GPUScreens[i]->confScreen = layout->screen;
+ break;
+ }
+
+ if (xf86GPUScreens[i]->PreInit &&
+ xf86GPUScreens[i]->PreInit(xf86GPUScreens[i], 0))
+ xf86GPUScreens[i]->configured = TRUE;
+
+ if (!xf86GPUScreens[i]->configured) {
+ ErrorF("hotplugged device %d didn't configure\n", i);
+ xf86DeleteScreen(xf86GPUScreens[i]);
+ return -1;
+ }
+
+ scr_index = AddGPUScreen(xf86GPUScreens[i]->ScreenInit, 0, NULL);
+
+ dixSetPrivate(&xf86GPUScreens[i]->pScreen->devPrivates,
+ xf86ScreenKey, xf86GPUScreens[i]);
+
+ CreateScratchPixmapsForScreen(xf86GPUScreens[i]->pScreen);
+
+ return 0;
+}
+
+void
+xf86platformRemoveDevice(int index)
+{
+ EntityPtr entity;
+ int ent_num, i, j;
+ Bool found;
+
+ for (ent_num = 0; ent_num < xf86NumEntities; ent_num++) {
+ entity = xf86Entities[ent_num];
+ if (entity->bus.type == BUS_PLATFORM &&
+ entity->bus.id.plat == &xf86_platform_devices[index])
+ break;
+ }
+ if (ent_num == xf86NumEntities)
+ goto out;
+
+ found = FALSE;
+ for (i = 0; i < xf86NumGPUScreens; i++) {
+ for (j = 0; j < xf86GPUScreens[i]->numEntities; j++)
+ if (xf86GPUScreens[i]->entityList[j] == ent_num) {
+ found = TRUE;
+ break;
+ }
+ if (found)
+ break;
+ }
+ if (!found) {
+ ErrorF("failed to find screen to remove\n");
+ goto out;
+ }
+
+ xf86GPUScreens[i]->pScreen->CloseScreen(xf86GPUScreens[i]->pScreen);
+
+ RemoveGPUScreen(xf86GPUScreens[i]->pScreen);
+ xf86DeleteScreen(xf86GPUScreens[i]);
+
+ xf86UnclaimPlatformSlot(&xf86_platform_devices[index], NULL);
+
+ xf86_remove_platform_device(index);
+
+ out:
+ return;
+}
+#endif
diff --git a/xorg-server/hw/xfree86/common/xf86platformBus.h b/xorg-server/hw/xfree86/common/xf86platformBus.h
new file mode 100644
index 000000000..49afc247b
--- /dev/null
+++ b/xorg-server/hw/xfree86/common/xf86platformBus.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright © 2012 Red Hat.
+ *
+ * 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.
+ *
+ * Author: Dave Airlie <airlied@redhat.com>
+ */
+#ifndef XF86_PLATFORM_BUS_H
+#define XF86_PLATFORM_BUS_H
+
+#include "hotplug.h"
+
+struct xf86_platform_device {
+ struct OdevAttributes *attribs;
+ /* for PCI devices */
+ struct pci_device *pdev;
+};
+
+#ifdef XSERVER_PLATFORM_BUS
+int xf86platformProbe(void);
+int xf86platformProbeDev(DriverPtr drvp);
+
+extern int xf86_num_platform_devices;
+
+extern char *
+xf86_get_platform_attrib(int index, int attrib_id);
+extern int
+xf86_add_platform_device(struct OdevAttributes *attribs);
+extern int
+xf86_remove_platform_device(int dev_index);
+extern Bool
+xf86_add_platform_device_attrib(int index, int attrib_id, char *attrib_str);
+
+extern int
+xf86platformAddDevice(int index);
+extern void
+xf86platformRemoveDevice(int index);
+
+extern _X_EXPORT char *
+xf86_get_platform_device_attrib(struct xf86_platform_device *device, int attrib_id);
+extern _X_EXPORT Bool
+xf86PlatformDeviceCheckBusID(struct xf86_platform_device *device, const char *busid);
+
+extern _X_EXPORT int
+xf86PlatformMatchDriver(char *matches[], int nmatches);
+#endif
+
+#endif
diff --git a/xorg-server/hw/xfree86/common/xf86str.h b/xorg-server/hw/xfree86/common/xf86str.h
index a1404c3aa..6bd6a6218 100644
--- a/xorg-server/hw/xfree86/common/xf86str.h
+++ b/xorg-server/hw/xfree86/common/xf86str.h
@@ -311,6 +311,7 @@ struct _SymTabRec;
struct _PciChipsets;
struct pci_device;
+struct xf86_platform_device;
typedef struct _DriverRec {
int driverVersion;
@@ -325,9 +326,16 @@ typedef struct _DriverRec {
const struct pci_id_match *supported_devices;
Bool (*PciProbe) (struct _DriverRec * drv, int entity_num,
struct pci_device * dev, intptr_t match_data);
+ Bool (*platformProbe) (struct _DriverRec * drv, int entity_num, int flags,
+ struct xf86_platform_device * dev, intptr_t match_data);
} DriverRec, *DriverPtr;
/*
+ * platform probe flags
+ */
+#define PLATFORM_PROBE_GPU_SCREEN 1
+
+/*
* AddDriver flags
*/
#define HaveDriverFuncs 1
@@ -343,6 +351,7 @@ typedef struct _DriverRec {
#undef BUS_NONE
#undef BUS_PCI
#undef BUS_SBUS
+#undef BUS_PLATFORM
#undef BUS_last
#endif
@@ -350,6 +359,7 @@ typedef enum {
BUS_NONE,
BUS_PCI,
BUS_SBUS,
+ BUS_PLATFORM,
BUS_last /* Keep last */
} BusType;
@@ -362,6 +372,7 @@ typedef struct _bus {
union {
struct pci_device *pci;
SbusBusId sbus;
+ struct xf86_platform_device *plat;
} id;
} BusRec, *BusPtr;
@@ -802,6 +813,7 @@ typedef struct _ScrnInfoRec {
*/
funcPointer reservedFuncs[NUM_RESERVED_FUNCS];
+ Bool is_gpu;
} ScrnInfoRec;
typedef struct {
diff --git a/xorg-server/hw/xfree86/modes/xf86EdidModes.c b/xorg-server/hw/xfree86/modes/xf86EdidModes.c
index 8aa82d114..258ada5b4 100644
--- a/xorg-server/hw/xfree86/modes/xf86EdidModes.c
+++ b/xorg-server/hw/xfree86/modes/xf86EdidModes.c
@@ -723,7 +723,13 @@ static const struct {
1920, 1200, 75, 0}, {
1920, 1200, 85, 0}, {
1920, 1440, 60, 0}, {
-1920, 1440, 75, 0},};
+ 1920, 1440, 75, 0},
+ /* fill up last byte */
+ {
+ 0,0,0,0}, {
+ 0,0,0,0}, {
+ 0,0,0,0}, {
+ 0,0,0,0}, };
static DisplayModePtr
DDCModesFromEstIII(unsigned char *est)
@@ -732,10 +738,11 @@ DDCModesFromEstIII(unsigned char *est)
int i, j, m;
for (i = 0; i < 6; i++) {
- for (j = 7; j > 0; j--) {
+ for (j = 7; j >= 0; j--) {
if (est[i] & (1 << j)) {
m = (i * 8) + (7 - j);
- modes = xf86ModesAdd(modes,
+ if (EstIIIModes[m].w)
+ modes = xf86ModesAdd(modes,
FindDMTMode(EstIIIModes[m].w,
EstIIIModes[m].h,
EstIIIModes[m].r,
diff --git a/xorg-server/hw/xfree86/os-support/linux/Makefile.am b/xorg-server/hw/xfree86/os-support/linux/Makefile.am
index 36748df2c..61175b386 100644
--- a/xorg-server/hw/xfree86/os-support/linux/Makefile.am
+++ b/xorg-server/hw/xfree86/os-support/linux/Makefile.am
@@ -22,7 +22,7 @@ XORG_CFLAGS += -DHAVE_APM
endif
liblinux_la_SOURCES = lnx_init.c lnx_video.c \
- lnx_agp.c lnx_kmod.c lnx_bell.c \
+ lnx_agp.c lnx_kmod.c lnx_bell.c lnx_platform.c \
$(srcdir)/../shared/bios_mmap.c \
$(srcdir)/../shared/VTsw_usl.c \
$(srcdir)/../shared/posix_tty.c \
diff --git a/xorg-server/hw/xfree86/os-support/linux/lnx_platform.c b/xorg-server/hw/xfree86/os-support/linux/lnx_platform.c
new file mode 100644
index 000000000..76f5583dd
--- /dev/null
+++ b/xorg-server/hw/xfree86/os-support/linux/lnx_platform.c
@@ -0,0 +1,179 @@
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#ifdef XSERVER_PLATFORM_BUS
+
+#include <xf86drm.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+/* Linux platform device support */
+#include "xf86_OSproc.h"
+
+#include "xf86.h"
+#include "xf86platformBus.h"
+#include "xf86Bus.h"
+
+#include "hotplug.h"
+
+static Bool
+get_drm_info(struct OdevAttributes *attribs, char *path)
+{
+ drmSetVersion sv;
+ char *buf;
+ int fd;
+
+ fd = open(path, O_RDWR, O_CLOEXEC);
+ if (fd == -1)
+ return FALSE;
+
+ sv.drm_di_major = 1;
+ sv.drm_di_minor = 4;
+ sv.drm_dd_major = -1; /* Don't care */
+ sv.drm_dd_minor = -1; /* Don't care */
+ if (drmSetInterfaceVersion(fd, &sv)) {
+ ErrorF("setversion 1.4 failed\n");
+ return FALSE;
+ }
+
+ xf86_add_platform_device(attribs);
+
+ buf = drmGetBusid(fd);
+ xf86_add_platform_device_attrib(xf86_num_platform_devices - 1,
+ ODEV_ATTRIB_BUSID, buf);
+ drmFreeBusid(buf);
+ close(fd);
+ return TRUE;
+}
+
+Bool
+xf86PlatformDeviceCheckBusID(struct xf86_platform_device *device, const char *busid)
+{
+ struct OdevAttribute *attrib;
+ const char *syspath = NULL;
+ BusType bustype;
+ const char *id;
+ xorg_list_for_each_entry(attrib, &device->attribs->list, member) {
+ if (attrib->attrib_id == ODEV_ATTRIB_SYSPATH) {
+ syspath = attrib->attrib_name;
+ break;
+ }
+ }
+
+ if (!syspath)
+ return FALSE;
+
+ bustype = StringToBusType(busid, &id);
+ if (bustype == BUS_PCI) {
+ struct pci_device *pPci = device->pdev;
+ if (xf86ComparePciBusString(busid,
+ ((pPci->domain << 8)
+ | pPci->bus),
+ pPci->dev, pPci->func)) {
+ return TRUE;
+ }
+ }
+ else if (bustype == BUS_PLATFORM) {
+ /* match on the minimum string */
+ int len = strlen(id);
+
+ if (strlen(syspath) < strlen(id))
+ len = strlen(syspath);
+
+ if (strncmp(id, syspath, len))
+ return FALSE;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void
+xf86PlatformDeviceProbe(struct OdevAttributes *attribs)
+{
+ struct OdevAttribute *attrib;
+ int i;
+ char *path = NULL;
+ Bool ret;
+
+ xorg_list_for_each_entry(attrib, &attribs->list, member) {
+ if (attrib->attrib_id == ODEV_ATTRIB_PATH) {
+ path = attrib->attrib_name;
+ break;
+ }
+ }
+ if (!path)
+ goto out_free;
+
+ for (i = 0; i < xf86_num_platform_devices; i++) {
+ char *dpath;
+ dpath = xf86_get_platform_attrib(i, ODEV_ATTRIB_PATH);
+
+ if (!strcmp(path, dpath))
+ break;
+ }
+
+ if (i != xf86_num_platform_devices)
+ goto out_free;
+
+ LogMessage(X_INFO, "config/udev: Adding drm device (%s)\n",
+ path);
+
+ ret = get_drm_info(attribs, path);
+ if (ret == FALSE)
+ goto out_free;
+
+ return;
+
+out_free:
+ config_odev_free_attribute_list(attribs);
+}
+
+void NewGPUDeviceRequest(struct OdevAttributes *attribs)
+{
+ int old_num = xf86_num_platform_devices;
+ int ret;
+ xf86PlatformDeviceProbe(attribs);
+
+ if (old_num == xf86_num_platform_devices)
+ return;
+
+ ret = xf86platformAddDevice(xf86_num_platform_devices-1);
+ if (ret == -1)
+ xf86_remove_platform_device(xf86_num_platform_devices-1);
+
+ ErrorF("xf86: found device %d\n", xf86_num_platform_devices);
+ return;
+}
+
+void DeleteGPUDeviceRequest(struct OdevAttributes *attribs)
+{
+ struct OdevAttribute *attrib;
+ int index;
+ char *syspath = NULL;
+
+ xorg_list_for_each_entry(attrib, &attribs->list, member) {
+ if (attrib->attrib_id == ODEV_ATTRIB_SYSPATH) {
+ syspath = attrib->attrib_name;
+ break;
+ }
+ }
+
+ for (index = 0; index < xf86_num_platform_devices; index++) {
+ char *dspath;
+ dspath = xf86_get_platform_attrib(index, ODEV_ATTRIB_SYSPATH);
+ if (!strcmp(syspath, dspath))
+ break;
+ }
+
+ if (index == xf86_num_platform_devices)
+ goto out;
+
+ ErrorF("xf86: remove device %d %s\n", index, syspath);
+
+ xf86platformRemoveDevice(index);
+out:
+ config_odev_free_attribute_list(attribs);
+}
+
+#endif
diff --git a/xorg-server/hw/xfree86/os-support/shared/platform_noop.c b/xorg-server/hw/xfree86/os-support/shared/platform_noop.c
new file mode 100644
index 000000000..199ae5e8e
--- /dev/null
+++ b/xorg-server/hw/xfree86/os-support/shared/platform_noop.c
@@ -0,0 +1,23 @@
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#ifdef XSERVER_PLATFORM_BUS
+/* noop platform device support */
+#include "xf86_OSproc.h"
+
+#include "xf86.h"
+#include "xf86platformBus.h"
+
+Bool
+xf86PlatformDeviceCheckBusID(struct xf86_platform_device *device, const char *busid)
+{
+ return FALSE;
+}
+
+void xf86PlatformDeviceProbe(struct OdevAttributes *attribs)
+{
+
+}
+#endif
diff --git a/xorg-server/hw/xfree86/os-support/xf86_OSproc.h b/xorg-server/hw/xfree86/os-support/xf86_OSproc.h
index e171146dd..2f0172e15 100644
--- a/xorg-server/hw/xfree86/os-support/xf86_OSproc.h
+++ b/xorg-server/hw/xfree86/os-support/xf86_OSproc.h
@@ -221,6 +221,12 @@ extern _X_EXPORT void xf86InitVidMem(void);
#endif /* XF86_OS_PRIVS */
+#ifdef XSERVER_PLATFORM_BUS
+#include "hotplug.h"
+void
+xf86PlatformDeviceProbe(struct OdevAttributes *attribs);
+#endif
+
_XFUNCPROTOEND
#endif /* NO_OSLIB_PROTOTYPES */
#endif /* _XF86_OSPROC_H */
diff --git a/xorg-server/hw/xfree86/ramdac/xf86Cursor.c b/xorg-server/hw/xfree86/ramdac/xf86Cursor.c
index 15e2ada78..8b91e0574 100644
--- a/xorg-server/hw/xfree86/ramdac/xf86Cursor.c
+++ b/xorg-server/hw/xfree86/ramdac/xf86Cursor.c
@@ -336,28 +336,19 @@ xf86CursorSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs,
if (!infoPtr->pScrn->vtSema)
ScreenPriv->SavedCursor = pCurs;
- if (infoPtr->pScrn->vtSema && (ScreenPriv->ForceHWCursorCount || ((
+ if (infoPtr->pScrn->vtSema &&
+ (ScreenPriv->ForceHWCursorCount ||
+ ((
#ifdef ARGB_CURSOR
- pCurs->
- bits->
- argb
- &&
- infoPtr->
- UseHWCursorARGB
- &&
- (*infoPtr->
- UseHWCursorARGB)
- (pScreen,
- pCurs))
- ||
- (pCurs->
- bits->
- argb
- == 0
- &&
+ pCurs->bits->argb &&
+ infoPtr->UseHWCursorARGB &&
+ (*infoPtr->UseHWCursorARGB)(pScreen, pCurs)) ||
+ (pCurs->bits->argb == 0 &&
#endif
- (pCurs->bits->height <= infoPtr->MaxHeight) && (pCurs->bits->width <= infoPtr->MaxWidth) && (!infoPtr->UseHWCursor || (*infoPtr->UseHWCursor) (pScreen, pCurs)))))) {
-
+ (pCurs->bits->height <= infoPtr->MaxHeight) &&
+ (pCurs->bits->width <= infoPtr->MaxWidth) &&
+ (!infoPtr->UseHWCursor || (*infoPtr->UseHWCursor) (pScreen, pCurs)))))) {
+
if (ScreenPriv->SWCursor) /* remove the SW cursor */
(*ScreenPriv->spriteFuncs->SetCursor) (pDev, pScreen,
NullCursor, x, y);