summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Makefile.am55
-rw-r--r--src/intel_device.c230
-rw-r--r--src/intel_driver.c2
-rw-r--r--src/intel_driver.h7
-rw-r--r--src/intel_module.c66
-rw-r--r--src/sna/sna_driver.c156
6 files changed, 299 insertions, 217 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 80837568..27b702bf 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -43,6 +43,7 @@ NULL:=#
intel_drv_la_SOURCES = \
intel_list.h \
intel_options.h \
+ intel_device.c \
intel_options.c \
intel_module.c \
compat-api.h \
@@ -53,33 +54,33 @@ AM_CFLAGS += @UDEV_CFLAGS@ @DRM_CFLAGS@ @DRMINTEL_CFLAGS@
AM_CFLAGS += -I$(top_srcdir)/uxa -I$(top_srcdir)/src/render_program
intel_drv_la_LIBADD += @UDEV_LIBS@ @DRMINTEL_LIBS@ @DRM_LIBS@ ../uxa/libuxa.la
intel_drv_la_SOURCES += \
- brw_defines.h \
- brw_structs.h \
- common.h \
- intel.h \
- intel_batchbuffer.c \
- intel_batchbuffer.h \
- intel_display.c \
- intel_driver.c \
- intel_driver.h \
- intel_glamor.h \
- intel_memory.c \
- intel_uxa.c \
- intel_video.c \
- intel_video.h \
- i830_3d.c \
- i830_render.c \
- i830_reg.h \
- i915_3d.h \
- i915_reg.h \
- i915_3d.c \
- i915_render.c \
- i915_video.c \
- i965_reg.h \
- i965_3d.c \
- i965_video.c \
- i965_render.c \
- $(NULL)
+ brw_defines.h \
+ brw_structs.h \
+ common.h \
+ intel.h \
+ intel_batchbuffer.c \
+ intel_batchbuffer.h \
+ intel_display.c \
+ intel_driver.c \
+ intel_driver.h \
+ intel_glamor.h \
+ intel_memory.c \
+ intel_uxa.c \
+ intel_video.c \
+ intel_video.h \
+ i830_3d.c \
+ i830_render.c \
+ i830_reg.h \
+ i915_3d.h \
+ i915_reg.h \
+ i915_3d.c \
+ i915_render.c \
+ i915_video.c \
+ i965_reg.h \
+ i965_3d.c \
+ i965_video.c \
+ i965_render.c \
+ $(NULL)
if GLAMOR
AM_CFLAGS += @LIBGLAMOR_CFLAGS@
diff --git a/src/intel_device.c b/src/intel_device.c
new file mode 100644
index 00000000..cb3cb16a
--- /dev/null
+++ b/src/intel_device.c
@@ -0,0 +1,230 @@
+/***************************************************************************
+
+ Copyright 2013 Intel Corporation. All Rights Reserved.
+
+ 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, sub license, 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 (including the
+ next paragraph) 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 NON-INFRINGEMENT.
+ IN NO EVENT SHALL INTEL, AND/OR ITS SUPPLIERS 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.
+
+ **************************************************************************/
+
+#include <assert.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include <sys/ioctl.h>
+
+#include <pciaccess.h>
+#include <xf86.h>
+#include <xf86drm.h>
+#include <xf86drmMode.h>
+#include <xf86_OSproc.h>
+
+#include "intel_driver.h"
+
+struct intel_device {
+ int fd;
+ int open_count;
+ int master_count;
+};
+
+static int intel_device_key = -1;
+
+static inline struct intel_device *intel_device(ScrnInfoPtr scrn)
+{
+ if (scrn->entityList == NULL)
+ return NULL;
+
+ return xf86GetEntityPrivate(scrn->entityList[0], intel_device_key)->ptr;
+}
+
+static inline void intel_set_device(ScrnInfoPtr scrn, struct intel_device *dev)
+{
+ xf86GetEntityPrivate(scrn->entityList[0], intel_device_key)->ptr = dev;
+}
+
+static int __intel_open_device(const struct pci_device *pci, const char *path)
+{
+ int fd;
+
+ if (path == NULL) {
+ char id[20];
+ int ret;
+
+ snprintf(id, sizeof(id),
+ "pci:%04x:%02x:%02x.%d",
+ pci->domain, pci->bus, pci->dev, pci->func);
+
+ ret = drmCheckModesettingSupported(id);
+ if (ret) {
+ if (xf86LoadKernelModule("i915"))
+ ret = drmCheckModesettingSupported(id);
+ if (ret)
+ return FALSE;
+ /* Be nice to the user and load fbcon too */
+ (void)xf86LoadKernelModule("fbcon");
+ }
+
+ fd = drmOpen(NULL, id);
+ } else
+ fd = open(path, O_RDWR | O_CLOEXEC);
+
+ return fd;
+}
+
+int intel_open_device(int entity_num,
+ const struct pci_device *pci,
+ const char *path)
+{
+ struct intel_device *dev;
+ int fd;
+
+ if (intel_device_key == -1)
+ intel_device_key = xf86AllocateEntityPrivateIndex();
+ if (intel_device_key == -1)
+ return -1;
+
+ dev = xf86GetEntityPrivate(entity_num, intel_device_key)->ptr;
+ if (dev)
+ return dev->fd;
+
+ fd = __intel_open_device(pci, path);
+ if (fd == -1)
+ return -1;
+
+ dev = malloc(sizeof(*dev));
+ if (dev == NULL) {
+ close(fd);
+ return -1;
+ }
+
+ dev->fd = fd;
+ dev->open_count = 0;
+ dev->master_count = 0;
+
+ xf86GetEntityPrivate(entity_num, intel_device_key)->ptr = dev;
+
+ return fd;
+}
+
+int intel_get_device(ScrnInfoPtr scrn)
+{
+ struct intel_device *dev;
+ int ret;
+
+ dev = intel_device(scrn);
+ assert(dev && dev->fd != -1);
+
+ if (dev->open_count++ == 0) {
+ drmSetVersion sv;
+ int retry = 2000;
+
+ /* Check that what we opened was a master or a
+ * master-capable FD, by setting the version of the
+ * interface we'll use to talk to it.
+ */
+ do {
+ sv.drm_di_major = 1;
+ sv.drm_di_minor = 1;
+ sv.drm_dd_major = -1;
+ sv.drm_dd_minor = -1;
+ ret = drmIoctl(dev->fd, DRM_IOCTL_SET_VERSION, &sv);
+ if (ret == 0)
+ break;
+
+ usleep(1000);
+ } while (--retry);
+ if (ret != 0) {
+ xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+ "[drm] failed to set drm interface version: %s [%d].\n",
+ strerror(ret), ret);
+ dev->open_count--;
+ return -1;
+ }
+ }
+
+ return dev->fd;
+}
+
+int intel_get_master(ScrnInfoPtr scrn)
+{
+ struct intel_device *dev = intel_device(scrn);
+ int ret;
+
+ assert(dev && dev->fd != -1);
+
+ ret = 0;
+ if (dev->master_count++ == 0) {
+ int retry = 2000;
+
+ do {
+ ret = ioctl(dev->fd, DRM_IOCTL_SET_MASTER);
+ if (ret == 0)
+ break;
+ usleep(1000);
+ } while (--retry);
+ }
+
+ return ret;
+}
+
+int intel_put_master(ScrnInfoPtr scrn)
+{
+ struct intel_device *dev = intel_device(scrn);
+ int ret;
+
+ assert(dev && dev->fd != -1);
+
+ ret = 0;
+ assert(dev->master_count);
+ if (--dev->master_count == 0)
+ ret = ioctl(dev->fd, DRM_IOCTL_DROP_MASTER);
+
+ return ret;
+}
+
+void __intel_uxa_release_device(ScrnInfoPtr scrn)
+{
+ struct intel_device *dev = intel_device(scrn);
+ if (dev && dev->open_count == 0) {
+ intel_set_device(scrn, NULL);
+
+ drmClose(dev->fd);
+ free(dev);
+ }
+}
+
+void intel_put_device(ScrnInfoPtr scrn)
+{
+ struct intel_device *dev = intel_device(scrn);
+
+ assert(dev && dev->fd != -1);
+
+ assert(dev->open_count);
+ if (--dev->open_count)
+ return;
+
+ intel_set_device(scrn, NULL);
+
+ drmClose(dev->fd);
+ free(dev);
+}
diff --git a/src/intel_driver.c b/src/intel_driver.c
index ae2e31e8..7569c130 100644
--- a/src/intel_driver.c
+++ b/src/intel_driver.c
@@ -1298,6 +1298,8 @@ static Bool I830PMEvent(SCRN_ARG_TYPE arg, pmEvent event, Bool undo)
Bool intel_init_scrn(ScrnInfoPtr scrn)
{
+ __intel_uxa_release_device(scrn);
+
scrn->PreInit = I830PreInit;
scrn->ScreenInit = I830ScreenInit;
scrn->SwitchMode = I830SwitchMode;
diff --git a/src/intel_driver.h b/src/intel_driver.h
index 32f623b2..ed58444f 100644
--- a/src/intel_driver.h
+++ b/src/intel_driver.h
@@ -311,5 +311,12 @@ void intel_detect_chipset(ScrnInfoPtr scrn,
EntityInfoPtr ent,
struct pci_device *pci);
+int intel_open_device(int entity_num, const struct pci_device *pci, const char *path);
+int intel_get_device(ScrnInfoPtr scrn);
+int intel_get_master(ScrnInfoPtr scrn);
+int intel_put_master(ScrnInfoPtr scrn);
+void intel_put_device(ScrnInfoPtr scrn);
+
+void __intel_uxa_release_device(ScrnInfoPtr scrn);
#endif /* INTEL_DRIVER_H */
diff --git a/src/intel_module.c b/src/intel_module.c
index c1d0e099..45de1ef6 100644
--- a/src/intel_module.c
+++ b/src/intel_module.c
@@ -29,7 +29,6 @@
#endif
#include <unistd.h>
-#include <xf86_OSproc.h>
#include <xf86Parser.h>
#include <xf86drm.h>
#include <xf86drmMode.h>
@@ -435,49 +434,37 @@ static Bool intel_driver_func(ScrnInfoPtr pScrn,
}
}
-static Bool has_kernel_mode_setting(const struct pci_device *dev)
+static Bool has_kernel_mode_setting(int entity_num,
+ const struct pci_device *dev,
+ const char *path)
{
- char id[20];
+ drmVersionPtr version;
int ret, fd;
- snprintf(id, sizeof(id),
- "pci:%04x:%02x:%02x.%d",
- dev->domain, dev->bus, dev->dev, dev->func);
-
- ret = drmCheckModesettingSupported(id);
- if (ret) {
- if (xf86LoadKernelModule("i915"))
- ret = drmCheckModesettingSupported(id);
- if (ret)
- return FALSE;
- /* Be nice to the user and load fbcon too */
- (void)xf86LoadKernelModule("fbcon");
- }
+ fd = intel_open_device(entity_num, dev, path);
+ if (fd == -1)
+ return FALSE;
/* Confirm that this is a i915.ko device with GEM/KMS enabled */
ret = FALSE;
- fd = drmOpen(NULL, id);
- if (fd != -1) {
- drmVersionPtr version = drmGetVersion(fd);
- if (version) {
- ret = strcmp ("i915", version->name) == 0;
- drmFreeVersion(version);
- }
- if (ret) {
- struct drm_i915_getparam gp;
- gp.param = I915_PARAM_HAS_GEM;
- gp.value = &ret;
- if (drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp))
- ret = FALSE;
- }
- if (ret) {
- struct drm_mode_card_res res;
+ version = drmGetVersion(fd);
+ if (version) {
+ ret = strcmp ("i915", version->name) == 0;
+ drmFreeVersion(version);
+ }
+ if (ret) {
+ struct drm_i915_getparam gp;
+ gp.param = I915_PARAM_HAS_GEM;
+ gp.value = &ret;
+ if (drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp))
+ ret = FALSE;
+ }
+ if (ret) {
+ struct drm_mode_card_res res;
- memset(&res, 0, sizeof(res));
- if (drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res))
- ret = FALSE;
- }
- close(fd);
+ memset(&res, 0, sizeof(res));
+ if (drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res))
+ ret = FALSE;
}
return ret;
@@ -578,7 +565,7 @@ static Bool intel_pci_probe(DriverPtr driver,
struct pci_device *device,
intptr_t match_data)
{
- if (!has_kernel_mode_setting(device)) {
+ if (!has_kernel_mode_setting(entity_num, device, NULL)) {
#if KMS_ONLY
return FALSE;
#else
@@ -609,7 +596,8 @@ intel_platform_probe(DriverPtr driver,
if (!dev->pdev)
return FALSE;
- if (!has_kernel_mode_setting(dev->pdev))
+ if (!has_kernel_mode_setting(entity_num, dev->pdev,
+ xf86_get_platform_device_attrib(dev, ODEV_ATTRIB_PATH)))
return FALSE;
/* Allow ourselves to act as a slaved output if not primary */
diff --git a/src/sna/sna_driver.c b/src/sna/sna_driver.c
index 013e27a9..e2037174 100644
--- a/src/sna/sna_driver.c
+++ b/src/sna/sna_driver.c
@@ -78,9 +78,6 @@ DevPrivateKeyRec sna_gc_key;
DevPrivateKeyRec sna_window_key;
DevPrivateKeyRec sna_glyph_key;
-static int sna_put_drm_master(ScrnInfoPtr scrn);
-static int sna_get_drm_master(ScrnInfoPtr scrn);
-
static void
sna_load_palette(ScrnInfoPtr scrn, int numColors, int *indices,
LOCO * colors, VisualPtr pVisual)
@@ -200,15 +197,8 @@ static Bool sna_become_master(struct sna *sna)
DBG(("%s\n", __FUNCTION__));
- if (sna_get_drm_master(scrn)) {
- sleep(2); /* XXX wait for the current master to decease */
- if (drmSetMaster(sna->kgem.fd)) {
- xf86DrvMsg(scrn->scrnIndex, X_ERROR,
- "drmSetMaster failed: %s\n",
- strerror(errno));
- return FALSE;
- }
- }
+ if (intel_get_master(scrn))
+ return FALSE;
if (!xf86SetDesiredModes(scrn)) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
@@ -293,139 +283,6 @@ static void PreInitCleanup(ScrnInfoPtr scrn)
scrn->driverPrivate = NULL;
}
-struct sna_device {
- int fd;
- int open_count;
- int master_count;
-};
-static int sna_device_key = -1;
-
-static inline struct sna_device *sna_device(ScrnInfoPtr scrn)
-{
- if (scrn->entityList == NULL)
- return NULL;
-
- return xf86GetEntityPrivate(scrn->entityList[0], sna_device_key)->ptr;
-}
-
-static inline void sna_set_device(ScrnInfoPtr scrn, struct sna_device *dev)
-{
- xf86GetEntityPrivate(scrn->entityList[0], sna_device_key)->ptr = dev;
-}
-
-static int sna_open_drm_master(ScrnInfoPtr scrn)
-{
- struct sna_device *dev;
- struct sna *sna = to_sna(scrn);
- struct pci_device *pci = sna->PciInfo;
- drmSetVersion sv;
- int err;
- char busid[20];
- int fd;
-
- DBG(("%s\n", __FUNCTION__));
-
- dev = sna_device(scrn);
- if (dev) {
- DBG(("%s: reusing device, count=%d (master=%d)\n",
- __FUNCTION__, dev->open_count, dev->master_count));
- assert(dev->open_count);
- dev->open_count++;
- return dev->fd;
- }
-
- snprintf(busid, sizeof(busid), "pci:%04x:%02x:%02x.%d",
- pci->domain, pci->bus, pci->dev, pci->func);
-
- DBG(("%s: opening device '%s'\n", __FUNCTION__, busid));
- fd = drmOpen(NULL, busid);
- if (fd == -1) {
- xf86DrvMsg(scrn->scrnIndex, X_ERROR,
- "[drm] Failed to open DRM device for %s: %s\n",
- busid, strerror(errno));
- return -1;
- }
-
- /* Check that what we opened was a master or a master-capable FD,
- * by setting the version of the interface we'll use to talk to it.
- * (see DRIOpenDRMMaster() in DRI1)
- */
- sv.drm_di_major = 1;
- sv.drm_di_minor = 1;
- sv.drm_dd_major = -1;
- sv.drm_dd_minor = -1;
- err = drmSetInterfaceVersion(fd, &sv);
- if (err != 0) {
- xf86DrvMsg(scrn->scrnIndex, X_ERROR,
- "[drm] failed to set drm interface version: %s [%d].\n",
- strerror(-err), -err);
- drmClose(fd);
- return -1;
- }
-
- dev = malloc(sizeof(*dev));
- if (dev) {
- int flags;
-
- /* make the fd nonblocking to handle event loops */
- flags = fcntl(fd, F_GETFL, 0);
- if (flags != -1)
- (void)fcntl(fd, F_SETFL, flags | O_NONBLOCK);
-
- dev->fd = fd;
- dev->open_count = 1;
- sna_set_device(scrn, dev);
- }
-
- return fd;
-}
-
-static int sna_get_drm_master(ScrnInfoPtr scrn)
-{
- struct sna_device *dev = sna_device(scrn);
- int ret;
-
- if (dev == NULL)
- return -1;
-
- ret = 0;
- if (dev->master_count++ == 0)
- ret = drmSetMaster(dev->fd);
- return ret;
-}
-
-static int sna_put_drm_master(ScrnInfoPtr scrn)
-{
- struct sna_device *dev = sna_device(scrn);
- int ret;
-
- if (dev == NULL)
- return -1;
-
- ret = 0;
- assert(dev->master_count);
- if (--dev->master_count == 0)
- ret = drmDropMaster(dev->fd);
-
- return ret;
-}
-
-static void sna_close_drm_master(ScrnInfoPtr scrn)
-{
- struct sna_device *dev = sna_device(scrn);
-
- if (dev == NULL)
- return;
-
- DBG(("%s(open_count=%d)\n", __FUNCTION__, dev->open_count));
- if (--dev->open_count)
- return;
-
- drmClose(dev->fd);
- sna_set_device(scrn, NULL);
- free(dev);
-}
-
static void sna_selftest(void)
{
sna_damage_selftest();
@@ -571,7 +428,7 @@ static Bool sna_pre_init(ScrnInfoPtr scrn, int flags)
scrn->progClock = TRUE;
scrn->rgbBits = 8;
- fd = sna_open_drm_master(scrn);
+ fd = intel_get_device(scrn);
if (fd == -1) {
xf86DrvMsg(scrn->scrnIndex, X_ERROR,
"Failed to become DRM master.\n");
@@ -865,7 +722,7 @@ static void sna_leave_vt(VT_FUNC_ARGS_DECL)
xf86_hide_cursors(scrn);
- if (sna_put_drm_master(scrn))
+ if (intel_put_master(scrn))
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"drmDropMaster failed: %s\n", strerror(errno));
}
@@ -1129,7 +986,7 @@ static void sna_free_screen(FREE_SCREEN_ARGS_DECL)
}
scrn->driverPrivate = NULL;
- sna_close_drm_master(scrn);
+ intel_put_device(scrn);
}
/*
@@ -1258,9 +1115,6 @@ Bool sna_init_scrn(ScrnInfoPtr scrn, int entity_num)
#endif
DBG(("pixman version: %s\n", pixman_version_string()));
- if (sna_device_key == -1)
- sna_device_key = xf86AllocateEntityPrivateIndex();
-
scrn->PreInit = sna_pre_init;
scrn->ScreenInit = sna_screen_init;
scrn->SwitchMode = sna_switch_mode;