diff options
-rw-r--r-- | src/Makefile.am | 55 | ||||
-rw-r--r-- | src/intel_device.c | 230 | ||||
-rw-r--r-- | src/intel_driver.c | 2 | ||||
-rw-r--r-- | src/intel_driver.h | 7 | ||||
-rw-r--r-- | src/intel_module.c | 66 | ||||
-rw-r--r-- | src/sna/sna_driver.c | 156 |
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; |