From 5718399f454457d2fede1f011bbf41c5c7070ecf Mon Sep 17 00:00:00 2001 From: =?utf8?q?Fran=C3=A7ois=20Tigeot?= Date: Sun, 1 Sep 2013 21:38:11 +0200 Subject: [PATCH] drm: Merge the drm and drm2 implementations * Move the drm2 i915 driver to sys/dev/drm/i915kms * The legacy i915 driver remains untouched * Only sys/dev/drm/ shall remain --- sys/dev/Makefile | 1 - sys/dev/drm/Makefile | 2 +- sys/dev/drm/ati_pcigart.c | 14 +- sys/dev/drm/drm.h | 79 +- sys/dev/drm/drm/Makefile | 44 +- sys/dev/drm/drmP.h | 601 +++++-- sys/dev/drm/drm_agpsupport.c | 29 +- sys/dev/drm/drm_atomic.h | 4 + sys/dev/drm/drm_auth.c | 21 +- sys/dev/drm/drm_bufs.c | 164 +- sys/dev/drm/drm_context.c | 51 +- sys/dev/{drm2 => drm}/drm_crtc.c | 10 +- sys/dev/{drm2 => drm}/drm_crtc.h | 4 +- sys/dev/{drm2 => drm}/drm_crtc_helper.c | 10 +- sys/dev/{drm2 => drm}/drm_crtc_helper.h | 0 sys/dev/drm/drm_dma.c | 19 +- sys/dev/{drm2 => drm}/drm_dp_helper.h | 0 sys/dev/{drm2 => drm}/drm_dp_iic_helper.c | 6 +- sys/dev/drm/drm_drawable.c | 52 +- sys/dev/drm/drm_drv.c | 389 ++++- sys/dev/{drm2 => drm}/drm_edid.c | 6 +- sys/dev/{drm2 => drm}/drm_edid.h | 2 +- sys/dev/{drm2 => drm}/drm_edid_modes.h | 4 +- sys/dev/{drm2 => drm}/drm_fb_helper.c | 8 +- sys/dev/{drm2 => drm}/drm_fb_helper.h | 0 sys/dev/drm/drm_fops.c | 150 +- sys/dev/{drm2 => drm}/drm_fourcc.h | 0 sys/dev/{drm2 => drm}/drm_gem.c | 6 +- sys/dev/{drm2 => drm}/drm_gem_names.c | 4 +- sys/dev/{drm2 => drm}/drm_gem_names.h | 0 sys/dev/{drm2 => drm}/drm_global.c | 4 +- sys/dev/{drm2 => drm}/drm_global.h | 0 sys/dev/drm/drm_hashtab.h | 4 +- sys/dev/drm/drm_ioctl.c | 80 +- sys/dev/drm/drm_irq.c | 1225 +++++++++++--- sys/dev/drm/drm_linux_list.h | 72 +- sys/dev/{drm2 => drm}/drm_linux_list_sort.c | 5 +- sys/dev/drm/drm_lock.c | 16 +- sys/dev/drm/drm_memory.c | 18 +- sys/dev/drm/drm_mm.c | 620 ++++--- sys/dev/drm/drm_mm.h | 102 +- sys/dev/{drm2 => drm}/drm_mode.h | 0 sys/dev/{drm2 => drm}/drm_modes.c | 6 +- sys/dev/drm/drm_pci.c | 17 +- sys/dev/drm/drm_pciids.h | 30 +- sys/dev/drm/drm_scatter.c | 28 +- sys/dev/drm/drm_sman.c | 25 +- sys/dev/{drm2 => drm}/drm_stub.c | 0 sys/dev/drm/drm_sysctl.c | 133 +- sys/dev/drm/drm_vm.c | 134 +- sys/dev/drm/i915/i915_dma.c | 28 +- sys/dev/drm/i915/i915_drv.c | 12 +- sys/dev/drm/i915/i915_drv.h | 2 +- sys/dev/drm/i915/i915_irq.c | 20 +- sys/dev/drm/i915/i915_mem.c | 12 +- sys/dev/{drm2/i915 => drm/i915kms}/Makefile | 0 .../{drm2/i915 => drm/i915kms}/i915_debug.c | 12 +- sys/dev/{drm2/i915 => drm/i915kms}/i915_dma.c | 12 +- sys/dev/{drm2/i915 => drm/i915kms}/i915_drm.h | 2 +- sys/dev/{drm2/i915 => drm/i915kms}/i915_drv.c | 18 +- sys/dev/{drm2/i915 => drm/i915kms}/i915_drv.h | 8 +- sys/dev/{drm2/i915 => drm/i915kms}/i915_gem.c | 12 +- .../i915 => drm/i915kms}/i915_gem_evict.c | 8 +- .../i915kms}/i915_gem_execbuffer.c | 10 +- .../{drm2/i915 => drm/i915kms}/i915_gem_gtt.c | 10 +- .../i915 => drm/i915kms}/i915_gem_tiling.c | 8 +- sys/dev/{drm2/i915 => drm/i915kms}/i915_irq.c | 10 +- sys/dev/{drm2/i915 => drm/i915kms}/i915_reg.h | 0 .../{drm2/i915 => drm/i915kms}/i915_suspend.c | 8 +- .../{drm2/i915 => drm/i915kms}/intel_bios.c | 12 +- .../{drm2/i915 => drm/i915kms}/intel_bios.h | 2 +- .../{drm2/i915 => drm/i915kms}/intel_crt.c | 16 +- .../i915 => drm/i915kms}/intel_display.c | 16 +- sys/dev/{drm2/i915 => drm/i915kms}/intel_dp.c | 16 +- .../{drm2/i915 => drm/i915kms}/intel_drv.h | 10 +- sys/dev/{drm2/i915 => drm/i915kms}/intel_fb.c | 14 +- .../{drm2/i915 => drm/i915kms}/intel_hdmi.c | 14 +- .../{drm2/i915 => drm/i915kms}/intel_iic.c | 14 +- .../{drm2/i915 => drm/i915kms}/intel_lvds.c | 14 +- .../{drm2/i915 => drm/i915kms}/intel_modes.c | 12 +- .../i915 => drm/i915kms}/intel_opregion.c | 8 +- .../i915 => drm/i915kms}/intel_overlay.c | 12 +- .../{drm2/i915 => drm/i915kms}/intel_panel.c | 8 +- .../i915 => drm/i915kms}/intel_ringbuffer.c | 12 +- .../i915 => drm/i915kms}/intel_ringbuffer.h | 0 .../{drm2/i915 => drm/i915kms}/intel_sdvo.c | 18 +- .../i915 => drm/i915kms}/intel_sdvo_regs.h | 0 .../{drm2/i915 => drm/i915kms}/intel_sprite.c | 12 +- sys/dev/{drm2/i915 => drm/i915kms}/intel_tv.c | 14 +- sys/dev/drm/mach64/mach64_dma.c | 13 +- sys/dev/drm/mach64/mach64_drv.c | 4 +- sys/dev/drm/mach64/mach64_state.c | 8 +- sys/dev/drm/mga/mga_dma.c | 4 +- sys/dev/drm/mga/mga_drv.c | 4 +- sys/dev/drm/r128/r128_cce.c | 3 +- sys/dev/drm/r128/r128_drv.c | 4 +- sys/dev/drm/r128/r128_state.c | 68 +- sys/dev/drm/radeon/radeon_cp.c | 12 +- sys/dev/drm/radeon/radeon_cs.c | 6 +- sys/dev/drm/radeon/radeon_drv.c | 4 +- sys/dev/drm/radeon/radeon_drv.h | 2 +- sys/dev/drm/radeon/radeon_mem.c | 12 +- sys/dev/drm/radeon/radeon_state.c | 10 +- sys/dev/drm/savage/savage_bci.c | 9 +- sys/dev/drm/savage/savage_drv.c | 4 +- sys/dev/drm/savage/savage_state.c | 9 +- sys/dev/drm/sis/sis_drv.c | 4 +- sys/dev/drm/sis/sis_ds.c | 4 +- sys/dev/drm/tdfx/tdfx_drv.c | 4 +- sys/dev/{drm2 => drm}/ttm/ttm_agp_backend.c | 10 +- sys/dev/{drm2 => drm}/ttm/ttm_bo.c | 8 +- sys/dev/{drm2 => drm}/ttm/ttm_bo_api.h | 2 +- sys/dev/{drm2 => drm}/ttm/ttm_bo_driver.h | 10 +- sys/dev/{drm2 => drm}/ttm/ttm_bo_manager.c | 10 +- sys/dev/{drm2 => drm}/ttm/ttm_bo_util.c | 6 +- sys/dev/{drm2 => drm}/ttm/ttm_bo_vm.c | 8 +- sys/dev/{drm2 => drm}/ttm/ttm_execbuf_util.c | 8 +- sys/dev/{drm2 => drm}/ttm/ttm_execbuf_util.h | 2 +- sys/dev/{drm2 => drm}/ttm/ttm_lock.c | 4 +- sys/dev/{drm2 => drm}/ttm/ttm_lock.h | 6 +- sys/dev/{drm2 => drm}/ttm/ttm_memory.c | 8 +- sys/dev/{drm2 => drm}/ttm/ttm_memory.h | 0 sys/dev/{drm2 => drm}/ttm/ttm_module.h | 0 sys/dev/{drm2 => drm}/ttm/ttm_object.c | 8 +- sys/dev/{drm2 => drm}/ttm/ttm_object.h | 4 +- sys/dev/{drm2 => drm}/ttm/ttm_page_alloc.c | 6 +- sys/dev/{drm2 => drm}/ttm/ttm_page_alloc.h | 4 +- .../{drm2 => drm}/ttm/ttm_page_alloc_dma.c | 0 sys/dev/{drm2 => drm}/ttm/ttm_placement.h | 0 sys/dev/{drm2 => drm}/ttm/ttm_tt.c | 10 +- sys/dev/drm2/Makefile | 3 - sys/dev/drm2/drm.h | 1213 -------------- sys/dev/drm2/drmP.h | 1421 ----------------- sys/dev/drm2/drm_agpsupport.c | 416 ----- sys/dev/drm2/drm_atomic.h | 96 -- sys/dev/drm2/drm_auth.c | 188 --- sys/dev/drm2/drm_bufs.c | 1123 ------------- sys/dev/drm2/drm_context.c | 310 ---- sys/dev/drm2/drm_dma.c | 137 -- sys/dev/drm2/drm_drawable.c | 173 -- sys/dev/drm2/drm_drv.c | 1069 ------------- sys/dev/drm2/drm_fops.c | 259 --- sys/dev/drm2/drm_hashtab.c | 178 --- sys/dev/drm2/drm_hashtab.h | 66 - sys/dev/drm2/drm_internal.h | 42 - sys/dev/drm2/drm_ioctl.c | 318 ---- sys/dev/drm2/drm_irq.c | 1221 -------------- sys/dev/drm2/drm_linux_list.h | 175 -- sys/dev/drm2/drm_lock.c | 197 --- sys/dev/drm2/drm_memory.c | 121 -- sys/dev/drm2/drm_mm.c | 597 ------- sys/dev/drm2/drm_mm.h | 186 --- sys/dev/drm2/drm_pci.c | 125 -- sys/dev/drm2/drm_pciids.h | 770 --------- sys/dev/drm2/drm_sarea.h | 86 - sys/dev/drm2/drm_scatter.c | 129 -- sys/dev/drm2/drm_sman.c | 349 ---- sys/dev/drm2/drm_sman.h | 178 --- sys/dev/drm2/drm_sysctl.c | 365 ----- sys/dev/drm2/drm_vm.c | 229 --- sys/dev/drm2/drmn/Makefile | 48 - 161 files changed, 3504 insertions(+), 13201 deletions(-) rename sys/dev/{drm2 => drm}/drm_crtc.c (99%) rename sys/dev/{drm2 => drm}/drm_crtc.h (99%) rename sys/dev/{drm2 => drm}/drm_crtc_helper.c (99%) rename sys/dev/{drm2 => drm}/drm_crtc_helper.h (100%) rename sys/dev/{drm2 => drm}/drm_dp_helper.h (100%) rename sys/dev/{drm2 => drm}/drm_dp_iic_helper.c (98%) rename sys/dev/{drm2 => drm}/drm_edid.c (99%) rename sys/dev/{drm2 => drm}/drm_edid.h (99%) rename sys/dev/{drm2 => drm}/drm_edid_modes.h (99%) rename sys/dev/{drm2 => drm}/drm_fb_helper.c (99%) rename sys/dev/{drm2 => drm}/drm_fb_helper.h (100%) rename sys/dev/{drm2 => drm}/drm_fourcc.h (100%) rename sys/dev/{drm2 => drm}/drm_gem.c (99%) rename sys/dev/{drm2 => drm}/drm_gem_names.c (98%) rename sys/dev/{drm2 => drm}/drm_gem_names.h (100%) rename sys/dev/{drm2 => drm}/drm_global.c (98%) rename sys/dev/{drm2 => drm}/drm_global.h (100%) rename sys/dev/{drm2 => drm}/drm_linux_list_sort.c (95%) rename sys/dev/{drm2 => drm}/drm_mode.h (100%) rename sys/dev/{drm2 => drm}/drm_modes.c (99%) rename sys/dev/{drm2 => drm}/drm_stub.c (100%) rename sys/dev/{drm2/i915 => drm/i915kms}/Makefile (100%) rename sys/dev/{drm2/i915 => drm/i915kms}/i915_debug.c (99%) rename sys/dev/{drm2/i915 => drm/i915kms}/i915_dma.c (99%) rename sys/dev/{drm2/i915 => drm/i915kms}/i915_drm.h (99%) rename sys/dev/{drm2/i915 => drm/i915kms}/i915_drv.c (98%) rename sys/dev/{drm2/i915 => drm/i915kms}/i915_drv.h (99%) rename sys/dev/{drm2/i915 => drm/i915kms}/i915_gem.c (99%) rename sys/dev/{drm2/i915 => drm/i915kms}/i915_gem_evict.c (98%) rename sys/dev/{drm2/i915 => drm/i915kms}/i915_gem_execbuffer.c (99%) rename sys/dev/{drm2/i915 => drm/i915kms}/i915_gem_gtt.c (98%) rename sys/dev/{drm2/i915 => drm/i915kms}/i915_gem_tiling.c (99%) rename sys/dev/{drm2/i915 => drm/i915kms}/i915_irq.c (99%) rename sys/dev/{drm2/i915 => drm/i915kms}/i915_reg.h (100%) rename sys/dev/{drm2/i915 => drm/i915kms}/i915_suspend.c (99%) rename sys/dev/{drm2/i915 => drm/i915kms}/intel_bios.c (99%) rename sys/dev/{drm2/i915 => drm/i915kms}/intel_bios.h (99%) rename sys/dev/{drm2/i915 => drm/i915kms}/intel_crt.c (98%) rename sys/dev/{drm2/i915 => drm/i915kms}/intel_display.c (99%) rename sys/dev/{drm2/i915 => drm/i915kms}/intel_dp.c (99%) rename sys/dev/{drm2/i915 => drm/i915kms}/intel_drv.h (98%) rename sys/dev/{drm2/i915 => drm/i915kms}/intel_fb.c (96%) rename sys/dev/{drm2/i915 => drm/i915kms}/intel_hdmi.c (98%) rename sys/dev/{drm2/i915 => drm/i915kms}/intel_iic.c (98%) rename sys/dev/{drm2/i915 => drm/i915kms}/intel_lvds.c (99%) rename sys/dev/{drm2/i915 => drm/i915kms}/intel_modes.c (95%) rename sys/dev/{drm2/i915 => drm/i915kms}/intel_opregion.c (99%) rename sys/dev/{drm2/i915 => drm/i915kms}/intel_overlay.c (99%) rename sys/dev/{drm2/i915 => drm/i915kms}/intel_panel.c (98%) rename sys/dev/{drm2/i915 => drm/i915kms}/intel_ringbuffer.c (99%) rename sys/dev/{drm2/i915 => drm/i915kms}/intel_ringbuffer.h (100%) rename sys/dev/{drm2/i915 => drm/i915kms}/intel_sdvo.c (99%) rename sys/dev/{drm2/i915 => drm/i915kms}/intel_sdvo_regs.h (100%) rename sys/dev/{drm2/i915 => drm/i915kms}/intel_sprite.c (98%) rename sys/dev/{drm2/i915 => drm/i915kms}/intel_tv.c (99%) rename sys/dev/{drm2 => drm}/ttm/ttm_agp_backend.c (95%) rename sys/dev/{drm2 => drm}/ttm/ttm_bo.c (99%) rename sys/dev/{drm2 => drm}/ttm/ttm_bo_api.h (99%) rename sys/dev/{drm2 => drm}/ttm/ttm_bo_driver.h (99%) rename sys/dev/{drm2 => drm}/ttm/ttm_bo_manager.c (96%) rename sys/dev/{drm2 => drm}/ttm/ttm_bo_util.c (99%) rename sys/dev/{drm2 => drm}/ttm/ttm_bo_vm.c (98%) rename sys/dev/{drm2 => drm}/ttm/ttm_execbuf_util.c (97%) rename sys/dev/{drm2 => drm}/ttm/ttm_execbuf_util.h (99%) rename sys/dev/{drm2 => drm}/ttm/ttm_lock.c (99%) rename sys/dev/{drm2 => drm}/ttm/ttm_lock.h (98%) rename sys/dev/{drm2 => drm}/ttm/ttm_memory.c (98%) rename sys/dev/{drm2 => drm}/ttm/ttm_memory.h (100%) rename sys/dev/{drm2 => drm}/ttm/ttm_module.h (100%) rename sys/dev/{drm2 => drm}/ttm/ttm_object.c (98%) rename sys/dev/{drm2 => drm}/ttm/ttm_object.h (99%) rename sys/dev/{drm2 => drm}/ttm/ttm_page_alloc.c (99%) rename sys/dev/{drm2 => drm}/ttm/ttm_page_alloc.h (97%) rename sys/dev/{drm2 => drm}/ttm/ttm_page_alloc_dma.c (100%) rename sys/dev/{drm2 => drm}/ttm/ttm_placement.h (100%) rename sys/dev/{drm2 => drm}/ttm/ttm_tt.c (98%) delete mode 100644 sys/dev/drm2/Makefile delete mode 100644 sys/dev/drm2/drm.h delete mode 100644 sys/dev/drm2/drmP.h delete mode 100644 sys/dev/drm2/drm_agpsupport.c delete mode 100644 sys/dev/drm2/drm_atomic.h delete mode 100644 sys/dev/drm2/drm_auth.c delete mode 100644 sys/dev/drm2/drm_bufs.c delete mode 100644 sys/dev/drm2/drm_context.c delete mode 100644 sys/dev/drm2/drm_dma.c delete mode 100644 sys/dev/drm2/drm_drawable.c delete mode 100644 sys/dev/drm2/drm_drv.c delete mode 100644 sys/dev/drm2/drm_fops.c delete mode 100644 sys/dev/drm2/drm_hashtab.c delete mode 100644 sys/dev/drm2/drm_hashtab.h delete mode 100644 sys/dev/drm2/drm_internal.h delete mode 100644 sys/dev/drm2/drm_ioctl.c delete mode 100644 sys/dev/drm2/drm_irq.c delete mode 100644 sys/dev/drm2/drm_linux_list.h delete mode 100644 sys/dev/drm2/drm_lock.c delete mode 100644 sys/dev/drm2/drm_memory.c delete mode 100644 sys/dev/drm2/drm_mm.c delete mode 100644 sys/dev/drm2/drm_mm.h delete mode 100644 sys/dev/drm2/drm_pci.c delete mode 100644 sys/dev/drm2/drm_pciids.h delete mode 100644 sys/dev/drm2/drm_sarea.h delete mode 100644 sys/dev/drm2/drm_scatter.c delete mode 100644 sys/dev/drm2/drm_sman.c delete mode 100644 sys/dev/drm2/drm_sman.h delete mode 100644 sys/dev/drm2/drm_sysctl.c delete mode 100644 sys/dev/drm2/drm_vm.c delete mode 100644 sys/dev/drm2/drmn/Makefile diff --git a/sys/dev/Makefile b/sys/dev/Makefile index 100613b8e0..a32fdfc9f2 100644 --- a/sys/dev/Makefile +++ b/sys/dev/Makefile @@ -6,7 +6,6 @@ SUBDIR= \ crypto \ disk \ drm \ - drm2 \ misc \ netif \ pccard \ diff --git a/sys/dev/drm/Makefile b/sys/dev/drm/Makefile index c3f0918f1c..41133cc5af 100644 --- a/sys/dev/drm/Makefile +++ b/sys/dev/drm/Makefile @@ -1,6 +1,6 @@ # $DragonFly: src/sys/dev/drm/Makefile,v 1.3 2008/04/05 18:12:28 hasso Exp $ -SUBDIR = drm mach64 mga r128 radeon savage sis tdfx i915 +SUBDIR = drm mach64 mga r128 radeon savage sis tdfx i915 i915kms .include diff --git a/sys/dev/drm/ati_pcigart.c b/sys/dev/drm/ati_pcigart.c index 1a417c32ea..62b0c0b65b 100644 --- a/sys/dev/drm/ati_pcigart.c +++ b/sys/dev/drm/ati_pcigart.c @@ -61,12 +61,12 @@ drm_ati_alloc_pcigart_table(struct drm_device *dev, struct drm_dma_handle *dmah; int flags, ret; - dmah = malloc(sizeof(struct drm_dma_handle), DRM_MEM_DMA, + dmah = kmalloc(sizeof(struct drm_dma_handle), DRM_MEM_DMA, M_ZERO | M_NOWAIT); if (dmah == NULL) return ENOMEM; - DRM_UNLOCK(); + DRM_UNLOCK(dev); ret = bus_dma_tag_create(NULL, PAGE_SIZE, 0, /* tag, align, boundary */ gart_info->table_mask, BUS_SPACE_MAXADDR, /* lowaddr, highaddr */ NULL, NULL, /* filtfunc, filtfuncargs */ @@ -75,7 +75,7 @@ drm_ati_alloc_pcigart_table(struct drm_device *dev, 0, /* flags */ &dmah->tag); if (ret != 0) { - free(dmah, DRM_MEM_DMA); + kfree(dmah, DRM_MEM_DMA); return ENOMEM; } @@ -87,10 +87,10 @@ drm_ati_alloc_pcigart_table(struct drm_device *dev, ret = bus_dmamem_alloc(dmah->tag, &dmah->vaddr, flags, &dmah->map); if (ret != 0) { bus_dma_tag_destroy(dmah->tag); - free(dmah, DRM_MEM_DMA); + kfree(dmah, DRM_MEM_DMA); return ENOMEM; } - DRM_LOCK(); + DRM_LOCK(dev); ret = bus_dmamap_load(dmah->tag, dmah->map, dmah->vaddr, gart_info->table_size, drm_ati_alloc_pcigart_table_cb, dmah, @@ -98,7 +98,7 @@ drm_ati_alloc_pcigart_table(struct drm_device *dev, if (ret != 0) { bus_dmamem_free(dmah->tag, dmah->vaddr, dmah->map); bus_dma_tag_destroy(dmah->tag); - free(dmah, DRM_MEM_DMA); + kfree(dmah, DRM_MEM_DMA); return ENOMEM; } @@ -115,7 +115,7 @@ drm_ati_free_pcigart_table(struct drm_device *dev, bus_dmamem_free(dmah->tag, dmah->vaddr, dmah->map); bus_dma_tag_destroy(dmah->tag); - free(dmah, DRM_MEM_DMA); + kfree(dmah, DRM_MEM_DMA); gart_info->dmah = NULL; } diff --git a/sys/dev/drm/drm.h b/sys/dev/drm/drm.h index 942a9aed02..886d88deca 100644 --- a/sys/dev/drm/drm.h +++ b/sys/dev/drm/drm.h @@ -31,6 +31,8 @@ * 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. + * + * $FreeBSD: src/sys/dev/drm2/drm.h,v 1.1 2012/05/22 11:07:44 kib Exp $ */ /** @@ -95,6 +97,7 @@ #if defined(__linux__) || defined(__NetBSD__) #define DRM_MAJOR 226 #endif +#define DRM_MAX_MINOR 15 #define DRM_NAME "drm" /**< Name in kernel, /dev, and /proc */ #define DRM_MIN_ORDER 5 /**< At least 2^5 bytes = 32 bytes */ @@ -235,7 +238,7 @@ enum drm_map_type { _DRM_AGP = 3, /**< AGP/GART */ _DRM_SCATTER_GATHER = 4, /**< Scatter/gather memory for PCI DMA */ _DRM_CONSISTENT = 5, /**< Consistent memory for PCI DMA */ - _DRM_TTM = 6 + _DRM_GEM = 6 /**< GEM */ }; /** @@ -521,15 +524,18 @@ struct drm_irq_busid { enum drm_vblank_seq_type { _DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */ _DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */ + _DRM_VBLANK_HIGH_CRTC_MASK = 0x0000003e, + _DRM_VBLANK_EVENT = 0x4000000, /**< Send event instead of blocking */ _DRM_VBLANK_FLIP = 0x8000000, /**< Scheduled buffer swap should flip */ _DRM_VBLANK_NEXTONMISS = 0x10000000, /**< If missed, wait for next vblank */ _DRM_VBLANK_SECONDARY = 0x20000000, /**< Secondary display controller */ _DRM_VBLANK_SIGNAL = 0x40000000 /**< Send signal instead of blocking */ }; +#define _DRM_VBLANK_HIGH_CRTC_SHIFT 1 #define _DRM_VBLANK_TYPES_MASK (_DRM_VBLANK_ABSOLUTE | _DRM_VBLANK_RELATIVE) -#define _DRM_VBLANK_FLAGS_MASK (_DRM_VBLANK_SIGNAL | _DRM_VBLANK_SECONDARY | \ - _DRM_VBLANK_NEXTONMISS) +#define _DRM_VBLANK_FLAGS_MASK (_DRM_VBLANK_EVENT | _DRM_VBLANK_SIGNAL | \ + _DRM_VBLANK_SECONDARY | _DRM_VBLANK_NEXTONMISS) struct drm_wait_vblank_request { enum drm_vblank_seq_type type; @@ -640,7 +646,6 @@ struct drm_set_version { int drm_dd_minor; }; - #define DRM_FENCE_FLAG_EMIT 0x00000001 #define DRM_FENCE_FLAG_SHAREABLE 0x00000002 /** @@ -667,7 +672,7 @@ struct drm_fence_arg { unsigned int error; unsigned int sequence; unsigned int pad64; - uint64_t expand_pad[2]; /*Future expansion */ + uint64_t expand_pad[2]; /* Future expansion */ }; /* Buffer permissions, referring to how the GPU uses the buffers. @@ -983,6 +988,35 @@ struct drm_gem_open { uint64_t size; }; +struct drm_get_cap { + uint64_t capability; + uint64_t value; +}; + +struct drm_event { + uint32_t type; + uint32_t length; +}; + +#define DRM_EVENT_VBLANK 0x01 +#define DRM_EVENT_FLIP_COMPLETE 0x02 + +struct drm_event_vblank { + struct drm_event base; + uint64_t user_data; + uint32_t tv_sec; + uint32_t tv_usec; + uint32_t sequence; + uint32_t reserved; +}; + +#define DRM_CAP_DUMB_BUFFER 0x1 +#define DRM_CAP_VBLANK_HIGH_CRTC 0x2 +#define DRM_CAP_DUMB_PREFERRED_DEPTH 0x3 +#define DRM_CAP_DUMB_PREFER_SHADOW 0x4 + +#include "drm_mode.h" + /** * \name Ioctls Definitions */ @@ -1008,6 +1042,8 @@ struct drm_gem_open { #define DRM_IOCTL_GEM_FLINK DRM_IOWR(0x0a, struct drm_gem_flink) #define DRM_IOCTL_GEM_OPEN DRM_IOWR(0x0b, struct drm_gem_open) +#define DRM_IOCTL_GET_CAP DRM_IOWR(0x0c, struct drm_get_cap) + #define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, struct drm_unique) #define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, struct drm_auth) #define DRM_IOCTL_BLOCK DRM_IOWR(0x12, struct drm_block) @@ -1025,6 +1061,9 @@ struct drm_gem_open { #define DRM_IOCTL_SET_SAREA_CTX DRM_IOW( 0x1c, struct drm_ctx_priv_map) #define DRM_IOCTL_GET_SAREA_CTX DRM_IOWR(0x1d, struct drm_ctx_priv_map) +#define DRM_IOCTL_SET_MASTER DRM_IO(0x1e) +#define DRM_IOCTL_DROP_MASTER DRM_IO(0x1f) + #define DRM_IOCTL_ADD_CTX DRM_IOWR(0x20, struct drm_ctx) #define DRM_IOCTL_RM_CTX DRM_IOWR(0x21, struct drm_ctx) #define DRM_IOCTL_MOD_CTX DRM_IOW( 0x22, struct drm_ctx) @@ -1039,6 +1078,8 @@ struct drm_gem_open { #define DRM_IOCTL_UNLOCK DRM_IOW( 0x2b, struct drm_lock) #define DRM_IOCTL_FINISH DRM_IOW( 0x2c, struct drm_lock) +#define DRM_IOCTL_GEM_PRIME_OPEN DRM_IOWR(0x2e, struct drm_gem_open) + #define DRM_IOCTL_AGP_ACQUIRE DRM_IO( 0x30) #define DRM_IOCTL_AGP_RELEASE DRM_IO( 0x31) #define DRM_IOCTL_AGP_ENABLE DRM_IOW( 0x32, struct drm_agp_mode) @@ -1055,6 +1096,34 @@ struct drm_gem_open { #define DRM_IOCTL_UPDATE_DRAW DRM_IOW(0x3f, struct drm_update_draw) +#define DRM_IOCTL_MODE_GETRESOURCES DRM_IOWR(0xA0, struct drm_mode_card_res) +#define DRM_IOCTL_MODE_GETCRTC DRM_IOWR(0xA1, struct drm_mode_crtc) +#define DRM_IOCTL_MODE_SETCRTC DRM_IOWR(0xA2, struct drm_mode_crtc) +#define DRM_IOCTL_MODE_CURSOR DRM_IOWR(0xA3, struct drm_mode_cursor) +#define DRM_IOCTL_MODE_GETGAMMA DRM_IOWR(0xA4, struct drm_mode_crtc_lut) +#define DRM_IOCTL_MODE_SETGAMMA DRM_IOWR(0xA5, struct drm_mode_crtc_lut) +#define DRM_IOCTL_MODE_GETENCODER DRM_IOWR(0xA6, struct drm_mode_get_encoder) +#define DRM_IOCTL_MODE_GETCONNECTOR DRM_IOWR(0xA7, struct drm_mode_get_connector) +#define DRM_IOCTL_MODE_ATTACHMODE DRM_IOWR(0xA8, struct drm_mode_mode_cmd) +#define DRM_IOCTL_MODE_DETACHMODE DRM_IOWR(0xA9, struct drm_mode_mode_cmd) + +#define DRM_IOCTL_MODE_GETPROPERTY DRM_IOWR(0xAA, struct drm_mode_get_property) +#define DRM_IOCTL_MODE_SETPROPERTY DRM_IOWR(0xAB, struct drm_mode_connector_set_property) +#define DRM_IOCTL_MODE_GETPROPBLOB DRM_IOWR(0xAC, struct drm_mode_get_blob) +#define DRM_IOCTL_MODE_GETFB DRM_IOWR(0xAD, struct drm_mode_fb_cmd) +#define DRM_IOCTL_MODE_ADDFB DRM_IOWR(0xAE, struct drm_mode_fb_cmd) +#define DRM_IOCTL_MODE_RMFB DRM_IOWR(0xAF, unsigned int) +#define DRM_IOCTL_MODE_PAGE_FLIP DRM_IOWR(0xB0, struct drm_mode_crtc_page_flip) +#define DRM_IOCTL_MODE_DIRTYFB DRM_IOWR(0xB1, struct drm_mode_fb_dirty_cmd) + +#define DRM_IOCTL_MODE_CREATE_DUMB DRM_IOWR(0xB2, struct drm_mode_create_dumb) +#define DRM_IOCTL_MODE_MAP_DUMB DRM_IOWR(0xB3, struct drm_mode_map_dumb) +#define DRM_IOCTL_MODE_DESTROY_DUMB DRM_IOWR(0xB4, struct drm_mode_destroy_dumb) +#define DRM_IOCTL_MODE_GETPLANERESOURCES DRM_IOWR(0xB5, struct drm_mode_get_plane_res) +#define DRM_IOCTL_MODE_GETPLANE DRM_IOWR(0xB6, struct drm_mode_get_plane) +#define DRM_IOCTL_MODE_SETPLANE DRM_IOWR(0xB7, struct drm_mode_set_plane) +#define DRM_IOCTL_MODE_ADDFB2 DRM_IOWR(0xB8, struct drm_mode_fb_cmd2) + #define DRM_IOCTL_MM_INIT DRM_IOWR(0xc0, struct drm_mm_init_arg) #define DRM_IOCTL_MM_TAKEDOWN DRM_IOWR(0xc1, struct drm_mm_type_arg) #define DRM_IOCTL_MM_LOCK DRM_IOWR(0xc2, struct drm_mm_type_arg) diff --git a/sys/dev/drm/drm/Makefile b/sys/dev/drm/drm/Makefile index c9b651a760..f55779679f 100644 --- a/sys/dev/drm/drm/Makefile +++ b/sys/dev/drm/drm/Makefile @@ -1,41 +1,49 @@ -.PATH: ${.CURDIR}/.. +.PATH: ${.CURDIR}/.. ${.CURDIR}/../ttm KMOD = drm -SRCS = \ +SRCS = \ ati_pcigart.c \ drm_agpsupport.c \ drm_auth.c \ drm_bufs.c \ drm_context.c \ + drm_crtc.c \ + drm_crtc_helper.c \ drm_dma.c \ + drm_dp_iic_helper.c \ drm_drawable.c \ drm_drv.c \ + drm_edid.c \ + drm_fb_helper.c \ drm_fops.c \ + drm_gem.c \ + drm_gem_names.c \ + drm_global.c \ drm_hashtab.c \ drm_ioctl.c \ drm_irq.c \ + drm_linux_list_sort.c \ drm_lock.c \ drm_memory.c \ drm_mm.c \ + drm_modes.c \ drm_pci.c \ drm_scatter.c \ drm_sman.c \ + drm_stub.c \ drm_sysctl.c \ - drm_vm.c + drm_vm.c \ + ttm_lock.c \ + ttm_object.c \ + ttm_tt.c \ + ttm_bo_util.c \ + ttm_bo.c \ + ttm_bo_manager.c \ + ttm_execbuf_util.c \ + ttm_memory.c \ + ttm_page_alloc.c \ + ttm_bo_vm.c -SRCS += device_if.h bus_if.h pci_if.h opt_drm.h -CFLAGS += ${DEBUG_FLAGS} -I. -I.. - -.if defined(DRM_DEBUG) -DRM_DEBUG_OPT= "\#define DRM_DEBUG 1" -.endif - -.if !defined(DRM_NOLINUX) -DRM_LINUX_OPT= "\#define DRM_LINUX 1" -.endif - -opt_drm.h: - touch ${.TARGET} - echo $(DRM_DEBUG_OPT) >> ${.TARGET} - echo $(DRM_LINUX_OPT) >> ${.TARGET} +SRCS += device_if.h bus_if.h pci_if.h device_if.h iicbus_if.h opt_drm.h \ + opt_ktr.h opt_vm.h .include diff --git a/sys/dev/drm/drmP.h b/sys/dev/drm/drmP.h index f6747807d6..6e46b7ae2a 100644 --- a/sys/dev/drm/drmP.h +++ b/sys/dev/drm/drmP.h @@ -29,6 +29,7 @@ * Rickard E. (Rik) Faith * Gareth Hughes * + * $FreeBSD: head/sys/dev/drm2/drmP.h 248084 2013-03-09 02:32:23Z attilio $ */ #ifndef _DRM_P_H_ @@ -43,23 +44,28 @@ struct drm_file; #include #include #include +#include #include #include -#include +#include #include #include #include #include #include +#include +#include #include #include #include #include #include +#include #include -#include -#include +#include +#include #include +#include #include #include #include @@ -72,7 +78,9 @@ struct drm_file; #include #include #include +#if defined(__i386__) || defined(__amd64__) #include +#endif #include #include #if _BYTE_ORDER == _BIG_ENDIAN @@ -84,36 +92,33 @@ struct drm_file; #include #include #include -#include #include -#include -#include +#include #include #include -#include - -#include "dev/drm/drm.h" -#include "dev/drm/drm_linux_list.h" -#include "dev/drm/drm_atomic.h" -#include "dev/drm/drm_internal.h" - -#include +/* XXX: bool definition */ +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "opt_drm.h" #ifdef DRM_DEBUG #undef DRM_DEBUG #define DRM_DEBUG_DEFAULT_ON 1 #endif /* DRM_DEBUG */ -#if defined(DRM_LINUX) && DRM_LINUX && !defined(__x86_64__) && !defined(__DragonFly__) /* XXX */ -#include -#include -#include -#else -/* Either it was defined when it shouldn't be (FreeBSD amd64) or it isn't - * supported on this OS yet. - */ +#define DRM_DEBUGBITS_DEBUG 0x1 +#define DRM_DEBUGBITS_KMS 0x2 +#define DRM_DEBUGBITS_FAILED_IOCTL 0x4 + #undef DRM_LINUX #define DRM_LINUX 0 -#endif /* driver capabilities and requirements mask */ #define DRIVER_USE_AGP 0x1 @@ -123,13 +128,29 @@ struct drm_file; #define DRIVER_SG 0x10 #define DRIVER_HAVE_DMA 0x20 #define DRIVER_HAVE_IRQ 0x40 -#define DRIVER_DMA_QUEUE 0x100 +#define DRIVER_IRQ_SHARED 0x80 +#define DRIVER_IRQ_VBL 0x100 +#define DRIVER_DMA_QUEUE 0x200 +#define DRIVER_FB_DMA 0x400 +#define DRIVER_IRQ_VBL2 0x800 +#define DRIVER_GEM 0x1000 +#define DRIVER_MODESET 0x2000 +#define DRIVER_USE_PLATFORM_DEVICE 0x4000 +#define DRIVER_LOCKLESS_IRQ 0x8000 #define DRM_HASH_SIZE 16 /* Size of key hash table */ #define DRM_KERNEL_CONTEXT 0 /* Change drm_resctx if changed */ #define DRM_RESERVED_CONTEXTS 1 /* Change drm_resctx if changed */ +#define DRM_GEM_MAPPING_MASK (3ULL << 62) +#define DRM_GEM_MAPPING_KEY (2ULL << 62) /* Non-canonical address form */ +#define DRM_GEM_MAX_IDX 0x3fffff +#define DRM_GEM_MAPPING_IDX(o) (((o) >> 40) & DRM_GEM_MAX_IDX) +#define DRM_GEM_MAPPING_OFF(i) (((uint64_t)(i)) << 40) +#define DRM_GEM_MAPPING_MAPOFF(o) \ + ((o) & ~(DRM_GEM_MAPPING_OFF(DRM_GEM_MAX_IDX) | DRM_GEM_MAPPING_KEY)) + MALLOC_DECLARE(DRM_MEM_DMA); MALLOC_DECLARE(DRM_MEM_SAREA); MALLOC_DECLARE(DRM_MEM_DRIVER); @@ -146,6 +167,9 @@ MALLOC_DECLARE(DRM_MEM_SGLISTS); MALLOC_DECLARE(DRM_MEM_DRAWABLE); MALLOC_DECLARE(DRM_MEM_MM); MALLOC_DECLARE(DRM_MEM_HASHTAB); +MALLOC_DECLARE(DRM_MEM_KMS); + +SYSCTL_DECL(_hw_drm); #define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8) @@ -169,21 +193,19 @@ MALLOC_DECLARE(DRM_MEM_HASHTAB); #define DRM_CURPROC curthread #define DRM_STRUCTPROC struct thread -#define DRM_SPINTYPE struct lock -#define DRM_SPININIT(l,name) lockinit(l, name, 0, LK_CANRECURSE) -#define DRM_SPINUNINIT(l) lockuninit(l) -#define DRM_SPINLOCK(l) lockmgr(l, LK_EXCLUSIVE|LK_RETRY|LK_CANRECURSE) -#define DRM_SPINUNLOCK(u) lockmgr(u, LK_RELEASE) -#define DRM_SPINLOCK_IRQSAVE(l, irqflags) do { \ - DRM_SPINLOCK(l); \ - (void)irqflags; \ -} while (0) -#define DRM_SPINUNLOCK_IRQRESTORE(u, irqflags) DRM_SPINUNLOCK(u) -#define DRM_SPINLOCK_ASSERT(l) -#define DRM_CURRENTPID (curthread->td_proc ? \ - curthread->td_proc->p_pid : -1) -#define DRM_LOCK() DRM_SPINLOCK(&dev->dev_lock) -#define DRM_UNLOCK() DRM_SPINUNLOCK(&dev->dev_lock) +#define DRM_CURRENTPID curthread->td_proc->p_pid +#define DRM_LOCK(dev) lockmgr(&(dev)->dev_struct_lock, LK_EXCLUSIVE); +#define DRM_UNLOCK(dev) lockmgr(&(dev)->dev_struct_lock, LK_RELEASE); +#define DRM_LOCK_SLEEP(dev, chan, flags, msg, timeout) \ + (lksleep((chan), &(dev)->dev_struct_lock, (flags), (msg), (timeout))) +#if defined(INVARIANTS) +#define DRM_LOCK_ASSERT(dev) KKASSERT(lockstatus(&(dev)->dev_struct_lock, curthread) != 0); +#define DRM_UNLOCK_ASSERT(dev) KKASSERT(lockstatus(&(dev)->dev_struct_lock, curthread) == 0); +#else +#define DRM_LOCK_ASSERT(d) +#define DRM_UNLOCK_ASSERT(d) +#endif + #define DRM_SYSCTL_HANDLER_ARGS (SYSCTL_HANDLER_ARGS) #define DRM_IRQ_ARGS void *arg @@ -192,6 +214,7 @@ typedef void irqreturn_t; #define IRQ_NONE /* nothing */ #define unlikely(x) __builtin_expect(!!(x), 0) +#define likely(x) __builtin_expect(!!(x), 1) #define container_of(ptr, type, member) ({ \ __typeof( ((type *)0)->member ) *__mptr = (ptr); \ (type *)( (char *)__mptr - offsetof(type,member) );}) @@ -211,12 +234,21 @@ enum { #define DRM_AGP_FIND_DEVICE() agp_find_device() #define DRM_MTRR_WC MDF_WRITECOMBINE #define jiffies ticks +#define jiffies_to_msecs(x) (((int64_t)(x)) * 1000 / hz) +#define msecs_to_jiffies(x) (((int64_t)(x)) * hz / 1000) +#define time_after(a,b) ((long)(b) - (long)(a) < 0) +#define time_after_eq(a,b) ((long)(b) - (long)(a) <= 0) +#define drm_msleep(x, msg) pause((msg), ((int64_t)(x)) * hz / 1000) typedef vm_paddr_t dma_addr_t; -typedef u_int64_t u64; -typedef u_int32_t u32; -typedef u_int16_t u16; -typedef u_int8_t u8; +typedef uint64_t u64; +typedef uint32_t u32; +typedef uint16_t u16; +typedef uint8_t u8; +typedef int64_t s64; +typedef int32_t s32; +typedef int16_t s16; +typedef int8_t s8; /* DRM_READMEMORYBARRIER() prevents reordering of reads. * DRM_WRITEMEMORYBARRIER() prevents reordering of writes. @@ -230,20 +262,26 @@ typedef u_int8_t u8; *(volatile u_int8_t *)(((vm_offset_t)(map)->virtual) + \ (vm_offset_t)(offset)) #define DRM_READ16(map, offset) \ - *(volatile u_int16_t *)(((vm_offset_t)(map)->virtual) + \ - (vm_offset_t)(offset)) + le16toh(*(volatile u_int16_t *)(((vm_offset_t)(map)->virtual) + \ + (vm_offset_t)(offset))) #define DRM_READ32(map, offset) \ - *(volatile u_int32_t *)(((vm_offset_t)(map)->virtual) + \ - (vm_offset_t)(offset)) + le32toh(*(volatile u_int32_t *)(((vm_offset_t)(map)->virtual) + \ + (vm_offset_t)(offset))) +#define DRM_READ64(map, offset) \ + le64toh(*(volatile u_int64_t *)(((vm_offset_t)(map)->virtual) + \ + (vm_offset_t)(offset))) #define DRM_WRITE8(map, offset, val) \ *(volatile u_int8_t *)(((vm_offset_t)(map)->virtual) + \ (vm_offset_t)(offset)) = val #define DRM_WRITE16(map, offset, val) \ *(volatile u_int16_t *)(((vm_offset_t)(map)->virtual) + \ - (vm_offset_t)(offset)) = val + (vm_offset_t)(offset)) = htole16(val) #define DRM_WRITE32(map, offset, val) \ *(volatile u_int32_t *)(((vm_offset_t)(map)->virtual) + \ - (vm_offset_t)(offset)) = val + (vm_offset_t)(offset)) = htole32(val) +#define DRM_WRITE64(map, offset, val) \ + *(volatile u_int64_t *)(((vm_offset_t)(map)->virtual) + \ + (vm_offset_t)(offset)) = htole64(val) #define DRM_VERIFYAREA_READ( uaddr, size ) \ (!useracc(__DECONST(caddr_t, uaddr), size, VM_PROT_READ)) @@ -275,7 +313,7 @@ do { \ if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) || \ dev->lock.file_priv != file_priv) { \ DRM_ERROR("%s called without lock held\n", \ - __func__); \ + __FUNCTION__); \ return EINVAL; \ } \ } while (0) @@ -283,42 +321,56 @@ do { \ /* Returns -errno to shared code */ #define DRM_WAIT_ON( ret, queue, timeout, condition ) \ for ( ret = 0 ; !ret && !(condition) ; ) { \ - DRM_UNLOCK(); \ + DRM_UNLOCK(dev); \ lwkt_serialize_enter(&dev->irq_lock); \ if (!(condition)) { \ tsleep_interlock(&(queue), PCATCH); \ lwkt_serialize_exit(&dev->irq_lock); \ ret = -tsleep(&(queue), PCATCH | PINTERLOCKED, \ "drmwtq", (timeout)); \ - } else { \ - lwkt_serialize_exit(&dev->irq_lock); \ - } \ - DRM_LOCK(); \ + } else { \ + lwkt_serialize_exit(&dev->irq_lock); \ + } \ + DRM_LOCK(dev); \ } -#define printf kprintf -#define snprintf ksnprintf -#define sscanf ksscanf -#define malloc kmalloc -#define realloc krealloc -#define reallocf krealloc /* XXX XXX XXX */ - __inline static void -free(void *addr, struct malloc_type *type) +vm_page_unhold_pages(vm_page_t *ma, int count) { - if (addr != NULL) - kfree(addr, type); + int i; + + for (i = 0; i < count; i++) + vm_page_unhold(ma[i]); } +vm_page_t +vm_phys_fictitious_to_vm_page(vm_paddr_t pa); + +int +vm_phys_fictitious_reg_range(vm_paddr_t start, vm_paddr_t end, int pat_mode); + + #define DRM_ERROR(fmt, ...) \ - printf("error: [" DRM_NAME ":pid%d:%s] *ERROR* " fmt, \ + kprintf("error: [" DRM_NAME ":pid%d:%s] *ERROR* " fmt, \ DRM_CURRENTPID, __func__ , ##__VA_ARGS__) -#define DRM_INFO(fmt, ...) printf("info: [" DRM_NAME "] " fmt , ##__VA_ARGS__) - +#define DRM_INFO(fmt, ...) kprintf("info: [" DRM_NAME "] " fmt , ##__VA_ARGS__) + #define DRM_DEBUG(fmt, ...) do { \ - if (drm_debug_flag) \ - printf("[" DRM_NAME ":pid%d:%s] " fmt, DRM_CURRENTPID, \ + if ((drm_debug_flag & DRM_DEBUGBITS_DEBUG) != 0) \ + kprintf("[" DRM_NAME ":pid%d:%s] " fmt, DRM_CURRENTPID, \ + __func__ , ##__VA_ARGS__); \ +} while (0) + +#define DRM_DEBUG_KMS(fmt, ...) do { \ + if ((drm_debug_flag & DRM_DEBUGBITS_KMS) != 0) \ + kprintf("[" DRM_NAME ":KMS:pid%d:%s] " fmt, DRM_CURRENTPID,\ + __func__ , ##__VA_ARGS__); \ +} while (0) + +#define DRM_DEBUG_DRIVER(fmt, ...) do { \ + if ((drm_debug_flag & DRM_DEBUGBITS_KMS) != 0) \ + kprintf("[" DRM_NAME ":KMS:pid%d:%s] " fmt, DRM_CURRENTPID,\ __func__ , ##__VA_ARGS__); \ } while (0) @@ -339,6 +391,9 @@ struct drm_msi_blacklist_entry #define DRM_AUTH 0x1 #define DRM_MASTER 0x2 #define DRM_ROOT_ONLY 0x4 +#define DRM_CONTROL_ALLOW 0x8 +#define DRM_UNLOCKED 0x10 + typedef struct drm_ioctl_desc { unsigned long cmd; int (*func)(struct drm_device *dev, void *data, @@ -415,19 +470,37 @@ typedef struct drm_buf_entry { drm_freelist_t freelist; } drm_buf_entry_t; +/* Event queued up for userspace to read */ +struct drm_pending_event { + struct drm_event *event; + struct list_head link; + struct drm_file *file_priv; + pid_t pid; /* pid of requester, no guarantee it's valid by the time + we deliver the event, for tracing only */ + void (*destroy)(struct drm_pending_event *event); +}; + typedef TAILQ_HEAD(drm_file_list, drm_file) drm_file_list_t; struct drm_file { TAILQ_ENTRY(drm_file) link; struct drm_device *dev; int authenticated; int master; - int minor; pid_t pid; uid_t uid; - int refs; drm_magic_t magic; unsigned long ioctl_count; + void *driver_priv; + struct drm_gem_names object_names; + + int is_master; + struct drm_master *masterp; + + struct list_head fbs; + + struct list_head event_list; + int event_space; }; typedef struct drm_lock_data { @@ -521,6 +594,21 @@ struct drm_vblank_info { int inmodeset; /* Display driver is setting mode */ }; +/* Size of ringbuffer for vblank timestamps. Just double-buffer + * in initial implementation. + */ +#define DRM_VBLANKTIME_RBSIZE 2 + +/* Flags and return codes for get_vblank_timestamp() driver function. */ +#define DRM_CALLED_FROM_VBLIRQ 1 +#define DRM_VBLANKTIME_SCANOUTPOS_METHOD (1 << 0) +#define DRM_VBLANKTIME_INVBL (1 << 1) + +/* get_scanout_position() return flags */ +#define DRM_SCANOUTPOS_VALID (1 << 0) +#define DRM_SCANOUTPOS_INVBL (1 << 1) +#define DRM_SCANOUTPOS_ACCURATE (1 << 2) + /* location of GART table */ #define DRM_ATI_GART_MAIN 1 #define DRM_ATI_GART_FB 2 @@ -542,6 +630,67 @@ struct drm_ati_pcigart_info { struct drm_dma_handle *dmah; /* handle for ATI PCIGART table */ }; +typedef vm_paddr_t resource_size_t; + +/** + * GEM specific mm private for tracking GEM objects + */ +struct drm_gem_mm { + struct drm_open_hash offset_hash; /**< User token hash table for maps */ + struct unrhdr *idxunr; +}; + +struct drm_gem_object { + /** Reference count of this object */ + u_int refcount; + + /** Handle count of this object. Each handle also holds a reference */ + u_int handle_count; /* number of handles on this object */ + + /** Related drm device */ + struct drm_device *dev; + + /** File representing the shmem storage: filp in Linux parlance */ + vm_object_t vm_obj; + + bool on_map; + struct drm_hash_item map_list; + + /** + * Size of the object, in bytes. Immutable over the object's + * lifetime. + */ + size_t size; + + /** + * Global name for this object, starts at 1. 0 means unnamed. + * Access is covered by the object_name_lock in the related drm_device + */ + int name; + + /** + * Memory domains. These monitor which caches contain read/write data + * related to the object. When transitioning from one set of domains + * to another, the driver is called to ensure that caches are suitably + * flushed and invalidated + */ + uint32_t read_domains; + uint32_t write_domain; + + /** + * While validating an exec operation, the + * new read/write domain values are computed here. + * They will be transferred to the above values + * at the point that any cache flushing occurs + */ + uint32_t pending_read_domains; + uint32_t pending_write_domain; + + void *driver_private; +}; + +#include "drm_crtc.h" + #ifndef DMA_BIT_MASK #define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : (1ULL<<(n)) - 1) #endif @@ -575,9 +724,32 @@ struct drm_driver_info { int (*irq_postinstall)(struct drm_device *dev); void (*irq_uninstall)(struct drm_device *dev); void (*irq_handler)(DRM_IRQ_ARGS); + u32 (*get_vblank_counter)(struct drm_device *dev, int crtc); int (*enable_vblank)(struct drm_device *dev, int crtc); void (*disable_vblank)(struct drm_device *dev, int crtc); + int (*get_scanout_position)(struct drm_device *dev, int crtc, + int *vpos, int *hpos); + + int (*get_vblank_timestamp)(struct drm_device *dev, int crtc, + int *max_error, struct timeval *vblank_time, + unsigned flags); + + int (*gem_init_object)(struct drm_gem_object *obj); + void (*gem_free_object)(struct drm_gem_object *obj); + + struct cdev_pager_ops *gem_pager_ops; + + int (*dumb_create)(struct drm_file *file_priv, + struct drm_device *dev, struct drm_mode_create_dumb *args); + int (*dumb_map_offset)(struct drm_file *file_priv, + struct drm_device *dev, uint32_t handle, uint64_t *offset); + int (*dumb_destroy)(struct drm_file *file_priv, + struct drm_device *dev, uint32_t handle); + + int (*sysctl_init)(struct drm_device *dev, + struct sysctl_ctx_list *ctx, struct sysctl_oid *top); + void (*sysctl_cleanup)(struct drm_device *dev); drm_pci_id_list_t *id_entry; /* PCI ID, name, and chipset private */ @@ -609,6 +781,41 @@ struct drm_driver_info { u32 driver_features; }; +/** + * DRM minor structure. This structure represents a drm minor number. + */ +struct drm_minor { + int index; /**< Minor device number */ + int type; /**< Control or render */ + device_t kdev; /**< OS device */ + struct drm_device *dev; + + struct drm_master *master; /* currently active master for this node */ + struct list_head master_list; + struct drm_mode_group mode_group; +}; + +/* mode specified on the command line */ +struct drm_cmdline_mode { + bool specified; + bool refresh_specified; + bool bpp_specified; + int xres, yres; + int bpp; + int refresh; + bool rb; + bool interlace; + bool cvt; + bool margins; + enum drm_connector_force force; +}; + +struct drm_pending_vblank_event { + struct drm_pending_event base; + int pipe; + struct drm_event_vblank event; +}; + /* Length for the array of resource pointers for drm_get_resource_*. */ #define DRM_MAX_PCI_RESOURCE 6 @@ -631,11 +838,11 @@ struct drm_device { int flags; /* Flags to open(2) */ /* Locks */ - DRM_SPINTYPE vbl_lock; /* protects vblank operations */ - DRM_SPINTYPE dma_lock; /* protects dev->dma */ + struct spinlock dma_lock; /* protects dev->dma */ struct lwkt_serialize irq_lock; /* protects irq condition checks */ - DRM_SPINTYPE dev_lock; /* protects everything else */ - DRM_SPINTYPE drw_lock; + struct lock dev_lock; /* protects everything else */ + struct lock dev_struct_lock; + struct spinlock drw_lock; /* Usage Counters */ int open_count; /* Outstanding files open */ @@ -682,16 +889,13 @@ struct drm_device { atomic_t context_flag; /* Context swapping flag */ int last_context; /* Last current context */ - int vblank_disable_allowed; - struct callout vblank_disable_timer; - u32 max_vblank_count; /* size of vblank counter register */ - struct drm_vblank_info *vblank; /* per crtc vblank info */ int num_crtcs; struct sigio *buf_sigio; /* Processes waiting for SIGIO */ /* Sysctl support */ struct drm_sysctl_info *sysctl; + int sysctl_node_idx; drm_agp_head_t *agp; drm_sg_mem_t *sg; /* Scatter gather memory */ @@ -700,8 +904,44 @@ struct drm_device { unsigned int agp_buffer_token; drm_local_map_t *agp_buffer_map; + struct drm_minor *control; /**< Control node for card */ + struct drm_minor *primary; /**< render type primary screen head */ + + void *drm_ttm_bo; + struct unrhdr *drw_unrhdr; /* RB tree of drawable infos */ RB_HEAD(drawable_tree, bsd_drm_drawable_info) drw_head; + + int vblank_disable_allowed; + + atomic_t *_vblank_count; /**< number of VBLANK interrupts (driver must alloc the right number of counters) */ + struct timeval *_vblank_time; /**< timestamp of current vblank_count (drivers must alloc right number of fields) */ + struct lock vblank_time_lock; /**< Protects vblank count and time updates during vblank enable/disable */ + struct lock vbl_lock; + atomic_t *vblank_refcount; /* number of users of vblank interruptsper crtc */ + u32 *last_vblank; /* protected by dev->vbl_lock, used */ + /* for wraparound handling */ + int *vblank_enabled; /* so we don't call enable more than + once per disable */ + int *vblank_inmodeset; /* Display driver is setting mode */ + u32 *last_vblank_wait; /* Last vblank seqno waited per CRTC */ + struct callout vblank_disable_callout; + + u32 max_vblank_count; /**< size of vblank counter register */ + + struct list_head vblank_event_list; + struct lock event_lock; + + struct drm_mode_config mode_config; /**< Current mode config */ + + /* GEM part */ + struct lock object_name_lock; + struct drm_gem_names object_names; + void *mm_private; + + void *sysctl_private; + char busid_str[128]; + int modesetting; }; static __inline__ int drm_core_check_feature(struct drm_device *dev, @@ -719,11 +959,51 @@ static inline int drm_core_has_AGP(struct drm_device *dev) #define drm_core_has_AGP(dev) (0) #endif +enum dmi_field { + DMI_NONE, + DMI_BIOS_VENDOR, + DMI_BIOS_VERSION, + DMI_BIOS_DATE, + DMI_SYS_VENDOR, + DMI_PRODUCT_NAME, + DMI_PRODUCT_VERSION, + DMI_PRODUCT_SERIAL, + DMI_PRODUCT_UUID, + DMI_BOARD_VENDOR, + DMI_BOARD_NAME, + DMI_BOARD_VERSION, + DMI_BOARD_SERIAL, + DMI_BOARD_ASSET_TAG, + DMI_CHASSIS_VENDOR, + DMI_CHASSIS_TYPE, + DMI_CHASSIS_VERSION, + DMI_CHASSIS_SERIAL, + DMI_CHASSIS_ASSET_TAG, + DMI_STRING_MAX, +}; + +struct dmi_strmatch { + unsigned char slot; + char substr[79]; +}; + +struct dmi_system_id { + int (*callback)(const struct dmi_system_id *); + const char *ident; + struct dmi_strmatch matches[4]; +}; +#define DMI_MATCH(a, b) {(a), (b)} +bool dmi_check_system(const struct dmi_system_id *); + extern int drm_debug_flag; +extern int drm_notyet_flag; +extern unsigned int drm_vblank_offdelay; +extern unsigned int drm_timestamp_precision; /* Device setup support (drm_drv.c) */ int drm_probe(device_t kdev, drm_pci_id_list_t *idlist); int drm_attach(device_t kdev, drm_pci_id_list_t *idlist); +int drm_create_cdevs(device_t kdev); int drm_detach(device_t kdev); d_ioctl_t drm_ioctl; d_open_t drm_open; @@ -731,8 +1011,14 @@ d_close_t drm_close; d_read_t drm_read; d_kqfilter_t drm_kqfilter; d_mmap_t drm_mmap; +d_mmap_single_t drm_mmap_single; extern drm_local_map_t *drm_getsarea(struct drm_device *dev); +void drm_event_wakeup(struct drm_pending_event *e); + +int drm_add_busid_modesetting(struct drm_device *dev, + struct sysctl_ctx_list *ctx, struct sysctl_oid *top); + /* File operations helpers (drm_fops.c) */ extern int drm_open_helper(struct cdev *kdev, int flags, int fmt, DRM_STRUCTPROC *p, @@ -794,16 +1080,37 @@ irqreturn_t drm_irq_handler(DRM_IRQ_ARGS); void drm_driver_irq_preinstall(struct drm_device *dev); void drm_driver_irq_postinstall(struct drm_device *dev); void drm_driver_irq_uninstall(struct drm_device *dev); -void drm_handle_vblank(struct drm_device *dev, int crtc); -u32 drm_vblank_count(struct drm_device *dev, int crtc); -int drm_vblank_get(struct drm_device *dev, int crtc); -void drm_vblank_put(struct drm_device *dev, int crtc); -void drm_vblank_cleanup(struct drm_device *dev); -int drm_vblank_wait(struct drm_device *dev, unsigned int *vbl_seq); -int drm_vblank_init(struct drm_device *dev, int num_crtcs); + +void drm_vblank_pre_modeset(struct drm_device *dev, int crtc); +void drm_vblank_post_modeset(struct drm_device *dev, int crtc); int drm_modeset_ctl(struct drm_device *dev, void *data, struct drm_file *file_priv); +extern int drm_vblank_init(struct drm_device *dev, int num_crtcs); +extern int drm_wait_vblank(struct drm_device *dev, void *data, + struct drm_file *filp); +extern int drm_vblank_wait(struct drm_device *dev, unsigned int *vbl_seq); +extern u32 drm_vblank_count(struct drm_device *dev, int crtc); +extern u32 drm_vblank_count_and_time(struct drm_device *dev, int crtc, + struct timeval *vblanktime); +extern bool drm_handle_vblank(struct drm_device *dev, int crtc); +void drm_handle_vblank_events(struct drm_device *dev, int crtc); +extern int drm_vblank_get(struct drm_device *dev, int crtc); +extern void drm_vblank_put(struct drm_device *dev, int crtc); +extern void drm_vblank_off(struct drm_device *dev, int crtc); +extern void drm_vblank_cleanup(struct drm_device *dev); +extern u32 drm_get_last_vbltimestamp(struct drm_device *dev, int crtc, + struct timeval *tvblank, unsigned flags); +extern int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, + int crtc, int *max_error, + struct timeval *vblank_time, + unsigned flags, + struct drm_crtc *refcrtc); +extern void drm_calc_timestamping_constants(struct drm_crtc *crtc); + +struct timeval ns_to_timeval(const int64_t nsec); +int64_t timeval_to_ns(const struct timeval *tv); + /* AGP/PCI Express/GART support (drm_agpsupport.c) */ int drm_device_is_agp(struct drm_device *dev); int drm_device_is_pcie(struct drm_device *dev); @@ -835,6 +1142,9 @@ int drm_ati_pcigart_init(struct drm_device *dev, int drm_ati_pcigart_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info); +/* Cache management (drm_memory.c) */ +void drm_clflush_pages(vm_page_t *pages, unsigned long num_pages); + /* Locking IOCTL support (drm_drv.c) */ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv); @@ -858,6 +1168,8 @@ int drm_getclient(struct drm_device *dev, void *data, struct drm_file *file_priv); int drm_getstats(struct drm_device *dev, void *data, struct drm_file *file_priv); +int drm_getcap(struct drm_device *dev, void *data, + struct drm_file *file_priv); int drm_noop(struct drm_device *dev, void *data, struct drm_file *file_priv); @@ -922,8 +1234,6 @@ int drm_dma(struct drm_device *dev, void *data, struct drm_file *file_priv); /* IRQ support (drm_irq.c) */ int drm_control(struct drm_device *dev, void *data, struct drm_file *file_priv); -int drm_wait_vblank(struct drm_device *dev, void *data, - struct drm_file *file_priv); /* AGP/GART support (drm_agpsupport.c) */ int drm_agp_acquire_ioctl(struct drm_device *dev, void *data, @@ -943,6 +1253,12 @@ int drm_agp_unbind_ioctl(struct drm_device *dev, void *data, int drm_agp_bind_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); + /* Stub support (drm_stub.h) */ +extern int drm_setmaster_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int drm_dropmaster_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); + /* Scatter Gather Support (drm_scatter.c) */ int drm_sg_alloc_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); @@ -954,30 +1270,106 @@ drm_dma_handle_t *drm_pci_alloc(struct drm_device *dev, size_t size, size_t align, dma_addr_t maxaddr); void drm_pci_free(struct drm_device *dev, drm_dma_handle_t *dmah); +/* Graphics Execution Manager library functions (drm_gem.c) */ +int drm_gem_init(struct drm_device *dev); +void drm_gem_destroy(struct drm_device *dev); + +int drm_gem_close_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +int drm_gem_flink_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +int drm_gem_open_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +int drm_gem_handle_create(struct drm_file *file_priv, + struct drm_gem_object *obj, + u32 *handlep); +int drm_gem_handle_delete(struct drm_file *file_priv, uint32_t handle); +void drm_gem_object_handle_reference(struct drm_gem_object *obj); +void drm_gem_object_handle_unreference(struct drm_gem_object *obj); +void drm_gem_object_handle_unreference_unlocked(struct drm_gem_object *obj); +void drm_gem_object_handle_free(struct drm_gem_object *obj); +void drm_gem_object_reference(struct drm_gem_object *obj); +void drm_gem_object_unreference(struct drm_gem_object *obj); +void drm_gem_object_unreference_unlocked(struct drm_gem_object *obj); +void drm_gem_object_release(struct drm_gem_object *obj); +void drm_gem_object_free(struct drm_gem_object *obj); +int drm_gem_object_init(struct drm_device *dev, struct drm_gem_object *obj, + size_t size); +int drm_gem_private_object_init(struct drm_device *dev, + struct drm_gem_object *obj, size_t size); +struct drm_gem_object *drm_gem_object_alloc(struct drm_device *dev, + size_t size); +struct drm_gem_object *drm_gem_object_lookup(struct drm_device *dev, + struct drm_file *file_priv, uint32_t handle); + +void drm_gem_open(struct drm_device *dev, struct drm_file *file_priv); +void drm_gem_release(struct drm_device *dev, struct drm_file *file_priv); + +int drm_gem_create_mmap_offset(struct drm_gem_object *obj); +void drm_gem_free_mmap_offset(struct drm_gem_object *obj); +int drm_gem_mmap_single(struct drm_device *dev, vm_ooffset_t *offset, + vm_size_t size, struct vm_object **obj_res, int nprot); +void drm_gem_pager_dtr(void *obj); + +struct ttm_bo_device; +int ttm_bo_mmap_single(struct ttm_bo_device *bdev, vm_ooffset_t *offset, + vm_size_t size, struct vm_object **obj_res, int nprot); + +void drm_device_lock_mtx(struct drm_device *dev); +void drm_device_unlock_mtx(struct drm_device *dev); +int drm_device_sleep_mtx(struct drm_device *dev, void *chan, int flags, + const char *msg, int timeout); +void drm_device_assert_mtx_locked(struct drm_device *dev); +void drm_device_assert_mtx_unlocked(struct drm_device *dev); + +void drm_device_lock_struct(struct drm_device *dev); +void drm_device_unlock_struct(struct drm_device *dev); +int drm_device_sleep_struct(struct drm_device *dev, void *chan, int flags, + const char *msg, int timeout); +void drm_device_assert_struct_locked(struct drm_device *dev); +void drm_device_assert_struct_unlocked(struct drm_device *dev); + +void drm_compat_locking_init(struct drm_device *dev); +void drm_sleep_locking_init(struct drm_device *dev); + +/* drm_modes.c */ +bool drm_mode_parse_command_line_for_connector(const char *mode_option, + struct drm_connector *connector, struct drm_cmdline_mode *mode); +struct drm_display_mode *drm_mode_create_from_cmdline_mode( + struct drm_device *dev, struct drm_cmdline_mode *cmd); + +/* drm_edid.c */ +u8 *drm_find_cea_extension(struct edid *edid); + /* Inline replacements for drm_alloc and friends */ static __inline__ void * drm_alloc(size_t size, struct malloc_type *area) { - return malloc(size, area, M_NOWAIT); + return kmalloc(size, area, M_NOWAIT); } static __inline__ void * drm_calloc(size_t nmemb, size_t size, struct malloc_type *area) { - return malloc(size * nmemb, area, M_NOWAIT | M_ZERO); + return kmalloc(size * nmemb, area, M_NOWAIT | M_ZERO); } static __inline__ void * drm_realloc(void *oldpt, size_t oldsize, size_t size, struct malloc_type *area) { - return reallocf(oldpt, size, area, M_NOWAIT); + void *res; + res = krealloc(oldpt, size, area, M_NOWAIT); + if (res == NULL && oldpt != NULL) + kfree(oldpt,area); + return res; } static __inline__ void -drm_free(void *pt, size_t size, struct malloc_type *area) +drm_free(void *pt, struct malloc_type *area) { - free(pt, area); + if (pt != NULL) + kfree(pt, area); } /* Inline replacements for DRM_IOREMAP macros */ @@ -1003,7 +1395,7 @@ drm_core_findmap(struct drm_device *dev, unsigned long offset) { drm_local_map_t *map; - DRM_SPINLOCK_ASSERT(&dev->dev_lock); + DRM_LOCK_ASSERT(dev); TAILQ_FOREACH(map, &dev->maplist, link) { if (offset == (unsigned long)map->handle) return map; @@ -1015,5 +1407,24 @@ static __inline__ void drm_core_dropmap(struct drm_map *map) { } +#define KIB_NOTYET() \ +do { \ + if (drm_debug_flag && drm_notyet_flag) \ + kprintf("NOTYET: %s at %s:%d\n", __func__, __FILE__, __LINE__); \ +} while (0) + +#define KTR_DRM KTR_DEV +#define KTR_DRM_REG KTR_SPARE3 + + +/* FreeBSD compatibility macros */ +#define PROC_LOCK(p) +#define PROC_UNLOCK(p) + +#define VM_OBJECT_RLOCK(object) VM_OBJECT_LOCK(object) +#define VM_OBJECT_RUNLOCK(object) VM_OBJECT_UNLOCK(object) +#define VM_OBJECT_WLOCK(object) VM_OBJECT_LOCK(object) +#define VM_OBJECT_WUNLOCK(object) VM_OBJECT_UNLOCK(object) + #endif /* __KERNEL__ */ #endif /* _DRM_P_H_ */ diff --git a/sys/dev/drm/drm_agpsupport.c b/sys/dev/drm/drm_agpsupport.c index 66bc6a78a2..fe3a931df7 100644 --- a/sys/dev/drm/drm_agpsupport.c +++ b/sys/dev/drm/drm_agpsupport.c @@ -26,6 +26,7 @@ * Rickard E. (Rik) Faith * Gareth Hughes * + * $FreeBSD: src/sys/dev/drm2/drm_agpsupport.c,v 1.1 2012/05/22 11:07:44 kib Exp $ */ /** @file drm_agpsupport.c @@ -33,7 +34,7 @@ * the DRM's AGP ioctls. */ -#include "dev/drm/drmP.h" +#include #include #include @@ -173,18 +174,16 @@ int drm_agp_alloc(struct drm_device *dev, struct drm_agp_buffer *request) if (!dev->agp || !dev->agp->acquired) return EINVAL; - entry = malloc(sizeof(*entry), DRM_MEM_AGPLISTS, M_NOWAIT | M_ZERO); + entry = kmalloc(sizeof(*entry), DRM_MEM_AGPLISTS, M_NOWAIT | M_ZERO); if (entry == NULL) return ENOMEM; pages = (request->size + PAGE_SIZE - 1) / PAGE_SIZE; type = (u_int32_t) request->type; - DRM_UNLOCK(); handle = drm_agp_allocate_memory(pages, type); - DRM_LOCK(); if (handle == NULL) { - free(entry, DRM_MEM_AGPLISTS); + drm_free(entry, DRM_MEM_AGPLISTS); return ENOMEM; } @@ -213,9 +212,7 @@ int drm_agp_alloc_ioctl(struct drm_device *dev, void *data, request = *(struct drm_agp_buffer *) data; - DRM_LOCK(); retcode = drm_agp_alloc(dev, &request); - DRM_UNLOCK(); *(struct drm_agp_buffer *) data = request; @@ -245,9 +242,7 @@ int drm_agp_unbind(struct drm_device *dev, struct drm_agp_binding *request) if (entry == NULL || !entry->bound) return EINVAL; - DRM_UNLOCK(); retcode = drm_agp_unbind_memory(entry->handle); - DRM_LOCK(); if (retcode == 0) entry->bound = 0; @@ -263,9 +258,7 @@ int drm_agp_unbind_ioctl(struct drm_device *dev, void *data, request = *(struct drm_agp_binding *) data; - DRM_LOCK(); retcode = drm_agp_unbind(dev, &request); - DRM_UNLOCK(); return retcode; } @@ -279,7 +272,7 @@ int drm_agp_bind(struct drm_device *dev, struct drm_agp_binding *request) if (!dev->agp || !dev->agp->acquired) return EINVAL; - DRM_DEBUG("agp_bind, page_size=%x\n", PAGE_SIZE); + DRM_DEBUG("agp_bind, page_size=%x\n", (int)PAGE_SIZE); entry = drm_agp_lookup_entry(dev, (void *)request->handle); if (entry == NULL || entry->bound) @@ -287,9 +280,7 @@ int drm_agp_bind(struct drm_device *dev, struct drm_agp_binding *request) page = (request->offset + PAGE_SIZE - 1) / PAGE_SIZE; - DRM_UNLOCK(); retcode = drm_agp_bind_memory(entry->handle, page); - DRM_LOCK(); if (retcode == 0) entry->bound = dev->agp->base + (page << PAGE_SHIFT); @@ -304,9 +295,7 @@ int drm_agp_bind_ioctl(struct drm_device *dev, void *data, request = *(struct drm_agp_binding *) data; - DRM_LOCK(); retcode = drm_agp_bind(dev, &request); - DRM_UNLOCK(); return retcode; } @@ -329,13 +318,11 @@ int drm_agp_free(struct drm_device *dev, struct drm_agp_buffer *request) if (entry->next) entry->next->prev = entry->prev; - DRM_UNLOCK(); if (entry->bound) drm_agp_unbind_memory(entry->handle); drm_agp_free_memory(entry->handle); - DRM_LOCK(); - free(entry, DRM_MEM_AGPLISTS); + drm_free(entry, DRM_MEM_AGPLISTS); return 0; @@ -349,9 +336,7 @@ int drm_agp_free_ioctl(struct drm_device *dev, void *data, request = *(struct drm_agp_buffer *) data; - DRM_LOCK(); retcode = drm_agp_free(dev, &request); - DRM_UNLOCK(); return retcode; } @@ -369,7 +354,7 @@ drm_agp_head_t *drm_agp_init(void) DRM_DEBUG("agp_available = %d\n", agp_available); if (agp_available) { - head = malloc(sizeof(*head), DRM_MEM_AGPLISTS, + head = kmalloc(sizeof(*head), DRM_MEM_AGPLISTS, M_NOWAIT | M_ZERO); if (head == NULL) return NULL; diff --git a/sys/dev/drm/drm_atomic.h b/sys/dev/drm/drm_atomic.h index 10576d5add..bcd595830f 100644 --- a/sys/dev/drm/drm_atomic.h +++ b/sys/dev/drm/drm_atomic.h @@ -27,6 +27,8 @@ * 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. + * + * $FreeBSD: src/sys/dev/drm2/drm_atomic.h,v 1.1 2012/05/22 11:07:44 kib Exp $ */ /* Many of these implementations are rather fake, but good enough. */ @@ -89,3 +91,5 @@ find_first_zero_bit(volatile void *p, int max) } return max; } + +#define BITS_TO_LONGS(x) (howmany((x), NBBY * sizeof(long))) diff --git a/sys/dev/drm/drm_auth.c b/sys/dev/drm/drm_auth.c index 303722c205..cd952f20b3 100644 --- a/sys/dev/drm/drm_auth.c +++ b/sys/dev/drm/drm_auth.c @@ -26,6 +26,7 @@ * Rickard E. (Rik) Faith * Gareth Hughes * + * $FreeBSD: src/sys/dev/drm2/drm_auth.c,v 1.1 2012/05/22 11:07:44 kib Exp $ */ /** @file drm_auth.c @@ -48,7 +49,7 @@ static struct drm_file *drm_find_file(struct drm_device *dev, drm_magic_t magic) drm_magic_entry_t *pt; int hash = drm_hash_magic(magic); - DRM_SPINLOCK_ASSERT(&dev->dev_lock); + DRM_LOCK_ASSERT(dev); for (pt = dev->magiclist[hash].head; pt; pt = pt->next) { if (pt->magic == magic) { @@ -71,10 +72,10 @@ static int drm_add_magic(struct drm_device *dev, struct drm_file *priv, DRM_DEBUG("%d\n", magic); - DRM_SPINLOCK_ASSERT(&dev->dev_lock); + DRM_LOCK_ASSERT(dev); hash = drm_hash_magic(magic); - entry = malloc(sizeof(*entry), DRM_MEM_MAGIC, M_ZERO | M_NOWAIT); + entry = kmalloc(sizeof(*entry), DRM_MEM_MAGIC, M_ZERO | M_NOWAIT); if (!entry) return ENOMEM; entry->magic = magic; @@ -102,7 +103,7 @@ static int drm_remove_magic(struct drm_device *dev, drm_magic_t magic) drm_magic_entry_t *pt; int hash; - DRM_SPINLOCK_ASSERT(&dev->dev_lock); + DRM_LOCK_ASSERT(dev); DRM_DEBUG("%d\n", magic); hash = drm_hash_magic(magic); @@ -118,7 +119,7 @@ static int drm_remove_magic(struct drm_device *dev, drm_magic_t magic) if (prev) { prev->next = pt->next; } - free(pt, DRM_MEM_MAGIC); + drm_free(pt, DRM_MEM_MAGIC); return 0; } } @@ -143,7 +144,7 @@ int drm_getmagic(struct drm_device *dev, void *data, struct drm_file *file_priv) if (file_priv->magic) { auth->magic = file_priv->magic; } else { - DRM_LOCK(); + DRM_LOCK(dev); do { int old = sequence; @@ -154,7 +155,7 @@ int drm_getmagic(struct drm_device *dev, void *data, struct drm_file *file_priv) } while (drm_find_file(dev, auth->magic)); file_priv->magic = auth->magic; drm_add_magic(dev, file_priv, auth->magic); - DRM_UNLOCK(); + DRM_UNLOCK(dev); } DRM_DEBUG("%u\n", auth->magic); @@ -173,15 +174,15 @@ int drm_authmagic(struct drm_device *dev, void *data, DRM_DEBUG("%u\n", auth->magic); - DRM_LOCK(); + DRM_LOCK(dev); priv = drm_find_file(dev, auth->magic); if (priv != NULL) { priv->authenticated = 1; drm_remove_magic(dev, auth->magic); - DRM_UNLOCK(); + DRM_UNLOCK(dev); return 0; } else { - DRM_UNLOCK(); + DRM_UNLOCK(dev); return EINVAL; } } diff --git a/sys/dev/drm/drm_bufs.c b/sys/dev/drm/drm_bufs.c index c1b73c79c8..c29dc6a6d7 100644 --- a/sys/dev/drm/drm_bufs.c +++ b/sys/dev/drm/drm_bufs.c @@ -26,13 +26,15 @@ * Rickard E. (Rik) Faith * Gareth Hughes * + * $FreeBSD: src/sys/dev/drm2/drm_bufs.c,v 1.1 2012/05/22 11:07:44 kib Exp $ */ /** @file drm_bufs.c * Implementation of the ioctls for setup of DRM mappings and DMA buffers. */ -#include "bus/pci/pcireg.h" +#include +#include #include "dev/drm/drmP.h" @@ -45,7 +47,7 @@ static int drm_alloc_resource(struct drm_device *dev, int resource) struct resource *res; int rid; - DRM_SPINLOCK_ASSERT(&dev->dev_lock); + DRM_LOCK_ASSERT(dev); if (resource >= DRM_MAX_PCI_RESOURCE) { DRM_ERROR("Resource %d too large\n", resource); @@ -56,11 +58,11 @@ static int drm_alloc_resource(struct drm_device *dev, int resource) return 0; } - DRM_UNLOCK(); + DRM_UNLOCK(dev); rid = PCIR_BAR(resource); res = bus_alloc_resource_any(dev->device, SYS_RES_MEMORY, &rid, RF_SHAREABLE); - DRM_LOCK(); + DRM_LOCK(dev); if (res == NULL) { DRM_ERROR("Couldn't find resource 0x%x\n", resource); return 1; @@ -119,10 +121,6 @@ int drm_addmap(struct drm_device * dev, unsigned long offset, offset, size); return EINVAL; } - if (size == 0) { - DRM_ERROR("size is 0: 0x%lx/0x%lx\n", offset, size); - return EINVAL; - } DRM_DEBUG("offset = 0x%08lx, size = 0x%08lx, type = %d\n", offset, size, type); @@ -142,14 +140,14 @@ int drm_addmap(struct drm_device * dev, unsigned long offset, } } } - DRM_UNLOCK(); + DRM_UNLOCK(dev); /* Allocate a new map structure, fill it in, and do any type-specific * initialization necessary. */ - map = malloc(sizeof(*map), DRM_MEM_MAPS, M_ZERO | M_NOWAIT); + map = kmalloc(sizeof(*map), DRM_MEM_MAPS, M_ZERO | M_NOWAIT); if (!map) { - DRM_LOCK(); + DRM_LOCK(dev); return ENOMEM; } @@ -171,26 +169,26 @@ int drm_addmap(struct drm_device * dev, unsigned long offset, map->mtrr = 1; break; case _DRM_SHM: - map->virtual = malloc(map->size, DRM_MEM_MAPS, M_NOWAIT); + map->virtual = kmalloc(map->size, DRM_MEM_MAPS, M_NOWAIT); DRM_DEBUG("%lu %d %p\n", map->size, drm_order(map->size), map->virtual); if (!map->virtual) { - free(map, DRM_MEM_MAPS); - DRM_LOCK(); + drm_free(map, DRM_MEM_MAPS); + DRM_LOCK(dev); return ENOMEM; } map->offset = (unsigned long)map->virtual; if (map->flags & _DRM_CONTAINS_LOCK) { /* Prevent a 2nd X Server from creating a 2nd lock */ - DRM_LOCK(); + DRM_LOCK(dev); if (dev->lock.hw_lock != NULL) { - DRM_UNLOCK(); - free(map->virtual, DRM_MEM_MAPS); - free(map, DRM_MEM_MAPS); + DRM_UNLOCK(dev); + drm_free(map->virtual, DRM_MEM_MAPS); + drm_free(map, DRM_MEM_MAPS); return EBUSY; } dev->lock.hw_lock = map->virtual; /* Pointer to lock */ - DRM_UNLOCK(); + DRM_UNLOCK(dev); } break; case _DRM_AGP: @@ -216,15 +214,15 @@ int drm_addmap(struct drm_device * dev, unsigned long offset, } } if (!valid) { - free(map, DRM_MEM_MAPS); - DRM_LOCK(); + drm_free(map, DRM_MEM_MAPS); + DRM_LOCK(dev); return EACCES; }*/ break; case _DRM_SCATTER_GATHER: if (!dev->sg) { - free(map, DRM_MEM_MAPS); - DRM_LOCK(); + drm_free(map, DRM_MEM_MAPS); + DRM_LOCK(dev); return EINVAL; } map->virtual = (void *)(dev->sg->vaddr + offset); @@ -242,8 +240,8 @@ int drm_addmap(struct drm_device * dev, unsigned long offset, align = PAGE_SIZE; map->dmah = drm_pci_alloc(dev, map->size, align, 0xfffffffful); if (map->dmah == NULL) { - free(map, DRM_MEM_MAPS); - DRM_LOCK(); + drm_free(map, DRM_MEM_MAPS); + DRM_LOCK(dev); return ENOMEM; } map->virtual = map->dmah->vaddr; @@ -251,12 +249,12 @@ int drm_addmap(struct drm_device * dev, unsigned long offset, break; default: DRM_ERROR("Bad map type %d\n", map->type); - free(map, DRM_MEM_MAPS); - DRM_LOCK(); + drm_free(map, DRM_MEM_MAPS); + DRM_LOCK(dev); return EINVAL; } - DRM_LOCK(); + DRM_LOCK(dev); TAILQ_INSERT_TAIL(&dev->maplist, map, link); done: @@ -283,10 +281,10 @@ int drm_addmap_ioctl(struct drm_device *dev, void *data, if (!DRM_SUSER(DRM_CURPROC) && request->type != _DRM_AGP) return EACCES; - DRM_LOCK(); + DRM_LOCK(dev); err = drm_addmap(dev, request->offset, request->size, request->type, request->flags, &map); - DRM_UNLOCK(); + DRM_UNLOCK(dev); if (err != 0) return err; @@ -302,7 +300,7 @@ int drm_addmap_ioctl(struct drm_device *dev, void *data, void drm_rmmap(struct drm_device *dev, drm_local_map_t *map) { - DRM_SPINLOCK_ASSERT(&dev->dev_lock); + DRM_LOCK_ASSERT(dev); if (map == NULL) return; @@ -316,7 +314,7 @@ void drm_rmmap(struct drm_device *dev, drm_local_map_t *map) /* FALLTHROUGH */ case _DRM_FRAME_BUFFER: if (map->mtrr) { - int retcode; + int __unused retcode; retcode = drm_mtrr_del(0, map->offset, map->size, DRM_MTRR_WC); @@ -324,7 +322,7 @@ void drm_rmmap(struct drm_device *dev, drm_local_map_t *map) } break; case _DRM_SHM: - free(map->virtual, DRM_MEM_MAPS); + drm_free(map->virtual, DRM_MEM_MAPS); break; case _DRM_AGP: case _DRM_SCATTER_GATHER: @@ -342,13 +340,13 @@ void drm_rmmap(struct drm_device *dev, drm_local_map_t *map) map->bsr); } - DRM_UNLOCK(); + DRM_UNLOCK(dev); if (map->handle) free_unr(dev->map_unrhdr, (unsigned long)map->handle >> DRM_MAP_HANDLE_SHIFT); - DRM_LOCK(); + DRM_LOCK(dev); - free(map, DRM_MEM_MAPS); + drm_free(map, DRM_MEM_MAPS); } /* Remove a map private from list and deallocate resources if the mapping @@ -361,7 +359,7 @@ int drm_rmmap_ioctl(struct drm_device *dev, void *data, drm_local_map_t *map; struct drm_map *request = data; - DRM_LOCK(); + DRM_LOCK(dev); TAILQ_FOREACH(map, &dev->maplist, link) { if (map->handle == request->handle && map->flags & _DRM_REMOVABLE) @@ -370,13 +368,13 @@ int drm_rmmap_ioctl(struct drm_device *dev, void *data, /* No match found. */ if (map == NULL) { - DRM_UNLOCK(); + DRM_UNLOCK(dev); return EINVAL; } drm_rmmap(dev, map); - DRM_UNLOCK(); + DRM_UNLOCK(dev); return 0; } @@ -391,16 +389,16 @@ static void drm_cleanup_buf_error(struct drm_device *dev, for (i = 0; i < entry->seg_count; i++) { drm_pci_free(dev, entry->seglist[i]); } - free(entry->seglist, DRM_MEM_SEGS); + drm_free(entry->seglist, DRM_MEM_SEGS); entry->seg_count = 0; } if (entry->buf_count) { for (i = 0; i < entry->buf_count; i++) { - free(entry->buflist[i].dev_private, DRM_MEM_BUFS); + drm_free(entry->buflist[i].dev_private, DRM_MEM_BUFS); } - free(entry->buflist, DRM_MEM_BUFS); + drm_free(entry->buflist, DRM_MEM_BUFS); entry->buf_count = 0; } @@ -467,7 +465,7 @@ static int drm_do_addbufs_agp(struct drm_device *dev, struct drm_buf_desc *reque entry = &dma->bufs[order]; - entry->buflist = malloc(count * sizeof(*entry->buflist), DRM_MEM_BUFS, + entry->buflist = kmalloc(count * sizeof(*entry->buflist), DRM_MEM_BUFS, M_NOWAIT | M_ZERO); if (!entry->buflist) { return ENOMEM; @@ -493,7 +491,7 @@ static int drm_do_addbufs_agp(struct drm_device *dev, struct drm_buf_desc *reque buf->file_priv = NULL; buf->dev_priv_size = dev->driver->buf_priv_size; - buf->dev_private = malloc(buf->dev_priv_size, DRM_MEM_BUFS, + buf->dev_private = kmalloc(buf->dev_priv_size, DRM_MEM_BUFS, M_NOWAIT | M_ZERO); if (buf->dev_private == NULL) { /* Set count correctly so we free the proper amount. */ @@ -509,7 +507,7 @@ static int drm_do_addbufs_agp(struct drm_device *dev, struct drm_buf_desc *reque DRM_DEBUG("byte_count: %d\n", byte_count); - temp_buflist = realloc(dma->buflist, + temp_buflist = krealloc(dma->buflist, (dma->buf_count + entry->buf_count) * sizeof(*dma->buflist), DRM_MEM_BUFS, M_NOWAIT); if (temp_buflist == NULL) { @@ -569,22 +567,22 @@ static int drm_do_addbufs_pci(struct drm_device *dev, struct drm_buf_desc *reque entry = &dma->bufs[order]; - entry->buflist = malloc(count * sizeof(*entry->buflist), DRM_MEM_BUFS, + entry->buflist = kmalloc(count * sizeof(*entry->buflist), DRM_MEM_BUFS, M_NOWAIT | M_ZERO); - entry->seglist = malloc(count * sizeof(*entry->seglist), DRM_MEM_SEGS, + entry->seglist = kmalloc(count * sizeof(*entry->seglist), DRM_MEM_SEGS, M_NOWAIT | M_ZERO); /* Keep the original pagelist until we know all the allocations * have succeeded */ - temp_pagelist = malloc((dma->page_count + (count << page_order)) * + temp_pagelist = kmalloc((dma->page_count + (count << page_order)) * sizeof(*dma->pagelist), DRM_MEM_PAGES, M_NOWAIT); if (entry->buflist == NULL || entry->seglist == NULL || temp_pagelist == NULL) { - free(temp_pagelist, DRM_MEM_PAGES); - free(entry->seglist, DRM_MEM_SEGS); - free(entry->buflist, DRM_MEM_BUFS); + drm_free(temp_pagelist, DRM_MEM_PAGES); + drm_free(entry->seglist, DRM_MEM_SEGS); + drm_free(entry->buflist, DRM_MEM_BUFS); return ENOMEM; } @@ -600,16 +598,16 @@ static int drm_do_addbufs_pci(struct drm_device *dev, struct drm_buf_desc *reque page_count = 0; while (entry->buf_count < count) { - DRM_SPINUNLOCK(&dev->dma_lock); + spin_unlock(&dev->dma_lock); drm_dma_handle_t *dmah = drm_pci_alloc(dev, size, alignment, 0xfffffffful); - DRM_SPINLOCK(&dev->dma_lock); + spin_lock(&dev->dma_lock); if (dmah == NULL) { /* Set count correctly so we free the proper amount. */ entry->buf_count = count; entry->seg_count = count; drm_cleanup_buf_error(dev, entry); - free(temp_pagelist, DRM_MEM_PAGES); + drm_free(temp_pagelist, DRM_MEM_PAGES); return ENOMEM; } @@ -637,14 +635,14 @@ static int drm_do_addbufs_pci(struct drm_device *dev, struct drm_buf_desc *reque buf->file_priv = NULL; buf->dev_priv_size = dev->driver->buf_priv_size; - buf->dev_private = malloc(buf->dev_priv_size, + buf->dev_private = kmalloc(buf->dev_priv_size, DRM_MEM_BUFS, M_NOWAIT | M_ZERO); if (buf->dev_private == NULL) { /* Set count correctly so we free the proper amount. */ entry->buf_count = count; entry->seg_count = count; drm_cleanup_buf_error(dev, entry); - free(temp_pagelist, DRM_MEM_PAGES); + drm_free(temp_pagelist, DRM_MEM_PAGES); return ENOMEM; } @@ -654,13 +652,13 @@ static int drm_do_addbufs_pci(struct drm_device *dev, struct drm_buf_desc *reque byte_count += PAGE_SIZE << page_order; } - temp_buflist = realloc(dma->buflist, + temp_buflist = krealloc(dma->buflist, (dma->buf_count + entry->buf_count) * sizeof(*dma->buflist), DRM_MEM_BUFS, M_NOWAIT); if (temp_buflist == NULL) { /* Free the entry because it isn't valid */ drm_cleanup_buf_error(dev, entry); - free(temp_pagelist, DRM_MEM_PAGES); + drm_free(temp_pagelist, DRM_MEM_PAGES); return ENOMEM; } dma->buflist = temp_buflist; @@ -672,7 +670,7 @@ static int drm_do_addbufs_pci(struct drm_device *dev, struct drm_buf_desc *reque /* No allocations failed, so now we can replace the orginal pagelist * with the new one. */ - free(dma->pagelist, DRM_MEM_PAGES); + drm_free(dma->pagelist, DRM_MEM_PAGES); dma->pagelist = temp_pagelist; dma->buf_count += entry->buf_count; @@ -726,7 +724,7 @@ static int drm_do_addbufs_sg(struct drm_device *dev, struct drm_buf_desc *reques entry = &dma->bufs[order]; - entry->buflist = malloc(count * sizeof(*entry->buflist), DRM_MEM_BUFS, + entry->buflist = kmalloc(count * sizeof(*entry->buflist), DRM_MEM_BUFS, M_NOWAIT | M_ZERO); if (entry->buflist == NULL) return ENOMEM; @@ -751,7 +749,7 @@ static int drm_do_addbufs_sg(struct drm_device *dev, struct drm_buf_desc *reques buf->file_priv = NULL; buf->dev_priv_size = dev->driver->buf_priv_size; - buf->dev_private = malloc(buf->dev_priv_size, DRM_MEM_BUFS, + buf->dev_private = kmalloc(buf->dev_priv_size, DRM_MEM_BUFS, M_NOWAIT | M_ZERO); if (buf->dev_private == NULL) { /* Set count correctly so we free the proper amount. */ @@ -770,7 +768,7 @@ static int drm_do_addbufs_sg(struct drm_device *dev, struct drm_buf_desc *reques DRM_DEBUG("byte_count: %d\n", byte_count); - temp_buflist = realloc(dma->buflist, + temp_buflist = krealloc(dma->buflist, (dma->buf_count + entry->buf_count) * sizeof(*dma->buflist), DRM_MEM_BUFS, M_NOWAIT); if (temp_buflist == NULL) { @@ -809,22 +807,22 @@ int drm_addbufs_agp(struct drm_device *dev, struct drm_buf_desc *request) if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) return EINVAL; - DRM_SPINLOCK(&dev->dma_lock); + spin_lock(&dev->dma_lock); /* No more allocations after first buffer-using ioctl. */ if (dev->buf_use != 0) { - DRM_SPINUNLOCK(&dev->dma_lock); + spin_unlock(&dev->dma_lock); return EBUSY; } /* No more than one allocation per order */ if (dev->dma->bufs[order].buf_count != 0) { - DRM_SPINUNLOCK(&dev->dma_lock); + spin_unlock(&dev->dma_lock); return ENOMEM; } ret = drm_do_addbufs_agp(dev, request); - DRM_SPINUNLOCK(&dev->dma_lock); + spin_unlock(&dev->dma_lock); return ret; } @@ -843,22 +841,22 @@ int drm_addbufs_sg(struct drm_device *dev, struct drm_buf_desc *request) if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) return EINVAL; - DRM_SPINLOCK(&dev->dma_lock); + spin_lock(&dev->dma_lock); /* No more allocations after first buffer-using ioctl. */ if (dev->buf_use != 0) { - DRM_SPINUNLOCK(&dev->dma_lock); + spin_unlock(&dev->dma_lock); return EBUSY; } /* No more than one allocation per order */ if (dev->dma->bufs[order].buf_count != 0) { - DRM_SPINUNLOCK(&dev->dma_lock); + spin_unlock(&dev->dma_lock); return ENOMEM; } ret = drm_do_addbufs_sg(dev, request); - DRM_SPINUNLOCK(&dev->dma_lock); + spin_unlock(&dev->dma_lock); return ret; } @@ -877,22 +875,22 @@ int drm_addbufs_pci(struct drm_device *dev, struct drm_buf_desc *request) if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) return EINVAL; - DRM_SPINLOCK(&dev->dma_lock); + spin_lock(&dev->dma_lock); /* No more allocations after first buffer-using ioctl. */ if (dev->buf_use != 0) { - DRM_SPINUNLOCK(&dev->dma_lock); + spin_unlock(&dev->dma_lock); return EBUSY; } /* No more than one allocation per order */ if (dev->dma->bufs[order].buf_count != 0) { - DRM_SPINUNLOCK(&dev->dma_lock); + spin_unlock(&dev->dma_lock); return ENOMEM; } ret = drm_do_addbufs_pci(dev, request); - DRM_SPINUNLOCK(&dev->dma_lock); + spin_unlock(&dev->dma_lock); return ret; } @@ -920,9 +918,9 @@ int drm_infobufs(struct drm_device *dev, void *data, struct drm_file *file_priv) int count; int retcode = 0; - DRM_SPINLOCK(&dev->dma_lock); + spin_lock(&dev->dma_lock); ++dev->buf_use; /* Can't allocate more after this call */ - DRM_SPINUNLOCK(&dev->dma_lock); + spin_unlock(&dev->dma_lock); for (i = 0, count = 0; i < DRM_MAX_ORDER + 1; i++) { if (dma->bufs[i].buf_count) @@ -977,16 +975,16 @@ int drm_markbufs(struct drm_device *dev, void *data, struct drm_file *file_priv) return EINVAL; } - DRM_SPINLOCK(&dev->dma_lock); + spin_lock(&dev->dma_lock); if (request->low_mark > dma->bufs[order].buf_count || request->high_mark > dma->bufs[order].buf_count) { - DRM_SPINUNLOCK(&dev->dma_lock); + spin_unlock(&dev->dma_lock); return EINVAL; } dma->bufs[order].freelist.low_mark = request->low_mark; dma->bufs[order].freelist.high_mark = request->high_mark; - DRM_SPINUNLOCK(&dev->dma_lock); + spin_unlock(&dev->dma_lock); return 0; } @@ -1002,7 +1000,7 @@ int drm_freebufs(struct drm_device *dev, void *data, struct drm_file *file_priv) DRM_DEBUG("%d\n", request->count); - DRM_SPINLOCK(&dev->dma_lock); + spin_lock(&dev->dma_lock); for (i = 0; i < request->count; i++) { if (DRM_COPY_FROM_USER(&idx, &request->list[i], sizeof(idx))) { retcode = EFAULT; @@ -1023,7 +1021,7 @@ int drm_freebufs(struct drm_device *dev, void *data, struct drm_file *file_priv) } drm_free_buffer(dev, buf); } - DRM_SPINUNLOCK(&dev->dma_lock); + spin_unlock(&dev->dma_lock); return retcode; } @@ -1043,9 +1041,9 @@ int drm_mapbufs(struct drm_device *dev, void *data, struct drm_file *file_priv) vms = DRM_CURPROC->td_proc->p_vmspace; - DRM_SPINLOCK(&dev->dma_lock); + spin_lock(&dev->dma_lock); dev->buf_use++; /* Can't allocate more after this call */ - DRM_SPINUNLOCK(&dev->dma_lock); + spin_unlock(&dev->dma_lock); if (request->count < dma->buf_count) goto done; diff --git a/sys/dev/drm/drm_context.c b/sys/dev/drm/drm_context.c index 7bfa976229..5df3c76750 100644 --- a/sys/dev/drm/drm_context.c +++ b/sys/dev/drm/drm_context.c @@ -26,6 +26,7 @@ * Rickard E. (Rik) Faith * Gareth Hughes * + * $FreeBSD: src/sys/dev/drm2/drm_context.c,v 1.1 2012/05/22 11:07:44 kib Exp $ */ /** @file drm_context.c @@ -47,10 +48,10 @@ void drm_ctxbitmap_free(struct drm_device *dev, int ctx_handle) return; } - DRM_LOCK(); + DRM_LOCK(dev); clear_bit(ctx_handle, dev->ctx_bitmap); dev->context_sareas[ctx_handle] = NULL; - DRM_UNLOCK(); + DRM_UNLOCK(dev); return; } @@ -61,10 +62,10 @@ int drm_ctxbitmap_next(struct drm_device *dev) if (dev->ctx_bitmap == NULL) return -1; - DRM_LOCK(); + DRM_LOCK(dev); bit = find_first_zero_bit(dev->ctx_bitmap, DRM_MAX_CTXBITMAP); if (bit >= DRM_MAX_CTXBITMAP) { - DRM_UNLOCK(); + DRM_UNLOCK(dev); return -1; } @@ -74,20 +75,20 @@ int drm_ctxbitmap_next(struct drm_device *dev) drm_local_map_t **ctx_sareas; int max_ctx = (bit+1); - ctx_sareas = realloc(dev->context_sareas, + ctx_sareas = krealloc(dev->context_sareas, max_ctx * sizeof(*dev->context_sareas), DRM_MEM_SAREA, M_NOWAIT); if (ctx_sareas == NULL) { clear_bit(bit, dev->ctx_bitmap); DRM_DEBUG("failed to allocate bit : %d\n", bit); - DRM_UNLOCK(); + DRM_UNLOCK(dev); return -1; } dev->max_context = max_ctx; dev->context_sareas = ctx_sareas; dev->context_sareas[bit] = NULL; } - DRM_UNLOCK(); + DRM_UNLOCK(dev); return bit; } @@ -96,16 +97,16 @@ int drm_ctxbitmap_init(struct drm_device *dev) int i; int temp; - DRM_LOCK(); - dev->ctx_bitmap = malloc(PAGE_SIZE, DRM_MEM_CTXBITMAP, + DRM_LOCK(dev); + dev->ctx_bitmap = kmalloc(PAGE_SIZE, DRM_MEM_CTXBITMAP, M_NOWAIT | M_ZERO); if (dev->ctx_bitmap == NULL) { - DRM_UNLOCK(); + DRM_UNLOCK(dev); return ENOMEM; } dev->context_sareas = NULL; dev->max_context = -1; - DRM_UNLOCK(); + DRM_UNLOCK(dev); for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) { temp = drm_ctxbitmap_next(dev); @@ -117,11 +118,11 @@ int drm_ctxbitmap_init(struct drm_device *dev) void drm_ctxbitmap_cleanup(struct drm_device *dev) { - DRM_LOCK(); + DRM_LOCK(dev); if (dev->context_sareas != NULL) - free(dev->context_sareas, DRM_MEM_SAREA); - free(dev->ctx_bitmap, DRM_MEM_CTXBITMAP); - DRM_UNLOCK(); + drm_free(dev->context_sareas, DRM_MEM_SAREA); + drm_free(dev->ctx_bitmap, DRM_MEM_CTXBITMAP); + DRM_UNLOCK(dev); } /* ================================================================ @@ -134,15 +135,15 @@ int drm_getsareactx(struct drm_device *dev, void *data, struct drm_ctx_priv_map *request = data; drm_local_map_t *map; - DRM_LOCK(); + DRM_LOCK(dev); if (dev->max_context < 0 || request->ctx_id >= (unsigned) dev->max_context) { - DRM_UNLOCK(); + DRM_UNLOCK(dev); return EINVAL; } map = dev->context_sareas[request->ctx_id]; - DRM_UNLOCK(); + DRM_UNLOCK(dev); request->handle = (void *)map->handle; @@ -155,7 +156,7 @@ int drm_setsareactx(struct drm_device *dev, void *data, struct drm_ctx_priv_map *request = data; drm_local_map_t *map = NULL; - DRM_LOCK(); + DRM_LOCK(dev); TAILQ_FOREACH(map, &dev->maplist, link) { if (map->handle == request->handle) { if (dev->max_context < 0) @@ -163,13 +164,13 @@ int drm_setsareactx(struct drm_device *dev, void *data, if (request->ctx_id >= (unsigned) dev->max_context) goto bad; dev->context_sareas[request->ctx_id] = map; - DRM_UNLOCK(); + DRM_UNLOCK(dev); return 0; } } bad: - DRM_UNLOCK(); + DRM_UNLOCK(dev); return EINVAL; } @@ -247,9 +248,9 @@ int drm_addctx(struct drm_device *dev, void *data, struct drm_file *file_priv) } if (dev->driver->context_ctor && ctx->handle != DRM_KERNEL_CONTEXT) { - DRM_LOCK(); + DRM_LOCK(dev); dev->driver->context_ctor(dev, ctx->handle); - DRM_UNLOCK(); + DRM_UNLOCK(dev); } return 0; @@ -297,9 +298,9 @@ int drm_rmctx(struct drm_device *dev, void *data, struct drm_file *file_priv) DRM_DEBUG("%d\n", ctx->handle); if (ctx->handle != DRM_KERNEL_CONTEXT) { if (dev->driver->context_dtor) { - DRM_LOCK(); + DRM_LOCK(dev); dev->driver->context_dtor(dev, ctx->handle); - DRM_UNLOCK(); + DRM_UNLOCK(dev); } drm_ctxbitmap_free(dev, ctx->handle); diff --git a/sys/dev/drm2/drm_crtc.c b/sys/dev/drm/drm_crtc.c similarity index 99% rename from sys/dev/drm2/drm_crtc.c rename to sys/dev/drm/drm_crtc.c index 742fed5668..39d281834b 100644 --- a/sys/dev/drm2/drm_crtc.c +++ b/sys/dev/drm/drm_crtc.c @@ -32,11 +32,11 @@ * $FreeBSD: src/sys/dev/drm2/drm_crtc.c,v 1.1 2012/05/22 11:07:44 kib Exp $ */ -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include /* Avoid boilerplate. I'm tired of typing. */ diff --git a/sys/dev/drm2/drm_crtc.h b/sys/dev/drm/drm_crtc.h similarity index 99% rename from sys/dev/drm2/drm_crtc.h rename to sys/dev/drm/drm_crtc.h index 4aaa3a00e7..a7f0fd9971 100644 --- a/sys/dev/drm2/drm_crtc.h +++ b/sys/dev/drm/drm_crtc.h @@ -27,8 +27,8 @@ #ifndef __DRM_CRTC_H__ #define __DRM_CRTC_H__ -#include -#include +#include +#include struct drm_device; struct drm_mode_set; diff --git a/sys/dev/drm2/drm_crtc_helper.c b/sys/dev/drm/drm_crtc_helper.c similarity index 99% rename from sys/dev/drm2/drm_crtc_helper.c rename to sys/dev/drm/drm_crtc_helper.c index 3423ca158f..a0af691f6c 100644 --- a/sys/dev/drm2/drm_crtc_helper.c +++ b/sys/dev/drm/drm_crtc_helper.c @@ -33,11 +33,11 @@ #include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include bool drm_fetch_cmdline_mode_from_kenv(struct drm_connector *connector, diff --git a/sys/dev/drm2/drm_crtc_helper.h b/sys/dev/drm/drm_crtc_helper.h similarity index 100% rename from sys/dev/drm2/drm_crtc_helper.h rename to sys/dev/drm/drm_crtc_helper.h diff --git a/sys/dev/drm/drm_dma.c b/sys/dev/drm/drm_dma.c index 0cc5f7276f..7bf82416a7 100644 --- a/sys/dev/drm/drm_dma.c +++ b/sys/dev/drm/drm_dma.c @@ -26,6 +26,7 @@ * Rickard E. (Rik) Faith * Gareth Hughes * + * $FreeBSD: head/sys/dev/drm2/drm_dma.c 235783 2012-05-22 11:07:44Z kib $ */ /** @file drm_dma.c @@ -41,11 +42,11 @@ int drm_dma_setup(struct drm_device *dev) { - dev->dma = malloc(sizeof(*dev->dma), DRM_MEM_DRIVER, M_NOWAIT | M_ZERO); + dev->dma = kmalloc(sizeof(*dev->dma), DRM_MEM_DRIVER, M_NOWAIT | M_ZERO); if (dev->dma == NULL) return ENOMEM; - DRM_SPININIT(&dev->dma_lock, "drmdma"); + spin_init(&dev->dma_lock); return 0; } @@ -67,23 +68,23 @@ void drm_dma_takedown(struct drm_device *dev) for (j = 0; j < dma->bufs[i].seg_count; j++) { drm_pci_free(dev, dma->bufs[i].seglist[j]); } - free(dma->bufs[i].seglist, DRM_MEM_SEGS); + drm_free(dma->bufs[i].seglist, DRM_MEM_SEGS); } if (dma->bufs[i].buf_count) { for (j = 0; j < dma->bufs[i].buf_count; j++) { - free(dma->bufs[i].buflist[j].dev_private, + drm_free(dma->bufs[i].buflist[j].dev_private, DRM_MEM_BUFS); } - free(dma->bufs[i].buflist, DRM_MEM_BUFS); + drm_free(dma->bufs[i].buflist, DRM_MEM_BUFS); } } - free(dma->buflist, DRM_MEM_BUFS); - free(dma->pagelist, DRM_MEM_PAGES); - free(dev->dma, DRM_MEM_DRIVER); + drm_free(dma->buflist, DRM_MEM_BUFS); + drm_free(dma->pagelist, DRM_MEM_PAGES); + drm_free(dev->dma, DRM_MEM_DRIVER); dev->dma = NULL; - DRM_SPINUNINIT(&dev->dma_lock); + spin_uninit(&dev->dma_lock); } diff --git a/sys/dev/drm2/drm_dp_helper.h b/sys/dev/drm/drm_dp_helper.h similarity index 100% rename from sys/dev/drm2/drm_dp_helper.h rename to sys/dev/drm/drm_dp_helper.h diff --git a/sys/dev/drm2/drm_dp_iic_helper.c b/sys/dev/drm/drm_dp_iic_helper.c similarity index 98% rename from sys/dev/drm2/drm_dp_iic_helper.c rename to sys/dev/drm/drm_dp_iic_helper.c index ad47cb4c7c..39485dfa2e 100644 --- a/sys/dev/drm2/drm_dp_iic_helper.c +++ b/sys/dev/drm/drm_dp_iic_helper.c @@ -28,8 +28,8 @@ #include #include "iicbus_if.h" #include -#include -#include +#include +#include static int iic_dp_aux_transaction(device_t idev, int mode, uint8_t write_byte, @@ -282,5 +282,5 @@ static driver_t drm_iic_dp_aux_driver = { sizeof(struct iic_dp_aux_data) }; static devclass_t drm_iic_dp_aux_devclass; -DRIVER_MODULE_ORDERED(drm_iic_dp_aux, drmn, drm_iic_dp_aux_driver, +DRIVER_MODULE_ORDERED(drm_iic_dp_aux, drm, drm_iic_dp_aux_driver, drm_iic_dp_aux_devclass, 0, 0, SI_ORDER_SECOND); diff --git a/sys/dev/drm/drm_drawable.c b/sys/dev/drm/drm_drawable.c index 3ddd709fe5..55fedfba28 100644 --- a/sys/dev/drm/drm_drawable.c +++ b/sys/dev/drm/drm_drawable.c @@ -26,6 +26,7 @@ * Rickard E. (Rik) Faith * Gareth Hughes * + * $FreeBSD: src/sys/dev/drm2/drm_drawable.c,v 1.1 2012/05/22 11:07:44 kib Exp $ */ /** @file drm_drawable.c @@ -73,20 +74,16 @@ int drm_adddraw(struct drm_device *dev, void *data, struct drm_file *file_priv) struct drm_draw *draw = data; struct bsd_drm_drawable_info *info; - info = malloc(sizeof(struct bsd_drm_drawable_info), DRM_MEM_DRAWABLE, + info = kmalloc(sizeof(struct bsd_drm_drawable_info), DRM_MEM_DRAWABLE, M_NOWAIT | M_ZERO); if (info == NULL) return ENOMEM; - /* - * XXX Only valid for sizeof(int) == sizeof(void *) - */ - info->handle = (intptr_t)info; - - DRM_SPINLOCK(&dev->drw_lock); + info->handle = alloc_unr(dev->drw_unrhdr); + spin_lock(&dev->drw_lock); RB_INSERT(drawable_tree, &dev->drw_head, info); draw->handle = info->handle; - DRM_SPINUNLOCK(&dev->drw_lock); + spin_unlock(&dev->drw_lock); DRM_DEBUG("%d\n", draw->handle); @@ -98,17 +95,18 @@ int drm_rmdraw(struct drm_device *dev, void *data, struct drm_file *file_priv) struct drm_draw *draw = (struct drm_draw *)data; struct drm_drawable_info *info; - DRM_SPINLOCK(&dev->drw_lock); + spin_lock(&dev->drw_lock); info = drm_get_drawable_info(dev, draw->handle); if (info != NULL) { RB_REMOVE(drawable_tree, &dev->drw_head, (struct bsd_drm_drawable_info *)info); - DRM_SPINUNLOCK(&dev->drw_lock); - free(info->rects, DRM_MEM_DRAWABLE); - free(info, DRM_MEM_DRAWABLE); + spin_unlock(&dev->drw_lock); + free_unr(dev->drw_unrhdr, draw->handle); + drm_free(info->rects, DRM_MEM_DRAWABLE); + drm_free(info, DRM_MEM_DRAWABLE); return 0; } else { - DRM_SPINUNLOCK(&dev->drw_lock); + spin_unlock(&dev->drw_lock); return EINVAL; } } @@ -126,21 +124,21 @@ int drm_update_draw(struct drm_device *dev, void *data, switch (update->type) { case DRM_DRAWABLE_CLIPRECTS: - DRM_SPINLOCK(&dev->drw_lock); + spin_lock(&dev->drw_lock); if (update->num != info->num_rects) { - free(info->rects, DRM_MEM_DRAWABLE); + drm_free(info->rects, DRM_MEM_DRAWABLE); info->rects = NULL; info->num_rects = 0; } if (update->num == 0) { - DRM_SPINUNLOCK(&dev->drw_lock); + spin_unlock(&dev->drw_lock); return 0; } if (info->rects == NULL) { - info->rects = malloc(sizeof(*info->rects) * + info->rects = kmalloc(sizeof(*info->rects) * update->num, DRM_MEM_DRAWABLE, M_NOWAIT); if (info->rects == NULL) { - DRM_SPINUNLOCK(&dev->drw_lock); + spin_unlock(&dev->drw_lock); return ENOMEM; } info->num_rects = update->num; @@ -148,7 +146,7 @@ int drm_update_draw(struct drm_device *dev, void *data, /* For some reason the pointer arg is unsigned long long. */ ret = copyin((void *)(intptr_t)update->data, info->rects, sizeof(*info->rects) * info->num_rects); - DRM_SPINUNLOCK(&dev->drw_lock); + spin_unlock(&dev->drw_lock); return ret; default: return EINVAL; @@ -159,15 +157,17 @@ void drm_drawable_free_all(struct drm_device *dev) { struct bsd_drm_drawable_info *info, *next; - DRM_SPINLOCK(&dev->drw_lock); + spin_lock(&dev->drw_lock); for (info = RB_MIN(drawable_tree, &dev->drw_head); info != NULL ; info = next) { next = RB_NEXT(drawable_tree, &dev->drw_head, info); - RB_REMOVE(drawable_tree, &dev->drw_head, info); - DRM_SPINUNLOCK(&dev->drw_lock); - free(info->info.rects, DRM_MEM_DRAWABLE); - free(info, DRM_MEM_DRAWABLE); - DRM_SPINLOCK(&dev->drw_lock); + RB_REMOVE(drawable_tree, &dev->drw_head, + (struct bsd_drm_drawable_info *)info); + spin_unlock(&dev->drw_lock); + free_unr(dev->drw_unrhdr, info->handle); + drm_free(info->info.rects, DRM_MEM_DRAWABLE); + drm_free(info, DRM_MEM_DRAWABLE); + spin_lock(&dev->drw_lock); } - DRM_SPINUNLOCK(&dev->drw_lock); + spin_unlock(&dev->drw_lock); } diff --git a/sys/dev/drm/drm_drv.c b/sys/dev/drm/drm_drv.c index d4d9bd3e34..3b91cc8e82 100644 --- a/sys/dev/drm/drm_drv.c +++ b/sys/dev/drm/drm_drv.c @@ -26,6 +26,7 @@ * Rickard E. (Rik) Faith * Gareth Hughes * + * $FreeBSD: head/sys/dev/drm2/drm_drv.c 247835 2013-03-05 09:49:34Z kib $ */ /** @file drm_drv.c @@ -33,16 +34,23 @@ * open/close, and ioctl dispatch. */ +#include #include + #include "dev/drm/drmP.h" #include "dev/drm/drm.h" #include "dev/drm/drm_sarea.h" #ifdef DRM_DEBUG_DEFAULT_ON -int drm_debug_flag = 1; +int drm_debug_flag = (DRM_DEBUGBITS_DEBUG | DRM_DEBUGBITS_KMS | + DRM_DEBUGBITS_FAILED_IOCTL); #else int drm_debug_flag = 0; #endif +int drm_notyet_flag = 0; + +unsigned int drm_vblank_offdelay = 5000; /* Default to 5000 msecs. */ +unsigned int drm_timestamp_precision = 20; /* Default to 20 usecs. */ static int drm_load(struct drm_device *dev); static void drm_unload(struct drm_device *dev); @@ -52,9 +60,29 @@ static drm_pci_id_list_t *drm_find_description(int vendor, int device, #define DRIVER_SOFTC(unit) \ ((struct drm_device *)devclass_get_softc(drm_devclass, unit)) +static int +drm_modevent(module_t mod, int type, void *data) +{ + + switch (type) { + case MOD_LOAD: + TUNABLE_INT_FETCH("drm.debug", &drm_debug_flag); + TUNABLE_INT_FETCH("drm.notyet", &drm_notyet_flag); + break; + } + return (0); +} + +static moduledata_t drm_mod = { + "drm", + drm_modevent, + 0 +}; +DECLARE_MODULE(drm, drm_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST); MODULE_VERSION(drm, 1); MODULE_DEPEND(drm, agp, 1, 1, 1); MODULE_DEPEND(drm, pci, 1, 1, 1); +MODULE_DEPEND(drm, iicbus, 1, 1, 1); static drm_ioctl_desc_t drm_ioctls[256] = { DRM_IOCTL_DEF(DRM_IOCTL_VERSION, drm_version, 0), @@ -64,6 +92,7 @@ static drm_ioctl_desc_t drm_ioctls[256] = { DRM_IOCTL_DEF(DRM_IOCTL_GET_MAP, drm_getmap, 0), DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT, drm_getclient, 0), DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS, drm_getstats, 0), + DRM_IOCTL_DEF(DRM_IOCTL_GET_CAP, drm_getcap, DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF(DRM_IOCTL_SET_UNIQUE, drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), @@ -77,6 +106,9 @@ static drm_ioctl_desc_t drm_ioctls[256] = { DRM_IOCTL_DEF(DRM_IOCTL_SET_SAREA_CTX, drm_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF(DRM_IOCTL_GET_SAREA_CTX, drm_getsareactx, DRM_AUTH), + DRM_IOCTL_DEF(DRM_IOCTL_SET_MASTER, drm_setmaster_ioctl, DRM_ROOT_ONLY), + DRM_IOCTL_DEF(DRM_IOCTL_DROP_MASTER, drm_dropmaster_ioctl, DRM_ROOT_ONLY), + DRM_IOCTL_DEF(DRM_IOCTL_ADD_CTX, drm_addctx, DRM_AUTH|DRM_ROOT_ONLY), DRM_IOCTL_DEF(DRM_IOCTL_RM_CTX, drm_rmctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF(DRM_IOCTL_MOD_CTX, drm_modctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), @@ -113,23 +145,57 @@ static drm_ioctl_desc_t drm_ioctls[256] = { DRM_IOCTL_DEF(DRM_IOCTL_SG_ALLOC, drm_sg_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF(DRM_IOCTL_SG_FREE, drm_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, 0), + DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_modeset_ctl, 0), DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_update_draw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + + DRM_IOCTL_DEF(DRM_IOCTL_GEM_CLOSE, drm_gem_close_ioctl, DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH|DRM_UNLOCKED), + + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANE, drm_mode_getplane, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPLANE, drm_mode_setplane, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR, drm_mode_cursor_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETGAMMA, drm_mode_gamma_get_ioctl, DRM_MASTER|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETGAMMA, drm_mode_gamma_set_ioctl, DRM_MASTER|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETENCODER, drm_mode_getencoder, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCONNECTOR, drm_mode_getconnector, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_mode_attachmode_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_mode_detachmode_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, DRM_MASTER | DRM_CONTROL_ALLOW|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPROPERTY, drm_mode_connector_property_set_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB2, drm_mode_addfb2, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_PAGE_FLIP, drm_mode_page_flip_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_DIRTYFB, drm_mode_dirtyfb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_DUMB, drm_mode_create_dumb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_MAP_DUMB, drm_mode_mmap_dumb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_DESTROY_DUMB, drm_mode_destroy_dumb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), }; static struct dev_ops drm_cdevsw = { { "drm", 0, D_TRACKCLOSE }, - .d_open = drm_open, + .d_open = drm_open, .d_close = drm_close, - .d_read = drm_read, - .d_ioctl = drm_ioctl, + .d_read = drm_read, + .d_ioctl = drm_ioctl, .d_kqfilter = drm_kqfilter, - .d_mmap = drm_mmap + .d_mmap = drm_mmap, + .d_mmap_single = drm_mmap_single, }; static int drm_msi = 1; /* Enable by default. */ TUNABLE_INT("hw.drm.msi", &drm_msi); +SYSCTL_NODE(_hw, OID_AUTO, drm, CTLFLAG_RW, NULL, "DRM device"); +SYSCTL_INT(_hw_drm, OID_AUTO, msi, CTLFLAG_RD, &drm_msi, 1, + "Enable MSI interrupts for drm devices"); static struct drm_msi_blacklist_entry drm_msi_blacklist[] = { {0x8086, 0x2772}, /* Intel i945G */ \ @@ -160,8 +226,7 @@ int drm_probe(device_t kdev, drm_pci_id_list_t *idlist) vendor = pci_get_vendor(kdev); device = pci_get_device(kdev); - if (pci_get_class(kdev) != PCIC_DISPLAY - || pci_get_subclass(kdev) != PCIS_DISPLAY_VGA) + if (pci_get_class(kdev) != PCIC_DISPLAY) return ENXIO; id_entry = drm_find_description(vendor, device, idlist); @@ -221,16 +286,18 @@ int drm_attach(device_t kdev, drm_pci_id_list_t *idlist) dev->irqr = bus_alloc_resource_any(dev->device, SYS_RES_IRQ, &dev->irqrid, RF_SHAREABLE); if (!dev->irqr) { - return ENOENT; + return (ENOENT); } dev->irq = (int) rman_get_start(dev->irqr); } - DRM_SPININIT(&dev->dev_lock, "drmdev"); + lockinit(&dev->dev_lock, "drmdev", 0, LK_CANRECURSE); lwkt_serialize_init(&dev->irq_lock); - DRM_SPININIT(&dev->vbl_lock, "drmvbl"); - DRM_SPININIT(&dev->drw_lock, "drmdrw"); + lockinit(&dev->vbl_lock, "drmvbl", 0, LK_CANRECURSE); + spin_init(&dev->drw_lock); + lockinit(&dev->event_lock, "drmev", 0, LK_CANRECURSE); + lockinit(&dev->dev_struct_lock, "drmslk", 0, LK_CANRECURSE); id_entry = drm_find_description(dev->pci_vendor, dev->pci_device, idlist); @@ -244,20 +311,16 @@ int drm_detach(device_t kdev) struct drm_device *dev; dev = device_get_softc(kdev); - drm_unload(dev); - if (dev->irqr) { bus_release_resource(dev->device, SYS_RES_IRQ, dev->irqrid, dev->irqr); - if (dev->msi_enabled) { pci_release_msi(dev->device); DRM_INFO("MSI released\n"); } } - - return 0; + return (0); } #ifndef DRM_DEV_NAME @@ -286,7 +349,7 @@ static int drm_firstopen(struct drm_device *dev) drm_local_map_t *map; int i; - DRM_SPINLOCK_ASSERT(&dev->dev_lock); + DRM_LOCK_ASSERT(dev); /* prebuild the SAREA */ i = drm_addmap(dev, 0, SAREA_MAX, _DRM_SHM, @@ -311,7 +374,8 @@ static int drm_firstopen(struct drm_device *dev) } dev->lock.lock_queue = 0; - dev->irq_enabled = 0; + if (!drm_core_check_feature(dev, DRIVER_MODESET)) + dev->irq_enabled = 0; dev->context_flag = 0; dev->last_context = 0; dev->if_version = 0; @@ -329,18 +393,18 @@ static int drm_lastclose(struct drm_device *dev) drm_local_map_t *map, *mapsave; int i; - DRM_SPINLOCK_ASSERT(&dev->dev_lock); + DRM_LOCK_ASSERT(dev); DRM_DEBUG("\n"); if (dev->driver->lastclose != NULL) dev->driver->lastclose(dev); - if (dev->irq_enabled) + if (!drm_core_check_feature(dev, DRIVER_MODESET) && dev->irq_enabled) drm_irq_uninstall(dev); if (dev->unique) { - free(dev->unique, DRM_MEM_DRIVER); + drm_free(dev->unique, DRM_MEM_DRIVER); dev->unique = NULL; dev->unique_len = 0; } @@ -348,14 +412,14 @@ static int drm_lastclose(struct drm_device *dev) for (i = 0; i < DRM_HASH_SIZE; i++) { for (pt = dev->magiclist[i].head; pt; pt = next) { next = pt->next; - free(pt, DRM_MEM_MAGIC); + drm_free(pt, DRM_MEM_MAGIC); } dev->magiclist[i].head = dev->magiclist[i].tail = NULL; } - DRM_UNLOCK(); + DRM_UNLOCK(dev); drm_drawable_free_all(dev); - DRM_LOCK(); + DRM_LOCK(dev); /* Clear AGP information */ if (dev->agp) { @@ -370,7 +434,7 @@ static int drm_lastclose(struct drm_device *dev) if (entry->bound) drm_agp_unbind_memory(entry->handle); drm_agp_free_memory(entry->handle); - free(entry, DRM_MEM_AGPLISTS); + drm_free(entry, DRM_MEM_AGPLISTS); } dev->agp->memory = NULL; @@ -429,16 +493,7 @@ static int drm_load(struct drm_device *dev) for (i = 0; i < DRM_ARRAY_SIZE(dev->counts); i++) atomic_set(&dev->counts[i], 0); - if (dev->driver->load != NULL) { - DRM_LOCK(); - /* Shared code returns -errno. */ - retcode = -dev->driver->load(dev, - dev->id_entry->driver_private); - pci_enable_busmaster(dev->device); - DRM_UNLOCK(); - if (retcode != 0) - goto error; - } + INIT_LIST_HEAD(&dev->vblank_event_list); if (drm_core_has_AGP(dev)) { if (drm_device_is_agp(dev)) @@ -450,7 +505,7 @@ static int drm_load(struct drm_device *dev) retcode = ENOMEM; goto error; } - if (dev->agp != NULL) { + if (dev->agp != NULL && dev->agp->info.ai_aperture_base != 0) { if (drm_mtrr_add(dev->agp->info.ai_aperture_base, dev->agp->info.ai_aperture_size, DRM_MTRR_WC) == 0) dev->agp->mtrr = 1; @@ -463,6 +518,34 @@ static int drm_load(struct drm_device *dev) goto error; } + dev->drw_unrhdr = new_unrhdr(1, INT_MAX, NULL); + if (dev->drw_unrhdr == NULL) { + DRM_ERROR("Couldn't allocate drawable number allocator\n"); + retcode = ENOMEM; + goto error; + } + + if (dev->driver->driver_features & DRIVER_GEM) { + retcode = drm_gem_init(dev); + if (retcode != 0) { + DRM_ERROR("Cannot initialize graphics execution " + "manager (GEM)\n"); + goto error1; + } + } + + if (dev->driver->load != NULL) { + DRM_LOCK(dev); + /* Shared code returns -errno. */ + retcode = -dev->driver->load(dev, + dev->id_entry->driver_private); + if (pci_enable_busmaster(dev->device)) + DRM_ERROR("Request to enable bus-master failed.\n"); + DRM_UNLOCK(dev); + if (retcode != 0) + goto error; + } + DRM_INFO("Initialized %s %d.%d.%d %s\n", dev->driver->name, dev->driver->major, @@ -472,16 +555,21 @@ static int drm_load(struct drm_device *dev) return 0; +error1: + delete_unrhdr(dev->drw_unrhdr); error: drm_sysctl_cleanup(dev); - DRM_LOCK(); + DRM_LOCK(dev); drm_lastclose(dev); - DRM_UNLOCK(); - destroy_dev(dev->devnode); + DRM_UNLOCK(dev); + if (dev->devnode != NULL) + destroy_dev(dev->devnode); - DRM_SPINUNINIT(&dev->drw_lock); - DRM_SPINUNINIT(&dev->vbl_lock); - DRM_SPINUNINIT(&dev->dev_lock); + spin_uninit(&dev->drw_lock); + lockuninit(&dev->vbl_lock); + lockuninit(&dev->dev_lock); + lockuninit(&dev->event_lock); + lockuninit(&dev->dev_struct_lock); return retcode; } @@ -493,12 +581,16 @@ static void drm_unload(struct drm_device *dev) DRM_DEBUG("\n"); drm_sysctl_cleanup(dev); - destroy_dev(dev->devnode); + if (dev->devnode != NULL) + destroy_dev(dev->devnode); drm_ctxbitmap_cleanup(dev); + if (dev->driver->driver_features & DRIVER_GEM) + drm_gem_destroy(dev); + if (dev->agp && dev->agp->mtrr) { - int retcode; + int __unused retcode; retcode = drm_mtrr_del(0, dev->agp->info.ai_aperture_base, dev->agp->info.ai_aperture_size, DRM_MTRR_WC); @@ -507,9 +599,9 @@ static void drm_unload(struct drm_device *dev) drm_vblank_cleanup(dev); - DRM_LOCK(); + DRM_LOCK(dev); drm_lastclose(dev); - DRM_UNLOCK(); + DRM_UNLOCK(dev); /* Clean up PCI resources allocated by drm_bufs.c. We're not really * worried about resource consumption while the DRM is inactive (between @@ -525,23 +617,29 @@ static void drm_unload(struct drm_device *dev) } if (dev->agp) { - free(dev->agp, DRM_MEM_AGPLISTS); + drm_free(dev->agp, DRM_MEM_AGPLISTS); dev->agp = NULL; } if (dev->driver->unload != NULL) { - DRM_LOCK(); + DRM_LOCK(dev); dev->driver->unload(dev); - DRM_UNLOCK(); + DRM_UNLOCK(dev); } + delete_unrhdr(dev->drw_unrhdr); + delete_unrhdr(dev->map_unrhdr); + drm_mem_uninit(); - pci_disable_busmaster(dev->device); + if (pci_disable_busmaster(dev->device)) + DRM_ERROR("Request to disable bus-master failed.\n"); - DRM_SPINUNINIT(&dev->drw_lock); - DRM_SPINUNINIT(&dev->vbl_lock); - DRM_SPINUNINIT(&dev->dev_lock); + spin_uninit(&dev->drw_lock); + lockuninit(&dev->vbl_lock); + lockuninit(&dev->dev_lock); + lockuninit(&dev->event_lock); + lockuninit(&dev->dev_struct_lock); } int drm_version(struct drm_device *dev, void *data, struct drm_file *file_priv) @@ -569,31 +667,37 @@ int drm_version(struct drm_device *dev, void *data, struct drm_file *file_priv) return 0; } -int drm_open(struct dev_open_args *ap) +int +/* drm_open(struct cdev *kdev, int flags, int fmt, DRM_STRUCTPROC *p) */ +drm_open(struct dev_open_args *ap) { struct cdev *kdev = ap->a_head.a_dev; int flags = ap->a_oflags; int fmt = 0; struct thread *p = curthread; - struct drm_device *dev = NULL; - int retcode = 0; + struct drm_device *dev; + int retcode; dev = DRIVER_SOFTC(minor(kdev)); + if (dev == NULL) + return (ENXIO); DRM_DEBUG("open_count = %d\n", dev->open_count); retcode = drm_open_helper(kdev, flags, fmt, p, dev); - if (!retcode) { + if (retcode == 0) { atomic_inc(&dev->counts[_DRM_STAT_OPENS]); - DRM_LOCK(); + DRM_LOCK(dev); device_busy(dev->device); if (!dev->open_count++) retcode = drm_firstopen(dev); - DRM_UNLOCK(); + DRM_UNLOCK(dev); } - return retcode; + DRM_DEBUG("return %d\n", retcode); + + return (retcode); } int drm_close(struct dev_close_args *ap) @@ -608,10 +712,7 @@ int drm_close(struct dev_close_args *ap) DRM_DEBUG("open_count = %d\n", dev->open_count); - DRM_LOCK(); - - if (--file_priv->refs != 0) - goto done; + DRM_LOCK(dev); if (dev->driver->preclose != NULL) dev->driver->preclose(dev, file_priv); @@ -623,6 +724,9 @@ int drm_close(struct dev_close_args *ap) DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n", DRM_CURRENTPID, (long)dev->device, dev->open_count); + if (dev->driver->driver_features & DRIVER_GEM) + drm_gem_release(dev, file_priv); + if (dev->lock.hw_lock && _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) && dev->lock.file_priv == file_priv) { DRM_DEBUG("Process %d dead, freeing lock for context %d\n", @@ -654,11 +758,8 @@ int drm_close(struct dev_close_args *ap) break; /* Got lock */ } /* Contention */ - tsleep_interlock((void *)&dev->lock.lock_queue, PCATCH); - DRM_UNLOCK(); - retcode = tsleep((void *)&dev->lock.lock_queue, - PCATCH | PINTERLOCKED, "drmlk2", 0); - DRM_LOCK(); + retcode = DRM_LOCK_SLEEP(dev, &dev->lock.lock_queue, + PCATCH, "drmlk2", 0); if (retcode) break; } @@ -677,19 +778,19 @@ int drm_close(struct dev_close_args *ap) if (dev->driver->postclose != NULL) dev->driver->postclose(dev, file_priv); TAILQ_REMOVE(&dev->files, file_priv, link); - free(file_priv, DRM_MEM_FILES); + drm_free(file_priv, DRM_MEM_FILES); /* ======================================================== * End inline drm_release */ -done: + atomic_inc(&dev->counts[_DRM_STAT_CLOSES]); device_unbusy(dev->device); if (--dev->open_count == 0) { retcode = drm_lastclose(dev); } - DRM_UNLOCK(); + DRM_UNLOCK(dev); return (0); } @@ -711,10 +812,6 @@ int drm_ioctl(struct dev_ioctl_args *ap) struct drm_file *file_priv; file_priv = drm_find_file_by_proc(dev, p); - if (!file_priv) { - DRM_ERROR("can't find authenticator\n"); - return EINVAL; - } atomic_inc(&dev->counts[_DRM_STAT_IOCTLS]); ++file_priv->ioctl_count; @@ -767,16 +864,25 @@ int drm_ioctl(struct dev_ioctl_args *ap) return EACCES; if (is_driver_ioctl) { - DRM_LOCK(); + if ((ioctl->flags & DRM_UNLOCKED) == 0) + DRM_LOCK(dev); /* shared code returns -errno */ retcode = -func(dev, data, file_priv); - DRM_UNLOCK(); + if ((ioctl->flags & DRM_UNLOCKED) == 0) + DRM_UNLOCK(dev); } else { retcode = func(dev, data, file_priv); } if (retcode != 0) DRM_DEBUG(" returning %d\n", retcode); + if (retcode != 0 && + (drm_debug_flag & DRM_DEBUGBITS_FAILED_IOCTL) != 0) { + kprintf( +"pid %d, cmd 0x%02lx, nr 0x%02x/%1d, dev 0x%lx, auth %d, res %d\n", + DRM_CURRENTPID, cmd, nr, is_driver_ioctl, (long)dev->device, + file_priv->authenticated, retcode); + } return retcode; } @@ -785,7 +891,7 @@ drm_local_map_t *drm_getsarea(struct drm_device *dev) { drm_local_map_t *map; - DRM_SPINLOCK_ASSERT(&dev->dev_lock); + DRM_LOCK_ASSERT(dev); TAILQ_FOREACH(map, &dev->maplist, link) { if (map->type == _DRM_SHM && (map->flags & _DRM_CONTAINS_LOCK)) return map; @@ -794,6 +900,49 @@ drm_local_map_t *drm_getsarea(struct drm_device *dev) return NULL; } +int +drm_add_busid_modesetting(struct drm_device *dev, struct sysctl_ctx_list *ctx, + struct sysctl_oid *top) +{ + struct sysctl_oid *oid; + + ksnprintf(dev->busid_str, sizeof(dev->busid_str), + "pci:%04x:%02x:%02x.%d", dev->pci_domain, dev->pci_bus, + dev->pci_slot, dev->pci_func); + oid = SYSCTL_ADD_STRING(ctx, SYSCTL_CHILDREN(top), OID_AUTO, "busid", + CTLFLAG_RD, dev->busid_str, 0, NULL); + if (oid == NULL) + return (ENOMEM); + dev->modesetting = (dev->driver->driver_features & DRIVER_MODESET) != 0; + oid = SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(top), OID_AUTO, + "modesetting", CTLFLAG_RD, &dev->modesetting, 0, NULL); + if (oid == NULL) + return (ENOMEM); + + return (0); +} + +int +drm_mmap_single(struct dev_mmap_single_args *ap) +{ + struct drm_device *dev; + struct cdev *kdev = ap->a_head.a_dev; + vm_ooffset_t *offset = ap->a_offset; + vm_size_t size = ap->a_size; + struct vm_object **obj_res = ap->a_object; + int nprot = ap->a_nprot; + + dev = drm_get_device_from_kdev(kdev); + if ((dev->driver->driver_features & DRIVER_GEM) != 0) { + return (drm_gem_mmap_single(dev, offset, size, obj_res, nprot)); + } else if (dev->drm_ttm_bo != NULL) { + return (ttm_bo_mmap_single(dev->drm_ttm_bo, offset, size, + obj_res, nprot)); + } else { + return (ENODEV); + } +} + #if DRM_LINUX #include @@ -833,3 +982,83 @@ drm_linux_ioctl(DRM_STRUCTPROC *p, struct linux_ioctl_args* args) return error; } #endif /* DRM_LINUX */ + +/* + * Check if dmi_system_id structure matches system DMI data + */ +static bool +dmi_found(const struct dmi_system_id *dsi) +{ + int i, slot; + bool found = false; + char *sys_vendor, *board_vendor, *product_name, *board_name; + + sys_vendor = kgetenv("smbios.system.maker"); + board_vendor = kgetenv("smbios.planar.maker"); + product_name = kgetenv("smbios.system.product"); + board_name = kgetenv("smbios.planar.product"); + + for (i = 0; i < NELEM(dsi->matches); i++) { + slot = dsi->matches[i].slot; + switch (slot) { + case DMI_NONE: + break; + case DMI_SYS_VENDOR: + if (sys_vendor != NULL && + !strcmp(sys_vendor, dsi->matches[i].substr)) + break; + else + goto done; + case DMI_BOARD_VENDOR: + if (board_vendor != NULL && + !strcmp(board_vendor, dsi->matches[i].substr)) + break; + else + goto done; + case DMI_PRODUCT_NAME: + if (product_name != NULL && + !strcmp(product_name, dsi->matches[i].substr)) + break; + else + goto done; + case DMI_BOARD_NAME: + if (board_name != NULL && + !strcmp(board_name, dsi->matches[i].substr)) + break; + else + goto done; + default: + goto done; + } + } + found = true; + +done: + if (sys_vendor != NULL) + kfreeenv(sys_vendor); + if (board_vendor != NULL) + kfreeenv(board_vendor); + if (product_name != NULL) + kfreeenv(product_name); + if (board_name != NULL) + kfreeenv(board_name); + + return found; +} + +bool +dmi_check_system(const struct dmi_system_id *sysid) +{ + const struct dmi_system_id *dsi; + int num = 0; + + for (dsi = sysid; dsi->matches[0].slot != 0 ; dsi++) { + if (dmi_found(dsi)) { + num++; + if (dsi->callback && dsi->callback(dsi)) + break; + } + } + return (num); +} + diff --git a/sys/dev/drm2/drm_edid.c b/sys/dev/drm/drm_edid.c similarity index 99% rename from sys/dev/drm2/drm_edid.c rename to sys/dev/drm/drm_edid.c index 557563be2b..b202cf54df 100644 --- a/sys/dev/drm2/drm_edid.c +++ b/sys/dev/drm/drm_edid.c @@ -30,9 +30,9 @@ * $FreeBSD: head/sys/dev/drm2/drm_edid.c 249041 2013-04-03 08:27:35Z dumbbell $ */ -#include -#include -#include +#include +#include +#include #include #include #include "iicbus_if.h" diff --git a/sys/dev/drm2/drm_edid.h b/sys/dev/drm/drm_edid.h similarity index 99% rename from sys/dev/drm2/drm_edid.h rename to sys/dev/drm/drm_edid.h index f9a79f0735..839e5ae9ad 100644 --- a/sys/dev/drm2/drm_edid.h +++ b/sys/dev/drm/drm_edid.h @@ -26,7 +26,7 @@ #define __DRM_EDID_H__ #include -#include +#include #define EDID_LENGTH 128 #define DDC_ADDR 0x50 diff --git a/sys/dev/drm2/drm_edid_modes.h b/sys/dev/drm/drm_edid_modes.h similarity index 99% rename from sys/dev/drm2/drm_edid_modes.h rename to sys/dev/drm/drm_edid_modes.h index 4ab5641910..e422af7c45 100644 --- a/sys/dev/drm2/drm_edid_modes.h +++ b/sys/dev/drm/drm_edid_modes.h @@ -25,8 +25,8 @@ * $FreeBSD: src/sys/dev/drm2/drm_edid_modes.h,v 1.1 2012/05/22 11:07:44 kib Exp $ */ -#include -#include +#include +#include /* * Autogenerated from the DMT spec. diff --git a/sys/dev/drm2/drm_fb_helper.c b/sys/dev/drm/drm_fb_helper.c similarity index 99% rename from sys/dev/drm2/drm_fb_helper.c rename to sys/dev/drm/drm_fb_helper.c index f61f0c5460..897e085022 100644 --- a/sys/dev/drm2/drm_fb_helper.c +++ b/sys/dev/drm/drm_fb_helper.c @@ -30,10 +30,10 @@ * $FreeBSD: src/sys/dev/drm2/drm_fb_helper.c,v 1.1 2012/05/22 11:07:44 kib Exp $ */ -#include -#include -#include -#include +#include +#include +#include +#include static DRM_LIST_HEAD(kernel_fb_helper_list); diff --git a/sys/dev/drm2/drm_fb_helper.h b/sys/dev/drm/drm_fb_helper.h similarity index 100% rename from sys/dev/drm2/drm_fb_helper.h rename to sys/dev/drm/drm_fb_helper.h diff --git a/sys/dev/drm/drm_fops.c b/sys/dev/drm/drm_fops.c index ae4a9e29b9..2d11fd05e6 100644 --- a/sys/dev/drm/drm_fops.c +++ b/sys/dev/drm/drm_fops.c @@ -27,6 +27,7 @@ * Daryll Strauss * Gareth Hughes * + * $FreeBSD: src/sys/dev/drm2/drm_fops.c,v 1.1 2012/05/22 11:07:44 kib Exp $ */ /** @file drm_fops.c @@ -34,6 +35,9 @@ * open of the DRM device. */ +#include +#include + #include "dev/drm/drmP.h" struct drm_file *drm_find_file_by_proc(struct drm_device *dev, DRM_STRUCTPROC *p) @@ -53,60 +57,130 @@ int drm_open_helper(struct cdev *kdev, int flags, int fmt, DRM_STRUCTPROC *p, struct drm_device *dev) { struct drm_file *priv; - int m = minor(kdev); int retcode; if (flags & O_EXCL) return EBUSY; /* No exclusive opens */ dev->flags = flags; - DRM_DEBUG("pid = %d, minor = %d\n", DRM_CURRENTPID, m); - DRM_LOCK(); + DRM_DEBUG("pid = %d, device = %s\n", DRM_CURRENTPID, devtoname(kdev)); + DRM_LOCK(dev); + priv = drm_find_file_by_proc(dev, p); if (priv) { - priv->refs++; - } else { - priv = malloc(sizeof(*priv), DRM_MEM_FILES, M_NOWAIT | M_ZERO); - if (priv == NULL) { - DRM_UNLOCK(); - return ENOMEM; - } - priv->uid = p->td_proc->p_ucred->cr_svuid; - priv->pid = p->td_proc->p_pid; - priv->refs = 1; - priv->minor = m; - priv->ioctl_count = 0; - - /* for compatibility root is always authenticated */ - priv->authenticated = DRM_SUSER(p); - - if (dev->driver->open) { - /* shared code returns -errno */ - retcode = -dev->driver->open(dev, priv); - if (retcode != 0) { - free(priv, DRM_MEM_FILES); - DRM_UNLOCK(); - return retcode; - } - } - - /* first opener automatically becomes master */ - priv->master = TAILQ_EMPTY(&dev->files); - - TAILQ_INSERT_TAIL(&dev->files, priv, link); + goto priv_found; + } + + priv = kmalloc(sizeof(*priv), DRM_MEM_FILES, M_NOWAIT | M_ZERO); + if (priv == NULL) { + return ENOMEM; + } + +priv_found: + + priv->dev = dev; + priv->uid = p->td_proc->p_ucred->cr_svuid; + priv->uid = p->td_ucred->cr_svuid; + priv->pid = p->td_proc->p_pid; + priv->ioctl_count = 0; + + /* for compatibility root is always authenticated */ + priv->authenticated = DRM_SUSER(p); + + INIT_LIST_HEAD(&priv->fbs); + INIT_LIST_HEAD(&priv->event_list); + priv->event_space = 4096; /* set aside 4k for event buffer */ + + if (dev->driver->driver_features & DRIVER_GEM) + drm_gem_open(dev, priv); + + if (dev->driver->open) { + /* shared code returns -errno */ + retcode = -dev->driver->open(dev, priv); + if (retcode != 0) { + drm_free(priv, DRM_MEM_FILES); + DRM_UNLOCK(dev); + return retcode; + } } - DRM_UNLOCK(); + /* first opener automatically becomes master */ + priv->master = TAILQ_EMPTY(&dev->files); + + TAILQ_INSERT_TAIL(&dev->files, priv, link); + DRM_UNLOCK(dev); kdev->si_drv1 = dev; return 0; } +static bool +drm_dequeue_event(struct drm_device *dev, struct drm_file *file_priv, + struct uio *uio, struct drm_pending_event **out) +{ + struct drm_pending_event *e; + + if (list_empty(&file_priv->event_list)) + return (false); + e = list_first_entry(&file_priv->event_list, + struct drm_pending_event, link); + if (e->event->length > uio->uio_resid) + return (false); + + file_priv->event_space += e->event->length; + list_del(&e->link); + *out = e; + return (true); +} + +int +drm_read(struct dev_read_args *ap) +{ + struct cdev *kdev = ap->a_head.a_dev; + struct uio *uio = ap->a_uio; + int ioflag = ap->a_ioflag; + struct drm_file *file_priv; + struct drm_device *dev; + struct drm_pending_event *e; + int error; + + dev = drm_get_device_from_kdev(kdev); + file_priv = drm_find_file_by_proc(dev, curthread); + + lockmgr(&dev->event_lock, LK_EXCLUSIVE); + while (list_empty(&file_priv->event_list)) { + if ((ioflag & O_NONBLOCK) != 0) { + error = EAGAIN; + goto out; + } + error = lksleep(&file_priv->event_space, &dev->event_lock, + PCATCH, "drmrea", 0); + if (error != 0) + goto out; + } + while (drm_dequeue_event(dev, file_priv, uio, &e)) { + lockmgr(&dev->event_lock, LK_RELEASE); + error = uiomove((caddr_t)e->event, e->event->length, uio); + e->destroy(e); + if (error != 0) + return (error); + lockmgr(&dev->event_lock, LK_EXCLUSIVE); + } +out: + lockmgr(&dev->event_lock, LK_RELEASE); + return (error); +} -/* The drm_read and drm_poll are stubs to prevent spurious errors - * on older X Servers (4.3.0 and earlier) */ -int drm_read(struct dev_read_args *ap) +void +drm_event_wakeup(struct drm_pending_event *e) { - return 0; + struct drm_file *file_priv; + struct drm_device *dev; + + file_priv = e->file_priv; + dev = file_priv->dev; + KKASSERT(lockstatus(&dev->event_lock, curthread) != 0); + + wakeup(&file_priv->event_space); } static int diff --git a/sys/dev/drm2/drm_fourcc.h b/sys/dev/drm/drm_fourcc.h similarity index 100% rename from sys/dev/drm2/drm_fourcc.h rename to sys/dev/drm/drm_fourcc.h diff --git a/sys/dev/drm2/drm_gem.c b/sys/dev/drm/drm_gem.c similarity index 99% rename from sys/dev/drm2/drm_gem.c rename to sys/dev/drm/drm_gem.c index c6cc199956..9108532428 100644 --- a/sys/dev/drm2/drm_gem.c +++ b/sys/dev/drm/drm_gem.c @@ -41,9 +41,9 @@ #include #include -#include -#include -#include +#include +#include +#include /* * We make up offsets for buffer objects so we can recognize them at diff --git a/sys/dev/drm2/drm_gem_names.c b/sys/dev/drm/drm_gem_names.c similarity index 98% rename from sys/dev/drm2/drm_gem_names.c rename to sys/dev/drm/drm_gem_names.c index 2780296bde..1f7f2291bf 100644 --- a/sys/dev/drm2/drm_gem_names.c +++ b/sys/dev/drm/drm_gem_names.c @@ -36,8 +36,8 @@ #include #include -#include -#include +#include +#include MALLOC_DEFINE(M_GEM_NAMES, "gem_name", "Hash headers for the gem names"); diff --git a/sys/dev/drm2/drm_gem_names.h b/sys/dev/drm/drm_gem_names.h similarity index 100% rename from sys/dev/drm2/drm_gem_names.h rename to sys/dev/drm/drm_gem_names.h diff --git a/sys/dev/drm2/drm_global.c b/sys/dev/drm/drm_global.c similarity index 98% rename from sys/dev/drm2/drm_global.c rename to sys/dev/drm/drm_global.c index df20cd2e01..e321a79418 100644 --- a/sys/dev/drm2/drm_global.c +++ b/sys/dev/drm/drm_global.c @@ -29,8 +29,8 @@ * $FreeBSD: head/sys/dev/drm2/drm_global.c 248060 2013-03-08 18:11:02Z dumbbell $ */ -#include -#include +#include +#include MALLOC_DEFINE(M_DRM_GLOBAL, "drm_global", "DRM Global Items"); diff --git a/sys/dev/drm2/drm_global.h b/sys/dev/drm/drm_global.h similarity index 100% rename from sys/dev/drm2/drm_global.h rename to sys/dev/drm/drm_global.h diff --git a/sys/dev/drm/drm_hashtab.h b/sys/dev/drm/drm_hashtab.h index 2887187215..8842b065a2 100644 --- a/sys/dev/drm/drm_hashtab.h +++ b/sys/dev/drm/drm_hashtab.h @@ -24,7 +24,7 @@ * USE OR OTHER DEALINGS IN THE SOFTWARE. * * - * $FreeBSD: src/sys/dev/drm/drm_hashtab.h,v 1.1 2010/01/31 14:25:29 rnoland Exp $ + * $FreeBSD: head/sys/dev/drm2/drm_hashtab.h 235783 2012-05-22 11:07:44Z kib $ **************************************************************************/ /* @@ -46,7 +46,7 @@ struct drm_hash_item { struct drm_open_hash { LIST_HEAD(drm_hash_item_list, drm_hash_item) *table; - unsigned int size; + unsigned int size; unsigned int order; unsigned long mask; }; diff --git a/sys/dev/drm/drm_ioctl.c b/sys/dev/drm/drm_ioctl.c index 86760402ac..e1db9ab6ec 100644 --- a/sys/dev/drm/drm_ioctl.c +++ b/sys/dev/drm/drm_ioctl.c @@ -26,6 +26,7 @@ * Rickard E. (Rik) Faith * Gareth Hughes * + * $FreeBSD: src/sys/dev/drm2/drm_ioctl.c,v 1.1 2012/05/22 11:07:44 kib Exp $ */ /** @file drm_ioctl.c @@ -69,12 +70,12 @@ int drm_setunique(struct drm_device *dev, void *data, if (!u->unique_len || u->unique_len > 1024) return EINVAL; - busid = malloc(u->unique_len + 1, DRM_MEM_DRIVER, M_WAITOK); + busid = kmalloc(u->unique_len + 1, DRM_MEM_DRIVER, M_WAITOK); if (busid == NULL) return ENOMEM; if (DRM_COPY_FROM_USER(busid, u->unique, u->unique_len)) { - free(busid, DRM_MEM_DRIVER); + drm_free(busid, DRM_MEM_DRIVER); return EFAULT; } busid[u->unique_len] = '\0'; @@ -82,9 +83,9 @@ int drm_setunique(struct drm_device *dev, void *data, /* Return error if the busid submitted doesn't match the device's actual * busid. */ - ret = sscanf(busid, "PCI:%d:%d:%d", &bus, &slot, &func); + ret = ksscanf(busid, "PCI:%d:%d:%d", &bus, &slot, &func); if (ret != 3) { - free(busid, DRM_MEM_DRIVER); + drm_free(busid, DRM_MEM_DRIVER); return EINVAL; } domain = bus >> 8; @@ -94,20 +95,20 @@ int drm_setunique(struct drm_device *dev, void *data, (bus != dev->pci_bus) || (slot != dev->pci_slot) || (func != dev->pci_func)) { - free(busid, DRM_MEM_DRIVER); + drm_free(busid, DRM_MEM_DRIVER); return EINVAL; } /* Actually set the device's busid now. */ - DRM_LOCK(); + DRM_LOCK(dev); if (dev->unique_len || dev->unique) { - DRM_UNLOCK(); + DRM_UNLOCK(dev); return EBUSY; } dev->unique_len = u->unique_len; dev->unique = busid; - DRM_UNLOCK(); + DRM_UNLOCK(dev); return 0; } @@ -117,24 +118,24 @@ static int drm_set_busid(struct drm_device *dev) { - DRM_LOCK(); + DRM_LOCK(dev); if (dev->unique != NULL) { - DRM_UNLOCK(); + DRM_UNLOCK(dev); return EBUSY; } dev->unique_len = 20; - dev->unique = malloc(dev->unique_len + 1, DRM_MEM_DRIVER, M_NOWAIT); + dev->unique = kmalloc(dev->unique_len + 1, DRM_MEM_DRIVER, M_NOWAIT); if (dev->unique == NULL) { - DRM_UNLOCK(); + DRM_UNLOCK(dev); return ENOMEM; } - snprintf(dev->unique, dev->unique_len, "pci:%04x:%02x:%02x.%1x", + ksnprintf(dev->unique, dev->unique_len, "pci:%04x:%02x:%02x.%1x", dev->pci_domain, dev->pci_bus, dev->pci_slot, dev->pci_func); - DRM_UNLOCK(); + DRM_UNLOCK(dev); return 0; } @@ -148,9 +149,9 @@ int drm_getmap(struct drm_device *dev, void *data, struct drm_file *file_priv) idx = map->offset; - DRM_LOCK(); + DRM_LOCK(dev); if (idx < 0) { - DRM_UNLOCK(); + DRM_UNLOCK(dev); return EINVAL; } @@ -167,7 +168,7 @@ int drm_getmap(struct drm_device *dev, void *data, struct drm_file *file_priv) i++; } - DRM_UNLOCK(); + DRM_UNLOCK(dev); if (mapinlist == NULL) return EINVAL; @@ -184,7 +185,7 @@ int drm_getclient(struct drm_device *dev, void *data, int i = 0; idx = client->idx; - DRM_LOCK(); + DRM_LOCK(dev); TAILQ_FOREACH(pt, &dev->files, link) { if (i == idx) { client->auth = pt->authenticated; @@ -192,12 +193,12 @@ int drm_getclient(struct drm_device *dev, void *data, client->uid = pt->uid; client->magic = pt->magic; client->iocs = pt->ioctl_count; - DRM_UNLOCK(); + DRM_UNLOCK(dev); return 0; } i++; } - DRM_UNLOCK(); + DRM_UNLOCK(dev); return EINVAL; } @@ -209,7 +210,7 @@ int drm_getstats(struct drm_device *dev, void *data, struct drm_file *file_priv) memset(stats, 0, sizeof(struct drm_stats)); - DRM_LOCK(); + DRM_LOCK(dev); for (i = 0; i < dev->counters; i++) { if (dev->types[i] == _DRM_STAT_LOCK) @@ -222,11 +223,37 @@ int drm_getstats(struct drm_device *dev, void *data, struct drm_file *file_priv) stats->count = dev->counters; - DRM_UNLOCK(); + DRM_UNLOCK(dev); return 0; } +int drm_getcap(struct drm_device *dev, void *data, struct drm_file *file_priv) +{ + struct drm_get_cap *req = data; + + req->value = 0; + switch (req->capability) { + case DRM_CAP_DUMB_BUFFER: + if (dev->driver->dumb_create) + req->value = 1; + break; + case DRM_CAP_VBLANK_HIGH_CRTC: + req->value = 1; + break; + case DRM_CAP_DUMB_PREFERRED_DEPTH: + req->value = dev->mode_config.preferred_depth; + break; + case DRM_CAP_DUMB_PREFER_SHADOW: + req->value = dev->mode_config.prefer_shadow; + break; + default: + return EINVAL; + } + return 0; +} + + #define DRM_IF_MAJOR 1 #define DRM_IF_MINOR 2 @@ -246,6 +273,15 @@ int drm_setversion(struct drm_device *dev, void *data, sv->drm_dd_major = dev->driver->major; sv->drm_dd_minor = dev->driver->minor; + DRM_DEBUG("ver.drm_di_major %d ver.drm_di_minor %d " + "ver.drm_dd_major %d ver.drm_dd_minor %d\n", + ver.drm_di_major, ver.drm_di_minor, ver.drm_dd_major, + ver.drm_dd_minor); + DRM_DEBUG("sv->drm_di_major %d sv->drm_di_minor %d " + "sv->drm_dd_major %d sv->drm_dd_minor %d\n", + sv->drm_di_major, sv->drm_di_minor, sv->drm_dd_major, + sv->drm_dd_minor); + if (ver.drm_di_major != -1) { if (ver.drm_di_major != DRM_IF_MAJOR || ver.drm_di_minor < 0 || ver.drm_di_minor > DRM_IF_MINOR) { diff --git a/sys/dev/drm/drm_irq.c b/sys/dev/drm/drm_irq.c index bb53d28308..75d0f34000 100644 --- a/sys/dev/drm/drm_irq.c +++ b/sys/dev/drm/drm_irq.c @@ -23,6 +23,7 @@ * Authors: * Eric Anholt * + * $FreeBSD: src/sys/dev/drm2/drm_irq.c,v 1.1 2012/05/22 11:07:44 kib Exp $ */ /** @file drm_irq.c @@ -33,6 +34,23 @@ #include "dev/drm/drmP.h" #include "dev/drm/drm.h" +MALLOC_DEFINE(DRM_MEM_VBLANK, "drm_vblank", "DRM VBLANK Handling Data"); + +/* Access macro for slots in vblank timestamp ringbuffer. */ +#define vblanktimestamp(dev, crtc, count) ( \ + (dev)->_vblank_time[(crtc) * DRM_VBLANKTIME_RBSIZE + \ + ((count) % DRM_VBLANKTIME_RBSIZE)]) + +/* Retry timestamp calculation up to 3 times to satisfy + * drm_timestamp_precision before giving up. + */ +#define DRM_TIMESTAMP_MAXRETRIES 3 + +/* Threshold in nanoseconds for detection of redundant + * vblank irq in drm_handle_vblank(). 1 msec should be ok. + */ +#define DRM_REDUNDANT_VBLIRQ_THRESH_NS 1000000 + int drm_irq_by_busid(struct drm_device *dev, void *data, struct drm_file *file_priv) { @@ -52,105 +70,19 @@ int drm_irq_by_busid(struct drm_device *dev, void *data, return 0; } -static void vblank_disable_fn(void *arg) +int +drm_irq_install(struct drm_device *dev) { - struct drm_device *dev = (struct drm_device *)arg; - int i; - - DRM_SPINLOCK(&dev->vbl_lock); - - if (callout_pending(&dev->vblank_disable_timer)) { - /* callout was reset */ - DRM_SPINUNLOCK(&dev->vbl_lock); - return; - } - if (!callout_active(&dev->vblank_disable_timer)) { - /* callout was stopped */ - DRM_SPINUNLOCK(&dev->vbl_lock); - return; - } - callout_deactivate(&dev->vblank_disable_timer); - - DRM_DEBUG("vblank_disable: %s\n", dev->vblank_disable_allowed ? - "allowed" : "denied"); - if (!dev->vblank_disable_allowed) { - DRM_SPINUNLOCK(&dev->vbl_lock); - return; - } - - for (i = 0; i < dev->num_crtcs; i++) { - if (dev->vblank[i].refcount == 0 && - dev->vblank[i].enabled && !dev->vblank[i].inmodeset) { - DRM_DEBUG("disabling vblank on crtc %d\n", i); - dev->vblank[i].last = - dev->driver->get_vblank_counter(dev, i); - dev->driver->disable_vblank(dev, i); - dev->vblank[i].enabled = 0; - } - } - DRM_SPINUNLOCK(&dev->vbl_lock); -} - -void drm_vblank_cleanup(struct drm_device *dev) -{ - /* Bail if the driver didn't call drm_vblank_init() */ - if (dev->num_crtcs == 0) - return; - - DRM_SPINLOCK(&dev->vbl_lock); - callout_stop(&dev->vblank_disable_timer); - DRM_SPINUNLOCK(&dev->vbl_lock); - - vblank_disable_fn(dev); - - free(dev->vblank, DRM_MEM_DRIVER); - - dev->num_crtcs = 0; -} - -int drm_vblank_init(struct drm_device *dev, int num_crtcs) -{ - int i, ret = ENOMEM; - - callout_init(&dev->vblank_disable_timer); - dev->num_crtcs = num_crtcs; - - dev->vblank = malloc(sizeof(struct drm_vblank_info) * num_crtcs, - DRM_MEM_DRIVER, M_NOWAIT | M_ZERO); - if (!dev->vblank) - goto err; - - DRM_DEBUG("\n"); - - /* Zero per-crtc vblank stuff */ - DRM_SPINLOCK(&dev->vbl_lock); - for (i = 0; i < num_crtcs; i++) { - DRM_INIT_WAITQUEUE(&dev->vblank[i].queue); - dev->vblank[i].refcount = 0; - atomic_store_rel_32(&dev->vblank[i].count, 0); - } - dev->vblank_disable_allowed = 0; - DRM_SPINUNLOCK(&dev->vbl_lock); - - return 0; - -err: - drm_vblank_cleanup(dev); - return ret; -} - -int drm_irq_install(struct drm_device *dev) -{ - int crtc, retcode; + int retcode; if (dev->irq == 0 || dev->dev_private == NULL) - return EINVAL; + return (EINVAL); DRM_DEBUG("irq=%d\n", dev->irq); - DRM_LOCK(); + DRM_LOCK(dev); if (dev->irq_enabled) { - DRM_UNLOCK(); + DRM_UNLOCK(dev); return EBUSY; } dev->irq_enabled = 1; @@ -158,44 +90,33 @@ int drm_irq_install(struct drm_device *dev) dev->context_flag = 0; /* Before installing handler */ - dev->driver->irq_preinstall(dev); - DRM_UNLOCK(); + if (dev->driver->irq_preinstall) + dev->driver->irq_preinstall(dev); + DRM_UNLOCK(dev); /* Install handler */ retcode = bus_setup_intr(dev->device, dev->irqr, INTR_MPSAFE, - dev->driver->irq_handler, dev, &dev->irqh, - &dev->irq_lock); + dev->driver->irq_handler, dev, &dev->irqh, &dev->irq_lock); if (retcode != 0) goto err; /* After installing handler */ - DRM_LOCK(); - dev->driver->irq_postinstall(dev); - DRM_UNLOCK(); - if (dev->driver->enable_vblank) { - DRM_SPINLOCK(&dev->vbl_lock); - for( crtc = 0 ; crtc < dev->num_crtcs ; crtc++) { - if (dev->driver->enable_vblank(dev, crtc) == 0) { - dev->vblank[crtc].enabled = 1; - } - } - callout_reset(&dev->vblank_disable_timer, 5 * DRM_HZ, - (timeout_t *)vblank_disable_fn, (void *)dev); - DRM_SPINUNLOCK(&dev->vbl_lock); - } + DRM_LOCK(dev); + if (dev->driver->irq_postinstall) + dev->driver->irq_postinstall(dev); + DRM_UNLOCK(dev); - return 0; + return (0); err: - DRM_LOCK(); + device_printf(dev->device, "Error setting interrupt: %d\n", retcode); dev->irq_enabled = 0; - DRM_UNLOCK(); - return retcode; + return (retcode); } int drm_irq_uninstall(struct drm_device *dev) { - int crtc; + int i; if (!dev->irq_enabled) return EINVAL; @@ -205,24 +126,25 @@ int drm_irq_uninstall(struct drm_device *dev) /* * Wake up any waiters so they don't hang. */ - DRM_SPINLOCK(&dev->vbl_lock); - for (crtc = 0; crtc < dev->num_crtcs; crtc++) { - if (dev->vblank[crtc].enabled) { - DRM_WAKEUP(&dev->vblank[crtc].queue); - dev->vblank[crtc].last = - dev->driver->get_vblank_counter(dev, crtc); - dev->vblank[crtc].enabled = 0; + if (dev->num_crtcs) { + lockmgr(&dev->vbl_lock, LK_EXCLUSIVE); + for (i = 0; i < dev->num_crtcs; i++) { + wakeup(&dev->_vblank_count[i]); + dev->vblank_enabled[i] = 0; + dev->last_vblank[i] = + dev->driver->get_vblank_counter(dev, i); } + lockmgr(&dev->vbl_lock, LK_RELEASE); } - DRM_SPINUNLOCK(&dev->vbl_lock); DRM_DEBUG("irq=%d\n", dev->irq); - dev->driver->irq_uninstall(dev); + if (dev->driver->irq_uninstall) + dev->driver->irq_uninstall(dev); - DRM_UNLOCK(); + DRM_UNLOCK(dev); bus_teardown_intr(dev->device, dev->irqr, dev->irqh); - DRM_LOCK(); + DRM_LOCK(dev); return 0; } @@ -239,6 +161,8 @@ int drm_control(struct drm_device *dev, void *data, struct drm_file *file_priv) */ if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) return 0; + if (drm_core_check_feature(dev, DRIVER_MODESET)) + return 0; if (dev->if_version < DRM_IF_VERSION(1, 2) && ctl->irq != dev->irq) return EINVAL; @@ -246,23 +170,548 @@ int drm_control(struct drm_device *dev, void *data, struct drm_file *file_priv) case DRM_UNINST_HANDLER: if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) return 0; - DRM_LOCK(); + if (drm_core_check_feature(dev, DRIVER_MODESET)) + return 0; + DRM_LOCK(dev); err = drm_irq_uninstall(dev); - DRM_UNLOCK(); + DRM_UNLOCK(dev); return err; default: return EINVAL; } } +#define NSEC_PER_USEC 1000L +#define NSEC_PER_SEC 1000000000L + +int64_t +timeval_to_ns(const struct timeval *tv) +{ + return ((int64_t)tv->tv_sec * NSEC_PER_SEC) + + tv->tv_usec * NSEC_PER_USEC; +} + +struct timeval +ns_to_timeval(const int64_t nsec) +{ + struct timeval tv; + uint32_t rem; + + if (nsec == 0) { + tv.tv_sec = 0; + tv.tv_usec = 0; + return (tv); + } + + tv.tv_sec = nsec / NSEC_PER_SEC; + rem = nsec % NSEC_PER_SEC; + if (rem < 0) { + tv.tv_sec--; + rem += NSEC_PER_SEC; + } + tv.tv_usec = rem / 1000; + return (tv); +} + +/* + * Clear vblank timestamp buffer for a crtc. + */ +static void clear_vblank_timestamps(struct drm_device *dev, int crtc) +{ + memset(&dev->_vblank_time[crtc * DRM_VBLANKTIME_RBSIZE], 0, + DRM_VBLANKTIME_RBSIZE * sizeof(struct timeval)); +} + +static int64_t +abs64(int64_t x) +{ + + return (x < 0 ? -x : x); +} + +/* + * Disable vblank irq's on crtc, make sure that last vblank count + * of hardware and corresponding consistent software vblank counter + * are preserved, even if there are any spurious vblank irq's after + * disable. + */ +static void vblank_disable_and_save(struct drm_device *dev, int crtc) +{ + u32 vblcount; + int64_t diff_ns; + int vblrc; + struct timeval tvblank; + + /* Prevent vblank irq processing while disabling vblank irqs, + * so no updates of timestamps or count can happen after we've + * disabled. Needed to prevent races in case of delayed irq's. + */ + lockmgr(&dev->vblank_time_lock, LK_EXCLUSIVE); + + dev->driver->disable_vblank(dev, crtc); + dev->vblank_enabled[crtc] = 0; + + /* No further vblank irq's will be processed after + * this point. Get current hardware vblank count and + * vblank timestamp, repeat until they are consistent. + * + * FIXME: There is still a race condition here and in + * drm_update_vblank_count() which can cause off-by-one + * reinitialization of software vblank counter. If gpu + * vblank counter doesn't increment exactly at the leading + * edge of a vblank interval, then we can lose 1 count if + * we happen to execute between start of vblank and the + * delayed gpu counter increment. + */ + do { + dev->last_vblank[crtc] = dev->driver->get_vblank_counter(dev, crtc); + vblrc = drm_get_last_vbltimestamp(dev, crtc, &tvblank, 0); + } while (dev->last_vblank[crtc] != dev->driver->get_vblank_counter(dev, crtc)); + + /* Compute time difference to stored timestamp of last vblank + * as updated by last invocation of drm_handle_vblank() in vblank irq. + */ + vblcount = atomic_read(&dev->_vblank_count[crtc]); + diff_ns = timeval_to_ns(&tvblank) - + timeval_to_ns(&vblanktimestamp(dev, crtc, vblcount)); + + /* If there is at least 1 msec difference between the last stored + * timestamp and tvblank, then we are currently executing our + * disable inside a new vblank interval, the tvblank timestamp + * corresponds to this new vblank interval and the irq handler + * for this vblank didn't run yet and won't run due to our disable. + * Therefore we need to do the job of drm_handle_vblank() and + * increment the vblank counter by one to account for this vblank. + * + * Skip this step if there isn't any high precision timestamp + * available. In that case we can't account for this and just + * hope for the best. + */ + if ((vblrc > 0) && (abs64(diff_ns) > 1000000)) { + atomic_inc(&dev->_vblank_count[crtc]); + } + + /* Invalidate all timestamps while vblank irq's are off. */ + clear_vblank_timestamps(dev, crtc); + + lockmgr(&dev->vblank_time_lock, LK_RELEASE); +} + +static void vblank_disable_fn(void * arg) +{ + struct drm_device *dev = (struct drm_device *)arg; + int i; + + if (!dev->vblank_disable_allowed) + return; + + for (i = 0; i < dev->num_crtcs; i++) { + lockmgr(&dev->vbl_lock, LK_EXCLUSIVE); + if (atomic_read(&dev->vblank_refcount[i]) == 0 && + dev->vblank_enabled[i]) { + DRM_DEBUG("disabling vblank on crtc %d\n", i); + vblank_disable_and_save(dev, i); + } + lockmgr(&dev->vbl_lock, LK_RELEASE); + } +} + +void drm_vblank_cleanup(struct drm_device *dev) +{ + /* Bail if the driver didn't call drm_vblank_init() */ + if (dev->num_crtcs == 0) + return; + + callout_stop(&dev->vblank_disable_callout); + + vblank_disable_fn(dev); + + drm_free(dev->_vblank_count, DRM_MEM_VBLANK); + drm_free(dev->vblank_refcount, DRM_MEM_VBLANK); + drm_free(dev->vblank_enabled, DRM_MEM_VBLANK); + drm_free(dev->last_vblank, DRM_MEM_VBLANK); + drm_free(dev->last_vblank_wait, DRM_MEM_VBLANK); + drm_free(dev->vblank_inmodeset, DRM_MEM_VBLANK); + drm_free(dev->_vblank_time, DRM_MEM_VBLANK); + + dev->num_crtcs = 0; +} + +int drm_vblank_init(struct drm_device *dev, int num_crtcs) +{ + int i; + + callout_init_mp(&dev->vblank_disable_callout); +#if 0 + mtx_init(&dev->vbl_lock, "drmvbl", NULL, MTX_DEF); +#endif + lockinit(&dev->vblank_time_lock, "drmvtl", 0, LK_CANRECURSE); + + dev->num_crtcs = num_crtcs; + + dev->_vblank_count = kmalloc(sizeof(atomic_t) * num_crtcs, + DRM_MEM_VBLANK, M_WAITOK); + dev->vblank_refcount = kmalloc(sizeof(atomic_t) * num_crtcs, + DRM_MEM_VBLANK, M_WAITOK); + dev->vblank_enabled = kmalloc(num_crtcs * sizeof(int), + DRM_MEM_VBLANK, M_WAITOK | M_ZERO); + dev->last_vblank = kmalloc(num_crtcs * sizeof(u32), + DRM_MEM_VBLANK, M_WAITOK | M_ZERO); + dev->last_vblank_wait = kmalloc(num_crtcs * sizeof(u32), + DRM_MEM_VBLANK, M_WAITOK | M_ZERO); + dev->vblank_inmodeset = kmalloc(num_crtcs * sizeof(int), + DRM_MEM_VBLANK, M_WAITOK | M_ZERO); + dev->_vblank_time = kmalloc(num_crtcs * DRM_VBLANKTIME_RBSIZE * + sizeof(struct timeval), DRM_MEM_VBLANK, M_WAITOK | M_ZERO); + DRM_INFO("Supports vblank timestamp caching Rev 1 (10.10.2010).\n"); + + /* Driver specific high-precision vblank timestamping supported? */ + if (dev->driver->get_vblank_timestamp) + DRM_INFO("Driver supports precise vblank timestamp query.\n"); + else + DRM_INFO("No driver support for vblank timestamp query.\n"); + + /* Zero per-crtc vblank stuff */ + for (i = 0; i < num_crtcs; i++) { + atomic_set(&dev->_vblank_count[i], 0); + atomic_set(&dev->vblank_refcount[i], 0); + } + + dev->vblank_disable_allowed = 0; + return 0; +} + +void +drm_calc_timestamping_constants(struct drm_crtc *crtc) +{ + int64_t linedur_ns = 0, pixeldur_ns = 0, framedur_ns = 0; + uint64_t dotclock; + + /* Dot clock in Hz: */ + dotclock = (uint64_t) crtc->hwmode.clock * 1000; + + /* Fields of interlaced scanout modes are only halve a frame duration. + * Double the dotclock to get halve the frame-/line-/pixelduration. + */ + if (crtc->hwmode.flags & DRM_MODE_FLAG_INTERLACE) + dotclock *= 2; + + /* Valid dotclock? */ + if (dotclock > 0) { + /* Convert scanline length in pixels and video dot clock to + * line duration, frame duration and pixel duration in + * nanoseconds: + */ + pixeldur_ns = (int64_t)1000000000 / dotclock; + linedur_ns = ((uint64_t)crtc->hwmode.crtc_htotal * + 1000000000) / dotclock; + framedur_ns = (int64_t)crtc->hwmode.crtc_vtotal * linedur_ns; + } else + DRM_ERROR("crtc %d: Can't calculate constants, dotclock = 0!\n", + crtc->base.id); + + crtc->pixeldur_ns = pixeldur_ns; + crtc->linedur_ns = linedur_ns; + crtc->framedur_ns = framedur_ns; + + DRM_DEBUG("crtc %d: hwmode: htotal %d, vtotal %d, vdisplay %d\n", + crtc->base.id, crtc->hwmode.crtc_htotal, + crtc->hwmode.crtc_vtotal, crtc->hwmode.crtc_vdisplay); + DRM_DEBUG("crtc %d: clock %d kHz framedur %d linedur %d, pixeldur %d\n", + crtc->base.id, (int) dotclock/1000, (int) framedur_ns, + (int) linedur_ns, (int) pixeldur_ns); +} + +/** + * drm_calc_vbltimestamp_from_scanoutpos - helper routine for kms + * drivers. Implements calculation of exact vblank timestamps from + * given drm_display_mode timings and current video scanout position + * of a crtc. This can be called from within get_vblank_timestamp() + * implementation of a kms driver to implement the actual timestamping. + * + * Should return timestamps conforming to the OML_sync_control OpenML + * extension specification. The timestamp corresponds to the end of + * the vblank interval, aka start of scanout of topmost-leftmost display + * pixel in the following video frame. + * + * Requires support for optional dev->driver->get_scanout_position() + * in kms driver, plus a bit of setup code to provide a drm_display_mode + * that corresponds to the true scanout timing. + * + * The current implementation only handles standard video modes. It + * returns as no operation if a doublescan or interlaced video mode is + * active. Higher level code is expected to handle this. + * + * @dev: DRM device. + * @crtc: Which crtc's vblank timestamp to retrieve. + * @max_error: Desired maximum allowable error in timestamps (nanosecs). + * On return contains true maximum error of timestamp. + * @vblank_time: Pointer to struct timeval which should receive the timestamp. + * @flags: Flags to pass to driver: + * 0 = Default. + * DRM_CALLED_FROM_VBLIRQ = If function is called from vbl irq handler. + * @refcrtc: drm_crtc* of crtc which defines scanout timing. + * + * Returns negative value on error, failure or if not supported in current + * video mode: + * + * -EINVAL - Invalid crtc. + * -EAGAIN - Temporary unavailable, e.g., called before initial modeset. + * -ENOTSUPP - Function not supported in current display mode. + * -EIO - Failed, e.g., due to failed scanout position query. + * + * Returns or'ed positive status flags on success: + * + * DRM_VBLANKTIME_SCANOUTPOS_METHOD - Signal this method used for timestamping. + * DRM_VBLANKTIME_INVBL - Timestamp taken while scanout was in vblank interval. + * + */ +int +drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc, + int *max_error, struct timeval *vblank_time, unsigned flags, + struct drm_crtc *refcrtc) +{ + struct timeval stime, raw_time; + struct drm_display_mode *mode; + int vbl_status, vtotal, vdisplay; + int vpos, hpos, i; + int64_t framedur_ns, linedur_ns, pixeldur_ns, delta_ns, duration_ns; + bool invbl; + + if (crtc < 0 || crtc >= dev->num_crtcs) { + DRM_ERROR("Invalid crtc %d\n", crtc); + return -EINVAL; + } + + /* Scanout position query not supported? Should not happen. */ + if (!dev->driver->get_scanout_position) { + DRM_ERROR("Called from driver w/o get_scanout_position()!?\n"); + return -EIO; + } + + mode = &refcrtc->hwmode; + vtotal = mode->crtc_vtotal; + vdisplay = mode->crtc_vdisplay; + + /* Durations of frames, lines, pixels in nanoseconds. */ + framedur_ns = refcrtc->framedur_ns; + linedur_ns = refcrtc->linedur_ns; + pixeldur_ns = refcrtc->pixeldur_ns; + + /* If mode timing undefined, just return as no-op: + * Happens during initial modesetting of a crtc. + */ + if (vtotal <= 0 || vdisplay <= 0 || framedur_ns == 0) { + DRM_DEBUG("crtc %d: Noop due to uninitialized mode.\n", crtc); + return -EAGAIN; + } + + /* Get current scanout position with system timestamp. + * Repeat query up to DRM_TIMESTAMP_MAXRETRIES times + * if single query takes longer than max_error nanoseconds. + * + * This guarantees a tight bound on maximum error if + * code gets preempted or delayed for some reason. + */ + for (i = 0; i < DRM_TIMESTAMP_MAXRETRIES; i++) { + /* Disable preemption to make it very likely to + * succeed in the first iteration. + */ + crit_enter(); + + /* Get system timestamp before query. */ + getmicrouptime(&stime); + + /* Get vertical and horizontal scanout pos. vpos, hpos. */ + vbl_status = dev->driver->get_scanout_position(dev, crtc, &vpos, &hpos); + + /* Get system timestamp after query. */ + getmicrouptime(&raw_time); + + crit_exit(); + + /* Return as no-op if scanout query unsupported or failed. */ + if (!(vbl_status & DRM_SCANOUTPOS_VALID)) { + DRM_DEBUG("crtc %d : scanoutpos query failed [%d].\n", + crtc, vbl_status); + return -EIO; + } + + duration_ns = timeval_to_ns(&raw_time) - timeval_to_ns(&stime); + + /* Accept result with < max_error nsecs timing uncertainty. */ + if (duration_ns <= (int64_t) *max_error) + break; + } + + /* Noisy system timing? */ + if (i == DRM_TIMESTAMP_MAXRETRIES) { + DRM_DEBUG("crtc %d: Noisy timestamp %d us > %d us [%d reps].\n", + crtc, (int) duration_ns/1000, *max_error/1000, i); + } + + /* Return upper bound of timestamp precision error. */ + *max_error = (int) duration_ns; + + /* Check if in vblank area: + * vpos is >=0 in video scanout area, but negative + * within vblank area, counting down the number of lines until + * start of scanout. + */ + invbl = vbl_status & DRM_SCANOUTPOS_INVBL; + + /* Convert scanout position into elapsed time at raw_time query + * since start of scanout at first display scanline. delta_ns + * can be negative if start of scanout hasn't happened yet. + */ + delta_ns = (int64_t)vpos * linedur_ns + (int64_t)hpos * pixeldur_ns; + + /* Is vpos outside nominal vblank area, but less than + * 1/100 of a frame height away from start of vblank? + * If so, assume this isn't a massively delayed vblank + * interrupt, but a vblank interrupt that fired a few + * microseconds before true start of vblank. Compensate + * by adding a full frame duration to the final timestamp. + * Happens, e.g., on ATI R500, R600. + * + * We only do this if DRM_CALLED_FROM_VBLIRQ. + */ + if ((flags & DRM_CALLED_FROM_VBLIRQ) && !invbl && + ((vdisplay - vpos) < vtotal / 100)) { + delta_ns = delta_ns - framedur_ns; + + /* Signal this correction as "applied". */ + vbl_status |= 0x8; + } + + /* Subtract time delta from raw timestamp to get final + * vblank_time timestamp for end of vblank. + */ + *vblank_time = ns_to_timeval(timeval_to_ns(&raw_time) - delta_ns); + + DRM_DEBUG("crtc %d : v %d p(%d,%d)@ %jd.%jd -> %jd.%jd [e %d us, %d rep]\n", + crtc, (int)vbl_status, hpos, vpos, (uintmax_t)raw_time.tv_sec, + (uintmax_t)raw_time.tv_usec, (uintmax_t)vblank_time->tv_sec, + (uintmax_t)vblank_time->tv_usec, (int)duration_ns/1000, i); + + vbl_status = DRM_VBLANKTIME_SCANOUTPOS_METHOD; + if (invbl) + vbl_status |= DRM_VBLANKTIME_INVBL; + + return vbl_status; +} + +/** + * drm_get_last_vbltimestamp - retrieve raw timestamp for the most recent + * vblank interval. + * + * @dev: DRM device + * @crtc: which crtc's vblank timestamp to retrieve + * @tvblank: Pointer to target struct timeval which should receive the timestamp + * @flags: Flags to pass to driver: + * 0 = Default. + * DRM_CALLED_FROM_VBLIRQ = If function is called from vbl irq handler. + * + * Fetches the system timestamp corresponding to the time of the most recent + * vblank interval on specified crtc. May call into kms-driver to + * compute the timestamp with a high-precision GPU specific method. + * + * Returns zero if timestamp originates from uncorrected do_gettimeofday() + * call, i.e., it isn't very precisely locked to the true vblank. + * + * Returns non-zero if timestamp is considered to be very precise. + */ +u32 drm_get_last_vbltimestamp(struct drm_device *dev, int crtc, + struct timeval *tvblank, unsigned flags) +{ + int ret = 0; + + /* Define requested maximum error on timestamps (nanoseconds). */ + int max_error = (int) drm_timestamp_precision * 1000; + + /* Query driver if possible and precision timestamping enabled. */ + if (dev->driver->get_vblank_timestamp && (max_error > 0)) { + ret = dev->driver->get_vblank_timestamp(dev, crtc, &max_error, + tvblank, flags); + if (ret > 0) + return (u32) ret; + } + + /* GPU high precision timestamp query unsupported or failed. + * Return gettimeofday timestamp as best estimate. + */ + microtime(tvblank); + + return 0; +} + +/** + * drm_vblank_count - retrieve "cooked" vblank counter value + * @dev: DRM device + * @crtc: which counter to retrieve + * + * Fetches the "cooked" vblank count value that represents the number of + * vblank events since the system was booted, including lost events due to + * modesetting activity. + */ u32 drm_vblank_count(struct drm_device *dev, int crtc) { - return atomic_load_acq_32(&dev->vblank[crtc].count); + return atomic_read(&dev->_vblank_count[crtc]); } +/** + * drm_vblank_count_and_time - retrieve "cooked" vblank counter value + * and the system timestamp corresponding to that vblank counter value. + * + * @dev: DRM device + * @crtc: which counter to retrieve + * @vblanktime: Pointer to struct timeval to receive the vblank timestamp. + * + * Fetches the "cooked" vblank count value that represents the number of + * vblank events since the system was booted, including lost events due to + * modesetting activity. Returns corresponding system timestamp of the time + * of the vblank interval that corresponds to the current value vblank counter + * value. + */ +u32 drm_vblank_count_and_time(struct drm_device *dev, int crtc, + struct timeval *vblanktime) +{ + u32 cur_vblank; + + /* Read timestamp from slot of _vblank_time ringbuffer + * that corresponds to current vblank count. Retry if + * count has incremented during readout. This works like + * a seqlock. + */ + do { + cur_vblank = atomic_read(&dev->_vblank_count[crtc]); + *vblanktime = vblanktimestamp(dev, crtc, cur_vblank); + cpu_lfence(); + } while (cur_vblank != atomic_read(&dev->_vblank_count[crtc])); + + return cur_vblank; +} + +/** + * drm_update_vblank_count - update the master vblank counter + * @dev: DRM device + * @crtc: counter to update + * + * Call back into the driver to update the appropriate vblank counter + * (specified by @crtc). Deal with wraparound, if it occurred, and + * update the last read value so we can deal with wraparound on the next + * call if necessary. + * + * Only necessary when going from off->on, to account for frames we + * didn't get an interrupt for. + * + * Note: caller must hold dev->vbl_lock since this reads & writes + * device vblank fields. + */ static void drm_update_vblank_count(struct drm_device *dev, int crtc) { - u32 cur_vblank, diff; + u32 cur_vblank, diff, tslot, rc; + struct timeval t_vblank; /* * Interrupts were disabled prior to this call, so deal with counter @@ -270,68 +719,202 @@ static void drm_update_vblank_count(struct drm_device *dev, int crtc) * NOTE! It's possible we lost a full dev->max_vblank_count events * here if the register is small or we had vblank interrupts off for * a long time. + * + * We repeat the hardware vblank counter & timestamp query until + * we get consistent results. This to prevent races between gpu + * updating its hardware counter while we are retrieving the + * corresponding vblank timestamp. */ - cur_vblank = dev->driver->get_vblank_counter(dev, crtc); - diff = cur_vblank - dev->vblank[crtc].last; - if (cur_vblank < dev->vblank[crtc].last) { + do { + cur_vblank = dev->driver->get_vblank_counter(dev, crtc); + rc = drm_get_last_vbltimestamp(dev, crtc, &t_vblank, 0); + } while (cur_vblank != dev->driver->get_vblank_counter(dev, crtc)); + + /* Deal with counter wrap */ + diff = cur_vblank - dev->last_vblank[crtc]; + if (cur_vblank < dev->last_vblank[crtc]) { diff += dev->max_vblank_count; - DRM_DEBUG("vblank[%d].last=0x%x, cur_vblank=0x%x => diff=0x%x\n", - crtc, dev->vblank[crtc].last, cur_vblank, diff); + DRM_DEBUG("last_vblank[%d]=0x%x, cur_vblank=0x%x => diff=0x%x\n", + crtc, dev->last_vblank[crtc], cur_vblank, diff); } DRM_DEBUG("enabling vblank interrupts on crtc %d, missed %d\n", - crtc, diff); + crtc, diff); + + /* Reinitialize corresponding vblank timestamp if high-precision query + * available. Skip this step if query unsupported or failed. Will + * reinitialize delayed at next vblank interrupt in that case. + */ + if (rc) { + tslot = atomic_read(&dev->_vblank_count[crtc]) + diff; + vblanktimestamp(dev, crtc, tslot) = t_vblank; + } - atomic_add_rel_32(&dev->vblank[crtc].count, diff); + atomic_add(diff, &dev->_vblank_count[crtc]); } +/** + * drm_vblank_get - get a reference count on vblank events + * @dev: DRM device + * @crtc: which CRTC to own + * + * Acquire a reference count on vblank events to avoid having them disabled + * while in use. + * + * RETURNS + * Zero on success, nonzero on failure. + */ int drm_vblank_get(struct drm_device *dev, int crtc) { int ret = 0; - /* Make sure that we are called with the lock held */ - KKASSERT(lockstatus(&dev->vbl_lock, curthread) != 0); - + lockmgr(&dev->vbl_lock, LK_EXCLUSIVE); /* Going from 0->1 means we have to enable interrupts again */ - if (++dev->vblank[crtc].refcount == 1 && - !dev->vblank[crtc].enabled) { - ret = dev->driver->enable_vblank(dev, crtc); - DRM_DEBUG("enabling vblank on crtc %d, ret: %d\n", crtc, ret); - if (ret) - --dev->vblank[crtc].refcount; - else { - dev->vblank[crtc].enabled = 1; - drm_update_vblank_count(dev, crtc); + if (atomic_fetchadd_int(&dev->vblank_refcount[crtc], 1) == 0) { + lockmgr(&dev->vblank_time_lock, LK_EXCLUSIVE); + if (!dev->vblank_enabled[crtc]) { + /* Enable vblank irqs under vblank_time_lock protection. + * All vblank count & timestamp updates are held off + * until we are done reinitializing master counter and + * timestamps. Filtercode in drm_handle_vblank() will + * prevent double-accounting of same vblank interval. + */ + ret = -dev->driver->enable_vblank(dev, crtc); + DRM_DEBUG("enabling vblank on crtc %d, ret: %d\n", + crtc, ret); + if (ret) + atomic_dec(&dev->vblank_refcount[crtc]); + else { + dev->vblank_enabled[crtc] = 1; + drm_update_vblank_count(dev, crtc); + } + } + lockmgr(&dev->vblank_time_lock, LK_RELEASE); + } else { + if (!dev->vblank_enabled[crtc]) { + atomic_dec(&dev->vblank_refcount[crtc]); + ret = EINVAL; } } - - if (dev->vblank[crtc].enabled) - dev->vblank[crtc].last = - dev->driver->get_vblank_counter(dev, crtc); + lockmgr(&dev->vbl_lock, LK_RELEASE); return ret; } +/** + * drm_vblank_put - give up ownership of vblank events + * @dev: DRM device + * @crtc: which counter to give up + * + * Release ownership of a given vblank counter, turning off interrupts + * if possible. Disable interrupts after drm_vblank_offdelay milliseconds. + */ void drm_vblank_put(struct drm_device *dev, int crtc) { - /* Make sure that we are called with the lock held */ - KKASSERT(lockstatus(&dev->vbl_lock, curthread) != 0); - - KASSERT(dev->vblank[crtc].refcount > 0, - ("invalid refcount")); + KASSERT(atomic_read(&dev->vblank_refcount[crtc]) != 0, + ("Too many drm_vblank_put for crtc %d", crtc)); /* Last user schedules interrupt disable */ - if (--dev->vblank[crtc].refcount == 0) - callout_reset(&dev->vblank_disable_timer, 5 * DRM_HZ, - (timeout_t *)vblank_disable_fn, (void *)dev); + if (atomic_fetchadd_int(&dev->vblank_refcount[crtc], -1) == 1 && + (drm_vblank_offdelay > 0)) + callout_reset(&dev->vblank_disable_callout, + (drm_vblank_offdelay * DRM_HZ) / 1000, + vblank_disable_fn, dev); +} + +void drm_vblank_off(struct drm_device *dev, int crtc) +{ + struct drm_pending_vblank_event *e, *t; + struct timeval now; + unsigned int seq; + + lockmgr(&dev->vbl_lock, LK_EXCLUSIVE); + vblank_disable_and_save(dev, crtc); + lockmgr(&dev->event_lock, LK_EXCLUSIVE); + wakeup(&dev->_vblank_count[crtc]); + + /* Send any queued vblank events, lest the natives grow disquiet */ + seq = drm_vblank_count_and_time(dev, crtc, &now); + list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) { + if (e->pipe != crtc) + continue; + DRM_DEBUG("Sending premature vblank event on disable: \ + wanted %d, current %d\n", + e->event.sequence, seq); + + e->event.sequence = seq; + e->event.tv_sec = now.tv_sec; + e->event.tv_usec = now.tv_usec; + drm_vblank_put(dev, e->pipe); + list_move_tail(&e->base.link, &e->base.file_priv->event_list); + drm_event_wakeup(&e->base); + } + + lockmgr(&dev->event_lock, LK_RELEASE); + lockmgr(&dev->vbl_lock, LK_RELEASE); +} + +/** + * drm_vblank_pre_modeset - account for vblanks across mode sets + * @dev: DRM device + * @crtc: CRTC in question + * @post: post or pre mode set? + * + * Account for vblank events across mode setting events, which will likely + * reset the hardware frame counter. + */ +void drm_vblank_pre_modeset(struct drm_device *dev, int crtc) +{ + /* vblank is not initialized (IRQ not installed ?) */ + if (!dev->num_crtcs) + return; + /* + * To avoid all the problems that might happen if interrupts + * were enabled/disabled around or between these calls, we just + * have the kernel take a reference on the CRTC (just once though + * to avoid corrupting the count if multiple, mismatch calls occur), + * so that interrupts remain enabled in the interim. + */ + if (!dev->vblank_inmodeset[crtc]) { + dev->vblank_inmodeset[crtc] = 0x1; + if (drm_vblank_get(dev, crtc) == 0) + dev->vblank_inmodeset[crtc] |= 0x2; + } } +void drm_vblank_post_modeset(struct drm_device *dev, int crtc) +{ + + if (dev->vblank_inmodeset[crtc]) { + lockmgr(&dev->vbl_lock, LK_EXCLUSIVE); + dev->vblank_disable_allowed = 1; + lockmgr(&dev->vbl_lock, LK_RELEASE); + + if (dev->vblank_inmodeset[crtc] & 0x2) + drm_vblank_put(dev, crtc); + + dev->vblank_inmodeset[crtc] = 0; + } +} + +/** + * drm_modeset_ctl - handle vblank event counter changes across mode switch + * @DRM_IOCTL_ARGS: standard ioctl arguments + * + * Applications should call the %_DRM_PRE_MODESET and %_DRM_POST_MODESET + * ioctls around modesetting so that any lost vblank events are accounted for. + * + * Generally the counter will reset across mode sets. If interrupts are + * enabled around this call, we don't have to do anything since the counter + * will have already been incremented. + */ int drm_modeset_ctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_modeset_ctl *modeset = data; - int crtc, ret = 0; + int ret = 0; + unsigned int crtc; /* If drm_vblank_init() hasn't been called yet, just no-op */ if (!dev->num_crtcs) @@ -339,41 +922,19 @@ int drm_modeset_ctl(struct drm_device *dev, void *data, crtc = modeset->crtc; if (crtc >= dev->num_crtcs) { - ret = EINVAL; + ret = -EINVAL; goto out; } - /* - * To avoid all the problems that might happen if interrupts - * were enabled/disabled around or between these calls, we just - * have the kernel take a reference on the CRTC (just once though - * to avoid corrupting the count if multiple, mismatch calls occur), - * so that interrupts remain enabled in the interim. - */ switch (modeset->cmd) { case _DRM_PRE_MODESET: - DRM_DEBUG("pre-modeset, crtc %d\n", crtc); - DRM_SPINLOCK(&dev->vbl_lock); - if (!dev->vblank[crtc].inmodeset) { - dev->vblank[crtc].inmodeset = 0x1; - if (drm_vblank_get(dev, crtc) == 0) - dev->vblank[crtc].inmodeset |= 0x2; - } - DRM_SPINUNLOCK(&dev->vbl_lock); + drm_vblank_pre_modeset(dev, crtc); break; case _DRM_POST_MODESET: - DRM_DEBUG("post-modeset, crtc %d\n", crtc); - DRM_SPINLOCK(&dev->vbl_lock); - if (dev->vblank[crtc].inmodeset) { - if (dev->vblank[crtc].inmodeset & 0x2) - drm_vblank_put(dev, crtc); - dev->vblank[crtc].inmodeset = 0; - } - dev->vblank_disable_allowed = 1; - DRM_SPINUNLOCK(&dev->vbl_lock); + drm_vblank_post_modeset(dev, crtc); break; default: - ret = EINVAL; + ret = -EINVAL; break; } @@ -381,35 +942,128 @@ out: return ret; } -int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_priv) +static void +drm_vblank_event_destroy(struct drm_pending_event *e) +{ + + drm_free(e, DRM_MEM_VBLANK); +} + +static int drm_queue_vblank_event(struct drm_device *dev, int pipe, + union drm_wait_vblank *vblwait, + struct drm_file *file_priv) +{ + struct drm_pending_vblank_event *e; + struct timeval now; + unsigned int seq; + int ret; + + e = kmalloc(sizeof *e, DRM_MEM_VBLANK, M_WAITOK | M_ZERO); + + e->pipe = pipe; + e->base.pid = curproc->p_pid; + e->event.base.type = DRM_EVENT_VBLANK; + e->event.base.length = sizeof e->event; + e->event.user_data = vblwait->request.signal; + e->base.event = &e->event.base; + e->base.file_priv = file_priv; + e->base.destroy = drm_vblank_event_destroy; + + lockmgr(&dev->event_lock, LK_EXCLUSIVE); + + if (file_priv->event_space < sizeof e->event) { + ret = EBUSY; + goto err_unlock; + } + + file_priv->event_space -= sizeof e->event; + seq = drm_vblank_count_and_time(dev, pipe, &now); + + if ((vblwait->request.type & _DRM_VBLANK_NEXTONMISS) && + (seq - vblwait->request.sequence) <= (1 << 23)) { + vblwait->request.sequence = seq + 1; + vblwait->reply.sequence = vblwait->request.sequence; + } + + DRM_DEBUG("event on vblank count %d, current %d, crtc %d\n", + vblwait->request.sequence, seq, pipe); + + e->event.sequence = vblwait->request.sequence; + if ((seq - vblwait->request.sequence) <= (1 << 23)) { + e->event.sequence = seq; + e->event.tv_sec = now.tv_sec; + e->event.tv_usec = now.tv_usec; + drm_vblank_put(dev, pipe); + list_add_tail(&e->base.link, &e->base.file_priv->event_list); + drm_event_wakeup(&e->base); + vblwait->reply.sequence = seq; + } else { + /* drm_handle_vblank_events will call drm_vblank_put */ + list_add_tail(&e->base.link, &dev->vblank_event_list); + vblwait->reply.sequence = vblwait->request.sequence; + } + + lockmgr(&dev->event_lock, LK_RELEASE); + + return 0; + +err_unlock: + lockmgr(&dev->event_lock, LK_RELEASE); + drm_free(e, DRM_MEM_VBLANK); + drm_vblank_put(dev, pipe); + return ret; +} + +/** + * Wait for VBLANK. + * + * \param inode device inode. + * \param file_priv DRM file private. + * \param cmd command. + * \param data user argument, pointing to a drm_wait_vblank structure. + * \return zero on success or a negative number on failure. + * + * This function enables the vblank interrupt on the pipe requested, then + * sleeps waiting for the requested sequence number to occur, and drops + * the vblank interrupt refcount afterwards. (vblank irq disable follows that + * after a timeout with no further vblank waits scheduled). + */ +int drm_wait_vblank(struct drm_device *dev, void *data, + struct drm_file *file_priv) { union drm_wait_vblank *vblwait = data; - unsigned int flags, seq, crtc; int ret = 0; + unsigned int flags, seq, crtc, high_crtc; - if (!dev->irq_enabled) - return EINVAL; + if (/*(!drm_dev_to_irq(dev)) || */(!dev->irq_enabled)) + return (EINVAL); + + if (vblwait->request.type & _DRM_VBLANK_SIGNAL) + return (EINVAL); if (vblwait->request.type & - ~(_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK)) { + ~(_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK | + _DRM_VBLANK_HIGH_CRTC_MASK)) { DRM_ERROR("Unsupported type value 0x%x, supported mask 0x%x\n", - vblwait->request.type, - (_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK)); - return EINVAL; + vblwait->request.type, + (_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK | + _DRM_VBLANK_HIGH_CRTC_MASK)); + return (EINVAL); } flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK; - crtc = flags & _DRM_VBLANK_SECONDARY ? 1 : 0; - + high_crtc = (vblwait->request.type & _DRM_VBLANK_HIGH_CRTC_MASK); + if (high_crtc) + crtc = high_crtc >> _DRM_VBLANK_HIGH_CRTC_SHIFT; + else + crtc = flags & _DRM_VBLANK_SECONDARY ? 1 : 0; if (crtc >= dev->num_crtcs) - return EINVAL; + return (EINVAL); - DRM_SPINLOCK(&dev->vbl_lock); ret = drm_vblank_get(dev, crtc); - DRM_SPINUNLOCK(&dev->vbl_lock); if (ret) { - DRM_ERROR("failed to acquire vblank counter, %d\n", ret); - return ret; + DRM_DEBUG("failed to acquire vblank counter, %d\n", ret); + return (ret); } seq = drm_vblank_count(dev, crtc); @@ -420,59 +1074,148 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr case _DRM_VBLANK_ABSOLUTE: break; default: - ret = EINVAL; + ret = (EINVAL); goto done; } + if (flags & _DRM_VBLANK_EVENT) { + /* must hold on to the vblank ref until the event fires + * drm_vblank_put will be called asynchronously + */ + return drm_queue_vblank_event(dev, crtc, vblwait, file_priv); + } + if ((flags & _DRM_VBLANK_NEXTONMISS) && (seq - vblwait->request.sequence) <= (1<<23)) { vblwait->request.sequence = seq + 1; } - if (flags & _DRM_VBLANK_SIGNAL) { - /* There have never been any consumers */ - ret = EINVAL; - } else { - DRM_DEBUG("waiting on vblank count %d, crtc %d\n", - vblwait->request.sequence, crtc); - for ( ret = 0 ; !ret && !(((drm_vblank_count(dev, crtc) - - vblwait->request.sequence) <= (1 << 23)) || - !dev->irq_enabled) ; ) { - lwkt_serialize_enter(&dev->irq_lock); - if (!(((drm_vblank_count(dev, crtc) - - vblwait->request.sequence) <= (1 << 23)) || - !dev->irq_enabled)) - ret = zsleep(&dev->vblank[crtc].queue, - &dev->irq_lock, PCATCH, "vblwtq", - DRM_HZ); - lwkt_serialize_exit(&dev->irq_lock); - } - - if (ret != EINTR && ret != ERESTART) { - struct timeval now; - - microtime(&now); - vblwait->reply.tval_sec = now.tv_sec; - vblwait->reply.tval_usec = now.tv_usec; - vblwait->reply.sequence = drm_vblank_count(dev, crtc); - DRM_DEBUG("returning %d to client, irq_enabled %d\n", - vblwait->reply.sequence, dev->irq_enabled); - } else { - DRM_DEBUG("vblank wait interrupted by signal\n"); - } + dev->last_vblank_wait[crtc] = vblwait->request.sequence; + lockmgr(&dev->vblank_time_lock, LK_EXCLUSIVE); + while (((drm_vblank_count(dev, crtc) - vblwait->request.sequence) > + (1 << 23)) && dev->irq_enabled) { + /* + * The wakeups from the drm_irq_uninstall() and + * drm_vblank_off() may be lost there since vbl_lock + * is not held. Then, the timeout will wake us; the 3 + * seconds delay should not be a problem for + * application when crtc is disabled or irq + * uninstalled anyway. + */ + ret = lksleep(&dev->_vblank_count[crtc], &dev->vblank_time_lock, + PCATCH, "drmvbl", 3 * hz); + if (ret != 0) + break; + } + lockmgr(&dev->vblank_time_lock, LK_RELEASE); + if (ret != EINTR) { + struct timeval now; + long reply_seq; + + reply_seq = drm_vblank_count_and_time(dev, crtc, &now); + vblwait->reply.sequence = reply_seq; + vblwait->reply.tval_sec = now.tv_sec; + vblwait->reply.tval_usec = now.tv_usec; } done: - DRM_SPINLOCK(&dev->vbl_lock); drm_vblank_put(dev, crtc); - DRM_SPINUNLOCK(&dev->vbl_lock); - return ret; } -void drm_handle_vblank(struct drm_device *dev, int crtc) +void drm_handle_vblank_events(struct drm_device *dev, int crtc) { - atomic_add_rel_32(&dev->vblank[crtc].count, 1); - DRM_WAKEUP(&dev->vblank[crtc].queue); + struct drm_pending_vblank_event *e, *t; + struct timeval now; + unsigned int seq; + + seq = drm_vblank_count_and_time(dev, crtc, &now); + + lockmgr(&dev->event_lock, LK_EXCLUSIVE); + + list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) { + if (e->pipe != crtc) + continue; + if ((seq - e->event.sequence) > (1<<23)) + continue; + + e->event.sequence = seq; + e->event.tv_sec = now.tv_sec; + e->event.tv_usec = now.tv_usec; + drm_vblank_put(dev, e->pipe); + list_move_tail(&e->base.link, &e->base.file_priv->event_list); + drm_event_wakeup(&e->base); + } + + lockmgr(&dev->event_lock, LK_RELEASE); } +/** + * drm_handle_vblank - handle a vblank event + * @dev: DRM device + * @crtc: where this event occurred + * + * Drivers should call this routine in their vblank interrupt handlers to + * update the vblank counter and send any signals that may be pending. + */ +bool drm_handle_vblank(struct drm_device *dev, int crtc) +{ + u32 vblcount; + int64_t diff_ns; + struct timeval tvblank; + + if (!dev->num_crtcs) + return false; + + /* Need timestamp lock to prevent concurrent execution with + * vblank enable/disable, as this would cause inconsistent + * or corrupted timestamps and vblank counts. + */ + lockmgr(&dev->vblank_time_lock, LK_EXCLUSIVE); + + /* Vblank irq handling disabled. Nothing to do. */ + if (!dev->vblank_enabled[crtc]) { + lockmgr(&dev->vblank_time_lock, LK_RELEASE); + return false; + } + + /* Fetch corresponding timestamp for this vblank interval from + * driver and store it in proper slot of timestamp ringbuffer. + */ + + /* Get current timestamp and count. */ + vblcount = atomic_read(&dev->_vblank_count[crtc]); + drm_get_last_vbltimestamp(dev, crtc, &tvblank, DRM_CALLED_FROM_VBLIRQ); + + /* Compute time difference to timestamp of last vblank */ + diff_ns = timeval_to_ns(&tvblank) - + timeval_to_ns(&vblanktimestamp(dev, crtc, vblcount)); + + /* Update vblank timestamp and count if at least + * DRM_REDUNDANT_VBLIRQ_THRESH_NS nanoseconds + * difference between last stored timestamp and current + * timestamp. A smaller difference means basically + * identical timestamps. Happens if this vblank has + * been already processed and this is a redundant call, + * e.g., due to spurious vblank interrupts. We need to + * ignore those for accounting. + */ + if (abs64(diff_ns) > DRM_REDUNDANT_VBLIRQ_THRESH_NS) { + /* Store new timestamp in ringbuffer. */ + vblanktimestamp(dev, crtc, vblcount + 1) = tvblank; + + /* Increment cooked vblank count. This also atomically commits + * the timestamp computed above. + */ + atomic_inc(&dev->_vblank_count[crtc]); + } else { + DRM_DEBUG("crtc %d: Redundant vblirq ignored. diff_ns = %d\n", + crtc, (int) diff_ns); + } + + wakeup(&dev->_vblank_count[crtc]); + drm_handle_vblank_events(dev, crtc); + + lockmgr(&dev->vblank_time_lock, LK_RELEASE); + return true; +} diff --git a/sys/dev/drm/drm_linux_list.h b/sys/dev/drm/drm_linux_list.h index e5a478a28f..86fdfe7663 100644 --- a/sys/dev/drm/drm_linux_list.h +++ b/sys/dev/drm/drm_linux_list.h @@ -27,10 +27,9 @@ * Authors: * Eric Anholt * + * $FreeBSD: src/sys/dev/drm2/drm_linux_list.h,v 1.1 2012/05/22 11:07:44 kib Exp $ */ -#include - #ifndef _DRM_LINUX_LIST_H_ #define _DRM_LINUX_LIST_H_ @@ -47,8 +46,13 @@ INIT_LIST_HEAD(struct list_head *head) { (head)->prev = head; } +#define LIST_HEAD_INIT(name) { &(name), &(name) } + +#define DRM_LIST_HEAD(name) \ + struct list_head name = LIST_HEAD_INIT(name) + static __inline__ int -list_empty(struct list_head *head) { +list_empty(const struct list_head *head) { return (head)->next == head; } @@ -74,6 +78,28 @@ list_del(struct list_head *entry) { (entry)->prev->next = (entry)->next; } +static inline void list_replace(struct list_head *old, + struct list_head *new) +{ + new->next = old->next; + new->next->prev = new; + new->prev = old->prev; + new->prev->next = new; +} + +static inline void list_move(struct list_head *list, struct list_head *head) +{ + list_del(list); + list_add(list, head); +} + +static inline void list_move_tail(struct list_head *list, + struct list_head *head) +{ + list_del(list); + list_add_tail(list, head); +} + static __inline__ void list_del_init(struct list_head *entry) { (entry)->next->prev = (entry)->prev; @@ -93,6 +119,16 @@ list_del_init(struct list_head *entry) { entry != head; \ entry = temp, temp = entry->next) +#define list_for_each_entry(pos, head, member) \ + for (pos = list_entry((head)->next, __typeof(*pos), member); \ + &pos->member != (head); \ + pos = list_entry(pos->member.next, __typeof(*pos), member)) + +#define list_for_each_entry_continue_reverse(pos, head, member) \ + for (pos = list_entry(pos->member.prev, __typeof(*pos), member); \ + &pos->member != (head); \ + pos = list_entry(pos->member.prev, __typeof(*pos), member)) + /** * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry * @pos: the type * to use as a loop cursor. @@ -106,4 +142,34 @@ list_del_init(struct list_head *entry) { &pos->member != (head); \ pos = n, n = list_entry(n->member.next, __typeof(*n), member)) +#define list_first_entry(ptr, type, member) \ + list_entry((ptr)->next, type, member) + + +static inline void +__list_splice(const struct list_head *list, struct list_head *prev, + struct list_head *next) +{ + struct list_head *first = list->next; + struct list_head *last = list->prev; + + first->prev = prev; + prev->next = first; + + last->next = next; + next->prev = last; +} + +static inline void +list_splice(const struct list_head *list, struct list_head *head) +{ + if (list_empty(list)) + return; + + __list_splice(list, head, head->next); +} + +void drm_list_sort(void *priv, struct list_head *head, int (*cmp)(void *priv, + struct list_head *a, struct list_head *b)); + #endif /* _DRM_LINUX_LIST_H_ */ diff --git a/sys/dev/drm2/drm_linux_list_sort.c b/sys/dev/drm/drm_linux_list_sort.c similarity index 95% rename from sys/dev/drm2/drm_linux_list_sort.c rename to sys/dev/drm/drm_linux_list_sort.c index 4d64da8d5f..855a8ebada 100644 --- a/sys/dev/drm2/drm_linux_list_sort.c +++ b/sys/dev/drm/drm_linux_list_sort.c @@ -25,10 +25,11 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. + * + * $FreeBSD: src/sys/dev/drm2/drm_linux_list_sort.c,v 1.1 2012/05/22 11:07:44 kib Exp $ */ -#include -/* $FreeBSD: src/sys/dev/drm2/drm_linux_list_sort.c,v 1.1 2012/05/22 11:07:44 kib Exp $ */ +#include struct drm_list_sort_thunk { int (*cmp)(void *, struct list_head *, struct list_head *); diff --git a/sys/dev/drm/drm_lock.c b/sys/dev/drm/drm_lock.c index 4e71c21a8b..89707bc95c 100644 --- a/sys/dev/drm/drm_lock.c +++ b/sys/dev/drm/drm_lock.c @@ -26,6 +26,7 @@ * Rickard E. (Rik) Faith * Gareth Hughes * + * $FreeBSD: src/sys/dev/drm2/drm_lock.c,v 1.1 2012/05/22 11:07:44 kib Exp $ */ /** @file drm_lock.c @@ -68,7 +69,7 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv) lock->context < 0) return EINVAL; - DRM_LOCK(); + DRM_LOCK(dev); for (;;) { if (drm_lock_take(&dev->lock, lock->context)) { dev->lock.file_priv = file_priv; @@ -78,15 +79,12 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv) } /* Contention */ - tsleep_interlock((void *)&dev->lock.lock_queue, PCATCH); - DRM_UNLOCK(); - ret = tsleep((void *)&dev->lock.lock_queue, - PCATCH | PINTERLOCKED, "drmlk2", 0); - DRM_LOCK(); + ret = DRM_LOCK_SLEEP(dev, &dev->lock.lock_queue, + PCATCH, "drmlk2", 0); if (ret != 0) break; } - DRM_UNLOCK(); + DRM_UNLOCK(dev); if (ret == ERESTART) DRM_DEBUG("restarting syscall\n"); @@ -122,13 +120,13 @@ int drm_unlock(struct drm_device *dev, void *data, struct drm_file *file_priv) atomic_inc(&dev->counts[_DRM_STAT_UNLOCKS]); - DRM_LOCK(); + DRM_LOCK(dev); drm_lock_transfer(&dev->lock, DRM_KERNEL_CONTEXT); if (drm_lock_free(&dev->lock, DRM_KERNEL_CONTEXT)) { DRM_ERROR("\n"); } - DRM_UNLOCK(); + DRM_UNLOCK(dev); return 0; } diff --git a/sys/dev/drm/drm_memory.c b/sys/dev/drm/drm_memory.c index 199059b56d..394c5170d3 100644 --- a/sys/dev/drm/drm_memory.c +++ b/sys/dev/drm/drm_memory.c @@ -1,7 +1,11 @@ /*- *Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. + * Copyright (c) 2011 The FreeBSD Foundation + * All rights reserved. + * + * Portions of this software were developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -26,6 +30,7 @@ * Rickard E. (Rik) Faith * Gareth Hughes * + * $FreeBSD: src/sys/dev/drm2/drm_memory.c,v 1.1 2012/05/22 11:07:44 kib Exp $ */ /** @file drm_memory.c @@ -36,7 +41,7 @@ * has been stripped out for now. */ -#include "dev/drm/drmP.h" +#include MALLOC_DEFINE(DRM_MEM_DMA, "drm_dma", "DRM DMA Data Structures"); MALLOC_DEFINE(DRM_MEM_SAREA, "drm_sarea", "DRM SAREA Data Structures"); @@ -55,6 +60,7 @@ MALLOC_DEFINE(DRM_MEM_SGLISTS, "drm_sglists", "DRM SGLISTS Data Structures"); MALLOC_DEFINE(DRM_MEM_DRAWABLE, "drm_drawable", "DRM DRAWABLE Data Structures"); MALLOC_DEFINE(DRM_MEM_MM, "drm_sman", "DRM MEMORY MANAGER Data Structures"); MALLOC_DEFINE(DRM_MEM_HASHTAB, "drm_hashtab", "DRM HASHTABLE Data Structures"); +MALLOC_DEFINE(DRM_MEM_KMS, "drm_kms", "DRM KMS Data Structures"); void drm_mem_init(void) { @@ -67,7 +73,6 @@ void drm_mem_uninit(void) void *drm_ioremap_wc(struct drm_device *dev, drm_local_map_t *map) { return pmap_mapdev_attr(map->offset, map->size, VM_MEMATTR_WRITE_COMBINING); - return pmap_mapdev(map->offset, map->size); } void *drm_ioremap(struct drm_device *dev, drm_local_map_t *map) @@ -107,3 +112,10 @@ drm_mtrr_del(int __unused handle, unsigned long offset, size_t size, int flags) strlcpy(mrdesc.mr_owner, "drm", sizeof(mrdesc.mr_owner)); return mem_range_attr_set(&mrdesc, &act); } + +void +drm_clflush_pages(vm_page_t *pages, unsigned long num_pages) +{ + + pmap_invalidate_cache_pages(pages, num_pages); +} diff --git a/sys/dev/drm/drm_mm.c b/sys/dev/drm/drm_mm.c index 16e04cb136..cabc637df0 100644 --- a/sys/dev/drm/drm_mm.c +++ b/sys/dev/drm/drm_mm.c @@ -23,8 +23,7 @@ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * USE OR OTHER DEALINGS IN THE SOFTWARE. * - * - * $FreeBSD: src/sys/dev/drm/drm_mm.c,v 1.1 2010/01/31 14:25:29 rnoland Exp $ + * $FreeBSD: head/sys/dev/drm2/drm_mm.c 247833 2013-03-05 09:07:58Z kib $ **************************************************************************/ /* @@ -47,57 +46,25 @@ #define MM_UNUSED_TARGET 4 -unsigned long drm_mm_tail_space(struct drm_mm *mm) -{ - struct list_head *tail_node; - struct drm_mm_node *entry; - - tail_node = mm->ml_entry.prev; - entry = list_entry(tail_node, struct drm_mm_node, ml_entry); - if (!entry->free) - return 0; - - return entry->size; -} - -int drm_mm_remove_space_from_tail(struct drm_mm *mm, unsigned long size) -{ - struct list_head *tail_node; - struct drm_mm_node *entry; - - tail_node = mm->ml_entry.prev; - entry = list_entry(tail_node, struct drm_mm_node, ml_entry); - if (!entry->free) - return -ENOMEM; - - if (entry->size <= size) - return -ENOMEM; - - entry->size -= size; - return 0; -} - static struct drm_mm_node *drm_mm_kmalloc(struct drm_mm *mm, int atomic) { struct drm_mm_node *child; - if (atomic) - child = malloc(sizeof(*child), DRM_MEM_MM, M_NOWAIT); - else - child = malloc(sizeof(*child), DRM_MEM_MM, M_WAITOK); + child = kmalloc(sizeof(*child), DRM_MEM_MM, M_ZERO | + (atomic ? M_NOWAIT : M_WAITOK)); if (unlikely(child == NULL)) { - DRM_SPINLOCK(&mm->unused_lock); + spin_lock(&mm->unused_spin); if (list_empty(&mm->unused_nodes)) child = NULL; else { child = list_entry(mm->unused_nodes.next, - struct drm_mm_node, fl_entry); - list_del(&child->fl_entry); + struct drm_mm_node, node_list); + list_del(&child->node_list); --mm->num_unused; } - DRM_SPINUNLOCK(&mm->unused_lock); + spin_unlock(&mm->unused_spin); } return child; } @@ -106,262 +73,525 @@ int drm_mm_pre_get(struct drm_mm *mm) { struct drm_mm_node *node; - DRM_SPINLOCK(&mm->unused_lock); + spin_lock(&mm->unused_spin); while (mm->num_unused < MM_UNUSED_TARGET) { - DRM_SPINUNLOCK(&mm->unused_lock); - node = malloc(sizeof(*node), DRM_MEM_MM, M_WAITOK); - DRM_SPINLOCK(&mm->unused_lock); + spin_unlock(&mm->unused_spin); + node = kmalloc(sizeof(*node), DRM_MEM_MM, M_WAITOK); + spin_lock(&mm->unused_spin); if (unlikely(node == NULL)) { int ret = (mm->num_unused < 2) ? -ENOMEM : 0; - DRM_SPINUNLOCK(&mm->unused_lock); + spin_unlock(&mm->unused_spin); return ret; } ++mm->num_unused; - list_add_tail(&node->fl_entry, &mm->unused_nodes); + list_add_tail(&node->node_list, &mm->unused_nodes); } - DRM_SPINUNLOCK(&mm->unused_lock); + spin_unlock(&mm->unused_spin); return 0; } -static int drm_mm_create_tail_node(struct drm_mm *mm, - unsigned long start, - unsigned long size, int atomic) +static inline unsigned long drm_mm_hole_node_start(struct drm_mm_node *hole_node) { - struct drm_mm_node *child; - - child = drm_mm_kmalloc(mm, atomic); - if (unlikely(child == NULL)) - return -ENOMEM; - - child->free = 1; - child->size = size; - child->start = start; - child->mm = mm; + return hole_node->start + hole_node->size; +} - list_add_tail(&child->ml_entry, &mm->ml_entry); - list_add_tail(&child->fl_entry, &mm->fl_entry); +static inline unsigned long drm_mm_hole_node_end(struct drm_mm_node *hole_node) +{ + struct drm_mm_node *next_node = + list_entry(hole_node->node_list.next, struct drm_mm_node, + node_list); - return 0; + return next_node->start; } -int drm_mm_add_space_to_tail(struct drm_mm *mm, unsigned long size, int atomic) +static void drm_mm_insert_helper(struct drm_mm_node *hole_node, + struct drm_mm_node *node, + unsigned long size, unsigned alignment) { - struct list_head *tail_node; - struct drm_mm_node *entry; + struct drm_mm *mm = hole_node->mm; + unsigned long tmp = 0, wasted = 0; + unsigned long hole_start = drm_mm_hole_node_start(hole_node); + unsigned long hole_end = drm_mm_hole_node_end(hole_node); + + KASSERT(hole_node->hole_follows && !node->allocated, ("hole_node")); + + if (alignment) + tmp = hole_start % alignment; + + if (!tmp) { + hole_node->hole_follows = 0; + list_del_init(&hole_node->hole_stack); + } else + wasted = alignment - tmp; - tail_node = mm->ml_entry.prev; - entry = list_entry(tail_node, struct drm_mm_node, ml_entry); - if (!entry->free) { - return drm_mm_create_tail_node(mm, entry->start + entry->size, - size, atomic); + node->start = hole_start + wasted; + node->size = size; + node->mm = mm; + node->allocated = 1; + + INIT_LIST_HEAD(&node->hole_stack); + list_add(&node->node_list, &hole_node->node_list); + + KASSERT(node->start + node->size <= hole_end, ("hole pos")); + + if (node->start + node->size < hole_end) { + list_add(&node->hole_stack, &mm->hole_stack); + node->hole_follows = 1; + } else { + node->hole_follows = 0; } - entry->size += size; - return 0; } -static struct drm_mm_node *drm_mm_split_at_start(struct drm_mm_node *parent, - unsigned long size, - int atomic) +struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *hole_node, + unsigned long size, + unsigned alignment, + int atomic) { - struct drm_mm_node *child; + struct drm_mm_node *node; - child = drm_mm_kmalloc(parent->mm, atomic); - if (unlikely(child == NULL)) + node = drm_mm_kmalloc(hole_node->mm, atomic); + if (unlikely(node == NULL)) return NULL; - INIT_LIST_HEAD(&child->fl_entry); + drm_mm_insert_helper(hole_node, node, size, alignment); - child->free = 0; - child->size = size; - child->start = parent->start; - child->mm = parent->mm; + return node; +} - list_add_tail(&child->ml_entry, &parent->ml_entry); - INIT_LIST_HEAD(&child->fl_entry); +int drm_mm_insert_node(struct drm_mm *mm, struct drm_mm_node *node, + unsigned long size, unsigned alignment) +{ + struct drm_mm_node *hole_node; - parent->size -= size; - parent->start += size; - return child; -} + hole_node = drm_mm_search_free(mm, size, alignment, 0); + if (!hole_node) + return -ENOSPC; + drm_mm_insert_helper(hole_node, node, size, alignment); -struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *node, - unsigned long size, - unsigned alignment, - int atomic) + return 0; +} + +static void drm_mm_insert_helper_range(struct drm_mm_node *hole_node, + struct drm_mm_node *node, + unsigned long size, unsigned alignment, + unsigned long start, unsigned long end) { + struct drm_mm *mm = hole_node->mm; + unsigned long tmp = 0, wasted = 0; + unsigned long hole_start = drm_mm_hole_node_start(hole_node); + unsigned long hole_end = drm_mm_hole_node_end(hole_node); - struct drm_mm_node *align_splitoff = NULL; - unsigned tmp = 0; + KASSERT(hole_node->hole_follows && !node->allocated, ("hole_node")); + if (hole_start < start) + wasted += start - hole_start; if (alignment) - tmp = node->start % alignment; + tmp = (hole_start + wasted) % alignment; - if (tmp) { - align_splitoff = - drm_mm_split_at_start(node, alignment - tmp, atomic); - if (unlikely(align_splitoff == NULL)) - return NULL; + if (tmp) + wasted += alignment - tmp; + + if (!wasted) { + hole_node->hole_follows = 0; + list_del_init(&hole_node->hole_stack); } - if (node->size == size) { - list_del_init(&node->fl_entry); - node->free = 0; + node->start = hole_start + wasted; + node->size = size; + node->mm = mm; + node->allocated = 1; + + INIT_LIST_HEAD(&node->hole_stack); + list_add(&node->node_list, &hole_node->node_list); + + KASSERT(node->start + node->size <= hole_end, ("hole_end")); + KASSERT(node->start + node->size <= end, ("end")); + + if (node->start + node->size < hole_end) { + list_add(&node->hole_stack, &mm->hole_stack); + node->hole_follows = 1; } else { - node = drm_mm_split_at_start(node, size, atomic); + node->hole_follows = 0; } +} - if (align_splitoff) - drm_mm_put_block(align_splitoff); +struct drm_mm_node *drm_mm_get_block_range_generic(struct drm_mm_node *hole_node, + unsigned long size, + unsigned alignment, + unsigned long start, + unsigned long end, + int atomic) +{ + struct drm_mm_node *node; + + node = drm_mm_kmalloc(hole_node->mm, atomic); + if (unlikely(node == NULL)) + return NULL; + + drm_mm_insert_helper_range(hole_node, node, size, alignment, + start, end); return node; } +int drm_mm_insert_node_in_range(struct drm_mm *mm, struct drm_mm_node *node, + unsigned long size, unsigned alignment, + unsigned long start, unsigned long end) +{ + struct drm_mm_node *hole_node; + + hole_node = drm_mm_search_free_in_range(mm, size, alignment, + start, end, 0); + if (!hole_node) + return -ENOSPC; + + drm_mm_insert_helper_range(hole_node, node, size, alignment, + start, end); + + return 0; +} + +void drm_mm_remove_node(struct drm_mm_node *node) +{ + struct drm_mm *mm = node->mm; + struct drm_mm_node *prev_node; + + KASSERT(!node->scanned_block && !node->scanned_prev_free + && !node->scanned_next_free, ("node")); + + prev_node = + list_entry(node->node_list.prev, struct drm_mm_node, node_list); + + if (node->hole_follows) { + KASSERT(drm_mm_hole_node_start(node) + != drm_mm_hole_node_end(node), ("hole_follows")); + list_del(&node->hole_stack); + } else + KASSERT(drm_mm_hole_node_start(node) + == drm_mm_hole_node_end(node), ("!hole_follows")); + + if (!prev_node->hole_follows) { + prev_node->hole_follows = 1; + list_add(&prev_node->hole_stack, &mm->hole_stack); + } else + list_move(&prev_node->hole_stack, &mm->hole_stack); + + list_del(&node->node_list); + node->allocated = 0; +} + /* * Put a block. Merge with the previous and / or next block if they are free. * Otherwise add to the free stack. */ -void drm_mm_put_block(struct drm_mm_node *cur) +void drm_mm_put_block(struct drm_mm_node *node) { + struct drm_mm *mm = node->mm; - struct drm_mm *mm = cur->mm; - struct list_head *cur_head = &cur->ml_entry; - struct list_head *root_head = &mm->ml_entry; - struct drm_mm_node *prev_node = NULL; - struct drm_mm_node *next_node; + drm_mm_remove_node(node); - int merged = 0; + spin_lock(&mm->unused_spin); + if (mm->num_unused < MM_UNUSED_TARGET) { + list_add(&node->node_list, &mm->unused_nodes); + ++mm->num_unused; + } else + drm_free(node, DRM_MEM_MM); + spin_unlock(&mm->unused_spin); +} - if (cur_head->prev != root_head) { - prev_node = - list_entry(cur_head->prev, struct drm_mm_node, ml_entry); - if (prev_node->free) { - prev_node->size += cur->size; - merged = 1; - } - } - if (cur_head->next != root_head) { - next_node = - list_entry(cur_head->next, struct drm_mm_node, ml_entry); - if (next_node->free) { - if (merged) { - prev_node->size += next_node->size; - list_del(&next_node->ml_entry); - list_del(&next_node->fl_entry); - if (mm->num_unused < MM_UNUSED_TARGET) { - list_add(&next_node->fl_entry, - &mm->unused_nodes); - ++mm->num_unused; - } else - free(next_node, DRM_MEM_MM); - } else { - next_node->size += cur->size; - next_node->start = cur->start; - merged = 1; - } - } +static int check_free_hole(unsigned long start, unsigned long end, + unsigned long size, unsigned alignment) +{ + unsigned wasted = 0; + + if (end - start < size) + return 0; + + if (alignment) { + unsigned tmp = start % alignment; + if (tmp) + wasted = alignment - tmp; } - if (!merged) { - cur->free = 1; - list_add(&cur->fl_entry, &mm->fl_entry); - } else { - list_del(&cur->ml_entry); - if (mm->num_unused < MM_UNUSED_TARGET) { - list_add(&cur->fl_entry, &mm->unused_nodes); - ++mm->num_unused; - } else - free(cur, DRM_MEM_MM); + + if (end >= start + size + wasted) { + return 1; } + + return 0; } + struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm, unsigned long size, unsigned alignment, int best_match) { - struct list_head *list; - const struct list_head *free_stack = &mm->fl_entry; struct drm_mm_node *entry; struct drm_mm_node *best; unsigned long best_size; - unsigned wasted; best = NULL; best_size = ~0UL; - list_for_each(list, free_stack) { - entry = list_entry(list, struct drm_mm_node, fl_entry); - wasted = 0; - - if (entry->size < size) + list_for_each_entry(entry, &mm->hole_stack, hole_stack) { + KASSERT(entry->hole_follows, ("hole_follows")); + if (!check_free_hole(drm_mm_hole_node_start(entry), + drm_mm_hole_node_end(entry), + size, alignment)) continue; - if (alignment) { - register unsigned tmp = entry->start % alignment; - if (tmp) - wasted += alignment - tmp; + if (!best_match) + return entry; + + if (entry->size < best_size) { + best = entry; + best_size = entry->size; } + } + + return best; +} + +struct drm_mm_node *drm_mm_search_free_in_range(const struct drm_mm *mm, + unsigned long size, + unsigned alignment, + unsigned long start, + unsigned long end, + int best_match) +{ + struct drm_mm_node *entry; + struct drm_mm_node *best; + unsigned long best_size; + + KASSERT(!mm->scanned_blocks, ("scanned")); + + best = NULL; + best_size = ~0UL; + + list_for_each_entry(entry, &mm->hole_stack, hole_stack) { + unsigned long adj_start = drm_mm_hole_node_start(entry) < start ? + start : drm_mm_hole_node_start(entry); + unsigned long adj_end = drm_mm_hole_node_end(entry) > end ? + end : drm_mm_hole_node_end(entry); - if (entry->size >= size + wasted) { - if (!best_match) - return entry; - if (size < best_size) { - best = entry; - best_size = entry->size; - } + KASSERT(entry->hole_follows, ("hole_follows")); + if (!check_free_hole(adj_start, adj_end, size, alignment)) + continue; + + if (!best_match) + return entry; + + if (entry->size < best_size) { + best = entry; + best_size = entry->size; } } return best; } +void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new) +{ + list_replace(&old->node_list, &new->node_list); + list_replace(&old->hole_stack, &new->hole_stack); + new->hole_follows = old->hole_follows; + new->mm = old->mm; + new->start = old->start; + new->size = old->size; + + old->allocated = 0; + new->allocated = 1; +} + +void drm_mm_init_scan(struct drm_mm *mm, unsigned long size, + unsigned alignment) +{ + mm->scan_alignment = alignment; + mm->scan_size = size; + mm->scanned_blocks = 0; + mm->scan_hit_start = 0; + mm->scan_hit_size = 0; + mm->scan_check_range = 0; + mm->prev_scanned_node = NULL; +} + +void drm_mm_init_scan_with_range(struct drm_mm *mm, unsigned long size, + unsigned alignment, + unsigned long start, + unsigned long end) +{ + mm->scan_alignment = alignment; + mm->scan_size = size; + mm->scanned_blocks = 0; + mm->scan_hit_start = 0; + mm->scan_hit_size = 0; + mm->scan_start = start; + mm->scan_end = end; + mm->scan_check_range = 1; + mm->prev_scanned_node = NULL; +} + +int drm_mm_scan_add_block(struct drm_mm_node *node) +{ + struct drm_mm *mm = node->mm; + struct drm_mm_node *prev_node; + unsigned long hole_start, hole_end; + unsigned long adj_start; + unsigned long adj_end; + + mm->scanned_blocks++; + + KASSERT(!node->scanned_block, ("node->scanned_block")); + node->scanned_block = 1; + + prev_node = list_entry(node->node_list.prev, struct drm_mm_node, + node_list); + + node->scanned_preceeds_hole = prev_node->hole_follows; + prev_node->hole_follows = 1; + list_del(&node->node_list); + node->node_list.prev = &prev_node->node_list; + node->node_list.next = &mm->prev_scanned_node->node_list; + mm->prev_scanned_node = node; + + hole_start = drm_mm_hole_node_start(prev_node); + hole_end = drm_mm_hole_node_end(prev_node); + if (mm->scan_check_range) { + adj_start = hole_start < mm->scan_start ? + mm->scan_start : hole_start; + adj_end = hole_end > mm->scan_end ? + mm->scan_end : hole_end; + } else { + adj_start = hole_start; + adj_end = hole_end; + } + + if (check_free_hole(adj_start , adj_end, + mm->scan_size, mm->scan_alignment)) { + mm->scan_hit_start = hole_start; + mm->scan_hit_size = hole_end; + + return 1; + } + + return 0; +} + +int drm_mm_scan_remove_block(struct drm_mm_node *node) +{ + struct drm_mm *mm = node->mm; + struct drm_mm_node *prev_node; + + mm->scanned_blocks--; + + KASSERT(node->scanned_block, ("scanned_block")); + node->scanned_block = 0; + + prev_node = list_entry(node->node_list.prev, struct drm_mm_node, + node_list); + + prev_node->hole_follows = node->scanned_preceeds_hole; + INIT_LIST_HEAD(&node->node_list); + list_add(&node->node_list, &prev_node->node_list); + + /* Only need to check for containement because start&size for the + * complete resulting free block (not just the desired part) is + * stored. */ + if (node->start >= mm->scan_hit_start && + node->start + node->size + <= mm->scan_hit_start + mm->scan_hit_size) { + return 1; + } + + return 0; +} + int drm_mm_clean(struct drm_mm * mm) { - struct list_head *head = &mm->ml_entry; + struct list_head *head = &mm->head_node.node_list; return (head->next->next == head); } int drm_mm_init(struct drm_mm * mm, unsigned long start, unsigned long size) { - INIT_LIST_HEAD(&mm->ml_entry); - INIT_LIST_HEAD(&mm->fl_entry); + INIT_LIST_HEAD(&mm->hole_stack); INIT_LIST_HEAD(&mm->unused_nodes); mm->num_unused = 0; - DRM_SPININIT(&mm->unused_lock, "drm_unused"); + mm->scanned_blocks = 0; + spin_init(&mm->unused_spin); + + INIT_LIST_HEAD(&mm->head_node.node_list); + INIT_LIST_HEAD(&mm->head_node.hole_stack); + mm->head_node.hole_follows = 1; + mm->head_node.scanned_block = 0; + mm->head_node.scanned_prev_free = 0; + mm->head_node.scanned_next_free = 0; + mm->head_node.mm = mm; + mm->head_node.start = start + size; + mm->head_node.size = start - mm->head_node.start; + list_add_tail(&mm->head_node.hole_stack, &mm->hole_stack); - /* XXX This could be non-atomic but gets called from a locked path */ - return drm_mm_create_tail_node(mm, start, size, 1); + return 0; } void drm_mm_takedown(struct drm_mm * mm) { - struct list_head *bnode = mm->fl_entry.next; - struct drm_mm_node *entry; - struct drm_mm_node *next; - - entry = list_entry(bnode, struct drm_mm_node, fl_entry); + struct drm_mm_node *entry, *next; - if (entry->ml_entry.next != &mm->ml_entry || - entry->fl_entry.next != &mm->fl_entry) { + if (!list_empty(&mm->head_node.node_list)) { DRM_ERROR("Memory manager not clean. Delaying takedown\n"); return; } - list_del(&entry->fl_entry); - list_del(&entry->ml_entry); - free(entry, DRM_MEM_MM); - - DRM_SPINLOCK(&mm->unused_lock); - list_for_each_entry_safe(entry, next, &mm->unused_nodes, fl_entry) { - list_del(&entry->fl_entry); - free(entry, DRM_MEM_MM); + spin_lock(&mm->unused_spin); + list_for_each_entry_safe(entry, next, &mm->unused_nodes, node_list) { + list_del(&entry->node_list); + drm_free(entry, DRM_MEM_MM); --mm->num_unused; } - DRM_SPINUNLOCK(&mm->unused_lock); + spin_unlock(&mm->unused_spin); - DRM_SPINUNINIT(&mm->unused_lock); + spin_uninit(&mm->unused_spin); KASSERT(mm->num_unused == 0, ("num_unused != 0")); } + +void drm_mm_debug_table(struct drm_mm *mm, const char *prefix) +{ + struct drm_mm_node *entry; + unsigned long total_used = 0, total_free = 0, total = 0; + unsigned long hole_start, hole_end, hole_size; + + hole_start = drm_mm_hole_node_start(&mm->head_node); + hole_end = drm_mm_hole_node_end(&mm->head_node); + hole_size = hole_end - hole_start; + if (hole_size) + kprintf("%s 0x%08lx-0x%08lx: %8lu: free\n", + prefix, hole_start, hole_end, + hole_size); + total_free += hole_size; + + drm_mm_for_each_node(entry, mm) { + kprintf("%s 0x%08lx-0x%08lx: %8lu: used\n", + prefix, entry->start, entry->start + entry->size, + entry->size); + total_used += entry->size; + + if (entry->hole_follows) { + hole_start = drm_mm_hole_node_start(entry); + hole_end = drm_mm_hole_node_end(entry); + hole_size = hole_end - hole_start; + kprintf("%s 0x%08lx-0x%08lx: %8lu: free\n", + prefix, hole_start, hole_end, + hole_size); + total_free += hole_size; + } + } + total = total_free + total_used; + + kprintf("%s total: %lu, used %lu free %lu\n", prefix, total, + total_used, total_free); +} diff --git a/sys/dev/drm/drm_mm.h b/sys/dev/drm/drm_mm.h index 56bea22350..9c3dbe08a0 100644 --- a/sys/dev/drm/drm_mm.h +++ b/sys/dev/drm/drm_mm.h @@ -24,7 +24,7 @@ * USE OR OTHER DEALINGS IN THE SOFTWARE. * * - * $FreeBSD: src/sys/dev/drm/drm_mm.h,v 1.1 2010/01/31 14:25:29 rnoland Exp $ + * $FreeBSD: head/sys/dev/drm2/drm_mm.h 247833 2013-03-05 09:07:58Z kib $ **************************************************************************/ /* @@ -36,11 +36,17 @@ #define _DRM_MM_H_ #include "dev/drm/drm_linux_list.h" +#include struct drm_mm_node { - struct list_head fl_entry; - struct list_head ml_entry; - int free; + struct list_head node_list; + struct list_head hole_stack; + unsigned hole_follows : 1; + unsigned scanned_block : 1; + unsigned scanned_prev_free : 1; + unsigned scanned_next_free : 1; + unsigned scanned_preceeds_hole : 1; + unsigned allocated : 1; unsigned long start; unsigned long size; struct drm_mm *mm; @@ -48,13 +54,42 @@ struct drm_mm_node { }; struct drm_mm { - struct list_head fl_entry; - struct list_head ml_entry; + struct list_head hole_stack; + struct drm_mm_node head_node; struct list_head unused_nodes; int num_unused; - DRM_SPINTYPE unused_lock; + struct spinlock unused_spin; + unsigned int scan_check_range : 1; + unsigned scan_alignment; + unsigned long scan_size; + unsigned long scan_hit_start; + unsigned scan_hit_size; + unsigned scanned_blocks; + unsigned long scan_start; + unsigned long scan_end; + struct drm_mm_node *prev_scanned_node; }; +static inline bool drm_mm_node_allocated(struct drm_mm_node *node) +{ + return node->allocated; +} + +static inline bool drm_mm_initialized(struct drm_mm *mm) +{ + return (mm->hole_stack.next != NULL); +} +#define drm_mm_for_each_node(entry, mm) list_for_each_entry(entry, \ + &(mm)->head_node.node_list, \ + node_list) +#define drm_mm_for_each_scanned_node_reverse(entry, n, mm) \ + for (entry = (mm)->prev_scanned_node, \ + next = entry ? list_entry(entry->node_list.next, \ + struct drm_mm_node, node_list) : NULL; \ + entry != NULL; entry = next, \ + next = entry ? list_entry(entry->node_list.next, \ + struct drm_mm_node, node_list) : NULL) + /* * Basic range manager support (drm_mm.c) */ @@ -62,6 +97,13 @@ extern struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *node, unsigned long size, unsigned alignment, int atomic); +extern struct drm_mm_node *drm_mm_get_block_range_generic( + struct drm_mm_node *node, + unsigned long size, + unsigned alignment, + unsigned long start, + unsigned long end, + int atomic); static inline struct drm_mm_node *drm_mm_get_block(struct drm_mm_node *parent, unsigned long size, unsigned alignment) @@ -74,11 +116,46 @@ static inline struct drm_mm_node *drm_mm_get_block_atomic(struct drm_mm_node *pa { return drm_mm_get_block_generic(parent, size, alignment, 1); } +static inline struct drm_mm_node *drm_mm_get_block_range( + struct drm_mm_node *parent, + unsigned long size, + unsigned alignment, + unsigned long start, + unsigned long end) +{ + return drm_mm_get_block_range_generic(parent, size, alignment, + start, end, 0); +} +static inline struct drm_mm_node *drm_mm_get_block_atomic_range( + struct drm_mm_node *parent, + unsigned long size, + unsigned alignment, + unsigned long start, + unsigned long end) +{ + return drm_mm_get_block_range_generic(parent, size, alignment, + start, end, 1); +} +extern int drm_mm_insert_node(struct drm_mm *mm, struct drm_mm_node *node, + unsigned long size, unsigned alignment); +extern int drm_mm_insert_node_in_range(struct drm_mm *mm, + struct drm_mm_node *node, + unsigned long size, unsigned alignment, + unsigned long start, unsigned long end); extern void drm_mm_put_block(struct drm_mm_node *cur); +extern void drm_mm_remove_node(struct drm_mm_node *node); +extern void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new); extern struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm, unsigned long size, unsigned alignment, int best_match); +extern struct drm_mm_node *drm_mm_search_free_in_range( + const struct drm_mm *mm, + unsigned long size, + unsigned alignment, + unsigned long start, + unsigned long end, + int best_match); extern int drm_mm_init(struct drm_mm *mm, unsigned long start, unsigned long size); extern void drm_mm_takedown(struct drm_mm *mm); @@ -95,4 +172,15 @@ static inline struct drm_mm *drm_get_mm(struct drm_mm_node *block) return block->mm; } +void drm_mm_init_scan(struct drm_mm *mm, unsigned long size, + unsigned alignment); +void drm_mm_init_scan_with_range(struct drm_mm *mm, unsigned long size, + unsigned alignment, + unsigned long start, + unsigned long end); +int drm_mm_scan_add_block(struct drm_mm_node *node); +int drm_mm_scan_remove_block(struct drm_mm_node *node); + +void drm_mm_debug_table(struct drm_mm *mm, const char *prefix); + #endif diff --git a/sys/dev/drm2/drm_mode.h b/sys/dev/drm/drm_mode.h similarity index 100% rename from sys/dev/drm2/drm_mode.h rename to sys/dev/drm/drm_mode.h diff --git a/sys/dev/drm2/drm_modes.c b/sys/dev/drm/drm_modes.c similarity index 99% rename from sys/dev/drm2/drm_modes.c rename to sys/dev/drm/drm_modes.c index 292a2283f2..0b85e2eef9 100644 --- a/sys/dev/drm2/drm_modes.c +++ b/sys/dev/drm/drm_modes.c @@ -32,9 +32,9 @@ * $FreeBSD: src/sys/dev/drm2/drm_modes.c,v 1.1 2012/05/22 11:07:44 kib Exp $ */ -#include -#include -#include +#include +#include +#include #define KHZ2PICOS(a) (1000000000UL/(a)) diff --git a/sys/dev/drm/drm_pci.c b/sys/dev/drm/drm_pci.c index 104ed23cbc..0daf8db5b4 100644 --- a/sys/dev/drm/drm_pci.c +++ b/sys/dev/drm/drm_pci.c @@ -19,6 +19,8 @@ * AUTHOR 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. + * + * $FreeBSD: src/sys/dev/drm2/drm_pci.c,v 1.1 2012/05/22 11:07:44 kib Exp $ */ /** @@ -64,7 +66,7 @@ drm_pci_alloc(struct drm_device *dev, size_t size, return NULL; } - dmah = malloc(sizeof(drm_dma_handle_t), DRM_MEM_DMA, M_ZERO | M_NOWAIT); + dmah = kmalloc(sizeof(drm_dma_handle_t), DRM_MEM_DMA, M_ZERO | M_NOWAIT); if (dmah == NULL) return NULL; @@ -82,19 +84,18 @@ drm_pci_alloc(struct drm_device *dev, size_t size, maxaddr, BUS_SPACE_MAXADDR, /* lowaddr, highaddr */ NULL, NULL, /* filtfunc, filtfuncargs */ size, 1, size, /* maxsize, nsegs, maxsegsize */ - 0, /* flags */ + 0, /* flags */ &dmah->tag); if (ret != 0) { - free(dmah, DRM_MEM_DMA); + drm_free(dmah, DRM_MEM_DMA); return NULL; } - /* XXX BUS_DMA_NOCACHE */ ret = bus_dmamem_alloc(dmah->tag, &dmah->vaddr, - BUS_DMA_WAITOK | BUS_DMA_ZERO, &dmah->map); + BUS_DMA_WAITOK | BUS_DMA_ZERO | BUS_DMA_NOCACHE, &dmah->map); if (ret != 0) { bus_dma_tag_destroy(dmah->tag); - free(dmah, DRM_MEM_DMA); + drm_free(dmah, DRM_MEM_DMA); return NULL; } @@ -103,7 +104,7 @@ drm_pci_alloc(struct drm_device *dev, size_t size, if (ret != 0) { bus_dmamem_free(dmah->tag, dmah->vaddr, dmah->map); bus_dma_tag_destroy(dmah->tag); - free(dmah, DRM_MEM_DMA); + drm_free(dmah, DRM_MEM_DMA); return NULL; } @@ -122,7 +123,7 @@ drm_pci_free(struct drm_device *dev, drm_dma_handle_t *dmah) bus_dmamem_free(dmah->tag, dmah->vaddr, dmah->map); bus_dma_tag_destroy(dmah->tag); - free(dmah, DRM_MEM_DMA); + drm_free(dmah, DRM_MEM_DMA); } /*@}*/ diff --git a/sys/dev/drm/drm_pciids.h b/sys/dev/drm/drm_pciids.h index 7327708b8c..d4125b554c 100644 --- a/sys/dev/drm/drm_pciids.h +++ b/sys/dev/drm/drm_pciids.h @@ -1,5 +1,5 @@ /* - * $FreeBSD: src/sys/dev/drm/drm_pciids.h,v 1.21 2010/03/13 11:51:18 rnoland Exp $ + * $FreeBSD: head/sys/dev/drm2/drm_pciids.h 237411 2012-06-21 22:06:57Z emaste $ */ /* This file is auto-generated from the drm_pciids.txt in the DRM CVS @@ -533,6 +533,7 @@ {0x8086, 0x3577, CHIP_I8XX, "Intel i830M GMCH"}, \ {0x8086, 0x2562, CHIP_I8XX, "Intel i845G GMCH"}, \ {0x8086, 0x3582, CHIP_I8XX, "Intel i852GM/i855GM GMCH"}, \ + {0x8086, 0x358e, CHIP_I8XX, "Intel i852GM/i855GM GMCH"}, \ {0x8086, 0x2572, CHIP_I8XX, "Intel i865G GMCH"}, \ {0x8086, 0x2582, CHIP_I9XX|CHIP_I915, "Intel i915G"}, \ {0x8086, 0x258a, CHIP_I9XX|CHIP_I915, "Intel E7221 (i915)"}, \ @@ -544,18 +545,35 @@ {0x8086, 0x2982, CHIP_I9XX|CHIP_I965, "Intel i965G"}, \ {0x8086, 0x2992, CHIP_I9XX|CHIP_I965, "Intel i965Q"}, \ {0x8086, 0x29A2, CHIP_I9XX|CHIP_I965, "Intel i965G"}, \ - {0x8086, 0x2A02, CHIP_I9XX|CHIP_I965, "Intel i965GM"}, \ - {0x8086, 0x2A12, CHIP_I9XX|CHIP_I965, "Intel i965GME/GLE"}, \ - {0x8086, 0x29C2, CHIP_I9XX|CHIP_I915, "Intel G33"}, \ {0x8086, 0x29B2, CHIP_I9XX|CHIP_I915, "Intel Q35"}, \ + {0x8086, 0x29C2, CHIP_I9XX|CHIP_I915, "Intel G33"}, \ {0x8086, 0x29D2, CHIP_I9XX|CHIP_I915, "Intel Q33"}, \ + {0x8086, 0x2A02, CHIP_I9XX|CHIP_I965, "Intel i965GM"}, \ + {0x8086, 0x2A12, CHIP_I9XX|CHIP_I965, "Intel i965GME/GLE"}, \ {0x8086, 0x2A42, CHIP_I9XX|CHIP_I965, "Mobile Intel® GM45 Express Chipset"}, \ {0x8086, 0x2E02, CHIP_I9XX|CHIP_I965, "Intel Eaglelake"}, \ - {0x8086, 0xA001, CHIP_I9XX|CHIP_I965, "Intel Pineview"}, \ - {0x8086, 0xA011, CHIP_I9XX|CHIP_I965, "Intel Pineview (M)"}, \ {0x8086, 0x2E12, CHIP_I9XX|CHIP_I965, "Intel Q45/Q43"}, \ {0x8086, 0x2E22, CHIP_I9XX|CHIP_I965, "Intel G45/G43"}, \ {0x8086, 0x2E32, CHIP_I9XX|CHIP_I965, "Intel G41"}, \ + {0x8086, 0x2e42, CHIP_I9XX|CHIP_I915, "Intel G43 ?"}, \ + {0x8086, 0x2e92, CHIP_I9XX|CHIP_I915, "Intel G43 ?"}, \ + {0x8086, 0x0042, CHIP_I9XX|CHIP_I915, "Intel IronLake"}, \ + {0x8086, 0x0046, CHIP_I9XX|CHIP_I915, "Intel IronLake"}, \ + {0x8086, 0x0102, CHIP_I9XX|CHIP_I915, "Intel SandyBridge"}, \ + {0x8086, 0x0112, CHIP_I9XX|CHIP_I915, "Intel SandyBridge"}, \ + {0x8086, 0x0122, CHIP_I9XX|CHIP_I915, "Intel SandyBridge"}, \ + {0x8086, 0x0106, CHIP_I9XX|CHIP_I915, "Intel SandyBridge (M)"}, \ + {0x8086, 0x0116, CHIP_I9XX|CHIP_I915, "Intel SandyBridge (M)"}, \ + {0x8086, 0x0126, CHIP_I9XX|CHIP_I915, "Intel SandyBridge (M)"}, \ + {0x8086, 0x010A, CHIP_I9XX|CHIP_I915, "Intel SandyBridge (M)"}, \ + {0x8086, 0x0152, CHIP_I9XX|CHIP_I915, "Intel IvyBridge"}, \ + {0x8086, 0x0162, CHIP_I9XX|CHIP_I915, "Intel IvyBridge"}, \ + {0x8086, 0x0156, CHIP_I9XX|CHIP_I915, "Intel IvyBridge (M)"}, \ + {0x8086, 0x0166, CHIP_I9XX|CHIP_I915, "Intel IvyBridge (M)"}, \ + {0x8086, 0x015A, CHIP_I9XX|CHIP_I915, "Intel IvyBridge (S)"}, \ + {0x8086, 0x016A, CHIP_I9XX|CHIP_I915, "Intel IvyBridge (S)"}, \ + {0x8086, 0xA001, CHIP_I9XX|CHIP_I965, "Intel Pineview"}, \ + {0x8086, 0xA011, CHIP_I9XX|CHIP_I965, "Intel Pineview (M)"}, \ {0, 0, 0, NULL} #define imagine_PCI_IDS \ diff --git a/sys/dev/drm/drm_scatter.c b/sys/dev/drm/drm_scatter.c index 9c2f84969f..2e89d378fb 100644 --- a/sys/dev/drm/drm_scatter.c +++ b/sys/dev/drm/drm_scatter.c @@ -20,11 +20,12 @@ * 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. + * + * $FreeBSD: src/sys/dev/drm2/drm_scatter.c,v 1.1 2012/05/22 11:07:44 kib Exp $ */ /** @file drm_scatter.c * Allocation of memory for scatter-gather mappings by the graphics chip. - * * The memory allocated here is then made into an aperture in the card * by mapping the pages into the GART. */ @@ -43,11 +44,11 @@ drm_sg_alloc(struct drm_device *dev, struct drm_scatter_gather *request) DRM_DEBUG("request size=%ld\n", request->size); - entry = malloc(sizeof(*entry), DRM_MEM_DRIVER, M_WAITOK | M_ZERO); + entry = kmalloc(sizeof(*entry), DRM_MEM_DRIVER, M_WAITOK | M_ZERO); size = round_page(request->size); entry->pages = OFF_TO_IDX(size); - entry->busaddr = malloc(entry->pages * sizeof(*entry->busaddr), + entry->busaddr = kmalloc(entry->pages * sizeof(*entry->busaddr), DRM_MEM_SGLISTS, M_WAITOK | M_ZERO); entry->vaddr = kmem_alloc_attr(&kernel_map, size, M_WAITOK | M_ZERO, @@ -62,19 +63,20 @@ drm_sg_alloc(struct drm_device *dev, struct drm_scatter_gather *request) vtophys(entry->vaddr + IDX_TO_OFF(pindex)); } - DRM_LOCK(); + DRM_LOCK(dev); if (dev->sg) { - DRM_UNLOCK(); + DRM_UNLOCK(dev); drm_sg_cleanup(entry); return (EINVAL); } dev->sg = entry; - DRM_UNLOCK(); + DRM_UNLOCK(dev); request->handle = entry->vaddr; - DRM_DEBUG("allocated %ju pages @ 0x%08zx, contents=%08lx\n", - entry->pages, entry->vaddr, *(unsigned long *)entry->vaddr); + DRM_DEBUG("allocated %ju pages @ 0x%08jx, contents=%08lx\n", + entry->pages, (uintmax_t)entry->vaddr, + *(unsigned long *)entry->vaddr); return (0); } @@ -99,8 +101,8 @@ drm_sg_cleanup(struct drm_sg_mem *entry) if (entry->vaddr != 0) kmem_free(&kernel_map, entry->vaddr, IDX_TO_OFF(entry->pages)); - free(entry->busaddr, DRM_MEM_SGLISTS); - free(entry, DRM_MEM_DRIVER); + drm_free(entry->busaddr, DRM_MEM_SGLISTS); + drm_free(entry, DRM_MEM_DRIVER); return; } @@ -111,15 +113,15 @@ drm_sg_free(struct drm_device *dev, void *data, struct drm_file *file_priv) struct drm_scatter_gather *request = data; struct drm_sg_mem *entry; - DRM_LOCK(); + DRM_LOCK(dev); entry = dev->sg; dev->sg = NULL; - DRM_UNLOCK(); + DRM_UNLOCK(dev); if (!entry || entry->vaddr != request->handle) return (EINVAL); - DRM_DEBUG("free 0x%zx\n", entry->vaddr); + DRM_DEBUG("free 0x%jx\n", (uintmax_t)entry->vaddr); drm_sg_cleanup(entry); diff --git a/sys/dev/drm/drm_sman.c b/sys/dev/drm/drm_sman.c index 3117f4c324..3b00f72fcc 100644 --- a/sys/dev/drm/drm_sman.c +++ b/sys/dev/drm/drm_sman.c @@ -24,7 +24,7 @@ * of the Software. * * - * $FreeBSD: src/sys/dev/drm/drm_sman.c,v 1.1 2010/01/31 14:25:29 rnoland Exp $ + * $FreeBSD: src/sys/dev/drm2/drm_sman.c,v 1.1 2012/05/22 11:07:44 kib Exp $ **************************************************************************/ /* @@ -52,8 +52,7 @@ void drm_sman_takedown(struct drm_sman * sman) drm_ht_remove(&sman->user_hash_tab); drm_ht_remove(&sman->owner_hash_tab); if (sman->mm) - drm_free(sman->mm, sman->num_managers * sizeof(*sman->mm), - DRM_MEM_MM); + drm_free(sman->mm, DRM_MEM_MM); } int @@ -79,7 +78,7 @@ drm_sman_init(struct drm_sman * sman, unsigned int num_managers, drm_ht_remove(&sman->owner_hash_tab); out1: - drm_free(sman->mm, num_managers * sizeof(*sman->mm), DRM_MEM_MM); + drm_free(sman->mm, DRM_MEM_MM); out: return ret; } @@ -110,7 +109,7 @@ static void drm_sman_mm_destroy(void *private) { struct drm_mm *mm = (struct drm_mm *) private; drm_mm_takedown(mm); - drm_free(mm, sizeof(*mm), DRM_MEM_MM); + drm_free(mm, DRM_MEM_MM); } static unsigned long drm_sman_mm_offset(void *private, void *ref) @@ -130,7 +129,7 @@ drm_sman_set_range(struct drm_sman * sman, unsigned int manager, KASSERT(manager < sman->num_managers, ("Invalid manager")); sman_mm = &sman->mm[manager]; - mm = malloc(sizeof(*mm), DRM_MEM_MM, M_NOWAIT | M_ZERO); + mm = kmalloc(sizeof(*mm), DRM_MEM_MM, M_NOWAIT | M_ZERO); if (!mm) { return -ENOMEM; } @@ -138,7 +137,7 @@ drm_sman_set_range(struct drm_sman * sman, unsigned int manager, ret = drm_mm_init(mm, start, size); if (ret) { - drm_free(mm, sizeof(*mm), DRM_MEM_MM); + drm_free(mm, DRM_MEM_MM); return ret; } @@ -173,7 +172,7 @@ static struct drm_owner_item *drm_sman_get_owner_item(struct drm_sman * sman, owner_hash); } - owner_item = malloc(sizeof(*owner_item), DRM_MEM_MM, M_NOWAIT | M_ZERO); + owner_item = kmalloc(sizeof(*owner_item), DRM_MEM_MM, M_NOWAIT | M_ZERO); if (!owner_item) goto out; @@ -187,7 +186,7 @@ static struct drm_owner_item *drm_sman_get_owner_item(struct drm_sman * sman, return owner_item; out1: - drm_free(owner_item, sizeof(*owner_item), DRM_MEM_MM); + drm_free(owner_item, DRM_MEM_MM); out: return NULL; } @@ -209,7 +208,7 @@ struct drm_memblock_item *drm_sman_alloc(struct drm_sman *sman, unsigned int man return NULL; } - memblock = malloc(sizeof(*memblock), DRM_MEM_MM, M_NOWAIT | M_ZERO); + memblock = kmalloc(sizeof(*memblock), DRM_MEM_MM, M_NOWAIT | M_ZERO); DRM_DEBUG("allocated mem_block %p\n", memblock); if (!memblock) goto out; @@ -239,7 +238,7 @@ struct drm_memblock_item *drm_sman_alloc(struct drm_sman *sman, unsigned int man out2: drm_ht_remove_item(&sman->user_hash_tab, &memblock->user_hash); out1: - drm_free(memblock, sizeof(*memblock), DRM_MEM_MM); + drm_free(memblock, DRM_MEM_MM); out: sman_mm->free(sman_mm->private, tmp); @@ -253,7 +252,7 @@ static void drm_sman_free(struct drm_memblock_item *item) list_del(&item->owner_list); drm_ht_remove_item(&sman->user_hash_tab, &item->user_hash); item->mm->free(item->mm->private, item->mm_info); - drm_free(item, sizeof(*item), DRM_MEM_MM); + drm_free(item, DRM_MEM_MM); } int drm_sman_free_key(struct drm_sman *sman, unsigned int key) @@ -275,7 +274,7 @@ static void drm_sman_remove_owner(struct drm_sman *sman, { list_del(&owner_item->sman_list); drm_ht_remove_item(&sman->owner_hash_tab, &owner_item->owner_hash); - drm_free(owner_item, sizeof(*owner_item), DRM_MEM_MM); + drm_free(owner_item, DRM_MEM_MM); } int drm_sman_owner_clean(struct drm_sman *sman, unsigned long owner) diff --git a/sys/dev/drm2/drm_stub.c b/sys/dev/drm/drm_stub.c similarity index 100% rename from sys/dev/drm2/drm_stub.c rename to sys/dev/drm/drm_stub.c diff --git a/sys/dev/drm/drm_sysctl.c b/sys/dev/drm/drm_sysctl.c index c3d87413ea..bea36e22b0 100644 --- a/sys/dev/drm/drm_sysctl.c +++ b/sys/dev/drm/drm_sysctl.c @@ -19,6 +19,8 @@ * ERIC ANHOLT 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. + * + * $FreeBSD: src/sys/dev/drm2/drm_sysctl.c,v 1.1 2012/05/22 11:07:44 kib Exp $ */ /** @file drm_sysctl.c @@ -26,11 +28,13 @@ * debug information. */ +#include +#include +#include + #include "dev/drm/drmP.h" #include "dev/drm/drm.h" -#include - static int drm_name_info DRM_SYSCTL_HANDLER_ARGS; static int drm_vm_info DRM_SYSCTL_HANDLER_ARGS; static int drm_clients_info DRM_SYSCTL_HANDLER_ARGS; @@ -61,13 +65,14 @@ int drm_sysctl_init(struct drm_device *dev) struct sysctl_oid *top, *drioid; int i; - info = malloc(sizeof *info, DRM_MEM_DRIVER, M_WAITOK | M_ZERO); + info = kmalloc(sizeof *info, DRM_MEM_DRIVER, M_WAITOK | M_ZERO); if ( !info ) return 1; dev->sysctl = info; /* Add the sysctl node for DRI if it doesn't already exist */ - drioid = SYSCTL_ADD_NODE( &info->ctx, &sysctl__hw_children, OID_AUTO, "dri", CTLFLAG_RW, NULL, "DRI Graphics"); + drioid = SYSCTL_ADD_NODE(&info->ctx, &sysctl__hw_children, OID_AUTO, + "dri", CTLFLAG_RW, NULL, "DRI Graphics"); if (!drioid) return 1; @@ -80,48 +85,67 @@ int drm_sysctl_init(struct drm_device *dev) if (i>9) return 1; + dev->sysctl_node_idx = i; /* Add the hw.dri.x for our device */ info->name[0] = '0' + i; info->name[1] = 0; - top = SYSCTL_ADD_NODE( &info->ctx, SYSCTL_CHILDREN(drioid), OID_AUTO, info->name, CTLFLAG_RW, NULL, NULL); + top = SYSCTL_ADD_NODE(&info->ctx, SYSCTL_CHILDREN(drioid), + OID_AUTO, info->name, CTLFLAG_RW, NULL, NULL); if (!top) return 1; for (i = 0; i < DRM_SYSCTL_ENTRIES; i++) { - oid = SYSCTL_ADD_OID(&info->ctx, - SYSCTL_CHILDREN(top), - OID_AUTO, - drm_sysctl_list[i].name, - CTLTYPE_STRING | CTLFLAG_RD, - dev, - 0, - drm_sysctl_list[i].f, - "A", + oid = SYSCTL_ADD_OID(&info->ctx, + SYSCTL_CHILDREN(top), + OID_AUTO, + drm_sysctl_list[i].name, + CTLTYPE_STRING | CTLFLAG_RD, + dev, + 0, + drm_sysctl_list[i].f, + "A", NULL); if (!oid) return 1; } - SYSCTL_ADD_INT(&info->ctx, SYSCTL_CHILDREN(top), OID_AUTO, "debug", + SYSCTL_ADD_INT(&info->ctx, SYSCTL_CHILDREN(drioid), OID_AUTO, "debug", CTLFLAG_RW, &drm_debug_flag, sizeof(drm_debug_flag), "Enable debugging output"); - - return 0; + SYSCTL_ADD_INT(&info->ctx, SYSCTL_CHILDREN(drioid), OID_AUTO, "notyet", + CTLFLAG_RW, &drm_notyet_flag, sizeof(drm_debug_flag), + "Enable notyet reminders"); + + if (dev->driver->sysctl_init != NULL) + dev->driver->sysctl_init(dev, &info->ctx, top); + + SYSCTL_ADD_INT(&info->ctx, SYSCTL_CHILDREN(drioid), OID_AUTO, + "vblank_offdelay", CTLFLAG_RW, &drm_vblank_offdelay, + sizeof(drm_vblank_offdelay), + ""); + SYSCTL_ADD_INT(&info->ctx, SYSCTL_CHILDREN(drioid), OID_AUTO, + "timestamp_precision", CTLFLAG_RW, &drm_timestamp_precision, + sizeof(drm_timestamp_precision), + ""); + + return (0); } int drm_sysctl_cleanup(struct drm_device *dev) { int error; - error = sysctl_ctx_free( &dev->sysctl->ctx ); - free(dev->sysctl, DRM_MEM_DRIVER); + error = sysctl_ctx_free(&dev->sysctl->ctx); + drm_free(dev->sysctl, DRM_MEM_DRIVER); dev->sysctl = NULL; + if (dev->driver->sysctl_cleanup != NULL) + dev->driver->sysctl_cleanup(dev); - return error; + return (error); } #define DRM_SYSCTL_PRINT(fmt, arg...) \ do { \ - snprintf(buf, sizeof(buf), fmt, ##arg); \ + ksnprintf(buf, sizeof(buf), fmt, ##arg); \ retcode = SYSCTL_OUT(req, buf, strlen(buf)); \ if (retcode) \ goto done; \ @@ -136,12 +160,12 @@ static int drm_name_info DRM_SYSCTL_HANDLER_ARGS DRM_SYSCTL_PRINT("%s 0x%x", dev->driver->name, dev2udev(dev->devnode)); - DRM_LOCK(); + DRM_LOCK(dev); if (dev->unique) { - snprintf(buf, sizeof(buf), " %s", dev->unique); + ksnprintf(buf, sizeof(buf), " %s", dev->unique); hasunique = 1; } - DRM_UNLOCK(); + DRM_UNLOCK(dev); if (hasunique) SYSCTL_OUT(req, buf, strlen(buf)); @@ -165,16 +189,16 @@ static int drm_vm_info DRM_SYSCTL_HANDLER_ARGS /* We can't hold the lock while doing SYSCTL_OUTs, so allocate a * temporary copy of all the map entries and then SYSCTL_OUT that. */ - DRM_LOCK(); + DRM_LOCK(dev); mapcount = 0; TAILQ_FOREACH(map, &dev->maplist, link) mapcount++; - tempmaps = malloc(sizeof(drm_local_map_t) * mapcount, DRM_MEM_DRIVER, + tempmaps = kmalloc(sizeof(drm_local_map_t) * mapcount, DRM_MEM_DRIVER, M_NOWAIT); if (tempmaps == NULL) { - DRM_UNLOCK(); + DRM_UNLOCK(dev); return ENOMEM; } @@ -182,7 +206,7 @@ static int drm_vm_info DRM_SYSCTL_HANDLER_ARGS TAILQ_FOREACH(map, &dev->maplist, link) tempmaps[i++] = *map; - DRM_UNLOCK(); + DRM_UNLOCK(dev); DRM_SYSCTL_PRINT("\nslot offset size " "type flags address handle mtrr\n"); @@ -210,7 +234,7 @@ static int drm_vm_info DRM_SYSCTL_HANDLER_ARGS SYSCTL_OUT(req, "", 1); done: - free(tempmaps, DRM_MEM_DRIVER); + drm_free(tempmaps, DRM_MEM_DRIVER); return retcode; } @@ -227,20 +251,20 @@ static int drm_bufs_info DRM_SYSCTL_HANDLER_ARGS /* We can't hold the locks around DRM_SYSCTL_PRINT, so make a temporary * copy of the whole structure and the relevant data from buflist. */ - DRM_LOCK(); + DRM_LOCK(dev); if (dma == NULL) { - DRM_UNLOCK(); + DRM_UNLOCK(dev); return 0; } - DRM_SPINLOCK(&dev->dma_lock); + spin_lock(&dev->dma_lock); tempdma = *dma; - templists = malloc(sizeof(int) * dma->buf_count, DRM_MEM_DRIVER, + templists = kmalloc(sizeof(int) * dma->buf_count, DRM_MEM_DRIVER, M_NOWAIT); for (i = 0; i < dma->buf_count; i++) templists[i] = dma->buflist[i]->list; dma = &tempdma; - DRM_SPINUNLOCK(&dev->dma_lock); - DRM_UNLOCK(); + spin_unlock(&dev->dma_lock); + DRM_UNLOCK(dev); DRM_SYSCTL_PRINT("\n o size count free segs pages kB\n"); for (i = 0; i <= DRM_MAX_ORDER; i++) { @@ -256,7 +280,7 @@ static int drm_bufs_info DRM_SYSCTL_HANDLER_ARGS *(1 << dma->bufs[i].page_order), (dma->bufs[i].seg_count * (1 << dma->bufs[i].page_order)) - * PAGE_SIZE / 1024); + * (int)PAGE_SIZE / 1024); } DRM_SYSCTL_PRINT("\n"); for (i = 0; i < dma->buf_count; i++) { @@ -267,7 +291,7 @@ static int drm_bufs_info DRM_SYSCTL_HANDLER_ARGS SYSCTL_OUT(req, "", 1); done: - free(templists, DRM_MEM_DRIVER); + drm_free(templists, DRM_MEM_DRIVER); return retcode; } @@ -279,30 +303,31 @@ static int drm_clients_info DRM_SYSCTL_HANDLER_ARGS int retcode; int privcount, i; - DRM_LOCK(); + DRM_LOCK(dev); privcount = 0; TAILQ_FOREACH(priv, &dev->files, link) privcount++; - tempprivs = malloc(sizeof(struct drm_file) * privcount, DRM_MEM_DRIVER, + tempprivs = kmalloc(sizeof(struct drm_file) * privcount, DRM_MEM_DRIVER, M_NOWAIT); if (tempprivs == NULL) { - DRM_UNLOCK(); + DRM_UNLOCK(dev); return ENOMEM; } i = 0; TAILQ_FOREACH(priv, &dev->files, link) tempprivs[i++] = *priv; - DRM_UNLOCK(); + DRM_UNLOCK(dev); - DRM_SYSCTL_PRINT("\na dev pid uid magic ioctls\n"); + DRM_SYSCTL_PRINT( + "\na dev pid uid magic ioctls\n"); for (i = 0; i < privcount; i++) { priv = &tempprivs[i]; - DRM_SYSCTL_PRINT("%c %3d %5d %5d %10u %10lu\n", + DRM_SYSCTL_PRINT("%c %-12s %5d %5d %10u %10lu\n", priv->authenticated ? 'y' : 'n', - priv->minor, + devtoname(priv->dev->devnode), priv->pid, priv->uid, priv->magic, @@ -311,7 +336,7 @@ static int drm_clients_info DRM_SYSCTL_HANDLER_ARGS SYSCTL_OUT(req, "", 1); done: - free(tempprivs, DRM_MEM_DRIVER); + drm_free(tempprivs, DRM_MEM_DRIVER); return retcode; } @@ -323,16 +348,20 @@ static int drm_vblank_info DRM_SYSCTL_HANDLER_ARGS int i; DRM_SYSCTL_PRINT("\ncrtc ref count last enabled inmodeset\n"); - for(i = 0 ; i < dev->num_crtcs ; i++) { + DRM_LOCK(dev); + if (dev->_vblank_count == NULL) + goto done; + for (i = 0 ; i < dev->num_crtcs ; i++) { DRM_SYSCTL_PRINT(" %02d %02d %08d %08d %02d %02d\n", - i, atomic_load_acq_32(&dev->vblank[i].refcount), - atomic_load_acq_32(&dev->vblank[i].count), - atomic_load_acq_32(&dev->vblank[i].last), - atomic_load_acq_int(&dev->vblank[i].enabled), - atomic_load_acq_int(&dev->vblank[i].inmodeset)); + i, dev->vblank_refcount[i], + dev->_vblank_count[i], + dev->last_vblank[i], + dev->vblank_enabled[i], + dev->vblank_inmodeset[i]); } +done: + DRM_UNLOCK(dev); SYSCTL_OUT(req, "", -1); -done: return retcode; } diff --git a/sys/dev/drm/drm_vm.c b/sys/dev/drm/drm_vm.c index 13a1c7bae0..b0c7bc526c 100644 --- a/sys/dev/drm/drm_vm.c +++ b/sys/dev/drm/drm_vm.c @@ -19,12 +19,19 @@ * ERIC ANHOLT 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. + * + * $FreeBSD: head/sys/dev/drm2/drm_vm.c 235783 2012-05-22 11:07:44Z kib $" */ /** @file drm_vm.c * Support code for mmaping of DRM maps. */ +#include +#include +#include +#include + #include "dev/drm/drmP.h" #include "dev/drm/drm.h" @@ -38,32 +45,38 @@ int drm_mmap(struct dev_mmap_args *ap) enum drm_map_type type; vm_paddr_t phys; - DRM_LOCK(); - file_priv = drm_find_file_by_proc(dev, DRM_CURPROC); - DRM_UNLOCK(); + /* d_mmap gets called twice, we can only reference file_priv during + * the first call. We need to assume that if error is EBADF the + * call was succesful and the client is authenticated. + */ + DRM_LOCK(dev); + file_priv = drm_find_file_by_proc(dev, curthread); + DRM_UNLOCK(dev); - if (file_priv == NULL) { - DRM_ERROR("can't find authenticator\n"); - return EINVAL; - } + if (!file_priv) { + DRM_ERROR("Could not find authenticator!\n"); + return EINVAL; + } - if (!file_priv->authenticated) - return EACCES; + if (!file_priv->authenticated) + return EACCES; - DRM_DEBUG("called with offset %016jx\n", offset); + DRM_DEBUG("called with offset %016jx\n", (uintmax_t)offset); if (dev->dma && offset < ptoa(dev->dma->page_count)) { drm_device_dma_t *dma = dev->dma; - DRM_SPINLOCK(&dev->dma_lock); + spin_lock(&dev->dma_lock); if (dma->pagelist != NULL) { unsigned long page = offset >> PAGE_SHIFT; unsigned long phys = dma->pagelist[page]; - ap->a_result = atop(phys); - DRM_SPINUNLOCK(&dev->dma_lock); + + spin_unlock(&dev->dma_lock); + // XXX *paddr = phys; + ap->a_result = phys; return 0; } else { - DRM_SPINUNLOCK(&dev->dma_lock); + spin_unlock(&dev->dma_lock); return -1; } } @@ -76,7 +89,7 @@ int drm_mmap(struct dev_mmap_args *ap) for performance, even if the list was a bit longer. */ - DRM_LOCK(); + DRM_LOCK(dev); TAILQ_FOREACH(map, &dev->maplist, link) { if (offset >> DRM_MAP_HANDLE_SHIFT == (unsigned long)map->handle >> DRM_MAP_HANDLE_SHIFT) @@ -84,21 +97,22 @@ int drm_mmap(struct dev_mmap_args *ap) } if (map == NULL) { - DRM_DEBUG("Can't find map, request offset = %016jx\n", offset); + DRM_DEBUG("Can't find map, request offset = %016jx\n", + (uintmax_t)offset); TAILQ_FOREACH(map, &dev->maplist, link) { DRM_DEBUG("map offset = %016lx, handle = %016lx\n", map->offset, (unsigned long)map->handle); } - DRM_UNLOCK(); + DRM_UNLOCK(dev); return -1; } if (((map->flags & _DRM_RESTRICTED) && !DRM_SUSER(DRM_CURPROC))) { - DRM_UNLOCK(); + DRM_UNLOCK(dev); DRM_DEBUG("restricted map\n"); return -1; } type = map->type; - DRM_UNLOCK(); + DRM_UNLOCK(dev); offset = offset & ((1ULL << DRM_MAP_HANDLE_SHIFT) - 1); @@ -130,3 +144,85 @@ int drm_mmap(struct dev_mmap_args *ap) return 0; } +/* XXX The following is just temporary hack to replace the + * vm_phys_fictitious functions available on FreeBSD + */ +#define VM_PHYS_FICTITIOUS_NSEGS 8 +static struct vm_phys_fictitious_seg { + vm_paddr_t start; + vm_paddr_t end; + vm_page_t first_page; +} vm_phys_fictitious_segs[VM_PHYS_FICTITIOUS_NSEGS]; +static struct mtx vm_phys_fictitious_reg_mtx = MTX_INITIALIZER; + +vm_page_t +vm_phys_fictitious_to_vm_page(vm_paddr_t pa) +{ + struct vm_phys_fictitious_seg *seg; + vm_page_t m; + int segind; + + m = NULL; + for (segind = 0; segind < VM_PHYS_FICTITIOUS_NSEGS; segind++) { + seg = &vm_phys_fictitious_segs[segind]; + if (pa >= seg->start && pa < seg->end) { + m = &seg->first_page[atop(pa - seg->start)]; + KASSERT((m->flags & PG_FICTITIOUS) != 0, + ("%p not fictitious", m)); + break; + } + } + return (m); +} + +static void page_init(vm_page_t m, vm_paddr_t paddr, int pat_mode) +{ + bzero(m, sizeof(*m)); + + pmap_page_init(m); + + //m->flags = PG_BUSY | PG_FICTITIOUS; + m->flags = PG_FICTITIOUS; + m->valid = VM_PAGE_BITS_ALL; + m->dirty = 0; + m->busy = 0; + m->queue = PQ_NONE; + m->object = NULL; + m->pat_mode = pat_mode; + + m->wire_count = 1; + m->hold_count = 0; + m->phys_addr = paddr; +} + +int +vm_phys_fictitious_reg_range(vm_paddr_t start, vm_paddr_t end, int pat_mode) +{ + struct vm_phys_fictitious_seg *seg; + vm_page_t fp; + long i, page_count; + int segind; + + page_count = (end - start) / PAGE_SIZE; + + fp = kmalloc(page_count * sizeof(struct vm_page), DRM_MEM_DRIVER, + M_WAITOK | M_ZERO); + + for (i = 0; i < page_count; i++) { + page_init(&fp[i], start + PAGE_SIZE * i, pat_mode); + } + mtx_lock(&vm_phys_fictitious_reg_mtx); + for (segind = 0; segind < VM_PHYS_FICTITIOUS_NSEGS; segind++) { + seg = &vm_phys_fictitious_segs[segind]; + if (seg->start == 0 && seg->end == 0) { + seg->start = start; + seg->end = end; + seg->first_page = fp; + mtx_unlock(&vm_phys_fictitious_reg_mtx); + return (0); + } + } + mtx_unlock(&vm_phys_fictitious_reg_mtx); + drm_free(fp, DRM_MEM_DRIVER); + return (EBUSY); +} diff --git a/sys/dev/drm/i915/i915_dma.c b/sys/dev/drm/i915/i915_dma.c index 10a594453a..5bb119b873 100644 --- a/sys/dev/drm/i915/i915_dma.c +++ b/sys/dev/drm/i915/i915_dma.c @@ -81,10 +81,10 @@ static int i915_init_phys_hws(struct drm_device *dev) drm_i915_private_t *dev_priv = dev->dev_private; /* Program Hardware Status Page */ - DRM_UNLOCK(); + DRM_UNLOCK(dev); dev_priv->status_page_dmah = drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff); - DRM_LOCK(); + DRM_LOCK(dev); if (!dev_priv->status_page_dmah) { DRM_ERROR("Can not allocate hardware status page\n"); return -ENOMEM; @@ -626,11 +626,11 @@ static int i915_batchbuffer(struct drm_device *dev, void *data, RING_LOCK_TEST_WITH_RETURN(dev, file_priv); - DRM_UNLOCK(); + DRM_UNLOCK(dev); cliplen = batch->num_cliprects * sizeof(struct drm_clip_rect); if (batch->num_cliprects && DRM_VERIFYAREA_READ(batch->cliprects, cliplen)) { - DRM_LOCK(); + DRM_LOCK(dev); return -EFAULT; } if (batch->num_cliprects) { @@ -645,7 +645,7 @@ static int i915_batchbuffer(struct drm_device *dev, void *data, if (sarea_priv) sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); - DRM_LOCK(); + DRM_LOCK(dev); return ret; } @@ -664,12 +664,12 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data, RING_LOCK_TEST_WITH_RETURN(dev, file_priv); - DRM_UNLOCK(); + DRM_UNLOCK(dev); cliplen = cmdbuf->num_cliprects * sizeof(struct drm_clip_rect); if (cmdbuf->num_cliprects && DRM_VERIFYAREA_READ(cmdbuf->cliprects, cliplen)) { DRM_ERROR("Fault accessing cliprects\n"); - DRM_LOCK(); + DRM_LOCK(dev); return -EFAULT; } if (cmdbuf->num_cliprects) { @@ -683,7 +683,7 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data, vsunlock((caddr_t)cmdbuf->buf, cmdbuf->sz); vsunlock((caddr_t)cmdbuf->cliprects, cliplen); } - DRM_LOCK(); + DRM_LOCK(dev); if (ret) { DRM_ERROR("i915_dispatch_cmdbuffer failed\n"); return ret; @@ -865,8 +865,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) ret = i915_init_phys_hws(dev); if (ret != 0) { drm_rmmap(dev, dev_priv->mmio_map); - drm_free(dev_priv, sizeof(struct drm_i915_private), - DRM_MEM_DRIVER); + drm_free(dev_priv, DRM_MEM_DRIVER); return ret; } } @@ -887,7 +886,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) intel_opregion_init(dev); #endif - DRM_SPININIT(&dev_priv->user_irq_lock, "userirq"); + spin_init(&dev_priv->user_irq_lock); dev_priv->user_irq_refcount = 0; ret = drm_vblank_init(dev, I915_NUM_PIPE); @@ -910,10 +909,9 @@ int i915_driver_unload(struct drm_device *dev) #ifdef __linux__ intel_opregion_free(dev); #endif - DRM_SPINUNINIT(&dev_priv->user_irq_lock); + spin_uninit(&dev_priv->user_irq_lock); - drm_free(dev->dev_private, sizeof(drm_i915_private_t), - DRM_MEM_DRIVER); + drm_free(dev->dev_private, DRM_MEM_DRIVER); return 0; } @@ -962,7 +960,7 @@ void i915_driver_postclose(struct drm_device *dev, struct drm_file *file_priv) { struct drm_i915_file_private *i915_file_priv = file_priv->driver_priv; - drm_free(i915_file_priv, sizeof(*i915_file_priv), DRM_MEM_FILES); + drm_free(i915_file_priv, DRM_MEM_FILES); } struct drm_ioctl_desc i915_ioctls[] = { diff --git a/sys/dev/drm/i915/i915_drv.c b/sys/dev/drm/i915/i915_drv.c index 4bda988ad4..4fb515037d 100644 --- a/sys/dev/drm/i915/i915_drv.c +++ b/sys/dev/drm/i915/i915_drv.c @@ -50,10 +50,10 @@ static int i915_suspend(device_t kdev) return -ENODEV; } - DRM_LOCK(); + DRM_LOCK(dev); DRM_DEBUG("starting suspend\n"); i915_save_state(dev); - DRM_UNLOCK(); + DRM_UNLOCK(dev); return (bus_generic_suspend(kdev)); } @@ -62,10 +62,10 @@ static int i915_resume(device_t kdev) { struct drm_device *dev = device_get_softc(kdev); - DRM_LOCK(); + DRM_LOCK(dev); i915_restore_state(dev); DRM_DEBUG("finished resume\n"); - DRM_UNLOCK(); + DRM_UNLOCK(dev); return (bus_generic_resume(kdev)); } @@ -111,7 +111,7 @@ i915_attach(device_t kdev) { struct drm_device *dev = device_get_softc(kdev); - dev->driver = malloc(sizeof(struct drm_driver_info), DRM_MEM_DRIVER, + dev->driver = kmalloc(sizeof(struct drm_driver_info), DRM_MEM_DRIVER, M_WAITOK | M_ZERO); i915_configure(dev); @@ -127,7 +127,7 @@ i915_detach(device_t kdev) ret = drm_detach(kdev); - free(dev->driver, DRM_MEM_DRIVER); + kfree(dev->driver, DRM_MEM_DRIVER); return ret; } diff --git a/sys/dev/drm/i915/i915_drv.h b/sys/dev/drm/i915/i915_drv.h index b6fb5289da..faa9b787d0 100644 --- a/sys/dev/drm/i915/i915_drv.h +++ b/sys/dev/drm/i915/i915_drv.h @@ -128,7 +128,7 @@ typedef struct drm_i915_private { wait_queue_head_t irq_queue; /** Protects user_irq_refcount and irq_mask_reg */ - DRM_SPINTYPE user_irq_lock; + struct spinlock user_irq_lock; /** Refcount for i915_user_irq_get() versus i915_user_irq_put(). */ int user_irq_refcount; /** Cached value of IER to avoid reads in updating the bitfield */ diff --git a/sys/dev/drm/i915/i915_irq.c b/sys/dev/drm/i915/i915_irq.c index a320d91f94..952b62e390 100644 --- a/sys/dev/drm/i915/i915_irq.c +++ b/sys/dev/drm/i915/i915_irq.c @@ -205,7 +205,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) * It doesn't set the bit in iir again, but it still produces * interrupts (for non-MSI). */ - DRM_SPINLOCK(&dev_priv->user_irq_lock); + spin_lock(&dev_priv->user_irq_lock); pipea_stats = I915_READ(PIPEASTAT); pipeb_stats = I915_READ(PIPEBSTAT); @@ -221,7 +221,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) I915_WRITE(PIPEBSTAT, pipeb_stats); irq_received = 1; } - DRM_SPINUNLOCK(&dev_priv->user_irq_lock); + spin_unlock(&dev_priv->user_irq_lock); if (!irq_received) break; @@ -294,10 +294,10 @@ void i915_user_irq_get(struct drm_device *dev) return; DRM_DEBUG("\n"); - DRM_SPINLOCK(&dev_priv->user_irq_lock); + spin_lock(&dev_priv->user_irq_lock); if (++dev_priv->user_irq_refcount == 1) i915_enable_irq(dev_priv, I915_USER_INTERRUPT); - DRM_SPINUNLOCK(&dev_priv->user_irq_lock); + spin_unlock(&dev_priv->user_irq_lock); } void i915_user_irq_put(struct drm_device *dev) @@ -307,11 +307,11 @@ void i915_user_irq_put(struct drm_device *dev) if (dev->irq_enabled == 0) return; - DRM_SPINLOCK(&dev_priv->user_irq_lock); + spin_lock(&dev_priv->user_irq_lock); KASSERT(dev_priv->user_irq_refcount > 0, ("invalid refcount")); if (--dev_priv->user_irq_refcount == 0) i915_disable_irq(dev_priv, I915_USER_INTERRUPT); - DRM_SPINUNLOCK(&dev_priv->user_irq_lock); + spin_unlock(&dev_priv->user_irq_lock); } static int i915_wait_irq(struct drm_device * dev, int irq_nr) @@ -401,14 +401,14 @@ int i915_enable_vblank(struct drm_device *dev, int pipe) if (!i915_pipe_enabled(dev, pipe)) return -EINVAL; - DRM_SPINLOCK(&dev_priv->user_irq_lock); + spin_lock(&dev_priv->user_irq_lock); if (IS_I965G(dev)) i915_enable_pipestat(dev_priv, pipe, PIPE_START_VBLANK_INTERRUPT_ENABLE); else i915_enable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_ENABLE); - DRM_SPINUNLOCK(&dev_priv->user_irq_lock); + spin_unlock(&dev_priv->user_irq_lock); return 0; } @@ -419,11 +419,11 @@ void i915_disable_vblank(struct drm_device *dev, int pipe) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - DRM_SPINLOCK(&dev_priv->user_irq_lock); + spin_lock(&dev_priv->user_irq_lock); i915_disable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_ENABLE | PIPE_START_VBLANK_INTERRUPT_ENABLE); - DRM_SPINUNLOCK(&dev_priv->user_irq_lock); + spin_unlock(&dev_priv->user_irq_lock); } /* Set the vblank monitor pipe diff --git a/sys/dev/drm/i915/i915_mem.c b/sys/dev/drm/i915/i915_mem.c index c23928175f..c925e6a75b 100644 --- a/sys/dev/drm/i915/i915_mem.c +++ b/sys/dev/drm/i915/i915_mem.c @@ -168,7 +168,7 @@ static void free_block(struct mem_block *p) p->size += q->size; p->next = q->next; p->next->prev = p; - drm_free(q, sizeof(*q), DRM_MEM_BUFLISTS); + drm_free(q, DRM_MEM_BUFLISTS); } if (p->prev->file_priv == NULL) { @@ -176,7 +176,7 @@ static void free_block(struct mem_block *p) q->size += p->size; q->next = p->next; q->next->prev = q; - drm_free(p, sizeof(*q), DRM_MEM_BUFLISTS); + drm_free(p, DRM_MEM_BUFLISTS); } } @@ -191,7 +191,7 @@ static int init_heap(struct mem_block **heap, int start, int size) *heap = drm_alloc(sizeof(**heap), DRM_MEM_BUFLISTS); if (!*heap) { - drm_free(blocks, sizeof(*blocks), DRM_MEM_BUFLISTS); + drm_free(blocks, DRM_MEM_BUFLISTS); return -ENOMEM; } @@ -232,7 +232,7 @@ void i915_mem_release(struct drm_device * dev, struct drm_file *file_priv, p->size += q->size; p->next = q->next; p->next->prev = p; - drm_free(q, sizeof(*q), DRM_MEM_BUFLISTS); + drm_free(q, DRM_MEM_BUFLISTS); } } } @@ -249,10 +249,10 @@ void i915_mem_takedown(struct mem_block **heap) for (p = (*heap)->next; p != *heap;) { struct mem_block *q = p; p = p->next; - drm_free(q, sizeof(*q), DRM_MEM_BUFLISTS); + drm_free(q, DRM_MEM_BUFLISTS); } - drm_free(*heap, sizeof(**heap), DRM_MEM_BUFLISTS); + drm_free(*heap, DRM_MEM_BUFLISTS); *heap = NULL; } diff --git a/sys/dev/drm2/i915/Makefile b/sys/dev/drm/i915kms/Makefile similarity index 100% rename from sys/dev/drm2/i915/Makefile rename to sys/dev/drm/i915kms/Makefile diff --git a/sys/dev/drm2/i915/i915_debug.c b/sys/dev/drm/i915kms/i915_debug.c similarity index 99% rename from sys/dev/drm2/i915/i915_debug.c rename to sys/dev/drm/i915kms/i915_debug.c index 5bbdbc17bc..7e2e8cc847 100644 --- a/sys/dev/drm2/i915/i915_debug.c +++ b/sys/dev/drm/i915kms/i915_debug.c @@ -27,12 +27,12 @@ * $FreeBSD: src/sys/dev/drm2/i915/i915_debug.c,v 1.1 2012/05/22 11:07:44 kib Exp $ */ -#include -#include -#include -#include -#include -#include +#include +#include +#include "i915_drm.h" +#include "i915_drv.h" +#include "intel_drv.h" +#include "intel_ringbuffer.h" #include diff --git a/sys/dev/drm2/i915/i915_dma.c b/sys/dev/drm/i915kms/i915_dma.c similarity index 99% rename from sys/dev/drm2/i915/i915_dma.c rename to sys/dev/drm/i915kms/i915_dma.c index f19374d190..010288ca3b 100644 --- a/sys/dev/drm2/i915/i915_dma.c +++ b/sys/dev/drm/i915kms/i915_dma.c @@ -27,12 +27,12 @@ * $FreeBSD: src/sys/dev/drm2/i915/i915_dma.c,v 1.1 2012/05/22 11:07:44 kib Exp $ */ -#include -#include -#include -#include -#include -#include +#include +#include +#include "i915_drm.h" +#include "i915_drv.h" +#include "intel_drv.h" +#include "intel_ringbuffer.h" static struct drm_i915_private *i915_mch_dev; /* diff --git a/sys/dev/drm2/i915/i915_drm.h b/sys/dev/drm/i915kms/i915_drm.h similarity index 99% rename from sys/dev/drm2/i915/i915_drm.h rename to sys/dev/drm/i915kms/i915_drm.h index 4259be8943..7487d78cf0 100644 --- a/sys/dev/drm2/i915/i915_drm.h +++ b/sys/dev/drm/i915kms/i915_drm.h @@ -32,7 +32,7 @@ * subject to backwards-compatibility constraints. */ -#include +#include /* Each region is a minimum of 16k, and there are at most 255 of them. */ diff --git a/sys/dev/drm2/i915/i915_drv.c b/sys/dev/drm/i915kms/i915_drv.c similarity index 98% rename from sys/dev/drm2/i915/i915_drv.c rename to sys/dev/drm/i915kms/i915_drv.c index 9603717e3e..725043ab05 100644 --- a/sys/dev/drm2/i915/i915_drv.c +++ b/sys/dev/drm/i915kms/i915_drv.c @@ -30,13 +30,13 @@ * $FreeBSD: src/sys/dev/drm2/i915/i915_drv.c,v 1.1 2012/05/22 11:07:44 kib Exp $ */ -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include "i915_drm.h" +#include "i915_drv.h" +#include +#include "intel_drv.h" /* drv_PCI_IDs comes from drm_pciids.h, generated from drm_pciids.txt. */ static drm_pci_id_list_t i915_pciidlist[] = { @@ -402,7 +402,7 @@ static device_method_t i915_methods[] = { }; static driver_t i915_driver = { - "drmn", + "drm", i915_methods, sizeof(struct drm_device) }; @@ -410,7 +410,7 @@ static driver_t i915_driver = { extern devclass_t drm_devclass; DRIVER_MODULE_ORDERED(i915kms, vgapci, i915_driver, drm_devclass, 0, 0, SI_ORDER_ANY); -MODULE_DEPEND(i915kms, drmn, 1, 1, 1); +MODULE_DEPEND(i915kms, drm, 1, 1, 1); MODULE_DEPEND(i915kms, agp, 1, 1, 1); MODULE_DEPEND(i915kms, iicbus, 1, 1, 1); MODULE_DEPEND(i915kms, iic, 1, 1, 1); diff --git a/sys/dev/drm2/i915/i915_drv.h b/sys/dev/drm/i915kms/i915_drv.h similarity index 99% rename from sys/dev/drm2/i915/i915_drv.h rename to sys/dev/drm/i915kms/i915_drv.h index 7aa7fd0742..0add67eac9 100644 --- a/sys/dev/drm2/i915/i915_drv.h +++ b/sys/dev/drm/i915kms/i915_drv.h @@ -34,10 +34,10 @@ #include #include -#include -#include -#include -#include +#include +#include "i915_reg.h" +#include "intel_ringbuffer.h" +#include "intel_bios.h" /* General customization: */ diff --git a/sys/dev/drm2/i915/i915_gem.c b/sys/dev/drm/i915kms/i915_gem.c similarity index 99% rename from sys/dev/drm2/i915/i915_gem.c rename to sys/dev/drm/i915kms/i915_gem.c index cca0ed7c08..867d6a2c36 100644 --- a/sys/dev/drm2/i915/i915_gem.c +++ b/sys/dev/drm/i915kms/i915_gem.c @@ -56,12 +56,12 @@ #include #include -#include -#include -#include -#include -#include -#include +#include +#include +#include "i915_drm.h" +#include "i915_drv.h" +#include "intel_drv.h" +#include "intel_ringbuffer.h" static void i915_gem_object_flush_cpu_write_domain( struct drm_i915_gem_object *obj); diff --git a/sys/dev/drm2/i915/i915_gem_evict.c b/sys/dev/drm/i915kms/i915_gem_evict.c similarity index 98% rename from sys/dev/drm2/i915/i915_gem_evict.c rename to sys/dev/drm/i915kms/i915_gem_evict.c index 71dd44f38c..bfb0625034 100644 --- a/sys/dev/drm2/i915/i915_gem_evict.c +++ b/sys/dev/drm/i915kms/i915_gem_evict.c @@ -27,10 +27,10 @@ * $FreeBSD: src/sys/dev/drm2/i915/i915_gem_evict.c,v 1.1 2012/05/22 11:07:44 kib Exp $ */ -#include -#include -#include -#include +#include +#include +#include "i915_drm.h" +#include "i915_drv.h" static bool mark_free(struct drm_i915_gem_object *obj, struct list_head *unwind) diff --git a/sys/dev/drm2/i915/i915_gem_execbuffer.c b/sys/dev/drm/i915kms/i915_gem_execbuffer.c similarity index 99% rename from sys/dev/drm2/i915/i915_gem_execbuffer.c rename to sys/dev/drm/i915kms/i915_gem_execbuffer.c index 39ed85e4f3..e07c860ea3 100644 --- a/sys/dev/drm2/i915/i915_gem_execbuffer.c +++ b/sys/dev/drm/i915kms/i915_gem_execbuffer.c @@ -30,11 +30,11 @@ #include #include -#include -#include -#include -#include -#include +#include +#include +#include "i915_drm.h" +#include "i915_drv.h" +#include "intel_drv.h" struct change_domains { uint32_t invalidate_domains; diff --git a/sys/dev/drm2/i915/i915_gem_gtt.c b/sys/dev/drm/i915kms/i915_gem_gtt.c similarity index 98% rename from sys/dev/drm2/i915/i915_gem_gtt.c rename to sys/dev/drm/i915kms/i915_gem_gtt.c index e6491493c5..7eea24a007 100644 --- a/sys/dev/drm2/i915/i915_gem_gtt.c +++ b/sys/dev/drm/i915kms/i915_gem_gtt.c @@ -25,11 +25,11 @@ #include -#include -#include -#include -#include -#include +#include +#include +#include "i915_drm.h" +#include "i915_drv.h" +#include "intel_drv.h" /* PPGTT support for Sandybdrige/Gen6 and later */ static void diff --git a/sys/dev/drm2/i915/i915_gem_tiling.c b/sys/dev/drm/i915kms/i915_gem_tiling.c similarity index 99% rename from sys/dev/drm2/i915/i915_gem_tiling.c rename to sys/dev/drm/i915kms/i915_gem_tiling.c index f1ded3a0ed..bdfab9a817 100644 --- a/sys/dev/drm2/i915/i915_gem_tiling.c +++ b/sys/dev/drm/i915kms/i915_gem_tiling.c @@ -28,10 +28,10 @@ #include -#include -#include -#include -#include +#include +#include +#include "i915_drm.h" +#include "i915_drv.h" /** @file i915_gem_tiling.c * diff --git a/sys/dev/drm2/i915/i915_irq.c b/sys/dev/drm/i915kms/i915_irq.c similarity index 99% rename from sys/dev/drm2/i915/i915_irq.c rename to sys/dev/drm/i915kms/i915_irq.c index d3c7e1706d..4ae421f8d3 100644 --- a/sys/dev/drm2/i915/i915_irq.c +++ b/sys/dev/drm/i915kms/i915_irq.c @@ -29,11 +29,11 @@ #include -#include -#include -#include -#include -#include +#include +#include +#include "i915_drm.h" +#include "i915_drv.h" +#include "intel_drv.h" static void i915_capture_error_state(struct drm_device *dev); static u32 ring_last_seqno(struct intel_ring_buffer *ring); diff --git a/sys/dev/drm2/i915/i915_reg.h b/sys/dev/drm/i915kms/i915_reg.h similarity index 100% rename from sys/dev/drm2/i915/i915_reg.h rename to sys/dev/drm/i915kms/i915_reg.h diff --git a/sys/dev/drm2/i915/i915_suspend.c b/sys/dev/drm/i915kms/i915_suspend.c similarity index 99% rename from sys/dev/drm2/i915/i915_suspend.c rename to sys/dev/drm/i915kms/i915_suspend.c index 778b5af38a..6cee44f394 100644 --- a/sys/dev/drm2/i915/i915_suspend.c +++ b/sys/dev/drm/i915kms/i915_suspend.c @@ -26,10 +26,10 @@ * $FreeBSD: src/sys/dev/drm2/i915/i915_suspend.c,v 1.1 2012/05/22 11:07:44 kib Exp $ */ -#include -#include -#include -#include +#include +#include +#include "i915_drm.h" +#include "intel_drv.h" static bool i915_pipe_enabled(struct drm_device *dev, enum i915_pipe pipe) { diff --git a/sys/dev/drm2/i915/intel_bios.c b/sys/dev/drm/i915kms/intel_bios.c similarity index 99% rename from sys/dev/drm2/i915/intel_bios.c rename to sys/dev/drm/i915kms/intel_bios.c index b8cd42a6fd..0ecd438a29 100644 --- a/sys/dev/drm2/i915/intel_bios.c +++ b/sys/dev/drm/i915kms/intel_bios.c @@ -25,12 +25,12 @@ * * $FreeBSD: src/sys/dev/drm2/i915/intel_bios.c,v 1.1 2012/05/22 11:07:44 kib Exp $ */ -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include "i915_drm.h" +#include "i915_drv.h" +#include "intel_bios.h" #define SLAVE_ADDR1 0x70 #define SLAVE_ADDR2 0x72 diff --git a/sys/dev/drm2/i915/intel_bios.h b/sys/dev/drm/i915kms/intel_bios.h similarity index 99% rename from sys/dev/drm2/i915/intel_bios.h rename to sys/dev/drm/i915kms/intel_bios.h index dacbfa600c..6e67f36942 100644 --- a/sys/dev/drm2/i915/intel_bios.h +++ b/sys/dev/drm/i915kms/intel_bios.h @@ -29,7 +29,7 @@ #ifndef _I830_BIOS_H_ #define _I830_BIOS_H_ -#include +#include struct vbt_header { u8 signature[20]; /**< Always starts with 'VBT$' */ diff --git a/sys/dev/drm2/i915/intel_crt.c b/sys/dev/drm/i915kms/intel_crt.c similarity index 98% rename from sys/dev/drm2/i915/intel_crt.c rename to sys/dev/drm/i915kms/intel_crt.c index 7d8355c4d9..9f9f63e79b 100644 --- a/sys/dev/drm2/i915/intel_crt.c +++ b/sys/dev/drm/i915kms/intel_crt.c @@ -26,14 +26,14 @@ * $FreeBSD: src/sys/dev/drm2/i915/intel_crt.c,v 1.1 2012/05/22 11:07:44 kib Exp $ */ -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include "i915_drm.h" +#include "i915_drv.h" +#include "intel_drv.h" /* Here's the desired hotplug mode */ #define ADPA_HOTPLUG_BITS (ADPA_CRT_HOTPLUG_PERIOD_128 | \ diff --git a/sys/dev/drm2/i915/intel_display.c b/sys/dev/drm/i915kms/intel_display.c similarity index 99% rename from sys/dev/drm2/i915/intel_display.c rename to sys/dev/drm/i915kms/intel_display.c index a80b8731ec..deb7e7fe2c 100644 --- a/sys/dev/drm2/i915/intel_display.c +++ b/sys/dev/drm/i915kms/intel_display.c @@ -29,14 +29,14 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include "i915_drm.h" +#include "i915_drv.h" +#include "intel_drv.h" +#include +#include +#include #define HAS_eDP (intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP)) diff --git a/sys/dev/drm2/i915/intel_dp.c b/sys/dev/drm/i915kms/intel_dp.c similarity index 99% rename from sys/dev/drm2/i915/intel_dp.c rename to sys/dev/drm/i915kms/intel_dp.c index 7d4a461c95..bc19f81ba5 100644 --- a/sys/dev/drm2/i915/intel_dp.c +++ b/sys/dev/drm/i915kms/intel_dp.c @@ -26,14 +26,14 @@ * $FreeBSD: src/sys/dev/drm2/i915/intel_dp.c,v 1.1 2012/05/22 11:07:44 kib Exp $ */ -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include "i915_drm.h" +#include "i915_drv.h" +#include "intel_drv.h" +#include #define DP_RECEIVER_CAP_SIZE 0xf #define DP_LINK_STATUS_SIZE 6 diff --git a/sys/dev/drm2/i915/intel_drv.h b/sys/dev/drm/i915kms/intel_drv.h similarity index 98% rename from sys/dev/drm2/i915/intel_drv.h rename to sys/dev/drm/i915kms/intel_drv.h index 753530b9e2..fea00664bc 100644 --- a/sys/dev/drm2/i915/intel_drv.h +++ b/sys/dev/drm/i915kms/intel_drv.h @@ -28,11 +28,11 @@ #ifndef DRM_INTEL_DRV_H #define DRM_INTEL_DRV_H -#include -#include -#include -#include -#include +#include "i915_drm.h" +#include "i915_drv.h" +#include +#include +#include #define _intel_wait_for(DEV, COND, MS, W, WMSG) \ ({ \ diff --git a/sys/dev/drm2/i915/intel_fb.c b/sys/dev/drm/i915kms/intel_fb.c similarity index 96% rename from sys/dev/drm2/i915/intel_fb.c rename to sys/dev/drm/i915kms/intel_fb.c index e41a60ed97..1808a69265 100644 --- a/sys/dev/drm2/i915/intel_fb.c +++ b/sys/dev/drm/i915kms/intel_fb.c @@ -26,13 +26,13 @@ * $FreeBSD: head/sys/dev/drm2/i915/intel_fb.c 251961 2013-06-18 20:19:09Z kib $ */ -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include "i915_drm.h" +#include "i915_drv.h" +#include "intel_drv.h" static int intelfb_create(struct intel_fbdev *ifbdev, struct drm_fb_helper_surface_size *sizes) diff --git a/sys/dev/drm2/i915/intel_hdmi.c b/sys/dev/drm/i915kms/intel_hdmi.c similarity index 98% rename from sys/dev/drm2/i915/intel_hdmi.c rename to sys/dev/drm/i915kms/intel_hdmi.c index e23b21c07d..57ba47a86d 100644 --- a/sys/dev/drm2/i915/intel_hdmi.c +++ b/sys/dev/drm/i915kms/intel_hdmi.c @@ -27,13 +27,13 @@ * $FreeBSD: src/sys/dev/drm2/i915/intel_hdmi.c,v 1.1 2012/05/22 11:07:44 kib Exp $ */ -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include "i915_drm.h" +#include "i915_drv.h" +#include "intel_drv.h" struct intel_hdmi { struct intel_encoder base; diff --git a/sys/dev/drm2/i915/intel_iic.c b/sys/dev/drm/i915kms/intel_iic.c similarity index 98% rename from sys/dev/drm2/i915/intel_iic.c rename to sys/dev/drm/i915kms/intel_iic.c index a54cadc586..3a95f62d79 100644 --- a/sys/dev/drm2/i915/intel_iic.c +++ b/sys/dev/drm/i915kms/intel_iic.c @@ -58,11 +58,11 @@ #include -#include -#include -#include -#include -#include +#include +#include +#include "i915_drm.h" +#include "i915_drv.h" +#include "intel_drv.h" #include #include #include @@ -558,7 +558,7 @@ static driver_t intel_gmbus_driver = { sizeof(struct intel_iic_softc) }; static devclass_t intel_gmbus_devclass; -DRIVER_MODULE_ORDERED(intel_gmbus, drmn, intel_gmbus_driver, +DRIVER_MODULE_ORDERED(intel_gmbus, drm, intel_gmbus_driver, intel_gmbus_devclass, 0, 0, SI_ORDER_FIRST); DRIVER_MODULE(iicbus, intel_gmbus, iicbus_driver, iicbus_devclass, 0, 0); @@ -584,7 +584,7 @@ static driver_t intel_iicbb_driver = { sizeof(struct intel_iic_softc) }; static devclass_t intel_iicbb_devclass; -DRIVER_MODULE_ORDERED(intel_iicbb, drmn, intel_iicbb_driver, +DRIVER_MODULE_ORDERED(intel_iicbb, drm, intel_iicbb_driver, intel_iicbb_devclass, 0, 0, SI_ORDER_FIRST); DRIVER_MODULE(iicbb, intel_iicbb, iicbb_driver, iicbb_devclass, 0, 0); diff --git a/sys/dev/drm2/i915/intel_lvds.c b/sys/dev/drm/i915kms/intel_lvds.c similarity index 99% rename from sys/dev/drm2/i915/intel_lvds.c rename to sys/dev/drm/i915kms/intel_lvds.c index 7b1ef3133f..b928e7a419 100644 --- a/sys/dev/drm2/i915/intel_lvds.c +++ b/sys/dev/drm/i915kms/intel_lvds.c @@ -28,13 +28,13 @@ * $FreeBSD: src/sys/dev/drm2/i915/intel_lvds.c,v 1.1 2012/05/22 11:07:44 kib Exp $ */ -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include "i915_drm.h" +#include "i915_drv.h" +#include "intel_drv.h" /* Private structure for the integrated LVDS support */ struct intel_lvds { diff --git a/sys/dev/drm2/i915/intel_modes.c b/sys/dev/drm/i915kms/intel_modes.c similarity index 95% rename from sys/dev/drm2/i915/intel_modes.c rename to sys/dev/drm/i915kms/intel_modes.c index 04d1cb1a1b..b412acaf35 100644 --- a/sys/dev/drm2/i915/intel_modes.c +++ b/sys/dev/drm/i915kms/intel_modes.c @@ -25,12 +25,12 @@ * $FreeBSD: head/sys/dev/drm2/i915/intel_modes.c 249041 2013-04-03 08:27:35Z dumbbell $ */ -#include -#include -#include -#include -#include -#include +#include +#include +#include "i915_drm.h" +#include "i915_drv.h" +#include "intel_drv.h" +#include #include /** diff --git a/sys/dev/drm2/i915/intel_opregion.c b/sys/dev/drm/i915kms/intel_opregion.c similarity index 99% rename from sys/dev/drm2/i915/intel_opregion.c rename to sys/dev/drm/i915kms/intel_opregion.c index af3afdfa96..bd8568ebdb 100644 --- a/sys/dev/drm2/i915/intel_opregion.c +++ b/sys/dev/drm/i915kms/intel_opregion.c @@ -26,10 +26,10 @@ * $FreeBSD: src/sys/dev/drm2/i915/intel_opregion.c,v 1.1 2012/05/22 11:07:44 kib Exp $ */ -#include -#include -#include -#include +#include +#include "i915_drm.h" +#include "i915_drv.h" +#include "intel_drv.h" #define PCI_ASLE 0xe4 #define PCI_ASLS 0xfc diff --git a/sys/dev/drm2/i915/intel_overlay.c b/sys/dev/drm/i915kms/intel_overlay.c similarity index 99% rename from sys/dev/drm2/i915/intel_overlay.c rename to sys/dev/drm/i915kms/intel_overlay.c index 9b6118e73e..5cee55a2a2 100644 --- a/sys/dev/drm2/i915/intel_overlay.c +++ b/sys/dev/drm/i915kms/intel_overlay.c @@ -27,12 +27,12 @@ * $FreeBSD: src/sys/dev/drm2/i915/intel_overlay.c,v 1.1 2012/05/22 11:07:44 kib Exp $ */ -#include -#include -#include -#include -#include -#include +#include +#include +#include "i915_drm.h" +#include "i915_drv.h" +#include "i915_reg.h" +#include "intel_drv.h" /* Limits for overlay size. According to intel doc, the real limits are: * Y width: 4095, UV width (planar): 2047, Y height: 2047, diff --git a/sys/dev/drm2/i915/intel_panel.c b/sys/dev/drm/i915kms/intel_panel.c similarity index 98% rename from sys/dev/drm2/i915/intel_panel.c rename to sys/dev/drm/i915kms/intel_panel.c index f938076570..7dae5f5669 100644 --- a/sys/dev/drm2/i915/intel_panel.c +++ b/sys/dev/drm/i915kms/intel_panel.c @@ -30,10 +30,10 @@ * $FreeBSD: src/sys/dev/drm2/i915/intel_panel.c,v 1.1 2012/05/22 11:07:44 kib Exp $ */ -#include -#include -#include -#include +#include +#include +#include "i915_drm.h" +#include "intel_drv.h" #define PCI_LBPC 0xf4 /* legacy/combination backlight modes */ diff --git a/sys/dev/drm2/i915/intel_ringbuffer.c b/sys/dev/drm/i915kms/intel_ringbuffer.c similarity index 99% rename from sys/dev/drm2/i915/intel_ringbuffer.c rename to sys/dev/drm/i915kms/intel_ringbuffer.c index 24bf516ed5..814c453d97 100644 --- a/sys/dev/drm2/i915/intel_ringbuffer.c +++ b/sys/dev/drm/i915kms/intel_ringbuffer.c @@ -28,12 +28,12 @@ * $FreeBSD: head/sys/dev/drm2/i915/intel_ringbuffer.c 253709 2013-07-27 16:42:29Z kib $ */ -#include -#include -#include -#include -#include -#include +#include +#include +#include "i915_drm.h" +#include "i915_drv.h" +#include "intel_drv.h" +#include "intel_ringbuffer.h" #include /* diff --git a/sys/dev/drm2/i915/intel_ringbuffer.h b/sys/dev/drm/i915kms/intel_ringbuffer.h similarity index 100% rename from sys/dev/drm2/i915/intel_ringbuffer.h rename to sys/dev/drm/i915kms/intel_ringbuffer.h diff --git a/sys/dev/drm2/i915/intel_sdvo.c b/sys/dev/drm/i915kms/intel_sdvo.c similarity index 99% rename from sys/dev/drm2/i915/intel_sdvo.c rename to sys/dev/drm/i915kms/intel_sdvo.c index fca6686706..f894ff0ac6 100644 --- a/sys/dev/drm2/i915/intel_sdvo.c +++ b/sys/dev/drm/i915kms/intel_sdvo.c @@ -28,14 +28,14 @@ * $FreeBSD: head/sys/dev/drm2/i915/intel_sdvo.c 249041 2013-04-03 08:27:35Z dumbbell $ */ -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include "i915_drm.h" +#include "i915_drv.h" +#include "intel_sdvo_regs.h" +#include "intel_drv.h" #include #include #include "iicbus_if.h" @@ -2578,7 +2578,7 @@ static driver_t intel_sdvo_ddc_proxy_driver = { sizeof(struct intel_sdvo_ddc_proxy_sc) }; static devclass_t intel_sdvo_devclass; -DRIVER_MODULE_ORDERED(intel_sdvo_ddc_proxy, drmn, intel_sdvo_ddc_proxy_driver, +DRIVER_MODULE_ORDERED(intel_sdvo_ddc_proxy, drm, intel_sdvo_ddc_proxy_driver, intel_sdvo_devclass, 0, 0, SI_ORDER_FIRST); diff --git a/sys/dev/drm2/i915/intel_sdvo_regs.h b/sys/dev/drm/i915kms/intel_sdvo_regs.h similarity index 100% rename from sys/dev/drm2/i915/intel_sdvo_regs.h rename to sys/dev/drm/i915kms/intel_sdvo_regs.h diff --git a/sys/dev/drm2/i915/intel_sprite.c b/sys/dev/drm/i915kms/intel_sprite.c similarity index 98% rename from sys/dev/drm2/i915/intel_sprite.c rename to sys/dev/drm/i915kms/intel_sprite.c index 6605060407..9d7cf7162b 100644 --- a/sys/dev/drm2/i915/intel_sprite.c +++ b/sys/dev/drm/i915kms/intel_sprite.c @@ -32,12 +32,12 @@ * $FreeBSD: src/sys/dev/drm2/i915/intel_sprite.c,v 1.1 2012/05/22 11:07:44 kib Exp $ */ -#include -#include -#include -#include -#include -#include +#include +#include +#include "i915_drm.h" +#include "i915_drv.h" +#include "intel_drv.h" +#include static void ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, diff --git a/sys/dev/drm2/i915/intel_tv.c b/sys/dev/drm/i915kms/intel_tv.c similarity index 99% rename from sys/dev/drm2/i915/intel_tv.c rename to sys/dev/drm/i915kms/intel_tv.c index b653941e25..bc2ae5f9e2 100644 --- a/sys/dev/drm2/i915/intel_tv.c +++ b/sys/dev/drm/i915kms/intel_tv.c @@ -32,13 +32,13 @@ */ -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include "i915_drm.h" +#include "i915_drv.h" +#include "intel_drv.h" enum tv_margin { TV_MARGIN_LEFT, TV_MARGIN_TOP, diff --git a/sys/dev/drm/mach64/mach64_dma.c b/sys/dev/drm/mach64/mach64_dma.c index 97b7c03726..f061531365 100644 --- a/sys/dev/drm/mach64/mach64_dma.c +++ b/sys/dev/drm/mach64/mach64_dma.c @@ -835,12 +835,12 @@ static int mach64_bm_dma_test(struct drm_device * dev) /* FIXME: get a dma buffer from the freelist here */ DRM_DEBUG("Allocating data memory ...\n"); #if defined(__FreeBSD__) || defined(__DragonFly__) - DRM_UNLOCK(); + DRM_UNLOCK(dev); #endif cpu_addr_dmah = drm_pci_alloc(dev, 0x1000, 0x1000, 0xfffffffful); #if defined(__FreeBSD__) || defined(__DragonFly__) - DRM_LOCK(); + DRM_LOCK(dev); #endif if (!cpu_addr_dmah) { DRM_INFO("data-memory allocation failed!\n"); @@ -1393,8 +1393,7 @@ int mach64_do_cleanup_dma(struct drm_device * dev) mach64_destroy_freelist(dev); - drm_free(dev_priv, sizeof(drm_mach64_private_t), - DRM_MEM_DRIVER); + drm_free(dev_priv, DRM_MEM_DRIVER); dev->dev_private = NULL; } @@ -1507,18 +1506,18 @@ void mach64_destroy_freelist(struct drm_device * dev) list_for_each_safe(ptr, tmp, &dev_priv->pending) { list_del(ptr); entry = list_entry(ptr, drm_mach64_freelist_t, list); - drm_free(entry, sizeof(*entry), DRM_MEM_BUFLISTS); + drm_free(entry, DRM_MEM_BUFLISTS); } list_for_each_safe(ptr, tmp, &dev_priv->placeholders) { list_del(ptr); entry = list_entry(ptr, drm_mach64_freelist_t, list); - drm_free(entry, sizeof(*entry), DRM_MEM_BUFLISTS); + drm_free(entry, DRM_MEM_BUFLISTS); } list_for_each_safe(ptr, tmp, &dev_priv->free_list) { list_del(ptr); entry = list_entry(ptr, drm_mach64_freelist_t, list); - drm_free(entry, sizeof(*entry), DRM_MEM_BUFLISTS); + drm_free(entry, DRM_MEM_BUFLISTS); } } diff --git a/sys/dev/drm/mach64/mach64_drv.c b/sys/dev/drm/mach64/mach64_drv.c index 8c2b246ec9..030364778b 100644 --- a/sys/dev/drm/mach64/mach64_drv.c +++ b/sys/dev/drm/mach64/mach64_drv.c @@ -83,7 +83,7 @@ mach64_attach(device_t kdev) { struct drm_device *dev = device_get_softc(kdev); - dev->driver = malloc(sizeof(struct drm_driver_info), DRM_MEM_DRIVER, + dev->driver = kmalloc(sizeof(struct drm_driver_info), DRM_MEM_DRIVER, M_WAITOK | M_ZERO); mach64_configure(dev); @@ -105,7 +105,7 @@ mach64_detach(device_t kdev) ret = drm_detach(kdev); - free(dev->driver, DRM_MEM_DRIVER); + kfree(dev->driver, DRM_MEM_DRIVER); return ret; } diff --git a/sys/dev/drm/mach64/mach64_state.c b/sys/dev/drm/mach64/mach64_state.c index ec7bab1638..54166224f8 100644 --- a/sys/dev/drm/mach64/mach64_state.c +++ b/sys/dev/drm/mach64/mach64_state.c @@ -495,7 +495,7 @@ static __inline__ int copy_from_user_vertex(u32 *to, return -ENOMEM; if (DRM_COPY_FROM_USER(from, ufrom, bytes)) { - drm_free(from, bytes, DRM_MEM_DRIVER); + drm_free(from, DRM_MEM_DRIVER); return -EFAULT; } orig_from = from; /* we'll be modifying the "from" ptr, so save it */ @@ -526,19 +526,19 @@ static __inline__ int copy_from_user_vertex(u32 *to, to += count; } else { DRM_ERROR("Got bad command: 0x%04x\n", reg); - drm_free(orig_from, bytes, DRM_MEM_DRIVER); + drm_free(orig_from, DRM_MEM_DRIVER); return -EACCES; } } else { DRM_ERROR ("Got bad command count(=%u) dwords remaining=%lu\n", count, n); - drm_free(orig_from, bytes, DRM_MEM_DRIVER); + drm_free(orig_from, DRM_MEM_DRIVER); return -EINVAL; } } - drm_free(orig_from, bytes, DRM_MEM_DRIVER); + drm_free(orig_from, DRM_MEM_DRIVER); if (n == 0) return 0; else { diff --git a/sys/dev/drm/mga/mga_dma.c b/sys/dev/drm/mga/mga_dma.c index 36b7c5e982..a1861e0e56 100644 --- a/sys/dev/drm/mga/mga_dma.c +++ b/sys/dev/drm/mga/mga_dma.c @@ -301,7 +301,7 @@ static void mga_freelist_cleanup(struct drm_device * dev) entry = dev_priv->head; while (entry) { next = entry->next; - drm_free(entry, sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER); + drm_free(entry, DRM_MEM_DRIVER); entry = next; } @@ -1148,7 +1148,7 @@ int mga_dma_buffers(struct drm_device *dev, void *data, */ int mga_driver_unload(struct drm_device * dev) { - drm_free(dev->dev_private, sizeof(drm_mga_private_t), DRM_MEM_DRIVER); + drm_free(dev->dev_private, DRM_MEM_DRIVER); dev->dev_private = NULL; return 0; diff --git a/sys/dev/drm/mga/mga_drv.c b/sys/dev/drm/mga/mga_drv.c index 405b3753cf..f0835a4263 100644 --- a/sys/dev/drm/mga/mga_drv.c +++ b/sys/dev/drm/mga/mga_drv.c @@ -127,7 +127,7 @@ mga_attach(device_t kdev) { struct drm_device *dev = device_get_softc(kdev); - dev->driver = malloc(sizeof(struct drm_driver_info), DRM_MEM_DRIVER, + dev->driver = kmalloc(sizeof(struct drm_driver_info), DRM_MEM_DRIVER, M_WAITOK | M_ZERO); mga_configure(dev); @@ -143,7 +143,7 @@ mga_detach(device_t kdev) ret = drm_detach(kdev); - free(dev->driver, DRM_MEM_DRIVER); + kfree(dev->driver, DRM_MEM_DRIVER); return ret; } diff --git a/sys/dev/drm/r128/r128_cce.c b/sys/dev/drm/r128/r128_cce.c index 0e67f01f1d..4d45595744 100644 --- a/sys/dev/drm/r128/r128_cce.c +++ b/sys/dev/drm/r128/r128_cce.c @@ -616,8 +616,7 @@ int r128_do_cleanup_cce(struct drm_device * dev) DRM_ERROR("failed to cleanup PCI GART!\n"); } - drm_free(dev->dev_private, sizeof(drm_r128_private_t), - DRM_MEM_DRIVER); + drm_free(dev->dev_private, DRM_MEM_DRIVER); dev->dev_private = NULL; } diff --git a/sys/dev/drm/r128/r128_drv.c b/sys/dev/drm/r128/r128_drv.c index 3cc14ff25d..c24616aaf3 100644 --- a/sys/dev/drm/r128/r128_drv.c +++ b/sys/dev/drm/r128/r128_drv.c @@ -83,7 +83,7 @@ r128_attach(device_t kdev) { struct drm_device *dev = device_get_softc(kdev); - dev->driver = malloc(sizeof(struct drm_driver_info), DRM_MEM_DRIVER, + dev->driver = kmalloc(sizeof(struct drm_driver_info), DRM_MEM_DRIVER, M_WAITOK | M_ZERO); r128_configure(dev); @@ -104,7 +104,7 @@ r128_detach(device_t kdev) ret = drm_detach(kdev); - free(dev->driver, DRM_MEM_DRIVER); + kfree(dev->driver, DRM_MEM_DRIVER); return ret; } diff --git a/sys/dev/drm/r128/r128_state.c b/sys/dev/drm/r128/r128_state.c index 8340fc92c6..a9c6a93b31 100644 --- a/sys/dev/drm/r128/r128_state.c +++ b/sys/dev/drm/r128/r128_state.c @@ -914,7 +914,7 @@ static int r128_cce_dispatch_write_span(struct drm_device * dev, if (buffer == NULL) return -ENOMEM; if (DRM_COPY_FROM_USER(buffer, depth->buffer, buffer_size)) { - drm_free(buffer, buffer_size, DRM_MEM_BUFS); + drm_free(buffer, DRM_MEM_BUFS); return -EFAULT; } @@ -922,12 +922,12 @@ static int r128_cce_dispatch_write_span(struct drm_device * dev, if (depth->mask) { mask = drm_alloc(mask_size, DRM_MEM_BUFS); if (mask == NULL) { - drm_free(buffer, buffer_size, DRM_MEM_BUFS); + drm_free(buffer, DRM_MEM_BUFS); return -ENOMEM; } if (DRM_COPY_FROM_USER(mask, depth->mask, mask_size)) { - drm_free(buffer, buffer_size, DRM_MEM_BUFS); - drm_free(mask, mask_size, DRM_MEM_BUFS); + drm_free(buffer, DRM_MEM_BUFS); + drm_free(mask, DRM_MEM_BUFS); return -EFAULT; } @@ -954,7 +954,7 @@ static int r128_cce_dispatch_write_span(struct drm_device * dev, } } - drm_free(mask, mask_size, DRM_MEM_BUFS); + drm_free(mask, DRM_MEM_BUFS); } else { for (i = 0; i < count; i++, x++) { BEGIN_RING(6); @@ -978,7 +978,7 @@ static int r128_cce_dispatch_write_span(struct drm_device * dev, } } - drm_free(buffer, buffer_size, DRM_MEM_BUFS); + drm_free(buffer, DRM_MEM_BUFS); return 0; } @@ -1006,31 +1006,31 @@ static int r128_cce_dispatch_write_pixels(struct drm_device * dev, } y = drm_alloc(ybuf_size, DRM_MEM_BUFS); if (y == NULL) { - drm_free(x, xbuf_size, DRM_MEM_BUFS); + drm_free(x, DRM_MEM_BUFS); return -ENOMEM; } if (DRM_COPY_FROM_USER(x, depth->x, xbuf_size)) { - drm_free(x, xbuf_size, DRM_MEM_BUFS); - drm_free(y, ybuf_size, DRM_MEM_BUFS); + drm_free(x, DRM_MEM_BUFS); + drm_free(y, DRM_MEM_BUFS); return -EFAULT; } if (DRM_COPY_FROM_USER(y, depth->y, xbuf_size)) { - drm_free(x, xbuf_size, DRM_MEM_BUFS); - drm_free(y, ybuf_size, DRM_MEM_BUFS); + drm_free(x, DRM_MEM_BUFS); + drm_free(y, DRM_MEM_BUFS); return -EFAULT; } buffer_size = depth->n * sizeof(u32); buffer = drm_alloc(buffer_size, DRM_MEM_BUFS); if (buffer == NULL) { - drm_free(x, xbuf_size, DRM_MEM_BUFS); - drm_free(y, ybuf_size, DRM_MEM_BUFS); + drm_free(x, DRM_MEM_BUFS); + drm_free(y, DRM_MEM_BUFS); return -ENOMEM; } if (DRM_COPY_FROM_USER(buffer, depth->buffer, buffer_size)) { - drm_free(x, xbuf_size, DRM_MEM_BUFS); - drm_free(y, ybuf_size, DRM_MEM_BUFS); - drm_free(buffer, buffer_size, DRM_MEM_BUFS); + drm_free(x, DRM_MEM_BUFS); + drm_free(y, DRM_MEM_BUFS); + drm_free(buffer, DRM_MEM_BUFS); return -EFAULT; } @@ -1038,16 +1038,16 @@ static int r128_cce_dispatch_write_pixels(struct drm_device * dev, mask_size = depth->n * sizeof(u8); mask = drm_alloc(mask_size, DRM_MEM_BUFS); if (mask == NULL) { - drm_free(x, xbuf_size, DRM_MEM_BUFS); - drm_free(y, ybuf_size, DRM_MEM_BUFS); - drm_free(buffer, buffer_size, DRM_MEM_BUFS); + drm_free(x, DRM_MEM_BUFS); + drm_free(y, DRM_MEM_BUFS); + drm_free(buffer, DRM_MEM_BUFS); return -ENOMEM; } if (DRM_COPY_FROM_USER(mask, depth->mask, mask_size)) { - drm_free(x, xbuf_size, DRM_MEM_BUFS); - drm_free(y, ybuf_size, DRM_MEM_BUFS); - drm_free(buffer, buffer_size, DRM_MEM_BUFS); - drm_free(mask, mask_size, DRM_MEM_BUFS); + drm_free(x, DRM_MEM_BUFS); + drm_free(y, DRM_MEM_BUFS); + drm_free(buffer, DRM_MEM_BUFS); + drm_free(mask, DRM_MEM_BUFS); return -EFAULT; } @@ -1074,7 +1074,7 @@ static int r128_cce_dispatch_write_pixels(struct drm_device * dev, } } - drm_free(mask, mask_size, DRM_MEM_BUFS); + drm_free(mask, DRM_MEM_BUFS); } else { for (i = 0; i < count; i++) { BEGIN_RING(6); @@ -1098,9 +1098,9 @@ static int r128_cce_dispatch_write_pixels(struct drm_device * dev, } } - drm_free(x, xbuf_size, DRM_MEM_BUFS); - drm_free(y, ybuf_size, DRM_MEM_BUFS); - drm_free(buffer, buffer_size, DRM_MEM_BUFS); + drm_free(x, DRM_MEM_BUFS); + drm_free(y, DRM_MEM_BUFS); + drm_free(buffer, DRM_MEM_BUFS); return 0; } @@ -1173,17 +1173,17 @@ static int r128_cce_dispatch_read_pixels(struct drm_device * dev, } y = drm_alloc(ybuf_size, DRM_MEM_BUFS); if (y == NULL) { - drm_free(x, xbuf_size, DRM_MEM_BUFS); + drm_free(x, DRM_MEM_BUFS); return -ENOMEM; } if (DRM_COPY_FROM_USER(x, depth->x, xbuf_size)) { - drm_free(x, xbuf_size, DRM_MEM_BUFS); - drm_free(y, ybuf_size, DRM_MEM_BUFS); + drm_free(x, DRM_MEM_BUFS); + drm_free(y, DRM_MEM_BUFS); return -EFAULT; } if (DRM_COPY_FROM_USER(y, depth->y, ybuf_size)) { - drm_free(x, xbuf_size, DRM_MEM_BUFS); - drm_free(y, ybuf_size, DRM_MEM_BUFS); + drm_free(x, DRM_MEM_BUFS); + drm_free(y, DRM_MEM_BUFS); return -EFAULT; } @@ -1210,8 +1210,8 @@ static int r128_cce_dispatch_read_pixels(struct drm_device * dev, ADVANCE_RING(); } - drm_free(x, xbuf_size, DRM_MEM_BUFS); - drm_free(y, ybuf_size, DRM_MEM_BUFS); + drm_free(x, DRM_MEM_BUFS); + drm_free(y, DRM_MEM_BUFS); return 0; } diff --git a/sys/dev/drm/radeon/radeon_cp.c b/sys/dev/drm/radeon/radeon_cp.c index d7fd79274d..c3f457ddf6 100644 --- a/sys/dev/drm/radeon/radeon_cp.c +++ b/sys/dev/drm/radeon/radeon_cp.c @@ -1697,11 +1697,11 @@ void radeon_do_release(struct drm_device * dev) DRM_DEBUG("radeon_do_cp_idle %d\n", ret); tsleep_interlock(&dev->lock.lock_queue, PCATCH); - DRM_UNLOCK(); + DRM_UNLOCK(dev); ret = tsleep(&dev->lock.lock_queue, PCATCH | PINTERLOCKED, "rdnrel", 0); - DRM_LOCK(); + DRM_LOCK(dev); /* DragonFly equivalent of * mtx_sleep(&ret, &dev->dev_lock, 0, * "rdnrel", 1); @@ -1712,11 +1712,11 @@ void radeon_do_release(struct drm_device * dev) DRM_DEBUG("radeon_do_cp_idle %d\n", ret); tsleep_interlock(&dev->lock.lock_queue, PCATCH); - DRM_UNLOCK(); + DRM_UNLOCK(dev); ret = tsleep(&dev->lock.lock_queue, PCATCH | PINTERLOCKED, "rdnrel", 0); - DRM_LOCK(); + DRM_LOCK(dev); } } if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) { @@ -2042,7 +2042,7 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags) else dev_priv->flags |= RADEON_IS_PCI; - DRM_SPININIT(&dev_priv->cs.cs_mutex, "cs_mtx"); + lockinit(&dev_priv->cs.cs_mutex, "cs_mtx", 0, LK_EXCLUSIVE); ret = drm_addmap(dev, drm_get_resource_start(dev, 2), drm_get_resource_len(dev, 2), _DRM_REGISTERS, @@ -2098,7 +2098,7 @@ int radeon_driver_unload(struct drm_device *dev) lockuninit(&dev_priv->cs.cs_mutex); - drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER); + drm_free(dev_priv, DRM_MEM_DRIVER); dev->dev_private = NULL; return 0; diff --git a/sys/dev/drm/radeon/radeon_cs.c b/sys/dev/drm/radeon/radeon_cs.c index ca333bdb5a..c55b33a839 100644 --- a/sys/dev/drm/radeon/radeon_cs.c +++ b/sys/dev/drm/radeon/radeon_cs.c @@ -270,11 +270,11 @@ out: for (i = 0; i < parser.num_chunks; i++) { if (parser.chunks[i].kdata) - drm_free(parser.chunks[i].kdata, parser.chunks[i].length_dw * sizeof(uint32_t), DRM_MEM_DRIVER); + drm_free(parser.chunks[i].kdata, DRM_MEM_DRIVER); } - drm_free(parser.chunks, sizeof(struct drm_radeon_kernel_chunk)*parser.num_chunks, DRM_MEM_DRIVER); - drm_free(chunk_array, sizeof(uint64_t)*parser.num_chunks, DRM_MEM_DRIVER); + drm_free(parser.chunks, DRM_MEM_DRIVER); + drm_free(chunk_array, DRM_MEM_DRIVER); return r; } diff --git a/sys/dev/drm/radeon/radeon_drv.c b/sys/dev/drm/radeon/radeon_drv.c index 1dc2a94c11..22410e7f41 100644 --- a/sys/dev/drm/radeon/radeon_drv.c +++ b/sys/dev/drm/radeon/radeon_drv.c @@ -87,7 +87,7 @@ radeon_attach(device_t kdev) { struct drm_device *dev = device_get_softc(kdev); - dev->driver = malloc(sizeof(struct drm_driver_info), DRM_MEM_DRIVER, + dev->driver = kmalloc(sizeof(struct drm_driver_info), DRM_MEM_DRIVER, M_WAITOK | M_ZERO); radeon_configure(dev); @@ -103,7 +103,7 @@ radeon_detach(device_t kdev) ret = drm_detach(kdev); - free(dev->driver, DRM_MEM_DRIVER); + drm_free(dev->driver, DRM_MEM_DRIVER); return ret; } diff --git a/sys/dev/drm/radeon/radeon_drv.h b/sys/dev/drm/radeon/radeon_drv.h index 33001a20e7..2b926dde21 100644 --- a/sys/dev/drm/radeon/radeon_drv.h +++ b/sys/dev/drm/radeon/radeon_drv.h @@ -256,7 +256,7 @@ struct drm_radeon_cs_parser { /* command submission struct */ struct drm_radeon_cs_priv { - DRM_SPINTYPE cs_mutex; + struct lock cs_mutex; uint32_t id_wcnt; uint32_t id_scnt; uint32_t id_last_wcnt; diff --git a/sys/dev/drm/radeon/radeon_mem.c b/sys/dev/drm/radeon/radeon_mem.c index 9c03a49929..aea505a458 100644 --- a/sys/dev/drm/radeon/radeon_mem.c +++ b/sys/dev/drm/radeon/radeon_mem.c @@ -118,7 +118,7 @@ static void free_block(struct mem_block *p) p->size += q->size; p->next = q->next; p->next->prev = p; - drm_free(q, sizeof(*q), DRM_MEM_BUFS); + drm_free(q, DRM_MEM_BUFS); } if (p->prev->file_priv == NULL) { @@ -126,7 +126,7 @@ static void free_block(struct mem_block *p) q->size += p->size; q->next = p->next; q->next->prev = q; - drm_free(p, sizeof(*q), DRM_MEM_BUFS); + drm_free(p, DRM_MEM_BUFS); } } @@ -141,7 +141,7 @@ static int init_heap(struct mem_block **heap, int start, int size) *heap = drm_alloc(sizeof(**heap), DRM_MEM_BUFS); if (!*heap) { - drm_free(blocks, sizeof(*blocks), DRM_MEM_BUFS); + drm_free(blocks, DRM_MEM_BUFS); return -ENOMEM; } @@ -179,7 +179,7 @@ void radeon_mem_release(struct drm_file *file_priv, struct mem_block *heap) p->size += q->size; p->next = q->next; p->next->prev = p; - drm_free(q, sizeof(*q), DRM_MEM_DRIVER); + drm_free(q, DRM_MEM_DRIVER); } } } @@ -196,10 +196,10 @@ void radeon_mem_takedown(struct mem_block **heap) for (p = (*heap)->next; p != *heap;) { struct mem_block *q = p; p = p->next; - drm_free(q, sizeof(*q), DRM_MEM_DRIVER); + drm_free(q, DRM_MEM_DRIVER); } - drm_free(*heap, sizeof(**heap), DRM_MEM_DRIVER); + drm_free(*heap, DRM_MEM_DRIVER); *heap = NULL; } diff --git a/sys/dev/drm/radeon/radeon_state.c b/sys/dev/drm/radeon/radeon_state.c index 3f1caf9bcf..ded6d20c24 100644 --- a/sys/dev/drm/radeon/radeon_state.c +++ b/sys/dev/drm/radeon/radeon_state.c @@ -2864,7 +2864,7 @@ static int radeon_cp_cmdbuf(struct drm_device *dev, void *data, struct drm_file return -ENOMEM; if (DRM_COPY_FROM_USER(kbuf, (void __user *)cmdbuf->buf, cmdbuf->bufsz)) { - drm_free(kbuf, orig_bufsz, DRM_MEM_DRIVER); + drm_free(kbuf, DRM_MEM_DRIVER); return -EFAULT; } cmdbuf->buf = kbuf; @@ -2877,7 +2877,7 @@ static int radeon_cp_cmdbuf(struct drm_device *dev, void *data, struct drm_file temp = r300_do_cp_cmdbuf(dev, file_priv, cmdbuf); if (orig_bufsz != 0) - drm_free(kbuf, orig_bufsz, DRM_MEM_DRIVER); + drm_free(kbuf, DRM_MEM_DRIVER); return temp; } @@ -2984,7 +2984,7 @@ static int radeon_cp_cmdbuf(struct drm_device *dev, void *data, struct drm_file } if (orig_bufsz != 0) - drm_free(kbuf, orig_bufsz, DRM_MEM_DRIVER); + drm_free(kbuf, DRM_MEM_DRIVER); DRM_DEBUG("DONE\n"); COMMIT_RING(); @@ -2992,7 +2992,7 @@ static int radeon_cp_cmdbuf(struct drm_device *dev, void *data, struct drm_file err: if (orig_bufsz != 0) - drm_free(kbuf, orig_bufsz, DRM_MEM_DRIVER); + drm_free(kbuf, DRM_MEM_DRIVER); return -EINVAL; } @@ -3202,7 +3202,7 @@ void radeon_driver_postclose(struct drm_device *dev, struct drm_file *file_priv) struct drm_radeon_driver_file_fields *radeon_priv = file_priv->driver_priv; - drm_free(radeon_priv, sizeof(*radeon_priv), DRM_MEM_FILES); + drm_free(radeon_priv, DRM_MEM_FILES); } struct drm_ioctl_desc radeon_ioctls[] = { diff --git a/sys/dev/drm/savage/savage_bci.c b/sys/dev/drm/savage/savage_bci.c index 6c8b0b5133..83f170dfff 100644 --- a/sys/dev/drm/savage/savage_bci.c +++ b/sys/dev/drm/savage/savage_bci.c @@ -683,7 +683,7 @@ int savage_driver_unload(struct drm_device *dev) { drm_savage_private_t *dev_priv = dev->dev_private; - drm_free(dev_priv, sizeof(drm_savage_private_t), DRM_MEM_DRIVER); + drm_free(dev_priv, DRM_MEM_DRIVER); return 0; } @@ -916,8 +916,7 @@ static int savage_do_cleanup_bci(struct drm_device *dev) if (dev_priv->cmd_dma == &dev_priv->fake_dma) { if (dev_priv->fake_dma.virtual) - drm_free(dev_priv->fake_dma.virtual, - SAVAGE_FAKE_DMA_SIZE, DRM_MEM_DRIVER); + drm_free(dev_priv->fake_dma.virtual,DRM_MEM_DRIVER); } else if (dev_priv->cmd_dma && dev_priv->cmd_dma->virtual && dev_priv->cmd_dma->type == _DRM_AGP && dev_priv->dma_type == SAVAGE_DMA_AGP) @@ -933,9 +932,7 @@ static int savage_do_cleanup_bci(struct drm_device *dev) } if (dev_priv->dma_pages) - drm_free(dev_priv->dma_pages, - sizeof(drm_savage_dma_page_t)*dev_priv->nr_dma_pages, - DRM_MEM_DRIVER); + drm_free(dev_priv->dma_pages, DRM_MEM_DRIVER); return 0; } diff --git a/sys/dev/drm/savage/savage_drv.c b/sys/dev/drm/savage/savage_drv.c index a7e1a0c046..18014d3131 100644 --- a/sys/dev/drm/savage/savage_drv.c +++ b/sys/dev/drm/savage/savage_drv.c @@ -73,7 +73,7 @@ savage_attach(device_t kdev) { struct drm_device *dev = device_get_softc(kdev); - dev->driver = malloc(sizeof(struct drm_driver_info), DRM_MEM_DRIVER, + dev->driver = kmalloc(sizeof(struct drm_driver_info), DRM_MEM_DRIVER, M_WAITOK | M_ZERO); savage_configure(dev); @@ -89,7 +89,7 @@ savage_detach(device_t kdev) ret = drm_detach(kdev); - free(dev->driver, DRM_MEM_DRIVER); + kfree(dev->driver, DRM_MEM_DRIVER); return ret; } diff --git a/sys/dev/drm/savage/savage_state.c b/sys/dev/drm/savage/savage_state.c index e0cf1021d9..a6d48ff848 100644 --- a/sys/dev/drm/savage/savage_state.c +++ b/sys/dev/drm/savage/savage_state.c @@ -995,7 +995,7 @@ int savage_bci_cmdbuf(struct drm_device *dev, void *data, struct drm_file *file_ if (DRM_COPY_FROM_USER(kcmd_addr, cmdbuf->cmd_addr, cmdbuf->size * 8)) { - drm_free(kcmd_addr, cmdbuf->size * 8, DRM_MEM_DRIVER); + drm_free(kcmd_addr, DRM_MEM_DRIVER); return -EFAULT; } cmdbuf->cmd_addr = kcmd_addr; @@ -1157,10 +1157,9 @@ int savage_bci_cmdbuf(struct drm_device *dev, void *data, struct drm_file *file_ done: /* If we didn't need to allocate them, these'll be NULL */ - drm_free(kcmd_addr, cmdbuf->size * 8, DRM_MEM_DRIVER); - drm_free(kvb_addr, cmdbuf->vb_size, DRM_MEM_DRIVER); - drm_free(kbox_addr, cmdbuf->nbox * sizeof(struct drm_clip_rect), - DRM_MEM_DRIVER); + drm_free(kcmd_addr, DRM_MEM_DRIVER); + drm_free(kvb_addr, DRM_MEM_DRIVER); + drm_free(kbox_addr, DRM_MEM_DRIVER); return ret; } diff --git a/sys/dev/drm/sis/sis_drv.c b/sys/dev/drm/sis/sis_drv.c index 8e97a9574c..860a146621 100644 --- a/sys/dev/drm/sis/sis_drv.c +++ b/sys/dev/drm/sis/sis_drv.c @@ -67,7 +67,7 @@ sis_attach(device_t kdev) { struct drm_device *dev = device_get_softc(kdev); - dev->driver = malloc(sizeof(struct drm_driver_info), DRM_MEM_DRIVER, + dev->driver = kmalloc(sizeof(struct drm_driver_info), DRM_MEM_DRIVER, M_WAITOK | M_ZERO); sis_configure(dev); @@ -83,7 +83,7 @@ sis_detach(device_t kdev) ret = drm_detach(kdev); - free(dev->driver, DRM_MEM_DRIVER); + kfree(dev->driver, DRM_MEM_DRIVER); return ret; } diff --git a/sys/dev/drm/sis/sis_ds.c b/sys/dev/drm/sis/sis_ds.c index cdcadc7213..563b2ab8c5 100644 --- a/sys/dev/drm/sis/sis_ds.c +++ b/sys/dev/drm/sis/sis_ds.c @@ -127,7 +127,7 @@ int setNext(set_t * set, ITEM_TYPE * item) int setDestroy(set_t * set) { - drm_free(set, sizeof(set_t), DRM_MEM_DRIVER); + drm_free(set, DRM_MEM_DRIVER); return 1; } @@ -267,7 +267,7 @@ static __inline__ int Join2Blocks(TMemBlock * p) TMemBlock *q = p->next; p->size += q->size; p->next = q->next; - drm_free(q, sizeof(TMemBlock), DRM_MEM_DRIVER); + drm_free(q, DRM_MEM_DRIVER); return 1; } return 0; diff --git a/sys/dev/drm/tdfx/tdfx_drv.c b/sys/dev/drm/tdfx/tdfx_drv.c index b215d10fab..22df63e74f 100644 --- a/sys/dev/drm/tdfx/tdfx_drv.c +++ b/sys/dev/drm/tdfx/tdfx_drv.c @@ -69,7 +69,7 @@ tdfx_attach(device_t kdev) { struct drm_device *dev = device_get_softc(kdev); - dev->driver = malloc(sizeof(struct drm_driver_info), DRM_MEM_DRIVER, + dev->driver = kmalloc(sizeof(struct drm_driver_info), DRM_MEM_DRIVER, M_WAITOK | M_ZERO); tdfx_configure(dev); @@ -85,7 +85,7 @@ tdfx_detach(device_t kdev) ret = drm_detach(kdev); - free(dev->driver, DRM_MEM_DRIVER); + kfree(dev->driver, DRM_MEM_DRIVER); return ret; } diff --git a/sys/dev/drm2/ttm/ttm_agp_backend.c b/sys/dev/drm/ttm/ttm_agp_backend.c similarity index 95% rename from sys/dev/drm2/ttm/ttm_agp_backend.c rename to sys/dev/drm/ttm/ttm_agp_backend.c index 9093abe38c..600a3c8943 100644 --- a/sys/dev/drm2/ttm/ttm_agp_backend.c +++ b/sys/dev/drm/ttm/ttm_agp_backend.c @@ -31,12 +31,12 @@ * $FreeBSD: head/sys/dev/drm2/ttm/ttm_agp_backend.c 247835 2013-03-05 09:49:34Z kib $ */ -#include -#include -#include -#include +#include +#include +#include +#include #ifdef TTM_HAS_AGP -#include +#include struct ttm_agp_backend { struct ttm_tt ttm; diff --git a/sys/dev/drm2/ttm/ttm_bo.c b/sys/dev/drm/ttm/ttm_bo.c similarity index 99% rename from sys/dev/drm2/ttm/ttm_bo.c rename to sys/dev/drm/ttm/ttm_bo.c index 96b2e95c7d..67309040c7 100644 --- a/sys/dev/drm2/ttm/ttm_bo.c +++ b/sys/dev/drm/ttm/ttm_bo.c @@ -30,10 +30,10 @@ * $FreeBSD: head/sys/dev/drm2/ttm/ttm_bo.c 248060 2013-03-08 18:11:02Z dumbbell $ */ -#include -#include -#include -#include +#include +#include +#include +#include #define TTM_ASSERT_LOCKED(param) #define TTM_DEBUG(fmt, arg...) diff --git a/sys/dev/drm2/ttm/ttm_bo_api.h b/sys/dev/drm/ttm/ttm_bo_api.h similarity index 99% rename from sys/dev/drm2/ttm/ttm_bo_api.h rename to sys/dev/drm/ttm/ttm_bo_api.h index a4f04713ef..4819b68963 100644 --- a/sys/dev/drm2/ttm/ttm_bo_api.h +++ b/sys/dev/drm/ttm/ttm_bo_api.h @@ -32,7 +32,7 @@ #ifndef _TTM_BO_API_H_ #define _TTM_BO_API_H_ -#include +#include struct ttm_bo_device; diff --git a/sys/dev/drm2/ttm/ttm_bo_driver.h b/sys/dev/drm/ttm/ttm_bo_driver.h similarity index 99% rename from sys/dev/drm2/ttm/ttm_bo_driver.h rename to sys/dev/drm/ttm/ttm_bo_driver.h index 2660120e1f..fe4873848d 100644 --- a/sys/dev/drm2/ttm/ttm_bo_driver.h +++ b/sys/dev/drm/ttm/ttm_bo_driver.h @@ -32,11 +32,11 @@ #ifndef _TTM_BO_DRIVER_H_ #define _TTM_BO_DRIVER_H_ -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include struct ttm_backend_func { diff --git a/sys/dev/drm2/ttm/ttm_bo_manager.c b/sys/dev/drm/ttm/ttm_bo_manager.c similarity index 96% rename from sys/dev/drm2/ttm/ttm_bo_manager.c rename to sys/dev/drm/ttm/ttm_bo_manager.c index 9aaa80b423..ca839824e5 100644 --- a/sys/dev/drm2/ttm/ttm_bo_manager.c +++ b/sys/dev/drm/ttm/ttm_bo_manager.c @@ -30,11 +30,11 @@ * $FreeBSD: head/sys/dev/drm2/ttm/ttm_bo_manager.c 247835 2013-03-05 09:49:34Z kib $ */ -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include /** * Currently we use a spinlock for the lock, but a mutex *may* be diff --git a/sys/dev/drm2/ttm/ttm_bo_util.c b/sys/dev/drm/ttm/ttm_bo_util.c similarity index 99% rename from sys/dev/drm2/ttm/ttm_bo_util.c rename to sys/dev/drm/ttm/ttm_bo_util.c index 4e86f830a9..ab560f229a 100644 --- a/sys/dev/drm2/ttm/ttm_bo_util.c +++ b/sys/dev/drm/ttm/ttm_bo_util.c @@ -30,9 +30,9 @@ * $FreeBSD: head/sys/dev/drm2/ttm/ttm_bo_util.c 248666 2013-03-23 22:23:15Z kib $ */ -#include -#include -#include +#include +#include +#include #include void ttm_bo_free_old_node(struct ttm_buffer_object *bo) diff --git a/sys/dev/drm2/ttm/ttm_bo_vm.c b/sys/dev/drm/ttm/ttm_bo_vm.c similarity index 98% rename from sys/dev/drm2/ttm/ttm_bo_vm.c rename to sys/dev/drm/ttm/ttm_bo_vm.c index d8c45f7b0e..8f8cedb351 100644 --- a/sys/dev/drm2/ttm/ttm_bo_vm.c +++ b/sys/dev/drm/ttm/ttm_bo_vm.c @@ -39,10 +39,10 @@ #include "opt_vm.h" -#include -#include -#include -#include +#include +#include +#include +#include #include #include diff --git a/sys/dev/drm2/ttm/ttm_execbuf_util.c b/sys/dev/drm/ttm/ttm_execbuf_util.c similarity index 97% rename from sys/dev/drm2/ttm/ttm_execbuf_util.c rename to sys/dev/drm/ttm/ttm_execbuf_util.c index 60057e4c1a..e231e0dfaa 100644 --- a/sys/dev/drm2/ttm/ttm_execbuf_util.c +++ b/sys/dev/drm/ttm/ttm_execbuf_util.c @@ -26,10 +26,10 @@ * $FreeBSD: head/sys/dev/drm2/ttm/ttm_execbuf_util.c 247835 2013-03-05 09:49:34Z kib $ **************************************************************************/ -#include -#include -#include -#include +#include +#include +#include +#include static void ttm_eu_backoff_reservation_locked(struct list_head *list) { diff --git a/sys/dev/drm2/ttm/ttm_execbuf_util.h b/sys/dev/drm/ttm/ttm_execbuf_util.h similarity index 99% rename from sys/dev/drm2/ttm/ttm_execbuf_util.h rename to sys/dev/drm/ttm/ttm_execbuf_util.h index 56843356f4..55704c6bc2 100644 --- a/sys/dev/drm2/ttm/ttm_execbuf_util.h +++ b/sys/dev/drm/ttm/ttm_execbuf_util.h @@ -32,7 +32,7 @@ #ifndef _TTM_EXECBUF_UTIL_H_ #define _TTM_EXECBUF_UTIL_H_ -#include +#include /** * struct ttm_validate_buffer diff --git a/sys/dev/drm2/ttm/ttm_lock.c b/sys/dev/drm/ttm/ttm_lock.c similarity index 99% rename from sys/dev/drm2/ttm/ttm_lock.c rename to sys/dev/drm/ttm/ttm_lock.c index 07a294a55e..73becfbba6 100644 --- a/sys/dev/drm2/ttm/ttm_lock.c +++ b/sys/dev/drm/ttm/ttm_lock.c @@ -37,8 +37,8 @@ * $FreeBSD: head/sys/dev/drm2/ttm/ttm_lock.c 247835 2013-03-05 09:49:34Z kib $ */ -#include -#include +#include +#include #define TTM_WRITE_LOCK_PENDING (1 << 0) #define TTM_VT_LOCK_PENDING (1 << 1) diff --git a/sys/dev/drm2/ttm/ttm_lock.h b/sys/dev/drm/ttm/ttm_lock.h similarity index 98% rename from sys/dev/drm2/ttm/ttm_lock.h rename to sys/dev/drm/ttm/ttm_lock.h index 40013bee42..528197f76b 100644 --- a/sys/dev/drm2/ttm/ttm_lock.h +++ b/sys/dev/drm/ttm/ttm_lock.h @@ -50,9 +50,9 @@ #ifndef _TTM_LOCK_H_ #define _TTM_LOCK_H_ -#include -#include -#include +#include +#include +#include /** * struct ttm_lock diff --git a/sys/dev/drm2/ttm/ttm_memory.c b/sys/dev/drm/ttm/ttm_memory.c similarity index 98% rename from sys/dev/drm2/ttm/ttm_memory.c rename to sys/dev/drm/ttm/ttm_memory.c index 28c9608298..71e82bfaad 100644 --- a/sys/dev/drm2/ttm/ttm_memory.c +++ b/sys/dev/drm/ttm/ttm_memory.c @@ -26,10 +26,10 @@ * $FreeBSD: head/sys/dev/drm2/ttm/ttm_memory.c 248663 2013-03-23 20:46:47Z dumbbell $ **************************************************************************/ -#include -#include -#include -#include +#include +#include +#include +#include #define TTM_MEMORY_ALLOC_RETRIES 4 diff --git a/sys/dev/drm2/ttm/ttm_memory.h b/sys/dev/drm/ttm/ttm_memory.h similarity index 100% rename from sys/dev/drm2/ttm/ttm_memory.h rename to sys/dev/drm/ttm/ttm_memory.h diff --git a/sys/dev/drm2/ttm/ttm_module.h b/sys/dev/drm/ttm/ttm_module.h similarity index 100% rename from sys/dev/drm2/ttm/ttm_module.h rename to sys/dev/drm/ttm/ttm_module.h diff --git a/sys/dev/drm2/ttm/ttm_object.c b/sys/dev/drm/ttm/ttm_object.c similarity index 98% rename from sys/dev/drm2/ttm/ttm_object.c rename to sys/dev/drm/ttm/ttm_object.c index 3bc5336a57..59a349acc1 100644 --- a/sys/dev/drm2/ttm/ttm_object.c +++ b/sys/dev/drm/ttm/ttm_object.c @@ -53,10 +53,10 @@ #define pr_fmt(fmt) "[TTM] " fmt -#include -#include -#include -#include +#include +#include +#include +#include struct ttm_object_file { struct ttm_object_device *tdev; diff --git a/sys/dev/drm2/ttm/ttm_object.h b/sys/dev/drm/ttm/ttm_object.h similarity index 99% rename from sys/dev/drm2/ttm/ttm_object.h rename to sys/dev/drm/ttm/ttm_object.h index b8f4da1baf..1895b4eace 100644 --- a/sys/dev/drm2/ttm/ttm_object.h +++ b/sys/dev/drm/ttm/ttm_object.h @@ -38,8 +38,8 @@ #ifndef _TTM_OBJECT_H_ #define _TTM_OBJECT_H_ -#include -#include +#include +#include /** * enum ttm_ref_type diff --git a/sys/dev/drm2/ttm/ttm_page_alloc.c b/sys/dev/drm/ttm/ttm_page_alloc.c similarity index 99% rename from sys/dev/drm2/ttm/ttm_page_alloc.c rename to sys/dev/drm/ttm/ttm_page_alloc.c index 7c0fe01018..8cac8de8da 100644 --- a/sys/dev/drm2/ttm/ttm_page_alloc.c +++ b/sys/dev/drm/ttm/ttm_page_alloc.c @@ -42,9 +42,9 @@ #include -#include -#include -#include +#include +#include +#include #ifdef TTM_HAS_AGP #include diff --git a/sys/dev/drm2/ttm/ttm_page_alloc.h b/sys/dev/drm/ttm/ttm_page_alloc.h similarity index 97% rename from sys/dev/drm2/ttm/ttm_page_alloc.h rename to sys/dev/drm/ttm/ttm_page_alloc.h index 92c5d02b11..538076ac22 100644 --- a/sys/dev/drm2/ttm/ttm_page_alloc.h +++ b/sys/dev/drm/ttm/ttm_page_alloc.h @@ -27,8 +27,8 @@ #ifndef TTM_PAGE_ALLOC #define TTM_PAGE_ALLOC -#include -#include +#include +#include /** * Initialize pool allocator. diff --git a/sys/dev/drm2/ttm/ttm_page_alloc_dma.c b/sys/dev/drm/ttm/ttm_page_alloc_dma.c similarity index 100% rename from sys/dev/drm2/ttm/ttm_page_alloc_dma.c rename to sys/dev/drm/ttm/ttm_page_alloc_dma.c diff --git a/sys/dev/drm2/ttm/ttm_placement.h b/sys/dev/drm/ttm/ttm_placement.h similarity index 100% rename from sys/dev/drm2/ttm/ttm_placement.h rename to sys/dev/drm/ttm/ttm_placement.h diff --git a/sys/dev/drm2/ttm/ttm_tt.c b/sys/dev/drm/ttm/ttm_tt.c similarity index 98% rename from sys/dev/drm2/ttm/ttm_tt.c rename to sys/dev/drm/ttm/ttm_tt.c index 853d38ea62..687744be9d 100644 --- a/sys/dev/drm2/ttm/ttm_tt.c +++ b/sys/dev/drm/ttm/ttm_tt.c @@ -37,11 +37,11 @@ * $FreeBSD: head/sys/dev/drm2/ttm/ttm_tt.c 251452 2013-06-06 06:17:20Z alc $ */ -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include MALLOC_DEFINE(M_TTM_PD, "ttm_pd", "TTM Page Directories"); diff --git a/sys/dev/drm2/Makefile b/sys/dev/drm2/Makefile deleted file mode 100644 index 6ba4e0e178..0000000000 --- a/sys/dev/drm2/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -SUBDIR = drmn i915 - -.include diff --git a/sys/dev/drm2/drm.h b/sys/dev/drm2/drm.h deleted file mode 100644 index 886d88deca..0000000000 --- a/sys/dev/drm2/drm.h +++ /dev/null @@ -1,1213 +0,0 @@ -/** - * \file drm.h - * Header for the Direct Rendering Manager - * - * \author Rickard E. (Rik) Faith - * - * \par Acknowledgments: - * Dec 1999, Richard Henderson , move to generic \c cmpxchg. - */ - -/*- - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * 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, 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS 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. - * - * $FreeBSD: src/sys/dev/drm2/drm.h,v 1.1 2012/05/22 11:07:44 kib Exp $ - */ - -/** - * \mainpage - * - * The Direct Rendering Manager (DRM) is a device-independent kernel-level - * device driver that provides support for the XFree86 Direct Rendering - * Infrastructure (DRI). - * - * The DRM supports the Direct Rendering Infrastructure (DRI) in four major - * ways: - * -# The DRM provides synchronized access to the graphics hardware via - * the use of an optimized two-tiered lock. - * -# The DRM enforces the DRI security policy for access to the graphics - * hardware by only allowing authenticated X11 clients access to - * restricted regions of memory. - * -# The DRM provides a generic DMA engine, complete with multiple - * queues and the ability to detect the need for an OpenGL context - * switch. - * -# The DRM is extensible via the use of small device-specific modules - * that rely extensively on the API exported by the DRM module. - * - */ - -#ifndef _DRM_H_ -#define _DRM_H_ - -#ifndef __user -#define __user -#endif -#ifndef __iomem -#define __iomem -#endif - -#ifdef __GNUC__ -# define DEPRECATED __attribute__ ((deprecated)) -#else -# define DEPRECATED -#endif - -#if defined(__linux__) -#include /* For _IO* macros */ -#define DRM_IOCTL_NR(n) _IOC_NR(n) -#define DRM_IOC_VOID _IOC_NONE -#define DRM_IOC_READ _IOC_READ -#define DRM_IOC_WRITE _IOC_WRITE -#define DRM_IOC_READWRITE _IOC_READ|_IOC_WRITE -#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size) -#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) -#include -#define DRM_IOCTL_NR(n) ((n) & 0xff) -#define DRM_IOC_VOID IOC_VOID -#define DRM_IOC_READ IOC_OUT -#define DRM_IOC_WRITE IOC_IN -#define DRM_IOC_READWRITE IOC_INOUT -#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size) -#endif - -#ifdef __OpenBSD__ -#define DRM_MAJOR 81 -#endif -#if defined(__linux__) || defined(__NetBSD__) -#define DRM_MAJOR 226 -#endif -#define DRM_MAX_MINOR 15 - -#define DRM_NAME "drm" /**< Name in kernel, /dev, and /proc */ -#define DRM_MIN_ORDER 5 /**< At least 2^5 bytes = 32 bytes */ -#define DRM_MAX_ORDER 22 /**< Up to 2^22 bytes = 4MB */ -#define DRM_RAM_PERCENT 10 /**< How much system ram can we lock? */ - -#define _DRM_LOCK_HELD 0x80000000U /**< Hardware lock is held */ -#define _DRM_LOCK_CONT 0x40000000U /**< Hardware lock is contended */ -#define _DRM_LOCK_IS_HELD(lock) ((lock) & _DRM_LOCK_HELD) -#define _DRM_LOCK_IS_CONT(lock) ((lock) & _DRM_LOCK_CONT) -#define _DRM_LOCKING_CONTEXT(lock) ((lock) & ~(_DRM_LOCK_HELD|_DRM_LOCK_CONT)) - -#if defined(__linux__) -typedef unsigned int drm_handle_t; -#else -#include -typedef unsigned long drm_handle_t; /**< To mapped regions */ -#endif -typedef unsigned int drm_context_t; /**< GLXContext handle */ -typedef unsigned int drm_drawable_t; -typedef unsigned int drm_magic_t; /**< Magic for authentication */ - -/** - * Cliprect. - * - * \warning If you change this structure, make sure you change - * XF86DRIClipRectRec in the server as well - * - * \note KW: Actually it's illegal to change either for - * backwards-compatibility reasons. - */ -struct drm_clip_rect { - unsigned short x1; - unsigned short y1; - unsigned short x2; - unsigned short y2; -}; - -/** - * Texture region, - */ -struct drm_tex_region { - unsigned char next; - unsigned char prev; - unsigned char in_use; - unsigned char padding; - unsigned int age; -}; - -/** - * Hardware lock. - * - * The lock structure is a simple cache-line aligned integer. To avoid - * processor bus contention on a multiprocessor system, there should not be any - * other data stored in the same cache line. - */ -struct drm_hw_lock { - __volatile__ unsigned int lock; /**< lock variable */ - char padding[60]; /**< Pad to cache line */ -}; - -/* This is beyond ugly, and only works on GCC. However, it allows me to use - * drm.h in places (i.e., in the X-server) where I can't use size_t. The real - * fix is to use uint32_t instead of size_t, but that fix will break existing - * LP64 (i.e., PowerPC64, SPARC64, IA-64, Alpha, etc.) systems. That *will* - * eventually happen, though. I chose 'unsigned long' to be the fallback type - * because that works on all the platforms I know about. Hopefully, the - * real fix will happen before that bites us. - */ - -#ifdef __SIZE_TYPE__ -# define DRM_SIZE_T __SIZE_TYPE__ -#else -# warning "__SIZE_TYPE__ not defined. Assuming sizeof(size_t) == sizeof(unsigned long)!" -# define DRM_SIZE_T unsigned long -#endif - -/** - * DRM_IOCTL_VERSION ioctl argument type. - * - * \sa drmGetVersion(). - */ -struct drm_version { - int version_major; /**< Major version */ - int version_minor; /**< Minor version */ - int version_patchlevel; /**< Patch level */ - DRM_SIZE_T name_len; /**< Length of name buffer */ - char __user *name; /**< Name of driver */ - DRM_SIZE_T date_len; /**< Length of date buffer */ - char __user *date; /**< User-space buffer to hold date */ - DRM_SIZE_T desc_len; /**< Length of desc buffer */ - char __user *desc; /**< User-space buffer to hold desc */ -}; - -/** - * DRM_IOCTL_GET_UNIQUE ioctl argument type. - * - * \sa drmGetBusid() and drmSetBusId(). - */ -struct drm_unique { - DRM_SIZE_T unique_len; /**< Length of unique */ - char __user *unique; /**< Unique name for driver instantiation */ -}; - -#undef DRM_SIZE_T - -struct drm_list { - int count; /**< Length of user-space structures */ - struct drm_version __user *version; -}; - -struct drm_block { - int unused; -}; - -/** - * DRM_IOCTL_CONTROL ioctl argument type. - * - * \sa drmCtlInstHandler() and drmCtlUninstHandler(). - */ -struct drm_control { - enum { - DRM_ADD_COMMAND, - DRM_RM_COMMAND, - DRM_INST_HANDLER, - DRM_UNINST_HANDLER - } func; - int irq; -}; - -/** - * Type of memory to map. - */ -enum drm_map_type { - _DRM_FRAME_BUFFER = 0, /**< WC (no caching), no core dump */ - _DRM_REGISTERS = 1, /**< no caching, no core dump */ - _DRM_SHM = 2, /**< shared, cached */ - _DRM_AGP = 3, /**< AGP/GART */ - _DRM_SCATTER_GATHER = 4, /**< Scatter/gather memory for PCI DMA */ - _DRM_CONSISTENT = 5, /**< Consistent memory for PCI DMA */ - _DRM_GEM = 6 /**< GEM */ -}; - -/** - * Memory mapping flags. - */ -enum drm_map_flags { - _DRM_RESTRICTED = 0x01, /**< Cannot be mapped to user-virtual */ - _DRM_READ_ONLY = 0x02, - _DRM_LOCKED = 0x04, /**< shared, cached, locked */ - _DRM_KERNEL = 0x08, /**< kernel requires access */ - _DRM_WRITE_COMBINING = 0x10, /**< use write-combining if available */ - _DRM_CONTAINS_LOCK = 0x20, /**< SHM page that contains lock */ - _DRM_REMOVABLE = 0x40, /**< Removable mapping */ - _DRM_DRIVER = 0x80 /**< Managed by driver */ -}; - -struct drm_ctx_priv_map { - unsigned int ctx_id; /**< Context requesting private mapping */ - void *handle; /**< Handle of map */ -}; - -/** - * DRM_IOCTL_GET_MAP, DRM_IOCTL_ADD_MAP and DRM_IOCTL_RM_MAP ioctls - * argument type. - * - * \sa drmAddMap(). - */ -struct drm_map { - unsigned long offset; /**< Requested physical address (0 for SAREA)*/ - unsigned long size; /**< Requested physical size (bytes) */ - enum drm_map_type type; /**< Type of memory to map */ - enum drm_map_flags flags; /**< Flags */ - void *handle; /**< User-space: "Handle" to pass to mmap() */ - /**< Kernel-space: kernel-virtual address */ - int mtrr; /**< MTRR slot used */ - /* Private data */ -}; - -/** - * DRM_IOCTL_GET_CLIENT ioctl argument type. - */ -struct drm_client { - int idx; /**< Which client desired? */ - int auth; /**< Is client authenticated? */ - unsigned long pid; /**< Process ID */ - unsigned long uid; /**< User ID */ - unsigned long magic; /**< Magic */ - unsigned long iocs; /**< Ioctl count */ -}; - -enum drm_stat_type { - _DRM_STAT_LOCK, - _DRM_STAT_OPENS, - _DRM_STAT_CLOSES, - _DRM_STAT_IOCTLS, - _DRM_STAT_LOCKS, - _DRM_STAT_UNLOCKS, - _DRM_STAT_VALUE, /**< Generic value */ - _DRM_STAT_BYTE, /**< Generic byte counter (1024bytes/K) */ - _DRM_STAT_COUNT, /**< Generic non-byte counter (1000/k) */ - - _DRM_STAT_IRQ, /**< IRQ */ - _DRM_STAT_PRIMARY, /**< Primary DMA bytes */ - _DRM_STAT_SECONDARY, /**< Secondary DMA bytes */ - _DRM_STAT_DMA, /**< DMA */ - _DRM_STAT_SPECIAL, /**< Special DMA (e.g., priority or polled) */ - _DRM_STAT_MISSED /**< Missed DMA opportunity */ - /* Add to the *END* of the list */ -}; - -/** - * DRM_IOCTL_GET_STATS ioctl argument type. - */ -struct drm_stats { - unsigned long count; - struct { - unsigned long value; - enum drm_stat_type type; - } data[15]; -}; - -/** - * Hardware locking flags. - */ -enum drm_lock_flags { - _DRM_LOCK_READY = 0x01, /**< Wait until hardware is ready for DMA */ - _DRM_LOCK_QUIESCENT = 0x02, /**< Wait until hardware quiescent */ - _DRM_LOCK_FLUSH = 0x04, /**< Flush this context's DMA queue first */ - _DRM_LOCK_FLUSH_ALL = 0x08, /**< Flush all DMA queues first */ - /* These *HALT* flags aren't supported yet - -- they will be used to support the - full-screen DGA-like mode. */ - _DRM_HALT_ALL_QUEUES = 0x10, /**< Halt all current and future queues */ - _DRM_HALT_CUR_QUEUES = 0x20 /**< Halt all current queues */ -}; - -/** - * DRM_IOCTL_LOCK, DRM_IOCTL_UNLOCK and DRM_IOCTL_FINISH ioctl argument type. - * - * \sa drmGetLock() and drmUnlock(). - */ -struct drm_lock { - int context; - enum drm_lock_flags flags; -}; - -/** - * DMA flags - * - * \warning - * These values \e must match xf86drm.h. - * - * \sa drm_dma. - */ -enum drm_dma_flags { - /* Flags for DMA buffer dispatch */ - _DRM_DMA_BLOCK = 0x01, /**< - * Block until buffer dispatched. - * - * \note The buffer may not yet have - * been processed by the hardware -- - * getting a hardware lock with the - * hardware quiescent will ensure - * that the buffer has been - * processed. - */ - _DRM_DMA_WHILE_LOCKED = 0x02, /**< Dispatch while lock held */ - _DRM_DMA_PRIORITY = 0x04, /**< High priority dispatch */ - - /* Flags for DMA buffer request */ - _DRM_DMA_WAIT = 0x10, /**< Wait for free buffers */ - _DRM_DMA_SMALLER_OK = 0x20, /**< Smaller-than-requested buffers OK */ - _DRM_DMA_LARGER_OK = 0x40 /**< Larger-than-requested buffers OK */ -}; - -/** - * DRM_IOCTL_ADD_BUFS and DRM_IOCTL_MARK_BUFS ioctl argument type. - * - * \sa drmAddBufs(). - */ -struct drm_buf_desc { - int count; /**< Number of buffers of this size */ - int size; /**< Size in bytes */ - int low_mark; /**< Low water mark */ - int high_mark; /**< High water mark */ - enum { - _DRM_PAGE_ALIGN = 0x01, /**< Align on page boundaries for DMA */ - _DRM_AGP_BUFFER = 0x02, /**< Buffer is in AGP space */ - _DRM_SG_BUFFER = 0x04, /**< Scatter/gather memory buffer */ - _DRM_FB_BUFFER = 0x08, /**< Buffer is in frame buffer */ - _DRM_PCI_BUFFER_RO = 0x10 /**< Map PCI DMA buffer read-only */ - } flags; - unsigned long agp_start; /**< - * Start address of where the AGP buffers are - * in the AGP aperture - */ -}; - -/** - * DRM_IOCTL_INFO_BUFS ioctl argument type. - */ -struct drm_buf_info { - int count; /**< Number of buffers described in list */ - struct drm_buf_desc __user *list; /**< List of buffer descriptions */ -}; - -/** - * DRM_IOCTL_FREE_BUFS ioctl argument type. - */ -struct drm_buf_free { - int count; - int __user *list; -}; - -/** - * Buffer information - * - * \sa drm_buf_map. - */ -struct drm_buf_pub { - int idx; /**< Index into the master buffer list */ - int total; /**< Buffer size */ - int used; /**< Amount of buffer in use (for DMA) */ - void __user *address; /**< Address of buffer */ -}; - -/** - * DRM_IOCTL_MAP_BUFS ioctl argument type. - */ -struct drm_buf_map { - int count; /**< Length of the buffer list */ -#if defined(__cplusplus) - void __user *c_virtual; -#else - void __user *virtual; /**< Mmap'd area in user-virtual */ -#endif - struct drm_buf_pub __user *list; /**< Buffer information */ -}; - -/** - * DRM_IOCTL_DMA ioctl argument type. - * - * Indices here refer to the offset into the buffer list in drm_buf_get. - * - * \sa drmDMA(). - */ -struct drm_dma { - int context; /**< Context handle */ - int send_count; /**< Number of buffers to send */ - int __user *send_indices; /**< List of handles to buffers */ - int __user *send_sizes; /**< Lengths of data to send */ - enum drm_dma_flags flags; /**< Flags */ - int request_count; /**< Number of buffers requested */ - int request_size; /**< Desired size for buffers */ - int __user *request_indices; /**< Buffer information */ - int __user *request_sizes; - int granted_count; /**< Number of buffers granted */ -}; - -enum drm_ctx_flags { - _DRM_CONTEXT_PRESERVED = 0x01, - _DRM_CONTEXT_2DONLY = 0x02 -}; - -/** - * DRM_IOCTL_ADD_CTX ioctl argument type. - * - * \sa drmCreateContext() and drmDestroyContext(). - */ -struct drm_ctx { - drm_context_t handle; - enum drm_ctx_flags flags; -}; - -/** - * DRM_IOCTL_RES_CTX ioctl argument type. - */ -struct drm_ctx_res { - int count; - struct drm_ctx __user *contexts; -}; - -/** - * DRM_IOCTL_ADD_DRAW and DRM_IOCTL_RM_DRAW ioctl argument type. - */ -struct drm_draw { - drm_drawable_t handle; -}; - -/** - * DRM_IOCTL_UPDATE_DRAW ioctl argument type. - */ -typedef enum { - DRM_DRAWABLE_CLIPRECTS, -} drm_drawable_info_type_t; - -struct drm_update_draw { - drm_drawable_t handle; - unsigned int type; - unsigned int num; - unsigned long long data; -}; - -/** - * DRM_IOCTL_GET_MAGIC and DRM_IOCTL_AUTH_MAGIC ioctl argument type. - */ -struct drm_auth { - drm_magic_t magic; -}; - -/** - * DRM_IOCTL_IRQ_BUSID ioctl argument type. - * - * \sa drmGetInterruptFromBusID(). - */ -struct drm_irq_busid { - int irq; /**< IRQ number */ - int busnum; /**< bus number */ - int devnum; /**< device number */ - int funcnum; /**< function number */ -}; - -enum drm_vblank_seq_type { - _DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */ - _DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */ - _DRM_VBLANK_HIGH_CRTC_MASK = 0x0000003e, - _DRM_VBLANK_EVENT = 0x4000000, /**< Send event instead of blocking */ - _DRM_VBLANK_FLIP = 0x8000000, /**< Scheduled buffer swap should flip */ - _DRM_VBLANK_NEXTONMISS = 0x10000000, /**< If missed, wait for next vblank */ - _DRM_VBLANK_SECONDARY = 0x20000000, /**< Secondary display controller */ - _DRM_VBLANK_SIGNAL = 0x40000000 /**< Send signal instead of blocking */ -}; -#define _DRM_VBLANK_HIGH_CRTC_SHIFT 1 - -#define _DRM_VBLANK_TYPES_MASK (_DRM_VBLANK_ABSOLUTE | _DRM_VBLANK_RELATIVE) -#define _DRM_VBLANK_FLAGS_MASK (_DRM_VBLANK_EVENT | _DRM_VBLANK_SIGNAL | \ - _DRM_VBLANK_SECONDARY | _DRM_VBLANK_NEXTONMISS) - -struct drm_wait_vblank_request { - enum drm_vblank_seq_type type; - unsigned int sequence; - unsigned long signal; -}; - -struct drm_wait_vblank_reply { - enum drm_vblank_seq_type type; - unsigned int sequence; - long tval_sec; - long tval_usec; -}; - -/** - * DRM_IOCTL_WAIT_VBLANK ioctl argument type. - * - * \sa drmWaitVBlank(). - */ -union drm_wait_vblank { - struct drm_wait_vblank_request request; - struct drm_wait_vblank_reply reply; -}; - - -#define _DRM_PRE_MODESET 1 -#define _DRM_POST_MODESET 2 - -/** - * DRM_IOCTL_MODESET_CTL ioctl argument type - * - * \sa drmModesetCtl(). - */ -struct drm_modeset_ctl { - uint32_t crtc; - uint32_t cmd; -}; - -/** - * DRM_IOCTL_AGP_ENABLE ioctl argument type. - * - * \sa drmAgpEnable(). - */ -struct drm_agp_mode { - unsigned long mode; /**< AGP mode */ -}; - -/** - * DRM_IOCTL_AGP_ALLOC and DRM_IOCTL_AGP_FREE ioctls argument type. - * - * \sa drmAgpAlloc() and drmAgpFree(). - */ -struct drm_agp_buffer { - unsigned long size; /**< In bytes -- will round to page boundary */ - unsigned long handle; /**< Used for binding / unbinding */ - unsigned long type; /**< Type of memory to allocate */ - unsigned long physical; /**< Physical used by i810 */ -}; - -/** - * DRM_IOCTL_AGP_BIND and DRM_IOCTL_AGP_UNBIND ioctls argument type. - * - * \sa drmAgpBind() and drmAgpUnbind(). - */ -struct drm_agp_binding { - unsigned long handle; /**< From drm_agp_buffer */ - unsigned long offset; /**< In bytes -- will round to page boundary */ -}; - -/** - * DRM_IOCTL_AGP_INFO ioctl argument type. - * - * \sa drmAgpVersionMajor(), drmAgpVersionMinor(), drmAgpGetMode(), - * drmAgpBase(), drmAgpSize(), drmAgpMemoryUsed(), drmAgpMemoryAvail(), - * drmAgpVendorId() and drmAgpDeviceId(). - */ -struct drm_agp_info { - int agp_version_major; - int agp_version_minor; - unsigned long mode; - unsigned long aperture_base; /**< physical address */ - unsigned long aperture_size; /**< bytes */ - unsigned long memory_allowed; /**< bytes */ - unsigned long memory_used; - - /** \name PCI information */ - /*@{ */ - unsigned short id_vendor; - unsigned short id_device; - /*@} */ -}; - -/** - * DRM_IOCTL_SG_ALLOC ioctl argument type. - */ -struct drm_scatter_gather { - unsigned long size; /**< In bytes -- will round to page boundary */ - unsigned long handle; /**< Used for mapping / unmapping */ -}; - -/** - * DRM_IOCTL_SET_VERSION ioctl argument type. - */ -struct drm_set_version { - int drm_di_major; - int drm_di_minor; - int drm_dd_major; - int drm_dd_minor; -}; - -#define DRM_FENCE_FLAG_EMIT 0x00000001 -#define DRM_FENCE_FLAG_SHAREABLE 0x00000002 -/** - * On hardware with no interrupt events for operation completion, - * indicates that the kernel should sleep while waiting for any blocking - * operation to complete rather than spinning. - * - * Has no effect otherwise. - */ -#define DRM_FENCE_FLAG_WAIT_LAZY 0x00000004 -#define DRM_FENCE_FLAG_NO_USER 0x00000010 - -/* Reserved for driver use */ -#define DRM_FENCE_MASK_DRIVER 0xFF000000 - -#define DRM_FENCE_TYPE_EXE 0x00000001 - -struct drm_fence_arg { - unsigned int handle; - unsigned int fence_class; - unsigned int type; - unsigned int flags; - unsigned int signaled; - unsigned int error; - unsigned int sequence; - unsigned int pad64; - uint64_t expand_pad[2]; /* Future expansion */ -}; - -/* Buffer permissions, referring to how the GPU uses the buffers. - * these translate to fence types used for the buffers. - * Typically a texture buffer is read, A destination buffer is write and - * a command (batch-) buffer is exe. Can be or-ed together. - */ - -#define DRM_BO_FLAG_READ (1ULL << 0) -#define DRM_BO_FLAG_WRITE (1ULL << 1) -#define DRM_BO_FLAG_EXE (1ULL << 2) - -/* - * All of the bits related to access mode - */ -#define DRM_BO_MASK_ACCESS (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_EXE) -/* - * Status flags. Can be read to determine the actual state of a buffer. - * Can also be set in the buffer mask before validation. - */ - -/* - * Mask: Never evict this buffer. Not even with force. This type of buffer is only - * available to root and must be manually removed before buffer manager shutdown - * or lock. - * Flags: Acknowledge - */ -#define DRM_BO_FLAG_NO_EVICT (1ULL << 4) - -/* - * Mask: Require that the buffer is placed in mappable memory when validated. - * If not set the buffer may or may not be in mappable memory when validated. - * Flags: If set, the buffer is in mappable memory. - */ -#define DRM_BO_FLAG_MAPPABLE (1ULL << 5) - -/* Mask: The buffer should be shareable with other processes. - * Flags: The buffer is shareable with other processes. - */ -#define DRM_BO_FLAG_SHAREABLE (1ULL << 6) - -/* Mask: If set, place the buffer in cache-coherent memory if available. - * If clear, never place the buffer in cache coherent memory if validated. - * Flags: The buffer is currently in cache-coherent memory. - */ -#define DRM_BO_FLAG_CACHED (1ULL << 7) - -/* Mask: Make sure that every time this buffer is validated, - * it ends up on the same location provided that the memory mask is the same. - * The buffer will also not be evicted when claiming space for - * other buffers. Basically a pinned buffer but it may be thrown out as - * part of buffer manager shutdown or locking. - * Flags: Acknowledge. - */ -#define DRM_BO_FLAG_NO_MOVE (1ULL << 8) - -/* Mask: Make sure the buffer is in cached memory when mapped. In conjunction - * with DRM_BO_FLAG_CACHED it also allows the buffer to be bound into the GART - * with unsnooped PTEs instead of snooped, by using chipset-specific cache - * flushing at bind time. A better name might be DRM_BO_FLAG_TT_UNSNOOPED, - * as the eviction to local memory (TTM unbind) on map is just a side effect - * to prevent aggressive cache prefetch from the GPU disturbing the cache - * management that the DRM is doing. - * - * Flags: Acknowledge. - * Buffers allocated with this flag should not be used for suballocators - * This type may have issues on CPUs with over-aggressive caching - * http://marc.info/?l=linux-kernel&m=102376926732464&w=2 - */ -#define DRM_BO_FLAG_CACHED_MAPPED (1ULL << 19) - - -/* Mask: Force DRM_BO_FLAG_CACHED flag strictly also if it is set. - * Flags: Acknowledge. - */ -#define DRM_BO_FLAG_FORCE_CACHING (1ULL << 13) - -/* - * Mask: Force DRM_BO_FLAG_MAPPABLE flag strictly also if it is clear. - * Flags: Acknowledge. - */ -#define DRM_BO_FLAG_FORCE_MAPPABLE (1ULL << 14) -#define DRM_BO_FLAG_TILE (1ULL << 15) - -/* - * Memory type flags that can be or'ed together in the mask, but only - * one appears in flags. - */ - -/* System memory */ -#define DRM_BO_FLAG_MEM_LOCAL (1ULL << 24) -/* Translation table memory */ -#define DRM_BO_FLAG_MEM_TT (1ULL << 25) -/* Vram memory */ -#define DRM_BO_FLAG_MEM_VRAM (1ULL << 26) -/* Up to the driver to define. */ -#define DRM_BO_FLAG_MEM_PRIV0 (1ULL << 27) -#define DRM_BO_FLAG_MEM_PRIV1 (1ULL << 28) -#define DRM_BO_FLAG_MEM_PRIV2 (1ULL << 29) -#define DRM_BO_FLAG_MEM_PRIV3 (1ULL << 30) -#define DRM_BO_FLAG_MEM_PRIV4 (1ULL << 31) -/* We can add more of these now with a 64-bit flag type */ - -/* - * This is a mask covering all of the memory type flags; easier to just - * use a single constant than a bunch of | values. It covers - * DRM_BO_FLAG_MEM_LOCAL through DRM_BO_FLAG_MEM_PRIV4 - */ -#define DRM_BO_MASK_MEM 0x00000000FF000000ULL -/* - * This adds all of the CPU-mapping options in with the memory - * type to label all bits which change how the page gets mapped - */ -#define DRM_BO_MASK_MEMTYPE (DRM_BO_MASK_MEM | \ - DRM_BO_FLAG_CACHED_MAPPED | \ - DRM_BO_FLAG_CACHED | \ - DRM_BO_FLAG_MAPPABLE) - -/* Driver-private flags */ -#define DRM_BO_MASK_DRIVER 0xFFFF000000000000ULL - -/* - * Don't block on validate and map. Instead, return EBUSY. - */ -#define DRM_BO_HINT_DONT_BLOCK 0x00000002 -/* - * Don't place this buffer on the unfenced list. This means - * that the buffer will not end up having a fence associated - * with it as a result of this operation - */ -#define DRM_BO_HINT_DONT_FENCE 0x00000004 -/** - * On hardware with no interrupt events for operation completion, - * indicates that the kernel should sleep while waiting for any blocking - * operation to complete rather than spinning. - * - * Has no effect otherwise. - */ -#define DRM_BO_HINT_WAIT_LAZY 0x00000008 -/* - * The client has compute relocations refering to this buffer using the - * offset in the presumed_offset field. If that offset ends up matching - * where this buffer lands, the kernel is free to skip executing those - * relocations - */ -#define DRM_BO_HINT_PRESUMED_OFFSET 0x00000010 - -#define DRM_BO_INIT_MAGIC 0xfe769812 -#define DRM_BO_INIT_MAJOR 1 -#define DRM_BO_INIT_MINOR 0 -#define DRM_BO_INIT_PATCH 0 - - -struct drm_bo_info_req { - uint64_t mask; - uint64_t flags; - unsigned int handle; - unsigned int hint; - unsigned int fence_class; - unsigned int desired_tile_stride; - unsigned int tile_info; - unsigned int pad64; - uint64_t presumed_offset; -}; - -struct drm_bo_create_req { - uint64_t flags; - uint64_t size; - uint64_t buffer_start; - unsigned int hint; - unsigned int page_alignment; -}; - - -/* - * Reply flags - */ - -#define DRM_BO_REP_BUSY 0x00000001 - -struct drm_bo_info_rep { - uint64_t flags; - uint64_t proposed_flags; - uint64_t size; - uint64_t offset; - uint64_t arg_handle; - uint64_t buffer_start; - unsigned int handle; - unsigned int fence_flags; - unsigned int rep_flags; - unsigned int page_alignment; - unsigned int desired_tile_stride; - unsigned int hw_tile_stride; - unsigned int tile_info; - unsigned int pad64; - uint64_t expand_pad[4]; /*Future expansion */ -}; - -struct drm_bo_arg_rep { - struct drm_bo_info_rep bo_info; - int ret; - unsigned int pad64; -}; - -struct drm_bo_create_arg { - union { - struct drm_bo_create_req req; - struct drm_bo_info_rep rep; - } d; -}; - -struct drm_bo_handle_arg { - unsigned int handle; -}; - -struct drm_bo_reference_info_arg { - union { - struct drm_bo_handle_arg req; - struct drm_bo_info_rep rep; - } d; -}; - -struct drm_bo_map_wait_idle_arg { - union { - struct drm_bo_info_req req; - struct drm_bo_info_rep rep; - } d; -}; - -struct drm_bo_op_req { - enum { - drm_bo_validate, - drm_bo_fence, - drm_bo_ref_fence, - } op; - unsigned int arg_handle; - struct drm_bo_info_req bo_req; -}; - - -struct drm_bo_op_arg { - uint64_t next; - union { - struct drm_bo_op_req req; - struct drm_bo_arg_rep rep; - } d; - int handled; - unsigned int pad64; -}; - - -#define DRM_BO_MEM_LOCAL 0 -#define DRM_BO_MEM_TT 1 -#define DRM_BO_MEM_VRAM 2 -#define DRM_BO_MEM_PRIV0 3 -#define DRM_BO_MEM_PRIV1 4 -#define DRM_BO_MEM_PRIV2 5 -#define DRM_BO_MEM_PRIV3 6 -#define DRM_BO_MEM_PRIV4 7 - -#define DRM_BO_MEM_TYPES 8 /* For now. */ - -#define DRM_BO_LOCK_UNLOCK_BM (1 << 0) -#define DRM_BO_LOCK_IGNORE_NO_EVICT (1 << 1) - -struct drm_bo_version_arg { - uint32_t major; - uint32_t minor; - uint32_t patchlevel; -}; - -struct drm_mm_type_arg { - unsigned int mem_type; - unsigned int lock_flags; -}; - -struct drm_mm_init_arg { - unsigned int magic; - unsigned int major; - unsigned int minor; - unsigned int mem_type; - uint64_t p_offset; - uint64_t p_size; -}; - -struct drm_mm_info_arg { - unsigned int mem_type; - uint64_t p_size; -}; - -struct drm_gem_close { - /** Handle of the object to be closed. */ - uint32_t handle; - uint32_t pad; -}; - -struct drm_gem_flink { - /** Handle for the object being named */ - uint32_t handle; - - /** Returned global name */ - uint32_t name; -}; - -struct drm_gem_open { - /** Name of object being opened */ - uint32_t name; - - /** Returned handle for the object */ - uint32_t handle; - - /** Returned size of the object */ - uint64_t size; -}; - -struct drm_get_cap { - uint64_t capability; - uint64_t value; -}; - -struct drm_event { - uint32_t type; - uint32_t length; -}; - -#define DRM_EVENT_VBLANK 0x01 -#define DRM_EVENT_FLIP_COMPLETE 0x02 - -struct drm_event_vblank { - struct drm_event base; - uint64_t user_data; - uint32_t tv_sec; - uint32_t tv_usec; - uint32_t sequence; - uint32_t reserved; -}; - -#define DRM_CAP_DUMB_BUFFER 0x1 -#define DRM_CAP_VBLANK_HIGH_CRTC 0x2 -#define DRM_CAP_DUMB_PREFERRED_DEPTH 0x3 -#define DRM_CAP_DUMB_PREFER_SHADOW 0x4 - -#include "drm_mode.h" - -/** - * \name Ioctls Definitions - */ -/*@{*/ - -#define DRM_IOCTL_BASE 'd' -#define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr) -#define DRM_IOR(nr,type) _IOR(DRM_IOCTL_BASE,nr,type) -#define DRM_IOW(nr,type) _IOW(DRM_IOCTL_BASE,nr,type) -#define DRM_IOWR(nr,type) _IOWR(DRM_IOCTL_BASE,nr,type) - -#define DRM_IOCTL_VERSION DRM_IOWR(0x00, struct drm_version) -#define DRM_IOCTL_GET_UNIQUE DRM_IOWR(0x01, struct drm_unique) -#define DRM_IOCTL_GET_MAGIC DRM_IOR( 0x02, struct drm_auth) -#define DRM_IOCTL_IRQ_BUSID DRM_IOWR(0x03, struct drm_irq_busid) -#define DRM_IOCTL_GET_MAP DRM_IOWR(0x04, struct drm_map) -#define DRM_IOCTL_GET_CLIENT DRM_IOWR(0x05, struct drm_client) -#define DRM_IOCTL_GET_STATS DRM_IOR( 0x06, struct drm_stats) -#define DRM_IOCTL_SET_VERSION DRM_IOWR(0x07, struct drm_set_version) -#define DRM_IOCTL_MODESET_CTL DRM_IOW(0x08, struct drm_modeset_ctl) - -#define DRM_IOCTL_GEM_CLOSE DRM_IOW (0x09, struct drm_gem_close) -#define DRM_IOCTL_GEM_FLINK DRM_IOWR(0x0a, struct drm_gem_flink) -#define DRM_IOCTL_GEM_OPEN DRM_IOWR(0x0b, struct drm_gem_open) - -#define DRM_IOCTL_GET_CAP DRM_IOWR(0x0c, struct drm_get_cap) - -#define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, struct drm_unique) -#define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, struct drm_auth) -#define DRM_IOCTL_BLOCK DRM_IOWR(0x12, struct drm_block) -#define DRM_IOCTL_UNBLOCK DRM_IOWR(0x13, struct drm_block) -#define DRM_IOCTL_CONTROL DRM_IOW( 0x14, struct drm_control) -#define DRM_IOCTL_ADD_MAP DRM_IOWR(0x15, struct drm_map) -#define DRM_IOCTL_ADD_BUFS DRM_IOWR(0x16, struct drm_buf_desc) -#define DRM_IOCTL_MARK_BUFS DRM_IOW( 0x17, struct drm_buf_desc) -#define DRM_IOCTL_INFO_BUFS DRM_IOWR(0x18, struct drm_buf_info) -#define DRM_IOCTL_MAP_BUFS DRM_IOWR(0x19, struct drm_buf_map) -#define DRM_IOCTL_FREE_BUFS DRM_IOW( 0x1a, struct drm_buf_free) - -#define DRM_IOCTL_RM_MAP DRM_IOW( 0x1b, struct drm_map) - -#define DRM_IOCTL_SET_SAREA_CTX DRM_IOW( 0x1c, struct drm_ctx_priv_map) -#define DRM_IOCTL_GET_SAREA_CTX DRM_IOWR(0x1d, struct drm_ctx_priv_map) - -#define DRM_IOCTL_SET_MASTER DRM_IO(0x1e) -#define DRM_IOCTL_DROP_MASTER DRM_IO(0x1f) - -#define DRM_IOCTL_ADD_CTX DRM_IOWR(0x20, struct drm_ctx) -#define DRM_IOCTL_RM_CTX DRM_IOWR(0x21, struct drm_ctx) -#define DRM_IOCTL_MOD_CTX DRM_IOW( 0x22, struct drm_ctx) -#define DRM_IOCTL_GET_CTX DRM_IOWR(0x23, struct drm_ctx) -#define DRM_IOCTL_SWITCH_CTX DRM_IOW( 0x24, struct drm_ctx) -#define DRM_IOCTL_NEW_CTX DRM_IOW( 0x25, struct drm_ctx) -#define DRM_IOCTL_RES_CTX DRM_IOWR(0x26, struct drm_ctx_res) -#define DRM_IOCTL_ADD_DRAW DRM_IOWR(0x27, struct drm_draw) -#define DRM_IOCTL_RM_DRAW DRM_IOWR(0x28, struct drm_draw) -#define DRM_IOCTL_DMA DRM_IOWR(0x29, struct drm_dma) -#define DRM_IOCTL_LOCK DRM_IOW( 0x2a, struct drm_lock) -#define DRM_IOCTL_UNLOCK DRM_IOW( 0x2b, struct drm_lock) -#define DRM_IOCTL_FINISH DRM_IOW( 0x2c, struct drm_lock) - -#define DRM_IOCTL_GEM_PRIME_OPEN DRM_IOWR(0x2e, struct drm_gem_open) - -#define DRM_IOCTL_AGP_ACQUIRE DRM_IO( 0x30) -#define DRM_IOCTL_AGP_RELEASE DRM_IO( 0x31) -#define DRM_IOCTL_AGP_ENABLE DRM_IOW( 0x32, struct drm_agp_mode) -#define DRM_IOCTL_AGP_INFO DRM_IOR( 0x33, struct drm_agp_info) -#define DRM_IOCTL_AGP_ALLOC DRM_IOWR(0x34, struct drm_agp_buffer) -#define DRM_IOCTL_AGP_FREE DRM_IOW( 0x35, struct drm_agp_buffer) -#define DRM_IOCTL_AGP_BIND DRM_IOW( 0x36, struct drm_agp_binding) -#define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, struct drm_agp_binding) - -#define DRM_IOCTL_SG_ALLOC DRM_IOWR(0x38, struct drm_scatter_gather) -#define DRM_IOCTL_SG_FREE DRM_IOW( 0x39, struct drm_scatter_gather) - -#define DRM_IOCTL_WAIT_VBLANK DRM_IOWR(0x3a, union drm_wait_vblank) - -#define DRM_IOCTL_UPDATE_DRAW DRM_IOW(0x3f, struct drm_update_draw) - -#define DRM_IOCTL_MODE_GETRESOURCES DRM_IOWR(0xA0, struct drm_mode_card_res) -#define DRM_IOCTL_MODE_GETCRTC DRM_IOWR(0xA1, struct drm_mode_crtc) -#define DRM_IOCTL_MODE_SETCRTC DRM_IOWR(0xA2, struct drm_mode_crtc) -#define DRM_IOCTL_MODE_CURSOR DRM_IOWR(0xA3, struct drm_mode_cursor) -#define DRM_IOCTL_MODE_GETGAMMA DRM_IOWR(0xA4, struct drm_mode_crtc_lut) -#define DRM_IOCTL_MODE_SETGAMMA DRM_IOWR(0xA5, struct drm_mode_crtc_lut) -#define DRM_IOCTL_MODE_GETENCODER DRM_IOWR(0xA6, struct drm_mode_get_encoder) -#define DRM_IOCTL_MODE_GETCONNECTOR DRM_IOWR(0xA7, struct drm_mode_get_connector) -#define DRM_IOCTL_MODE_ATTACHMODE DRM_IOWR(0xA8, struct drm_mode_mode_cmd) -#define DRM_IOCTL_MODE_DETACHMODE DRM_IOWR(0xA9, struct drm_mode_mode_cmd) - -#define DRM_IOCTL_MODE_GETPROPERTY DRM_IOWR(0xAA, struct drm_mode_get_property) -#define DRM_IOCTL_MODE_SETPROPERTY DRM_IOWR(0xAB, struct drm_mode_connector_set_property) -#define DRM_IOCTL_MODE_GETPROPBLOB DRM_IOWR(0xAC, struct drm_mode_get_blob) -#define DRM_IOCTL_MODE_GETFB DRM_IOWR(0xAD, struct drm_mode_fb_cmd) -#define DRM_IOCTL_MODE_ADDFB DRM_IOWR(0xAE, struct drm_mode_fb_cmd) -#define DRM_IOCTL_MODE_RMFB DRM_IOWR(0xAF, unsigned int) -#define DRM_IOCTL_MODE_PAGE_FLIP DRM_IOWR(0xB0, struct drm_mode_crtc_page_flip) -#define DRM_IOCTL_MODE_DIRTYFB DRM_IOWR(0xB1, struct drm_mode_fb_dirty_cmd) - -#define DRM_IOCTL_MODE_CREATE_DUMB DRM_IOWR(0xB2, struct drm_mode_create_dumb) -#define DRM_IOCTL_MODE_MAP_DUMB DRM_IOWR(0xB3, struct drm_mode_map_dumb) -#define DRM_IOCTL_MODE_DESTROY_DUMB DRM_IOWR(0xB4, struct drm_mode_destroy_dumb) -#define DRM_IOCTL_MODE_GETPLANERESOURCES DRM_IOWR(0xB5, struct drm_mode_get_plane_res) -#define DRM_IOCTL_MODE_GETPLANE DRM_IOWR(0xB6, struct drm_mode_get_plane) -#define DRM_IOCTL_MODE_SETPLANE DRM_IOWR(0xB7, struct drm_mode_set_plane) -#define DRM_IOCTL_MODE_ADDFB2 DRM_IOWR(0xB8, struct drm_mode_fb_cmd2) - -#define DRM_IOCTL_MM_INIT DRM_IOWR(0xc0, struct drm_mm_init_arg) -#define DRM_IOCTL_MM_TAKEDOWN DRM_IOWR(0xc1, struct drm_mm_type_arg) -#define DRM_IOCTL_MM_LOCK DRM_IOWR(0xc2, struct drm_mm_type_arg) -#define DRM_IOCTL_MM_UNLOCK DRM_IOWR(0xc3, struct drm_mm_type_arg) - -#define DRM_IOCTL_FENCE_CREATE DRM_IOWR(0xc4, struct drm_fence_arg) -#define DRM_IOCTL_FENCE_REFERENCE DRM_IOWR(0xc6, struct drm_fence_arg) -#define DRM_IOCTL_FENCE_UNREFERENCE DRM_IOWR(0xc7, struct drm_fence_arg) -#define DRM_IOCTL_FENCE_SIGNALED DRM_IOWR(0xc8, struct drm_fence_arg) -#define DRM_IOCTL_FENCE_FLUSH DRM_IOWR(0xc9, struct drm_fence_arg) -#define DRM_IOCTL_FENCE_WAIT DRM_IOWR(0xca, struct drm_fence_arg) -#define DRM_IOCTL_FENCE_EMIT DRM_IOWR(0xcb, struct drm_fence_arg) -#define DRM_IOCTL_FENCE_BUFFERS DRM_IOWR(0xcc, struct drm_fence_arg) - -#define DRM_IOCTL_BO_CREATE DRM_IOWR(0xcd, struct drm_bo_create_arg) -#define DRM_IOCTL_BO_MAP DRM_IOWR(0xcf, struct drm_bo_map_wait_idle_arg) -#define DRM_IOCTL_BO_UNMAP DRM_IOWR(0xd0, struct drm_bo_handle_arg) -#define DRM_IOCTL_BO_REFERENCE DRM_IOWR(0xd1, struct drm_bo_reference_info_arg) -#define DRM_IOCTL_BO_UNREFERENCE DRM_IOWR(0xd2, struct drm_bo_handle_arg) -#define DRM_IOCTL_BO_SETSTATUS DRM_IOWR(0xd3, struct drm_bo_map_wait_idle_arg) -#define DRM_IOCTL_BO_INFO DRM_IOWR(0xd4, struct drm_bo_reference_info_arg) -#define DRM_IOCTL_BO_WAIT_IDLE DRM_IOWR(0xd5, struct drm_bo_map_wait_idle_arg) -#define DRM_IOCTL_BO_VERSION DRM_IOR(0xd6, struct drm_bo_version_arg) -#define DRM_IOCTL_MM_INFO DRM_IOWR(0xd7, struct drm_mm_info_arg) - -/*@}*/ - -/** - * Device specific ioctls should only be in their respective headers - * The device specific ioctl range is from 0x40 to 0x99. - * Generic IOCTLS restart at 0xA0. - * - * \sa drmCommandNone(), drmCommandRead(), drmCommandWrite(), and - * drmCommandReadWrite(). - */ -#define DRM_COMMAND_BASE 0x40 -#define DRM_COMMAND_END 0xA0 - -/* typedef area */ -#ifndef __KERNEL__ -typedef struct drm_clip_rect drm_clip_rect_t; -typedef struct drm_tex_region drm_tex_region_t; -typedef struct drm_hw_lock drm_hw_lock_t; -typedef struct drm_version drm_version_t; -typedef struct drm_unique drm_unique_t; -typedef struct drm_list drm_list_t; -typedef struct drm_block drm_block_t; -typedef struct drm_control drm_control_t; -typedef enum drm_map_type drm_map_type_t; -typedef enum drm_map_flags drm_map_flags_t; -typedef struct drm_ctx_priv_map drm_ctx_priv_map_t; -typedef struct drm_map drm_map_t; -typedef struct drm_client drm_client_t; -typedef enum drm_stat_type drm_stat_type_t; -typedef struct drm_stats drm_stats_t; -typedef enum drm_lock_flags drm_lock_flags_t; -typedef struct drm_lock drm_lock_t; -typedef enum drm_dma_flags drm_dma_flags_t; -typedef struct drm_buf_desc drm_buf_desc_t; -typedef struct drm_buf_info drm_buf_info_t; -typedef struct drm_buf_free drm_buf_free_t; -typedef struct drm_buf_pub drm_buf_pub_t; -typedef struct drm_buf_map drm_buf_map_t; -typedef struct drm_dma drm_dma_t; -typedef union drm_wait_vblank drm_wait_vblank_t; -typedef struct drm_agp_mode drm_agp_mode_t; -typedef enum drm_ctx_flags drm_ctx_flags_t; -typedef struct drm_ctx drm_ctx_t; -typedef struct drm_ctx_res drm_ctx_res_t; -typedef struct drm_draw drm_draw_t; -typedef struct drm_update_draw drm_update_draw_t; -typedef struct drm_auth drm_auth_t; -typedef struct drm_irq_busid drm_irq_busid_t; -typedef enum drm_vblank_seq_type drm_vblank_seq_type_t; -typedef struct drm_agp_buffer drm_agp_buffer_t; -typedef struct drm_agp_binding drm_agp_binding_t; -typedef struct drm_agp_info drm_agp_info_t; -typedef struct drm_scatter_gather drm_scatter_gather_t; -typedef struct drm_set_version drm_set_version_t; - -typedef struct drm_fence_arg drm_fence_arg_t; -typedef struct drm_mm_type_arg drm_mm_type_arg_t; -typedef struct drm_mm_init_arg drm_mm_init_arg_t; -typedef enum drm_bo_type drm_bo_type_t; -#endif - -#endif diff --git a/sys/dev/drm2/drmP.h b/sys/dev/drm2/drmP.h deleted file mode 100644 index 9b69de4211..0000000000 --- a/sys/dev/drm2/drmP.h +++ /dev/null @@ -1,1421 +0,0 @@ -/* drmP.h -- Private header for Direct Rendering Manager -*- linux-c -*- - * Created: Mon Jan 4 10:05:05 1999 by faith@precisioninsight.com - */ -/*- - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * 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, 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS 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. - * - * Authors: - * Rickard E. (Rik) Faith - * Gareth Hughes - * - * $FreeBSD: head/sys/dev/drm2/drmP.h 248084 2013-03-09 02:32:23Z attilio $ - */ - -#ifndef _DRM_P_H_ -#define _DRM_P_H_ - -#if defined(_KERNEL) || defined(__KERNEL__) - -struct drm_device; -struct drm_file; - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if defined(__i386__) || defined(__amd64__) -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -/* XXX: bool definition */ -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "opt_drm.h" -#ifdef DRM_DEBUG -#undef DRM_DEBUG -#define DRM_DEBUG_DEFAULT_ON 1 -#endif /* DRM_DEBUG */ - -#define DRM_DEBUGBITS_DEBUG 0x1 -#define DRM_DEBUGBITS_KMS 0x2 -#define DRM_DEBUGBITS_FAILED_IOCTL 0x4 - -#undef DRM_LINUX -#define DRM_LINUX 0 - -/* driver capabilities and requirements mask */ -#define DRIVER_USE_AGP 0x1 -#define DRIVER_REQUIRE_AGP 0x2 -#define DRIVER_USE_MTRR 0x4 -#define DRIVER_PCI_DMA 0x8 -#define DRIVER_SG 0x10 -#define DRIVER_HAVE_DMA 0x20 -#define DRIVER_HAVE_IRQ 0x40 -#define DRIVER_IRQ_SHARED 0x80 -#define DRIVER_IRQ_VBL 0x100 -#define DRIVER_DMA_QUEUE 0x200 -#define DRIVER_FB_DMA 0x400 -#define DRIVER_IRQ_VBL2 0x800 -#define DRIVER_GEM 0x1000 -#define DRIVER_MODESET 0x2000 -#define DRIVER_USE_PLATFORM_DEVICE 0x4000 -#define DRIVER_LOCKLESS_IRQ 0x8000 - - -#define DRM_HASH_SIZE 16 /* Size of key hash table */ -#define DRM_KERNEL_CONTEXT 0 /* Change drm_resctx if changed */ -#define DRM_RESERVED_CONTEXTS 1 /* Change drm_resctx if changed */ - -#define DRM_GEM_MAPPING_MASK (3ULL << 62) -#define DRM_GEM_MAPPING_KEY (2ULL << 62) /* Non-canonical address form */ -#define DRM_GEM_MAX_IDX 0x3fffff -#define DRM_GEM_MAPPING_IDX(o) (((o) >> 40) & DRM_GEM_MAX_IDX) -#define DRM_GEM_MAPPING_OFF(i) (((uint64_t)(i)) << 40) -#define DRM_GEM_MAPPING_MAPOFF(o) \ - ((o) & ~(DRM_GEM_MAPPING_OFF(DRM_GEM_MAX_IDX) | DRM_GEM_MAPPING_KEY)) - -MALLOC_DECLARE(DRM_MEM_DMA); -MALLOC_DECLARE(DRM_MEM_SAREA); -MALLOC_DECLARE(DRM_MEM_DRIVER); -MALLOC_DECLARE(DRM_MEM_MAGIC); -MALLOC_DECLARE(DRM_MEM_MAPS); -MALLOC_DECLARE(DRM_MEM_BUFS); -MALLOC_DECLARE(DRM_MEM_SEGS); -MALLOC_DECLARE(DRM_MEM_PAGES); -MALLOC_DECLARE(DRM_MEM_FILES); -MALLOC_DECLARE(DRM_MEM_BUFLISTS); -MALLOC_DECLARE(DRM_MEM_AGPLISTS); -MALLOC_DECLARE(DRM_MEM_CTXBITMAP); -MALLOC_DECLARE(DRM_MEM_SGLISTS); -MALLOC_DECLARE(DRM_MEM_DRAWABLE); -MALLOC_DECLARE(DRM_MEM_MM); -MALLOC_DECLARE(DRM_MEM_HASHTAB); -MALLOC_DECLARE(DRM_MEM_KMS); - -SYSCTL_DECL(_hw_drm); - -#define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8) - - /* Internal types and structures */ -#define DRM_ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) -#define DRM_MIN(a,b) ((a)<(b)?(a):(b)) -#define DRM_MAX(a,b) ((a)>(b)?(a):(b)) - -#define DRM_IF_VERSION(maj, min) (maj << 16 | min) - -#define __OS_HAS_AGP 1 - -#define DRM_DEV_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) -#define DRM_DEV_UID 0 -#define DRM_DEV_GID 0 - -#define wait_queue_head_t atomic_t -#define DRM_WAKEUP(w) wakeup((void *)w) -#define DRM_WAKEUP_INT(w) wakeup(w) -#define DRM_INIT_WAITQUEUE(queue) do {(void)(queue);} while (0) - -#define DRM_CURPROC curthread -#define DRM_STRUCTPROC struct thread -#define DRM_CURRENTPID curthread->td_proc->p_pid -#define DRM_LOCK(dev) lockmgr(&(dev)->dev_struct_lock, LK_EXCLUSIVE); -#define DRM_UNLOCK(dev) lockmgr(&(dev)->dev_struct_lock, LK_RELEASE); -#define DRM_LOCK_SLEEP(dev, chan, flags, msg, timeout) \ - (lksleep((chan), &(dev)->dev_struct_lock, (flags), (msg), (timeout))) -#if defined(INVARIANTS) -#define DRM_LOCK_ASSERT(dev) KKASSERT(lockstatus(&(dev)->dev_struct_lock, curthread) != 0); -#define DRM_UNLOCK_ASSERT(dev) KKASSERT(lockstatus(&(dev)->dev_struct_lock, curthread) == 0); -#else -#define DRM_LOCK_ASSERT(d) -#define DRM_UNLOCK_ASSERT(d) -#endif - -#define DRM_SYSCTL_HANDLER_ARGS (SYSCTL_HANDLER_ARGS) - -#define DRM_IRQ_ARGS void *arg -typedef void irqreturn_t; -#define IRQ_HANDLED /* nothing */ -#define IRQ_NONE /* nothing */ - -#define unlikely(x) __builtin_expect(!!(x), 0) -#define likely(x) __builtin_expect(!!(x), 1) -#define container_of(ptr, type, member) ({ \ - __typeof( ((type *)0)->member ) *__mptr = (ptr); \ - (type *)( (char *)__mptr - offsetof(type,member) );}) - -enum { - DRM_IS_NOT_AGP, - DRM_IS_AGP, - DRM_MIGHT_BE_AGP -}; -#define DRM_AGP_MEM struct agp_memory_info - -#define drm_get_device_from_kdev(_kdev) (_kdev->si_drv1) - -#define PAGE_ALIGN(addr) round_page(addr) -/* DRM_SUSER returns true if the user is superuser */ -#define DRM_SUSER(p) (priv_check(p, PRIV_DRIVER) == 0) -#define DRM_AGP_FIND_DEVICE() agp_find_device() -#define DRM_MTRR_WC MDF_WRITECOMBINE -#define jiffies ticks -#define jiffies_to_msecs(x) (((int64_t)(x)) * 1000 / hz) -#define msecs_to_jiffies(x) (((int64_t)(x)) * hz / 1000) -#define time_after(a,b) ((long)(b) - (long)(a) < 0) -#define time_after_eq(a,b) ((long)(b) - (long)(a) <= 0) -#define drm_msleep(x, msg) pause((msg), ((int64_t)(x)) * hz / 1000) - -typedef vm_paddr_t dma_addr_t; -typedef uint64_t u64; -typedef uint32_t u32; -typedef uint16_t u16; -typedef uint8_t u8; -typedef int64_t s64; -typedef int32_t s32; -typedef int16_t s16; -typedef int8_t s8; - -/* DRM_READMEMORYBARRIER() prevents reordering of reads. - * DRM_WRITEMEMORYBARRIER() prevents reordering of writes. - * DRM_MEMORYBARRIER() prevents reordering of reads and writes. - */ -#define DRM_READMEMORYBARRIER() rmb() -#define DRM_WRITEMEMORYBARRIER() wmb() -#define DRM_MEMORYBARRIER() mb() - -#define DRM_READ8(map, offset) \ - *(volatile u_int8_t *)(((vm_offset_t)(map)->virtual) + \ - (vm_offset_t)(offset)) -#define DRM_READ16(map, offset) \ - le16toh(*(volatile u_int16_t *)(((vm_offset_t)(map)->virtual) + \ - (vm_offset_t)(offset))) -#define DRM_READ32(map, offset) \ - le32toh(*(volatile u_int32_t *)(((vm_offset_t)(map)->virtual) + \ - (vm_offset_t)(offset))) -#define DRM_READ64(map, offset) \ - le64toh(*(volatile u_int64_t *)(((vm_offset_t)(map)->virtual) + \ - (vm_offset_t)(offset))) -#define DRM_WRITE8(map, offset, val) \ - *(volatile u_int8_t *)(((vm_offset_t)(map)->virtual) + \ - (vm_offset_t)(offset)) = val -#define DRM_WRITE16(map, offset, val) \ - *(volatile u_int16_t *)(((vm_offset_t)(map)->virtual) + \ - (vm_offset_t)(offset)) = htole16(val) -#define DRM_WRITE32(map, offset, val) \ - *(volatile u_int32_t *)(((vm_offset_t)(map)->virtual) + \ - (vm_offset_t)(offset)) = htole32(val) -#define DRM_WRITE64(map, offset, val) \ - *(volatile u_int64_t *)(((vm_offset_t)(map)->virtual) + \ - (vm_offset_t)(offset)) = htole64(val) - -#define DRM_VERIFYAREA_READ( uaddr, size ) \ - (!useracc(__DECONST(caddr_t, uaddr), size, VM_PROT_READ)) - -#define DRM_COPY_TO_USER(user, kern, size) \ - copyout(kern, user, size) -#define DRM_COPY_FROM_USER(kern, user, size) \ - copyin(user, kern, size) -#define DRM_COPY_FROM_USER_UNCHECKED(arg1, arg2, arg3) \ - copyin(arg2, arg1, arg3) -#define DRM_COPY_TO_USER_UNCHECKED(arg1, arg2, arg3) \ - copyout(arg2, arg1, arg3) -#define DRM_GET_USER_UNCHECKED(val, uaddr) \ - ((val) = fuword32(uaddr), 0) - -#define cpu_to_le32(x) htole32(x) -#define le32_to_cpu(x) le32toh(x) - -#define DRM_HZ hz -#define DRM_UDELAY(udelay) DELAY(udelay) -#define DRM_TIME_SLICE (hz/20) /* Time slice for GLXContexts */ - -#define DRM_GET_PRIV_SAREA(_dev, _ctx, _map) do { \ - (_map) = (_dev)->context_sareas[_ctx]; \ -} while(0) - -#define LOCK_TEST_WITH_RETURN(dev, file_priv) \ -do { \ - if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) || \ - dev->lock.file_priv != file_priv) { \ - DRM_ERROR("%s called without lock held\n", \ - __FUNCTION__); \ - return EINVAL; \ - } \ -} while (0) - -/* Returns -errno to shared code */ -#define DRM_WAIT_ON( ret, queue, timeout, condition ) \ -for ( ret = 0 ; !ret && !(condition) ; ) { \ - DRM_UNLOCK(dev); \ - lwkt_serialize_enter(&dev->irq_lock); \ - if (!(condition)) \ - ret = -mtx_sleep(&(queue), &dev->irq_lock, \ - PCATCH, "drmwtq", (timeout)); \ - lwkt_serialize_exit(&dev->irq_lock); \ - DRM_LOCK(dev); \ -} - -__inline static void -vm_page_unhold_pages(vm_page_t *ma, int count) -{ - int i; - - for (i = 0; i < count; i++) - vm_page_unhold(ma[i]); -} - -vm_page_t -vm_phys_fictitious_to_vm_page(vm_paddr_t pa); - -int -vm_phys_fictitious_reg_range(vm_paddr_t start, vm_paddr_t end, int pat_mode); - - -#define DRM_ERROR(fmt, ...) \ - kprintf("error: [" DRM_NAME ":pid%d:%s] *ERROR* " fmt, \ - DRM_CURRENTPID, __func__ , ##__VA_ARGS__) - -#define DRM_INFO(fmt, ...) kprintf("info: [" DRM_NAME "] " fmt , ##__VA_ARGS__) - -#define DRM_DEBUG(fmt, ...) do { \ - if ((drm_debug_flag & DRM_DEBUGBITS_DEBUG) != 0) \ - kprintf("[" DRM_NAME ":pid%d:%s] " fmt, DRM_CURRENTPID, \ - __func__ , ##__VA_ARGS__); \ -} while (0) - -#define DRM_DEBUG_KMS(fmt, ...) do { \ - if ((drm_debug_flag & DRM_DEBUGBITS_KMS) != 0) \ - kprintf("[" DRM_NAME ":KMS:pid%d:%s] " fmt, DRM_CURRENTPID,\ - __func__ , ##__VA_ARGS__); \ -} while (0) - -#define DRM_DEBUG_DRIVER(fmt, ...) do { \ - if ((drm_debug_flag & DRM_DEBUGBITS_KMS) != 0) \ - kprintf("[" DRM_NAME ":KMS:pid%d:%s] " fmt, DRM_CURRENTPID,\ - __func__ , ##__VA_ARGS__); \ -} while (0) - -typedef struct drm_pci_id_list -{ - int vendor; - int device; - long driver_private; - char *name; -} drm_pci_id_list_t; - -struct drm_msi_blacklist_entry -{ - int vendor; - int device; -}; - -#define DRM_AUTH 0x1 -#define DRM_MASTER 0x2 -#define DRM_ROOT_ONLY 0x4 -#define DRM_CONTROL_ALLOW 0x8 -#define DRM_UNLOCKED 0x10 - -typedef struct drm_ioctl_desc { - unsigned long cmd; - int (*func)(struct drm_device *dev, void *data, - struct drm_file *file_priv); - int flags; -} drm_ioctl_desc_t; -/** - * Creates a driver or general drm_ioctl_desc array entry for the given - * ioctl, for use by drm_ioctl(). - */ -#define DRM_IOCTL_DEF(ioctl, func, flags) \ - [DRM_IOCTL_NR(ioctl)] = {ioctl, func, flags} - -typedef struct drm_magic_entry { - drm_magic_t magic; - struct drm_file *priv; - struct drm_magic_entry *next; -} drm_magic_entry_t; - -typedef struct drm_magic_head { - struct drm_magic_entry *head; - struct drm_magic_entry *tail; -} drm_magic_head_t; - -typedef struct drm_buf { - int idx; /* Index into master buflist */ - int total; /* Buffer size */ - int order; /* log-base-2(total) */ - int used; /* Amount of buffer in use (for DMA) */ - unsigned long offset; /* Byte offset (used internally) */ - void *address; /* Address of buffer */ - unsigned long bus_address; /* Bus address of buffer */ - struct drm_buf *next; /* Kernel-only: used for free list */ - __volatile__ int pending; /* On hardware DMA queue */ - struct drm_file *file_priv; /* Unique identifier of holding process */ - int context; /* Kernel queue for this buffer */ - enum { - DRM_LIST_NONE = 0, - DRM_LIST_FREE = 1, - DRM_LIST_WAIT = 2, - DRM_LIST_PEND = 3, - DRM_LIST_PRIO = 4, - DRM_LIST_RECLAIM = 5 - } list; /* Which list we're on */ - - int dev_priv_size; /* Size of buffer private stoarge */ - void *dev_private; /* Per-buffer private storage */ -} drm_buf_t; - -typedef struct drm_freelist { - int initialized; /* Freelist in use */ - atomic_t count; /* Number of free buffers */ - drm_buf_t *next; /* End pointer */ - - int low_mark; /* Low water mark */ - int high_mark; /* High water mark */ -} drm_freelist_t; - -typedef struct drm_dma_handle { - void *vaddr; - bus_addr_t busaddr; - bus_dma_tag_t tag; - bus_dmamap_t map; -} drm_dma_handle_t; - -typedef struct drm_buf_entry { - int buf_size; - int buf_count; - drm_buf_t *buflist; - int seg_count; - drm_dma_handle_t **seglist; - int page_order; - - drm_freelist_t freelist; -} drm_buf_entry_t; - -/* Event queued up for userspace to read */ -struct drm_pending_event { - struct drm_event *event; - struct list_head link; - struct drm_file *file_priv; - pid_t pid; /* pid of requester, no guarantee it's valid by the time - we deliver the event, for tracing only */ - void (*destroy)(struct drm_pending_event *event); -}; - -typedef TAILQ_HEAD(drm_file_list, drm_file) drm_file_list_t; -struct drm_file { - TAILQ_ENTRY(drm_file) link; - struct drm_device *dev; - int authenticated; - int master; - pid_t pid; - uid_t uid; - drm_magic_t magic; - unsigned long ioctl_count; - - void *driver_priv; - struct drm_gem_names object_names; - - int is_master; - struct drm_master *masterp; - - struct list_head fbs; - - struct list_head event_list; - int event_space; -}; - -typedef struct drm_lock_data { - struct drm_hw_lock *hw_lock; /* Hardware lock */ - struct drm_file *file_priv; /* Unique identifier of holding process (NULL is kernel)*/ - int lock_queue; /* Queue of blocked processes */ - unsigned long lock_time; /* Time of last lock in jiffies */ -} drm_lock_data_t; - -/* This structure, in the struct drm_device, is always initialized while the - * device - * is open. dev->dma_lock protects the incrementing of dev->buf_use, which - * when set marks that no further bufs may be allocated until device teardown - * occurs (when the last open of the device has closed). The high/low - * watermarks of bufs are only touched by the X Server, and thus not - * concurrently accessed, so no locking is needed. - */ -typedef struct drm_device_dma { - drm_buf_entry_t bufs[DRM_MAX_ORDER+1]; - int buf_count; - drm_buf_t **buflist; /* Vector of pointers info bufs */ - int seg_count; - int page_count; - unsigned long *pagelist; - unsigned long byte_count; - enum { - _DRM_DMA_USE_AGP = 0x01, - _DRM_DMA_USE_SG = 0x02 - } flags; -} drm_device_dma_t; - -typedef struct drm_agp_mem { - void *handle; - unsigned long bound; /* address */ - int pages; - struct drm_agp_mem *prev; - struct drm_agp_mem *next; -} drm_agp_mem_t; - -typedef struct drm_agp_head { - device_t agpdev; - struct agp_info info; - const char *chipset; - drm_agp_mem_t *memory; - unsigned long mode; - int enabled; - int acquired; - unsigned long base; - int mtrr; - int cant_use_aperture; - unsigned long page_mask; -} drm_agp_head_t; - -typedef struct drm_sg_mem { - vm_offset_t vaddr; - vm_paddr_t *busaddr; - vm_pindex_t pages; -} drm_sg_mem_t; - -#define DRM_MAP_HANDLE_BITS (sizeof(void *) == 4 ? 4 : 24) -#define DRM_MAP_HANDLE_SHIFT (sizeof(void *) * 8 - DRM_MAP_HANDLE_BITS) -typedef TAILQ_HEAD(drm_map_list, drm_local_map) drm_map_list_t; - -typedef struct drm_local_map { - unsigned long offset; /* Physical address (0 for SAREA) */ - unsigned long size; /* Physical size (bytes) */ - enum drm_map_type type; /* Type of memory mapped */ - enum drm_map_flags flags; /* Flags */ - void *handle; /* User-space: "Handle" to pass to mmap */ - /* Kernel-space: kernel-virtual address */ - int mtrr; /* Boolean: MTRR used */ - /* Private data */ - int rid; /* PCI resource ID for bus_space */ - void *virtual; /* Kernel-space: kernel-virtual address */ - struct resource *bsr; - bus_space_tag_t bst; - bus_space_handle_t bsh; - drm_dma_handle_t *dmah; - TAILQ_ENTRY(drm_local_map) link; -} drm_local_map_t; - -struct drm_vblank_info { - wait_queue_head_t queue; /* vblank wait queue */ - atomic_t count; /* number of VBLANK interrupts */ - /* (driver must alloc the right number of counters) */ - atomic_t refcount; /* number of users of vblank interrupts */ - u32 last; /* protected by dev->vbl_lock, used */ - /* for wraparound handling */ - int enabled; /* so we don't call enable more than */ - /* once per disable */ - int inmodeset; /* Display driver is setting mode */ -}; - -/* Size of ringbuffer for vblank timestamps. Just double-buffer - * in initial implementation. - */ -#define DRM_VBLANKTIME_RBSIZE 2 - -/* Flags and return codes for get_vblank_timestamp() driver function. */ -#define DRM_CALLED_FROM_VBLIRQ 1 -#define DRM_VBLANKTIME_SCANOUTPOS_METHOD (1 << 0) -#define DRM_VBLANKTIME_INVBL (1 << 1) - -/* get_scanout_position() return flags */ -#define DRM_SCANOUTPOS_VALID (1 << 0) -#define DRM_SCANOUTPOS_INVBL (1 << 1) -#define DRM_SCANOUTPOS_ACCURATE (1 << 2) - -/* location of GART table */ -#define DRM_ATI_GART_MAIN 1 -#define DRM_ATI_GART_FB 2 - -#define DRM_ATI_GART_PCI 1 -#define DRM_ATI_GART_PCIE 2 -#define DRM_ATI_GART_IGP 3 - -struct drm_ati_pcigart_info { - int gart_table_location; - int gart_reg_if; - void *addr; - dma_addr_t bus_addr; - dma_addr_t table_mask; - dma_addr_t member_mask; - struct drm_dma_handle *table_handle; - drm_local_map_t mapping; - int table_size; - struct drm_dma_handle *dmah; /* handle for ATI PCIGART table */ -}; - -typedef vm_paddr_t resource_size_t; - -/** - * GEM specific mm private for tracking GEM objects - */ -struct drm_gem_mm { - struct drm_open_hash offset_hash; /**< User token hash table for maps */ - struct unrhdr *idxunr; -}; - -struct drm_gem_object { - /** Reference count of this object */ - u_int refcount; - - /** Handle count of this object. Each handle also holds a reference */ - u_int handle_count; /* number of handles on this object */ - - /** Related drm device */ - struct drm_device *dev; - - /** File representing the shmem storage: filp in Linux parlance */ - vm_object_t vm_obj; - - bool on_map; - struct drm_hash_item map_list; - - /** - * Size of the object, in bytes. Immutable over the object's - * lifetime. - */ - size_t size; - - /** - * Global name for this object, starts at 1. 0 means unnamed. - * Access is covered by the object_name_lock in the related drm_device - */ - int name; - - /** - * Memory domains. These monitor which caches contain read/write data - * related to the object. When transitioning from one set of domains - * to another, the driver is called to ensure that caches are suitably - * flushed and invalidated - */ - uint32_t read_domains; - uint32_t write_domain; - - /** - * While validating an exec operation, the - * new read/write domain values are computed here. - * They will be transferred to the above values - * at the point that any cache flushing occurs - */ - uint32_t pending_read_domains; - uint32_t pending_write_domain; - - void *driver_private; -}; - -#include "drm_crtc.h" - -#ifndef DMA_BIT_MASK -#define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : (1ULL<<(n)) - 1) -#endif - -#define upper_32_bits(n) ((u32)(((n) >> 16) >> 16)) - -struct drm_driver_info { - int (*load)(struct drm_device *, unsigned long flags); - int (*firstopen)(struct drm_device *); - int (*open)(struct drm_device *, struct drm_file *); - void (*preclose)(struct drm_device *, struct drm_file *file_priv); - void (*postclose)(struct drm_device *, struct drm_file *); - void (*lastclose)(struct drm_device *); - int (*unload)(struct drm_device *); - void (*reclaim_buffers_locked)(struct drm_device *, - struct drm_file *file_priv); - int (*dma_ioctl)(struct drm_device *dev, void *data, - struct drm_file *file_priv); - void (*dma_ready)(struct drm_device *); - int (*dma_quiescent)(struct drm_device *); - int (*dma_flush_block_and_flush)(struct drm_device *, int context, - enum drm_lock_flags flags); - int (*dma_flush_unblock)(struct drm_device *, int context, - enum drm_lock_flags flags); - int (*context_ctor)(struct drm_device *dev, int context); - int (*context_dtor)(struct drm_device *dev, int context); - int (*kernel_context_switch)(struct drm_device *dev, int old, - int new); - int (*kernel_context_switch_unlock)(struct drm_device *dev); - void (*irq_preinstall)(struct drm_device *dev); - int (*irq_postinstall)(struct drm_device *dev); - void (*irq_uninstall)(struct drm_device *dev); - void (*irq_handler)(DRM_IRQ_ARGS); - - u32 (*get_vblank_counter)(struct drm_device *dev, int crtc); - int (*enable_vblank)(struct drm_device *dev, int crtc); - void (*disable_vblank)(struct drm_device *dev, int crtc); - int (*get_scanout_position)(struct drm_device *dev, int crtc, - int *vpos, int *hpos); - - int (*get_vblank_timestamp)(struct drm_device *dev, int crtc, - int *max_error, struct timeval *vblank_time, - unsigned flags); - - int (*gem_init_object)(struct drm_gem_object *obj); - void (*gem_free_object)(struct drm_gem_object *obj); - - struct cdev_pager_ops *gem_pager_ops; - - int (*dumb_create)(struct drm_file *file_priv, - struct drm_device *dev, struct drm_mode_create_dumb *args); - int (*dumb_map_offset)(struct drm_file *file_priv, - struct drm_device *dev, uint32_t handle, uint64_t *offset); - int (*dumb_destroy)(struct drm_file *file_priv, - struct drm_device *dev, uint32_t handle); - - int (*sysctl_init)(struct drm_device *dev, - struct sysctl_ctx_list *ctx, struct sysctl_oid *top); - void (*sysctl_cleanup)(struct drm_device *dev); - - drm_pci_id_list_t *id_entry; /* PCI ID, name, and chipset private */ - - /** - * Called by \c drm_device_is_agp. Typically used to determine if a - * card is really attached to AGP or not. - * - * \param dev DRM device handle - * - * \returns - * One of three values is returned depending on whether or not the - * card is absolutely \b not AGP (return of 0), absolutely \b is AGP - * (return of 1), or may or may not be AGP (return of 2). - */ - int (*device_is_agp) (struct drm_device * dev); - - drm_ioctl_desc_t *ioctls; - int max_ioctl; - - int buf_priv_size; - - int major; - int minor; - int patchlevel; - const char *name; /* Simple driver name */ - const char *desc; /* Longer driver name */ - const char *date; /* Date of last major changes. */ - - u32 driver_features; -}; - -/** - * DRM minor structure. This structure represents a drm minor number. - */ -struct drm_minor { - int index; /**< Minor device number */ - int type; /**< Control or render */ - device_t kdev; /**< OS device */ - struct drm_device *dev; - - struct drm_master *master; /* currently active master for this node */ - struct list_head master_list; - struct drm_mode_group mode_group; -}; - -/* mode specified on the command line */ -struct drm_cmdline_mode { - bool specified; - bool refresh_specified; - bool bpp_specified; - int xres, yres; - int bpp; - int refresh; - bool rb; - bool interlace; - bool cvt; - bool margins; - enum drm_connector_force force; -}; - -struct drm_pending_vblank_event { - struct drm_pending_event base; - int pipe; - struct drm_event_vblank event; -}; - -/* Length for the array of resource pointers for drm_get_resource_*. */ -#define DRM_MAX_PCI_RESOURCE 6 - -/** - * DRM device functions structure - */ -struct drm_device { - struct drm_driver_info *driver; - drm_pci_id_list_t *id_entry; /* PCI ID, name, and chipset private */ - - u_int16_t pci_device; /* PCI device id */ - u_int16_t pci_vendor; /* PCI vendor id */ - - char *unique; /* Unique identifier: e.g., busid */ - int unique_len; /* Length of unique field */ - device_t device; /* Device instance from newbus */ - struct cdev *devnode; /* Device number for mknod */ - int if_version; /* Highest interface version set */ - - int flags; /* Flags to open(2) */ - - /* Locks */ - struct spinlock dma_lock; /* protects dev->dma */ - struct lwkt_serialize irq_lock; /* protects irq condition checks */ - struct lock dev_lock; /* protects everything else */ - struct lock dev_struct_lock; - struct spinlock drw_lock; - - /* Usage Counters */ - int open_count; /* Outstanding files open */ - int buf_use; /* Buffers in use -- cannot alloc */ - - /* Performance counters */ - unsigned long counters; - enum drm_stat_type types[15]; - atomic_t counts[15]; - - /* Authentication */ - drm_file_list_t files; - drm_magic_head_t magiclist[DRM_HASH_SIZE]; - - /* Linked list of mappable regions. Protected by dev_lock */ - drm_map_list_t maplist; - struct unrhdr *map_unrhdr; - - drm_local_map_t **context_sareas; - int max_context; - - drm_lock_data_t lock; /* Information on hardware lock */ - - /* DMA queues (contexts) */ - drm_device_dma_t *dma; /* Optional pointer for DMA support */ - - /* Context support */ - int irq; /* Interrupt used by board */ - int irq_enabled; /* True if the irq handler is enabled */ - int msi_enabled; /* MSI enabled */ - int irqrid; /* Interrupt used by board */ - struct resource *irqr; /* Resource for interrupt used by board */ - void *irqh; /* Handle from bus_setup_intr */ - - /* Storage of resource pointers for drm_get_resource_* */ - struct resource *pcir[DRM_MAX_PCI_RESOURCE]; - int pcirid[DRM_MAX_PCI_RESOURCE]; - - int pci_domain; - int pci_bus; - int pci_slot; - int pci_func; - - atomic_t context_flag; /* Context swapping flag */ - int last_context; /* Last current context */ - - int num_crtcs; - - struct sigio *buf_sigio; /* Processes waiting for SIGIO */ - - /* Sysctl support */ - struct drm_sysctl_info *sysctl; - int sysctl_node_idx; - - drm_agp_head_t *agp; - drm_sg_mem_t *sg; /* Scatter gather memory */ - atomic_t *ctx_bitmap; - void *dev_private; - unsigned int agp_buffer_token; - drm_local_map_t *agp_buffer_map; - - struct drm_minor *control; /**< Control node for card */ - struct drm_minor *primary; /**< render type primary screen head */ - - void *drm_ttm_bo; - struct unrhdr *drw_unrhdr; - /* RB tree of drawable infos */ - RB_HEAD(drawable_tree, bsd_drm_drawable_info) drw_head; - - int vblank_disable_allowed; - - atomic_t *_vblank_count; /**< number of VBLANK interrupts (driver must alloc the right number of counters) */ - struct timeval *_vblank_time; /**< timestamp of current vblank_count (drivers must alloc right number of fields) */ - struct lock vblank_time_lock; /**< Protects vblank count and time updates during vblank enable/disable */ - struct lock vbl_lock; - atomic_t *vblank_refcount; /* number of users of vblank interruptsper crtc */ - u32 *last_vblank; /* protected by dev->vbl_lock, used */ - /* for wraparound handling */ - int *vblank_enabled; /* so we don't call enable more than - once per disable */ - int *vblank_inmodeset; /* Display driver is setting mode */ - u32 *last_vblank_wait; /* Last vblank seqno waited per CRTC */ - struct callout vblank_disable_callout; - - u32 max_vblank_count; /**< size of vblank counter register */ - - struct list_head vblank_event_list; - struct lock event_lock; - - struct drm_mode_config mode_config; /**< Current mode config */ - - /* GEM part */ - struct lock object_name_lock; - struct drm_gem_names object_names; - void *mm_private; - - void *sysctl_private; - char busid_str[128]; - int modesetting; -}; - -static __inline__ int drm_core_check_feature(struct drm_device *dev, - int feature) -{ - return ((dev->driver->driver_features & feature) ? 1 : 0); -} - -#if __OS_HAS_AGP -static inline int drm_core_has_AGP(struct drm_device *dev) -{ - return drm_core_check_feature(dev, DRIVER_USE_AGP); -} -#else -#define drm_core_has_AGP(dev) (0) -#endif - -enum dmi_field { - DMI_NONE, - DMI_BIOS_VENDOR, - DMI_BIOS_VERSION, - DMI_BIOS_DATE, - DMI_SYS_VENDOR, - DMI_PRODUCT_NAME, - DMI_PRODUCT_VERSION, - DMI_PRODUCT_SERIAL, - DMI_PRODUCT_UUID, - DMI_BOARD_VENDOR, - DMI_BOARD_NAME, - DMI_BOARD_VERSION, - DMI_BOARD_SERIAL, - DMI_BOARD_ASSET_TAG, - DMI_CHASSIS_VENDOR, - DMI_CHASSIS_TYPE, - DMI_CHASSIS_VERSION, - DMI_CHASSIS_SERIAL, - DMI_CHASSIS_ASSET_TAG, - DMI_STRING_MAX, -}; - -struct dmi_strmatch { - unsigned char slot; - char substr[79]; -}; - -struct dmi_system_id { - int (*callback)(const struct dmi_system_id *); - const char *ident; - struct dmi_strmatch matches[4]; -}; -#define DMI_MATCH(a, b) {(a), (b)} -bool dmi_check_system(const struct dmi_system_id *); - -extern int drm_debug_flag; -extern int drm_notyet_flag; -extern unsigned int drm_vblank_offdelay; -extern unsigned int drm_timestamp_precision; - -/* Device setup support (drm_drv.c) */ -int drm_probe(device_t kdev, drm_pci_id_list_t *idlist); -int drm_attach(device_t kdev, drm_pci_id_list_t *idlist); -int drm_create_cdevs(device_t kdev); -int drm_detach(device_t kdev); -d_ioctl_t drm_ioctl; -d_open_t drm_open; -d_close_t drm_close; -d_read_t drm_read; -d_kqfilter_t drm_kqfilter; -d_mmap_t drm_mmap; -d_mmap_single_t drm_mmap_single; -extern drm_local_map_t *drm_getsarea(struct drm_device *dev); - -void drm_event_wakeup(struct drm_pending_event *e); - -int drm_add_busid_modesetting(struct drm_device *dev, - struct sysctl_ctx_list *ctx, struct sysctl_oid *top); - -/* File operations helpers (drm_fops.c) */ -extern int drm_open_helper(struct cdev *kdev, int flags, int fmt, - DRM_STRUCTPROC *p, - struct drm_device *dev); -extern struct drm_file *drm_find_file_by_proc(struct drm_device *dev, - DRM_STRUCTPROC *p); - -/* Memory management support (drm_memory.c) */ -void drm_mem_init(void); -void drm_mem_uninit(void); -void *drm_ioremap_wc(struct drm_device *dev, drm_local_map_t *map); -void *drm_ioremap(struct drm_device *dev, drm_local_map_t *map); -void drm_ioremapfree(drm_local_map_t *map); -int drm_mtrr_add(unsigned long offset, size_t size, int flags); -int drm_mtrr_del(int handle, unsigned long offset, size_t size, int flags); - -int drm_context_switch(struct drm_device *dev, int old, int new); -int drm_context_switch_complete(struct drm_device *dev, int new); - -int drm_ctxbitmap_init(struct drm_device *dev); -void drm_ctxbitmap_cleanup(struct drm_device *dev); -void drm_ctxbitmap_free(struct drm_device *dev, int ctx_handle); -int drm_ctxbitmap_next(struct drm_device *dev); - -/* Locking IOCTL support (drm_lock.c) */ -int drm_lock_take(struct drm_lock_data *lock_data, - unsigned int context); -int drm_lock_transfer(struct drm_lock_data *lock_data, - unsigned int context); -int drm_lock_free(struct drm_lock_data *lock_data, - unsigned int context); - -/* Buffer management support (drm_bufs.c) */ -unsigned long drm_get_resource_start(struct drm_device *dev, - unsigned int resource); -unsigned long drm_get_resource_len(struct drm_device *dev, - unsigned int resource); -void drm_rmmap(struct drm_device *dev, drm_local_map_t *map); -int drm_order(unsigned long size); -int drm_addmap(struct drm_device *dev, unsigned long offset, - unsigned long size, - enum drm_map_type type, enum drm_map_flags flags, - drm_local_map_t **map_ptr); -int drm_addbufs_pci(struct drm_device *dev, struct drm_buf_desc *request); -int drm_addbufs_sg(struct drm_device *dev, struct drm_buf_desc *request); -int drm_addbufs_agp(struct drm_device *dev, struct drm_buf_desc *request); - -/* DMA support (drm_dma.c) */ -int drm_dma_setup(struct drm_device *dev); -void drm_dma_takedown(struct drm_device *dev); -void drm_free_buffer(struct drm_device *dev, drm_buf_t *buf); -void drm_reclaim_buffers(struct drm_device *dev, struct drm_file *file_priv); -#define drm_core_reclaim_buffers drm_reclaim_buffers - -/* IRQ support (drm_irq.c) */ -int drm_irq_install(struct drm_device *dev); -int drm_irq_uninstall(struct drm_device *dev); -irqreturn_t drm_irq_handler(DRM_IRQ_ARGS); -void drm_driver_irq_preinstall(struct drm_device *dev); -void drm_driver_irq_postinstall(struct drm_device *dev); -void drm_driver_irq_uninstall(struct drm_device *dev); - -void drm_vblank_pre_modeset(struct drm_device *dev, int crtc); -void drm_vblank_post_modeset(struct drm_device *dev, int crtc); -int drm_modeset_ctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); - -extern int drm_vblank_init(struct drm_device *dev, int num_crtcs); -extern int drm_wait_vblank(struct drm_device *dev, void *data, - struct drm_file *filp); -extern int drm_vblank_wait(struct drm_device *dev, unsigned int *vbl_seq); -extern u32 drm_vblank_count(struct drm_device *dev, int crtc); -extern u32 drm_vblank_count_and_time(struct drm_device *dev, int crtc, - struct timeval *vblanktime); -extern bool drm_handle_vblank(struct drm_device *dev, int crtc); -void drm_handle_vblank_events(struct drm_device *dev, int crtc); -extern int drm_vblank_get(struct drm_device *dev, int crtc); -extern void drm_vblank_put(struct drm_device *dev, int crtc); -extern void drm_vblank_off(struct drm_device *dev, int crtc); -extern void drm_vblank_cleanup(struct drm_device *dev); -extern u32 drm_get_last_vbltimestamp(struct drm_device *dev, int crtc, - struct timeval *tvblank, unsigned flags); -extern int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, - int crtc, int *max_error, - struct timeval *vblank_time, - unsigned flags, - struct drm_crtc *refcrtc); -extern void drm_calc_timestamping_constants(struct drm_crtc *crtc); - -struct timeval ns_to_timeval(const int64_t nsec); -int64_t timeval_to_ns(const struct timeval *tv); - -/* AGP/PCI Express/GART support (drm_agpsupport.c) */ -int drm_device_is_agp(struct drm_device *dev); -int drm_device_is_pcie(struct drm_device *dev); -drm_agp_head_t *drm_agp_init(void); -int drm_agp_acquire(struct drm_device *dev); -int drm_agp_release(struct drm_device *dev); -int drm_agp_info(struct drm_device * dev, struct drm_agp_info *info); -int drm_agp_enable(struct drm_device *dev, struct drm_agp_mode mode); -void *drm_agp_allocate_memory(size_t pages, u32 type); -int drm_agp_free_memory(void *handle); -int drm_agp_bind_memory(void *handle, off_t start); -int drm_agp_unbind_memory(void *handle); -int drm_agp_alloc(struct drm_device *dev, struct drm_agp_buffer *request); -int drm_agp_free(struct drm_device *dev, struct drm_agp_buffer *request); -int drm_agp_bind(struct drm_device *dev, struct drm_agp_binding *request); -int drm_agp_unbind(struct drm_device *dev, struct drm_agp_binding *request); - -/* Scatter Gather Support (drm_scatter.c) */ -void drm_sg_cleanup(drm_sg_mem_t *entry); -int drm_sg_alloc(struct drm_device *dev, struct drm_scatter_gather * request); - -/* sysctl support (drm_sysctl.h) */ -extern int drm_sysctl_init(struct drm_device *dev); -extern int drm_sysctl_cleanup(struct drm_device *dev); - -/* ATI PCIGART support (ati_pcigart.c) */ -int drm_ati_pcigart_init(struct drm_device *dev, - struct drm_ati_pcigart_info *gart_info); -int drm_ati_pcigart_cleanup(struct drm_device *dev, - struct drm_ati_pcigart_info *gart_info); - -/* Cache management (drm_memory.c) */ -void drm_clflush_pages(vm_page_t *pages, unsigned long num_pages); - -/* Locking IOCTL support (drm_drv.c) */ -int drm_lock(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int drm_unlock(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int drm_version(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int drm_setversion(struct drm_device *dev, void *data, - struct drm_file *file_priv); - -/* Misc. IOCTL support (drm_ioctl.c) */ -int drm_irq_by_busid(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int drm_getunique(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int drm_setunique(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int drm_getmap(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int drm_getclient(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int drm_getstats(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int drm_getcap(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int drm_noop(struct drm_device *dev, void *data, - struct drm_file *file_priv); - -/* Context IOCTL support (drm_context.c) */ -int drm_resctx(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int drm_addctx(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int drm_modctx(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int drm_getctx(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int drm_switchctx(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int drm_newctx(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int drm_rmctx(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int drm_setsareactx(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int drm_getsareactx(struct drm_device *dev, void *data, - struct drm_file *file_priv); - -/* Drawable IOCTL support (drm_drawable.c) */ -int drm_adddraw(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int drm_rmdraw(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int drm_update_draw(struct drm_device *dev, void *data, - struct drm_file *file_priv); -struct drm_drawable_info *drm_get_drawable_info(struct drm_device *dev, - int handle); - -/* Drawable support (drm_drawable.c) */ -void drm_drawable_free_all(struct drm_device *dev); - -/* Authentication IOCTL support (drm_auth.c) */ -int drm_getmagic(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int drm_authmagic(struct drm_device *dev, void *data, - struct drm_file *file_priv); - -/* Buffer management support (drm_bufs.c) */ -int drm_addmap_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int drm_rmmap_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int drm_addbufs(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int drm_infobufs(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int drm_markbufs(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int drm_freebufs(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int drm_mapbufs(struct drm_device *dev, void *data, - struct drm_file *file_priv); - -/* DMA support (drm_dma.c) */ -int drm_dma(struct drm_device *dev, void *data, struct drm_file *file_priv); - -/* IRQ support (drm_irq.c) */ -int drm_control(struct drm_device *dev, void *data, - struct drm_file *file_priv); - -/* AGP/GART support (drm_agpsupport.c) */ -int drm_agp_acquire_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int drm_agp_release_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int drm_agp_enable_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int drm_agp_info_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int drm_agp_alloc_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int drm_agp_free_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int drm_agp_unbind_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int drm_agp_bind_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); - - /* Stub support (drm_stub.h) */ -extern int drm_setmaster_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int drm_dropmaster_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); - -/* Scatter Gather Support (drm_scatter.c) */ -int drm_sg_alloc_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int drm_sg_free(struct drm_device *dev, void *data, - struct drm_file *file_priv); - -/* consistent PCI memory functions (drm_pci.c) */ -drm_dma_handle_t *drm_pci_alloc(struct drm_device *dev, size_t size, - size_t align, dma_addr_t maxaddr); -void drm_pci_free(struct drm_device *dev, drm_dma_handle_t *dmah); - -/* Graphics Execution Manager library functions (drm_gem.c) */ -int drm_gem_init(struct drm_device *dev); -void drm_gem_destroy(struct drm_device *dev); - -int drm_gem_close_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int drm_gem_flink_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int drm_gem_open_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int drm_gem_handle_create(struct drm_file *file_priv, - struct drm_gem_object *obj, - u32 *handlep); -int drm_gem_handle_delete(struct drm_file *file_priv, uint32_t handle); -void drm_gem_object_handle_reference(struct drm_gem_object *obj); -void drm_gem_object_handle_unreference(struct drm_gem_object *obj); -void drm_gem_object_handle_unreference_unlocked(struct drm_gem_object *obj); -void drm_gem_object_handle_free(struct drm_gem_object *obj); -void drm_gem_object_reference(struct drm_gem_object *obj); -void drm_gem_object_unreference(struct drm_gem_object *obj); -void drm_gem_object_unreference_unlocked(struct drm_gem_object *obj); -void drm_gem_object_release(struct drm_gem_object *obj); -void drm_gem_object_free(struct drm_gem_object *obj); -int drm_gem_object_init(struct drm_device *dev, struct drm_gem_object *obj, - size_t size); -int drm_gem_private_object_init(struct drm_device *dev, - struct drm_gem_object *obj, size_t size); -struct drm_gem_object *drm_gem_object_alloc(struct drm_device *dev, - size_t size); -struct drm_gem_object *drm_gem_object_lookup(struct drm_device *dev, - struct drm_file *file_priv, uint32_t handle); - -void drm_gem_open(struct drm_device *dev, struct drm_file *file_priv); -void drm_gem_release(struct drm_device *dev, struct drm_file *file_priv); - -int drm_gem_create_mmap_offset(struct drm_gem_object *obj); -void drm_gem_free_mmap_offset(struct drm_gem_object *obj); -int drm_gem_mmap_single(struct drm_device *dev, vm_ooffset_t *offset, - vm_size_t size, struct vm_object **obj_res, int nprot); -void drm_gem_pager_dtr(void *obj); - -struct ttm_bo_device; -int ttm_bo_mmap_single(struct ttm_bo_device *bdev, vm_ooffset_t *offset, - vm_size_t size, struct vm_object **obj_res, int nprot); - -void drm_device_lock_mtx(struct drm_device *dev); -void drm_device_unlock_mtx(struct drm_device *dev); -int drm_device_sleep_mtx(struct drm_device *dev, void *chan, int flags, - const char *msg, int timeout); -void drm_device_assert_mtx_locked(struct drm_device *dev); -void drm_device_assert_mtx_unlocked(struct drm_device *dev); - -void drm_device_lock_struct(struct drm_device *dev); -void drm_device_unlock_struct(struct drm_device *dev); -int drm_device_sleep_struct(struct drm_device *dev, void *chan, int flags, - const char *msg, int timeout); -void drm_device_assert_struct_locked(struct drm_device *dev); -void drm_device_assert_struct_unlocked(struct drm_device *dev); - -void drm_compat_locking_init(struct drm_device *dev); -void drm_sleep_locking_init(struct drm_device *dev); - -/* drm_modes.c */ -bool drm_mode_parse_command_line_for_connector(const char *mode_option, - struct drm_connector *connector, struct drm_cmdline_mode *mode); -struct drm_display_mode *drm_mode_create_from_cmdline_mode( - struct drm_device *dev, struct drm_cmdline_mode *cmd); - -/* drm_edid.c */ -u8 *drm_find_cea_extension(struct edid *edid); - -/* Inline replacements for drm_alloc and friends */ -static __inline__ void * -drm_alloc(size_t size, struct malloc_type *area) -{ - return kmalloc(size, area, M_NOWAIT); -} - -static __inline__ void * -drm_calloc(size_t nmemb, size_t size, struct malloc_type *area) -{ - return kmalloc(size * nmemb, area, M_NOWAIT | M_ZERO); -} - -static __inline__ void * -drm_realloc(void *oldpt, size_t oldsize, size_t size, - struct malloc_type *area) -{ - void *res; - res = krealloc(oldpt, size, area, M_NOWAIT); - if (res == NULL && oldpt != NULL) - kfree(oldpt,area); - return res; -} - -static __inline__ void -drm_free(void *pt, struct malloc_type *area) -{ - if (pt != NULL) - kfree(pt, area); -} - -/* Inline replacements for DRM_IOREMAP macros */ -static __inline__ void -drm_core_ioremap_wc(struct drm_local_map *map, struct drm_device *dev) -{ - map->virtual = drm_ioremap_wc(dev, map); -} -static __inline__ void -drm_core_ioremap(struct drm_local_map *map, struct drm_device *dev) -{ - map->virtual = drm_ioremap(dev, map); -} -static __inline__ void -drm_core_ioremapfree(struct drm_local_map *map, struct drm_device *dev) -{ - if ( map->virtual && map->size ) - drm_ioremapfree(map); -} - -static __inline__ struct drm_local_map * -drm_core_findmap(struct drm_device *dev, unsigned long offset) -{ - drm_local_map_t *map; - - DRM_LOCK_ASSERT(dev); - TAILQ_FOREACH(map, &dev->maplist, link) { - if (offset == (unsigned long)map->handle) - return map; - } - return NULL; -} - -static __inline__ void drm_core_dropmap(struct drm_map *map) -{ -} - -#define KIB_NOTYET() \ -do { \ - if (drm_debug_flag && drm_notyet_flag) \ - kprintf("NOTYET: %s at %s:%d\n", __func__, __FILE__, __LINE__); \ -} while (0) - -#define KTR_DRM KTR_DEV -#define KTR_DRM_REG KTR_SPARE3 - - -/* FreeBSD compatibility macros */ -#define PROC_LOCK(p) -#define PROC_UNLOCK(p) - -#define VM_OBJECT_RLOCK(object) VM_OBJECT_LOCK(object) -#define VM_OBJECT_RUNLOCK(object) VM_OBJECT_UNLOCK(object) -#define VM_OBJECT_WLOCK(object) VM_OBJECT_LOCK(object) -#define VM_OBJECT_WUNLOCK(object) VM_OBJECT_UNLOCK(object) - -#endif /* __KERNEL__ */ -#endif /* _DRM_P_H_ */ diff --git a/sys/dev/drm2/drm_agpsupport.c b/sys/dev/drm2/drm_agpsupport.c deleted file mode 100644 index 3bf75d9a62..0000000000 --- a/sys/dev/drm2/drm_agpsupport.c +++ /dev/null @@ -1,416 +0,0 @@ -/*- - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * 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, 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS 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. - * - * Author: - * Rickard E. (Rik) Faith - * Gareth Hughes - * - * $FreeBSD: src/sys/dev/drm2/drm_agpsupport.c,v 1.1 2012/05/22 11:07:44 kib Exp $ - */ - -/** @file drm_agpsupport.c - * Support code for tying the kernel AGP support to DRM drivers and - * the DRM's AGP ioctls. - */ - -#include - -#include -#include - -/* Returns 1 if AGP or 0 if not. */ -static int -drm_device_find_capability(struct drm_device *dev, int cap) -{ - - return (pci_find_extcap(dev->device, cap, NULL) == 0); -} - -int drm_device_is_agp(struct drm_device *dev) -{ - if (dev->driver->device_is_agp != NULL) { - int ret; - - /* device_is_agp returns a tristate, 0 = not AGP, 1 = definitely - * AGP, 2 = fall back to PCI capability - */ - ret = (*dev->driver->device_is_agp)(dev); - if (ret != DRM_MIGHT_BE_AGP) - return ret; - } - - return (drm_device_find_capability(dev, PCIY_AGP)); -} - -int drm_device_is_pcie(struct drm_device *dev) -{ - return (drm_device_find_capability(dev, PCIY_EXPRESS)); -} - -int drm_agp_info(struct drm_device * dev, struct drm_agp_info *info) -{ - struct agp_info *kern; - - if (!dev->agp || !dev->agp->acquired) - return EINVAL; - - kern = &dev->agp->info; - agp_get_info(dev->agp->agpdev, kern); - info->agp_version_major = 1; - info->agp_version_minor = 0; - info->mode = kern->ai_mode; - info->aperture_base = kern->ai_aperture_base; - info->aperture_size = kern->ai_aperture_size; - info->memory_allowed = kern->ai_memory_allowed; - info->memory_used = kern->ai_memory_used; - info->id_vendor = kern->ai_devid & 0xffff; - info->id_device = kern->ai_devid >> 16; - - return 0; -} - -int drm_agp_info_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - int err; - struct drm_agp_info info; - - err = drm_agp_info(dev, &info); - if (err != 0) - return err; - - *(struct drm_agp_info *) data = info; - return 0; -} - -int drm_agp_acquire_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - - return drm_agp_acquire(dev); -} - -int drm_agp_acquire(struct drm_device *dev) -{ - int retcode; - - if (!dev->agp || dev->agp->acquired) - return EINVAL; - - retcode = agp_acquire(dev->agp->agpdev); - if (retcode) - return retcode; - - dev->agp->acquired = 1; - return 0; -} - -int drm_agp_release_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - - return drm_agp_release(dev); -} - -int drm_agp_release(struct drm_device * dev) -{ - if (!dev->agp || !dev->agp->acquired) - return EINVAL; - agp_release(dev->agp->agpdev); - dev->agp->acquired = 0; - return 0; -} - -int drm_agp_enable(struct drm_device *dev, struct drm_agp_mode mode) -{ - - if (!dev->agp || !dev->agp->acquired) - return EINVAL; - - dev->agp->mode = mode.mode; - agp_enable(dev->agp->agpdev, mode.mode); - dev->agp->enabled = 1; - return 0; -} - -int drm_agp_enable_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_agp_mode mode; - - mode = *(struct drm_agp_mode *) data; - - return drm_agp_enable(dev, mode); -} - -int drm_agp_alloc(struct drm_device *dev, struct drm_agp_buffer *request) -{ - drm_agp_mem_t *entry; - void *handle; - unsigned long pages; - u_int32_t type; - struct agp_memory_info info; - - if (!dev->agp || !dev->agp->acquired) - return EINVAL; - - entry = kmalloc(sizeof(*entry), DRM_MEM_AGPLISTS, M_NOWAIT | M_ZERO); - if (entry == NULL) - return ENOMEM; - - pages = (request->size + PAGE_SIZE - 1) / PAGE_SIZE; - type = (u_int32_t) request->type; - - handle = drm_agp_allocate_memory(pages, type); - if (handle == NULL) { - drm_free(entry, DRM_MEM_AGPLISTS); - return ENOMEM; - } - - entry->handle = handle; - entry->bound = 0; - entry->pages = pages; - entry->prev = NULL; - entry->next = dev->agp->memory; - if (dev->agp->memory) - dev->agp->memory->prev = entry; - dev->agp->memory = entry; - - agp_memory_info(dev->agp->agpdev, entry->handle, &info); - - request->handle = (unsigned long) entry->handle; - request->physical = info.ami_physical; - - return 0; -} - -int drm_agp_alloc_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_agp_buffer request; - int retcode; - - request = *(struct drm_agp_buffer *) data; - - retcode = drm_agp_alloc(dev, &request); - - *(struct drm_agp_buffer *) data = request; - - return retcode; -} - -static drm_agp_mem_t * drm_agp_lookup_entry(struct drm_device *dev, - void *handle) -{ - drm_agp_mem_t *entry; - - for (entry = dev->agp->memory; entry; entry = entry->next) { - if (entry->handle == handle) return entry; - } - return NULL; -} - -int drm_agp_unbind(struct drm_device *dev, struct drm_agp_binding *request) -{ - drm_agp_mem_t *entry; - int retcode; - - if (!dev->agp || !dev->agp->acquired) - return EINVAL; - - entry = drm_agp_lookup_entry(dev, (void *)request->handle); - if (entry == NULL || !entry->bound) - return EINVAL; - - retcode = drm_agp_unbind_memory(entry->handle); - - if (retcode == 0) - entry->bound = 0; - - return retcode; -} - -int drm_agp_unbind_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_agp_binding request; - int retcode; - - request = *(struct drm_agp_binding *) data; - - retcode = drm_agp_unbind(dev, &request); - - return retcode; -} - -int drm_agp_bind(struct drm_device *dev, struct drm_agp_binding *request) -{ - drm_agp_mem_t *entry; - int retcode; - int page; - - if (!dev->agp || !dev->agp->acquired) - return EINVAL; - - DRM_DEBUG("agp_bind, page_size=%x\n", (int)PAGE_SIZE); - - entry = drm_agp_lookup_entry(dev, (void *)request->handle); - if (entry == NULL || entry->bound) - return EINVAL; - - page = (request->offset + PAGE_SIZE - 1) / PAGE_SIZE; - - retcode = drm_agp_bind_memory(entry->handle, page); - if (retcode == 0) - entry->bound = dev->agp->base + (page << PAGE_SHIFT); - - return retcode; -} - -int drm_agp_bind_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_agp_binding request; - int retcode; - - request = *(struct drm_agp_binding *) data; - - retcode = drm_agp_bind(dev, &request); - - return retcode; -} - -int drm_agp_free(struct drm_device *dev, struct drm_agp_buffer *request) -{ - drm_agp_mem_t *entry; - - if (!dev->agp || !dev->agp->acquired) - return EINVAL; - - entry = drm_agp_lookup_entry(dev, (void*)request->handle); - if (entry == NULL) - return EINVAL; - - if (entry->prev) - entry->prev->next = entry->next; - else - dev->agp->memory = entry->next; - if (entry->next) - entry->next->prev = entry->prev; - - if (entry->bound) - drm_agp_unbind_memory(entry->handle); - drm_agp_free_memory(entry->handle); - - drm_free(entry, DRM_MEM_AGPLISTS); - - return 0; - -} - -int drm_agp_free_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_agp_buffer request; - int retcode; - - request = *(struct drm_agp_buffer *) data; - - retcode = drm_agp_free(dev, &request); - - return retcode; -} - -drm_agp_head_t *drm_agp_init(void) -{ - device_t agpdev; - drm_agp_head_t *head = NULL; - int agp_available = 1; - - agpdev = DRM_AGP_FIND_DEVICE(); - if (!agpdev) - agp_available = 0; - - DRM_DEBUG("agp_available = %d\n", agp_available); - - if (agp_available) { - head = kmalloc(sizeof(*head), DRM_MEM_AGPLISTS, - M_NOWAIT | M_ZERO); - if (head == NULL) - return NULL; - head->agpdev = agpdev; - agp_get_info(agpdev, &head->info); - head->base = head->info.ai_aperture_base; - head->memory = NULL; - DRM_INFO("AGP at 0x%08lx %dMB\n", - (long)head->info.ai_aperture_base, - (int)(head->info.ai_aperture_size >> 20)); - } - return head; -} - -void *drm_agp_allocate_memory(size_t pages, u32 type) -{ - device_t agpdev; - - agpdev = DRM_AGP_FIND_DEVICE(); - if (!agpdev) - return NULL; - - return agp_alloc_memory(agpdev, type, pages << AGP_PAGE_SHIFT); -} - -int drm_agp_free_memory(void *handle) -{ - device_t agpdev; - - agpdev = DRM_AGP_FIND_DEVICE(); - if (!agpdev || !handle) - return 0; - - agp_free_memory(agpdev, handle); - return 1; -} - -int drm_agp_bind_memory(void *handle, off_t start) -{ - device_t agpdev; - - agpdev = DRM_AGP_FIND_DEVICE(); - if (!agpdev || !handle) - return EINVAL; - - return agp_bind_memory(agpdev, handle, start * PAGE_SIZE); -} - -int drm_agp_unbind_memory(void *handle) -{ - device_t agpdev; - - agpdev = DRM_AGP_FIND_DEVICE(); - if (!agpdev || !handle) - return EINVAL; - - return agp_unbind_memory(agpdev, handle); -} diff --git a/sys/dev/drm2/drm_atomic.h b/sys/dev/drm2/drm_atomic.h deleted file mode 100644 index 5736528e65..0000000000 --- a/sys/dev/drm2/drm_atomic.h +++ /dev/null @@ -1,96 +0,0 @@ -/** - * \file drm_atomic.h - * Atomic operations used in the DRM which may or may not be provided by the OS. - * - * \author Eric Anholt - */ - -/*- - * Copyright 2004 Eric Anholt - * 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, 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS 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. - * - * $FreeBSD: src/sys/dev/drm2/drm_atomic.h,v 1.1 2012/05/22 11:07:44 kib Exp $ - */ - -/* Many of these implementations are rather fake, but good enough. */ - -typedef u_int32_t atomic_t; - -#define atomic_set(p, v) (*(p) = (v)) -#define atomic_read(p) (*(p)) -#define atomic_inc(p) atomic_add_int(p, 1) -#define atomic_dec(p) atomic_subtract_int(p, 1) -#define atomic_add(n, p) atomic_add_int(p, n) -#define atomic_sub(n, p) atomic_subtract_int(p, n) - -static __inline atomic_t -test_and_set_bit(int b, volatile void *p) -{ - unsigned int mask = 1 << b; - unsigned int v; - - for (;;) { - v = *(volatile unsigned int *)p; - cpu_ccfence(); - if (atomic_cmpset_int(p, v, v | mask)) - break; - } - return (v & mask); -} - -static __inline void -clear_bit(int b, volatile void *p) -{ - atomic_clear_int(((volatile int *)p) + (b >> 5), 1 << (b & 0x1f)); -} - -static __inline void -set_bit(int b, volatile void *p) -{ - atomic_set_int(((volatile int *)p) + (b >> 5), 1 << (b & 0x1f)); -} - -static __inline int -test_bit(int b, volatile void *p) -{ - return ((volatile int *)p)[b >> 5] & (1 << (b & 0x1f)); -} - -static __inline int -find_first_zero_bit(volatile void *p, int max) -{ - int b; - volatile int *ptr = (volatile int *)p; - - for (b = 0; b < max; b += 32) { - if (ptr[b >> 5] != ~0) { - for (;;) { - if ((ptr[b >> 5] & (1 << (b & 0x1f))) == 0) - return b; - b++; - } - } - } - return max; -} - -#define BITS_TO_LONGS(x) (howmany((x), NBBY * sizeof(long))) diff --git a/sys/dev/drm2/drm_auth.c b/sys/dev/drm2/drm_auth.c deleted file mode 100644 index b05b2ff469..0000000000 --- a/sys/dev/drm2/drm_auth.c +++ /dev/null @@ -1,188 +0,0 @@ -/*- - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * 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, 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS 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. - * - * Authors: - * Rickard E. (Rik) Faith - * Gareth Hughes - * - * $FreeBSD: src/sys/dev/drm2/drm_auth.c,v 1.1 2012/05/22 11:07:44 kib Exp $ - */ - -/** @file drm_auth.c - * Implementation of the get/authmagic ioctls implementing the authentication - * scheme between the master and clients. - */ - -#include - -static int drm_hash_magic(drm_magic_t magic) -{ - return magic & (DRM_HASH_SIZE-1); -} - -/** - * Returns the file private associated with the given magic number. - */ -static struct drm_file *drm_find_file(struct drm_device *dev, drm_magic_t magic) -{ - drm_magic_entry_t *pt; - int hash = drm_hash_magic(magic); - - DRM_LOCK_ASSERT(dev); - - for (pt = dev->magiclist[hash].head; pt; pt = pt->next) { - if (pt->magic == magic) { - return pt->priv; - } - } - - return NULL; -} - -/** - * Inserts the given magic number into the hash table of used magic number - * lists. - */ -static int drm_add_magic(struct drm_device *dev, struct drm_file *priv, - drm_magic_t magic) -{ - int hash; - drm_magic_entry_t *entry; - - DRM_DEBUG("%d\n", magic); - - DRM_LOCK_ASSERT(dev); - - hash = drm_hash_magic(magic); - entry = kmalloc(sizeof(*entry), DRM_MEM_MAGIC, M_ZERO | M_NOWAIT); - if (!entry) - return ENOMEM; - entry->magic = magic; - entry->priv = priv; - entry->next = NULL; - - if (dev->magiclist[hash].tail) { - dev->magiclist[hash].tail->next = entry; - dev->magiclist[hash].tail = entry; - } else { - dev->magiclist[hash].head = entry; - dev->magiclist[hash].tail = entry; - } - - return 0; -} - -/** - * Removes the given magic number from the hash table of used magic number - * lists. - */ -static int drm_remove_magic(struct drm_device *dev, drm_magic_t magic) -{ - drm_magic_entry_t *prev = NULL; - drm_magic_entry_t *pt; - int hash; - - DRM_LOCK_ASSERT(dev); - - DRM_DEBUG("%d\n", magic); - hash = drm_hash_magic(magic); - - for (pt = dev->magiclist[hash].head; pt; prev = pt, pt = pt->next) { - if (pt->magic == magic) { - if (dev->magiclist[hash].head == pt) { - dev->magiclist[hash].head = pt->next; - } - if (dev->magiclist[hash].tail == pt) { - dev->magiclist[hash].tail = prev; - } - if (prev) { - prev->next = pt->next; - } - drm_free(pt, DRM_MEM_MAGIC); - return 0; - } - } - - return EINVAL; -} - -/** - * Called by the client, this returns a unique magic number to be authorized - * by the master. - * - * The master may use its own knowledge of the client (such as the X - * connection that the magic is passed over) to determine if the magic number - * should be authenticated. - */ -int drm_getmagic(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - static drm_magic_t sequence = 0; - struct drm_auth *auth = data; - - /* Find unique magic */ - if (file_priv->magic) { - auth->magic = file_priv->magic; - } else { - DRM_LOCK(dev); - do { - int old = sequence; - - auth->magic = old+1; - - if (!atomic_cmpset_int(&sequence, old, auth->magic)) - continue; - } while (drm_find_file(dev, auth->magic)); - file_priv->magic = auth->magic; - drm_add_magic(dev, file_priv, auth->magic); - DRM_UNLOCK(dev); - } - - DRM_DEBUG("%u\n", auth->magic); - - return 0; -} - -/** - * Marks the client associated with the given magic number as authenticated. - */ -int drm_authmagic(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_auth *auth = data; - struct drm_file *priv; - - DRM_DEBUG("%u\n", auth->magic); - - DRM_LOCK(dev); - priv = drm_find_file(dev, auth->magic); - if (priv != NULL) { - priv->authenticated = 1; - drm_remove_magic(dev, auth->magic); - DRM_UNLOCK(dev); - return 0; - } else { - DRM_UNLOCK(dev); - return EINVAL; - } -} diff --git a/sys/dev/drm2/drm_bufs.c b/sys/dev/drm2/drm_bufs.c deleted file mode 100644 index 617aab10f9..0000000000 --- a/sys/dev/drm2/drm_bufs.c +++ /dev/null @@ -1,1123 +0,0 @@ -/*- - * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * 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, 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS 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. - * - * Authors: - * Rickard E. (Rik) Faith - * Gareth Hughes - * - * $FreeBSD: src/sys/dev/drm2/drm_bufs.c,v 1.1 2012/05/22 11:07:44 kib Exp $ - */ - -/** @file drm_bufs.c - * Implementation of the ioctls for setup of DRM mappings and DMA buffers. - */ - -#include -#include - -#include - -/* Allocation of PCI memory resources (framebuffer, registers, etc.) for - * drm_get_resource_*. Note that they are not RF_ACTIVE, so there's no virtual - * address for accessing them. Cleaned up at unload. - */ -static int drm_alloc_resource(struct drm_device *dev, int resource) -{ - struct resource *res; - int rid; - - DRM_LOCK_ASSERT(dev); - - if (resource >= DRM_MAX_PCI_RESOURCE) { - DRM_ERROR("Resource %d too large\n", resource); - return 1; - } - - if (dev->pcir[resource] != NULL) { - return 0; - } - - DRM_UNLOCK(dev); - rid = PCIR_BAR(resource); - res = bus_alloc_resource_any(dev->device, SYS_RES_MEMORY, &rid, - RF_SHAREABLE); - DRM_LOCK(dev); - if (res == NULL) { - DRM_ERROR("Couldn't find resource 0x%x\n", resource); - return 1; - } - - if (dev->pcir[resource] == NULL) { - dev->pcirid[resource] = rid; - dev->pcir[resource] = res; - } - - return 0; -} - -unsigned long drm_get_resource_start(struct drm_device *dev, - unsigned int resource) -{ - if (drm_alloc_resource(dev, resource) != 0) - return 0; - - return rman_get_start(dev->pcir[resource]); -} - -unsigned long drm_get_resource_len(struct drm_device *dev, - unsigned int resource) -{ - if (drm_alloc_resource(dev, resource) != 0) - return 0; - - return rman_get_size(dev->pcir[resource]); -} - -int drm_addmap(struct drm_device * dev, unsigned long offset, - unsigned long size, - enum drm_map_type type, enum drm_map_flags flags, drm_local_map_t **map_ptr) -{ - drm_local_map_t *map; - int align; - /*drm_agp_mem_t *entry; - int valid;*/ - - /* Only allow shared memory to be removable since we only keep enough - * book keeping information about shared memory to allow for removal - * when processes fork. - */ - if ((flags & _DRM_REMOVABLE) && type != _DRM_SHM) { - DRM_ERROR("Requested removable map for non-DRM_SHM\n"); - return EINVAL; - } - if ((offset & PAGE_MASK) || (size & PAGE_MASK)) { - DRM_ERROR("offset/size not page aligned: 0x%lx/0x%lx\n", - offset, size); - return EINVAL; - } - if (offset + size < offset) { - DRM_ERROR("offset and size wrap around: 0x%lx/0x%lx\n", - offset, size); - return EINVAL; - } - - DRM_DEBUG("offset = 0x%08lx, size = 0x%08lx, type = %d\n", offset, - size, type); - - /* Check if this is just another version of a kernel-allocated map, and - * just hand that back if so. - */ - if (type == _DRM_REGISTERS || type == _DRM_FRAME_BUFFER || - type == _DRM_SHM) { - TAILQ_FOREACH(map, &dev->maplist, link) { - if (map->type == type && (map->offset == offset || - (map->type == _DRM_SHM && - map->flags == _DRM_CONTAINS_LOCK))) { - map->size = size; - DRM_DEBUG("Found kernel map %d\n", type); - goto done; - } - } - } - DRM_UNLOCK(dev); - - /* Allocate a new map structure, fill it in, and do any type-specific - * initialization necessary. - */ - map = kmalloc(sizeof(*map), DRM_MEM_MAPS, M_ZERO | M_NOWAIT); - if (!map) { - DRM_LOCK(dev); - return ENOMEM; - } - - map->offset = offset; - map->size = size; - map->type = type; - map->flags = flags; - map->handle = (void *)((unsigned long)alloc_unr(dev->map_unrhdr) << - DRM_MAP_HANDLE_SHIFT); - - switch (map->type) { - case _DRM_REGISTERS: - map->virtual = drm_ioremap(dev, map); - if (!(map->flags & _DRM_WRITE_COMBINING)) - break; - /* FALLTHROUGH */ - case _DRM_FRAME_BUFFER: - if (drm_mtrr_add(map->offset, map->size, DRM_MTRR_WC) == 0) - map->mtrr = 1; - break; - case _DRM_SHM: - map->virtual = kmalloc(map->size, DRM_MEM_MAPS, M_NOWAIT); - DRM_DEBUG("%lu %d %p\n", - map->size, drm_order(map->size), map->virtual); - if (!map->virtual) { - drm_free(map, DRM_MEM_MAPS); - DRM_LOCK(dev); - return ENOMEM; - } - map->offset = (unsigned long)map->virtual; - if (map->flags & _DRM_CONTAINS_LOCK) { - /* Prevent a 2nd X Server from creating a 2nd lock */ - DRM_LOCK(dev); - if (dev->lock.hw_lock != NULL) { - DRM_UNLOCK(dev); - drm_free(map->virtual, DRM_MEM_MAPS); - drm_free(map, DRM_MEM_MAPS); - return EBUSY; - } - dev->lock.hw_lock = map->virtual; /* Pointer to lock */ - DRM_UNLOCK(dev); - } - break; - case _DRM_AGP: - /*valid = 0;*/ - /* In some cases (i810 driver), user space may have already - * added the AGP base itself, because dev->agp->base previously - * only got set during AGP enable. So, only add the base - * address if the map's offset isn't already within the - * aperture. - */ - if (map->offset < dev->agp->base || - map->offset > dev->agp->base + - dev->agp->info.ai_aperture_size - 1) { - map->offset += dev->agp->base; - } - map->mtrr = dev->agp->mtrr; /* for getmap */ - /*for (entry = dev->agp->memory; entry; entry = entry->next) { - if ((map->offset >= entry->bound) && - (map->offset + map->size <= - entry->bound + entry->pages * PAGE_SIZE)) { - valid = 1; - break; - } - } - if (!valid) { - drm_free(map, DRM_MEM_MAPS); - DRM_LOCK(dev); - return EACCES; - }*/ - break; - case _DRM_SCATTER_GATHER: - if (!dev->sg) { - drm_free(map, DRM_MEM_MAPS); - DRM_LOCK(dev); - return EINVAL; - } - map->virtual = (void *)(dev->sg->vaddr + offset); - map->offset = dev->sg->vaddr + offset; - break; - case _DRM_CONSISTENT: - /* Unfortunately, we don't get any alignment specification from - * the caller, so we have to guess. drm_pci_alloc requires - * a power-of-two alignment, so try to align the bus address of - * the map to it size if possible, otherwise just assume - * PAGE_SIZE alignment. - */ - align = map->size; - if ((align & (align - 1)) != 0) - align = PAGE_SIZE; - map->dmah = drm_pci_alloc(dev, map->size, align, 0xfffffffful); - if (map->dmah == NULL) { - drm_free(map, DRM_MEM_MAPS); - DRM_LOCK(dev); - return ENOMEM; - } - map->virtual = map->dmah->vaddr; - map->offset = map->dmah->busaddr; - break; - default: - DRM_ERROR("Bad map type %d\n", map->type); - drm_free(map, DRM_MEM_MAPS); - DRM_LOCK(dev); - return EINVAL; - } - - DRM_LOCK(dev); - TAILQ_INSERT_TAIL(&dev->maplist, map, link); - -done: - /* Jumped to, with lock held, when a kernel map is found. */ - - DRM_DEBUG("Added map %d 0x%lx/0x%lx\n", map->type, map->offset, - map->size); - - *map_ptr = map; - - return 0; -} - -int drm_addmap_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_map *request = data; - drm_local_map_t *map; - int err; - - if (!(dev->flags & (FREAD|FWRITE))) - return EACCES; /* Require read/write */ - - if (!DRM_SUSER(DRM_CURPROC) && request->type != _DRM_AGP) - return EACCES; - - DRM_LOCK(dev); - err = drm_addmap(dev, request->offset, request->size, request->type, - request->flags, &map); - DRM_UNLOCK(dev); - if (err != 0) - return err; - - request->offset = map->offset; - request->size = map->size; - request->type = map->type; - request->flags = map->flags; - request->mtrr = map->mtrr; - request->handle = (void *)map->handle; - - return 0; -} - -void drm_rmmap(struct drm_device *dev, drm_local_map_t *map) -{ - DRM_LOCK_ASSERT(dev); - - if (map == NULL) - return; - - TAILQ_REMOVE(&dev->maplist, map, link); - - switch (map->type) { - case _DRM_REGISTERS: - if (map->bsr == NULL) - drm_ioremapfree(map); - /* FALLTHROUGH */ - case _DRM_FRAME_BUFFER: - if (map->mtrr) { - int __unused retcode; - - retcode = drm_mtrr_del(0, map->offset, map->size, - DRM_MTRR_WC); - DRM_DEBUG("mtrr_del = %d\n", retcode); - } - break; - case _DRM_SHM: - drm_free(map->virtual, DRM_MEM_MAPS); - break; - case _DRM_AGP: - case _DRM_SCATTER_GATHER: - break; - case _DRM_CONSISTENT: - drm_pci_free(dev, map->dmah); - break; - default: - DRM_ERROR("Bad map type %d\n", map->type); - break; - } - - if (map->bsr != NULL) { - bus_release_resource(dev->device, SYS_RES_MEMORY, map->rid, - map->bsr); - } - - DRM_UNLOCK(dev); - if (map->handle) - free_unr(dev->map_unrhdr, (unsigned long)map->handle >> - DRM_MAP_HANDLE_SHIFT); - DRM_LOCK(dev); - - drm_free(map, DRM_MEM_MAPS); -} - -/* Remove a map private from list and deallocate resources if the mapping - * isn't in use. - */ - -int drm_rmmap_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_local_map_t *map; - struct drm_map *request = data; - - DRM_LOCK(dev); - TAILQ_FOREACH(map, &dev->maplist, link) { - if (map->handle == request->handle && - map->flags & _DRM_REMOVABLE) - break; - } - - /* No match found. */ - if (map == NULL) { - DRM_UNLOCK(dev); - return EINVAL; - } - - drm_rmmap(dev, map); - - DRM_UNLOCK(dev); - - return 0; -} - - -static void drm_cleanup_buf_error(struct drm_device *dev, - drm_buf_entry_t *entry) -{ - int i; - - if (entry->seg_count) { - for (i = 0; i < entry->seg_count; i++) { - drm_pci_free(dev, entry->seglist[i]); - } - drm_free(entry->seglist, DRM_MEM_SEGS); - - entry->seg_count = 0; - } - - if (entry->buf_count) { - for (i = 0; i < entry->buf_count; i++) { - drm_free(entry->buflist[i].dev_private, DRM_MEM_BUFS); - } - drm_free(entry->buflist, DRM_MEM_BUFS); - - entry->buf_count = 0; - } -} - -static int drm_do_addbufs_agp(struct drm_device *dev, struct drm_buf_desc *request) -{ - drm_device_dma_t *dma = dev->dma; - drm_buf_entry_t *entry; - /*drm_agp_mem_t *agp_entry; - int valid*/ - drm_buf_t *buf; - unsigned long offset; - unsigned long agp_offset; - int count; - int order; - int size; - int alignment; - int page_order; - int total; - int byte_count; - int i; - drm_buf_t **temp_buflist; - - count = request->count; - order = drm_order(request->size); - size = 1 << order; - - alignment = (request->flags & _DRM_PAGE_ALIGN) - ? round_page(size) : size; - page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0; - total = PAGE_SIZE << page_order; - - byte_count = 0; - agp_offset = dev->agp->base + request->agp_start; - - DRM_DEBUG("count: %d\n", count); - DRM_DEBUG("order: %d\n", order); - DRM_DEBUG("size: %d\n", size); - DRM_DEBUG("agp_offset: 0x%lx\n", agp_offset); - DRM_DEBUG("alignment: %d\n", alignment); - DRM_DEBUG("page_order: %d\n", page_order); - DRM_DEBUG("total: %d\n", total); - - /* Make sure buffers are located in AGP memory that we own */ - /* Breaks MGA due to drm_alloc_agp not setting up entries for the - * memory. Safe to ignore for now because these ioctls are still - * root-only. - */ - /*valid = 0; - for (agp_entry = dev->agp->memory; agp_entry; - agp_entry = agp_entry->next) { - if ((agp_offset >= agp_entry->bound) && - (agp_offset + total * count <= - agp_entry->bound + agp_entry->pages * PAGE_SIZE)) { - valid = 1; - break; - } - } - if (!valid) { - DRM_DEBUG("zone invalid\n"); - return EINVAL; - }*/ - - entry = &dma->bufs[order]; - - entry->buflist = kmalloc(count * sizeof(*entry->buflist), DRM_MEM_BUFS, - M_NOWAIT | M_ZERO); - if (!entry->buflist) { - return ENOMEM; - } - - entry->buf_size = size; - entry->page_order = page_order; - - offset = 0; - - while (entry->buf_count < count) { - buf = &entry->buflist[entry->buf_count]; - buf->idx = dma->buf_count + entry->buf_count; - buf->total = alignment; - buf->order = order; - buf->used = 0; - - buf->offset = (dma->byte_count + offset); - buf->bus_address = agp_offset + offset; - buf->address = (void *)(agp_offset + offset); - buf->next = NULL; - buf->pending = 0; - buf->file_priv = NULL; - - buf->dev_priv_size = dev->driver->buf_priv_size; - buf->dev_private = kmalloc(buf->dev_priv_size, DRM_MEM_BUFS, - M_NOWAIT | M_ZERO); - if (buf->dev_private == NULL) { - /* Set count correctly so we free the proper amount. */ - entry->buf_count = count; - drm_cleanup_buf_error(dev, entry); - return ENOMEM; - } - - offset += alignment; - entry->buf_count++; - byte_count += PAGE_SIZE << page_order; - } - - DRM_DEBUG("byte_count: %d\n", byte_count); - - temp_buflist = krealloc(dma->buflist, - (dma->buf_count + entry->buf_count) * sizeof(*dma->buflist), - DRM_MEM_BUFS, M_NOWAIT); - if (temp_buflist == NULL) { - /* Free the entry because it isn't valid */ - drm_cleanup_buf_error(dev, entry); - return ENOMEM; - } - dma->buflist = temp_buflist; - - for (i = 0; i < entry->buf_count; i++) { - dma->buflist[i + dma->buf_count] = &entry->buflist[i]; - } - - dma->buf_count += entry->buf_count; - dma->byte_count += byte_count; - - DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count); - DRM_DEBUG("entry->buf_count : %d\n", entry->buf_count); - - request->count = entry->buf_count; - request->size = size; - - dma->flags = _DRM_DMA_USE_AGP; - - return 0; -} - -static int drm_do_addbufs_pci(struct drm_device *dev, struct drm_buf_desc *request) -{ - drm_device_dma_t *dma = dev->dma; - int count; - int order; - int size; - int total; - int page_order; - drm_buf_entry_t *entry; - drm_buf_t *buf; - int alignment; - unsigned long offset; - int i; - int byte_count; - int page_count; - unsigned long *temp_pagelist; - drm_buf_t **temp_buflist; - - count = request->count; - order = drm_order(request->size); - size = 1 << order; - - DRM_DEBUG("count=%d, size=%d (%d), order=%d\n", - request->count, request->size, size, order); - - alignment = (request->flags & _DRM_PAGE_ALIGN) - ? round_page(size) : size; - page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0; - total = PAGE_SIZE << page_order; - - entry = &dma->bufs[order]; - - entry->buflist = kmalloc(count * sizeof(*entry->buflist), DRM_MEM_BUFS, - M_NOWAIT | M_ZERO); - entry->seglist = kmalloc(count * sizeof(*entry->seglist), DRM_MEM_SEGS, - M_NOWAIT | M_ZERO); - - /* Keep the original pagelist until we know all the allocations - * have succeeded - */ - temp_pagelist = kmalloc((dma->page_count + (count << page_order)) * - sizeof(*dma->pagelist), DRM_MEM_PAGES, M_NOWAIT); - - if (entry->buflist == NULL || entry->seglist == NULL || - temp_pagelist == NULL) { - drm_free(temp_pagelist, DRM_MEM_PAGES); - drm_free(entry->seglist, DRM_MEM_SEGS); - drm_free(entry->buflist, DRM_MEM_BUFS); - return ENOMEM; - } - - memcpy(temp_pagelist, dma->pagelist, dma->page_count * - sizeof(*dma->pagelist)); - - DRM_DEBUG("pagelist: %d entries\n", - dma->page_count + (count << page_order)); - - entry->buf_size = size; - entry->page_order = page_order; - byte_count = 0; - page_count = 0; - - while (entry->buf_count < count) { - spin_unlock(&dev->dma_lock); - drm_dma_handle_t *dmah = drm_pci_alloc(dev, size, alignment, - 0xfffffffful); - spin_lock(&dev->dma_lock); - if (dmah == NULL) { - /* Set count correctly so we free the proper amount. */ - entry->buf_count = count; - entry->seg_count = count; - drm_cleanup_buf_error(dev, entry); - drm_free(temp_pagelist, DRM_MEM_PAGES); - return ENOMEM; - } - - entry->seglist[entry->seg_count++] = dmah; - for (i = 0; i < (1 << page_order); i++) { - DRM_DEBUG("page %d @ %p\n", - dma->page_count + page_count, - (char *)dmah->vaddr + PAGE_SIZE * i); - temp_pagelist[dma->page_count + page_count++] = - (long)dmah->vaddr + PAGE_SIZE * i; - } - for (offset = 0; - offset + size <= total && entry->buf_count < count; - offset += alignment, ++entry->buf_count) { - buf = &entry->buflist[entry->buf_count]; - buf->idx = dma->buf_count + entry->buf_count; - buf->total = alignment; - buf->order = order; - buf->used = 0; - buf->offset = (dma->byte_count + byte_count + offset); - buf->address = ((char *)dmah->vaddr + offset); - buf->bus_address = dmah->busaddr + offset; - buf->next = NULL; - buf->pending = 0; - buf->file_priv = NULL; - - buf->dev_priv_size = dev->driver->buf_priv_size; - buf->dev_private = kmalloc(buf->dev_priv_size, - DRM_MEM_BUFS, M_NOWAIT | M_ZERO); - if (buf->dev_private == NULL) { - /* Set count correctly so we free the proper amount. */ - entry->buf_count = count; - entry->seg_count = count; - drm_cleanup_buf_error(dev, entry); - drm_free(temp_pagelist, DRM_MEM_PAGES); - return ENOMEM; - } - - DRM_DEBUG("buffer %d @ %p\n", - entry->buf_count, buf->address); - } - byte_count += PAGE_SIZE << page_order; - } - - temp_buflist = krealloc(dma->buflist, - (dma->buf_count + entry->buf_count) * sizeof(*dma->buflist), - DRM_MEM_BUFS, M_NOWAIT); - if (temp_buflist == NULL) { - /* Free the entry because it isn't valid */ - drm_cleanup_buf_error(dev, entry); - drm_free(temp_pagelist, DRM_MEM_PAGES); - return ENOMEM; - } - dma->buflist = temp_buflist; - - for (i = 0; i < entry->buf_count; i++) { - dma->buflist[i + dma->buf_count] = &entry->buflist[i]; - } - - /* No allocations failed, so now we can replace the orginal pagelist - * with the new one. - */ - drm_free(dma->pagelist, DRM_MEM_PAGES); - dma->pagelist = temp_pagelist; - - dma->buf_count += entry->buf_count; - dma->seg_count += entry->seg_count; - dma->page_count += entry->seg_count << page_order; - dma->byte_count += PAGE_SIZE * (entry->seg_count << page_order); - - request->count = entry->buf_count; - request->size = size; - - return 0; - -} - -static int drm_do_addbufs_sg(struct drm_device *dev, struct drm_buf_desc *request) -{ - drm_device_dma_t *dma = dev->dma; - drm_buf_entry_t *entry; - drm_buf_t *buf; - unsigned long offset; - unsigned long agp_offset; - int count; - int order; - int size; - int alignment; - int page_order; - int total; - int byte_count; - int i; - drm_buf_t **temp_buflist; - - count = request->count; - order = drm_order(request->size); - size = 1 << order; - - alignment = (request->flags & _DRM_PAGE_ALIGN) - ? round_page(size) : size; - page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0; - total = PAGE_SIZE << page_order; - - byte_count = 0; - agp_offset = request->agp_start; - - DRM_DEBUG("count: %d\n", count); - DRM_DEBUG("order: %d\n", order); - DRM_DEBUG("size: %d\n", size); - DRM_DEBUG("agp_offset: %ld\n", agp_offset); - DRM_DEBUG("alignment: %d\n", alignment); - DRM_DEBUG("page_order: %d\n", page_order); - DRM_DEBUG("total: %d\n", total); - - entry = &dma->bufs[order]; - - entry->buflist = kmalloc(count * sizeof(*entry->buflist), DRM_MEM_BUFS, - M_NOWAIT | M_ZERO); - if (entry->buflist == NULL) - return ENOMEM; - - entry->buf_size = size; - entry->page_order = page_order; - - offset = 0; - - while (entry->buf_count < count) { - buf = &entry->buflist[entry->buf_count]; - buf->idx = dma->buf_count + entry->buf_count; - buf->total = alignment; - buf->order = order; - buf->used = 0; - - buf->offset = (dma->byte_count + offset); - buf->bus_address = agp_offset + offset; - buf->address = (void *)(agp_offset + offset + dev->sg->vaddr); - buf->next = NULL; - buf->pending = 0; - buf->file_priv = NULL; - - buf->dev_priv_size = dev->driver->buf_priv_size; - buf->dev_private = kmalloc(buf->dev_priv_size, DRM_MEM_BUFS, - M_NOWAIT | M_ZERO); - if (buf->dev_private == NULL) { - /* Set count correctly so we free the proper amount. */ - entry->buf_count = count; - drm_cleanup_buf_error(dev, entry); - return ENOMEM; - } - - DRM_DEBUG("buffer %d @ %p\n", - entry->buf_count, buf->address); - - offset += alignment; - entry->buf_count++; - byte_count += PAGE_SIZE << page_order; - } - - DRM_DEBUG("byte_count: %d\n", byte_count); - - temp_buflist = krealloc(dma->buflist, - (dma->buf_count + entry->buf_count) * sizeof(*dma->buflist), - DRM_MEM_BUFS, M_NOWAIT); - if (temp_buflist == NULL) { - /* Free the entry because it isn't valid */ - drm_cleanup_buf_error(dev, entry); - return ENOMEM; - } - dma->buflist = temp_buflist; - - for (i = 0; i < entry->buf_count; i++) { - dma->buflist[i + dma->buf_count] = &entry->buflist[i]; - } - - dma->buf_count += entry->buf_count; - dma->byte_count += byte_count; - - DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count); - DRM_DEBUG("entry->buf_count : %d\n", entry->buf_count); - - request->count = entry->buf_count; - request->size = size; - - dma->flags = _DRM_DMA_USE_SG; - - return 0; -} - -int drm_addbufs_agp(struct drm_device *dev, struct drm_buf_desc *request) -{ - int order, ret; - - if (request->count < 0 || request->count > 4096) - return EINVAL; - - order = drm_order(request->size); - if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) - return EINVAL; - - spin_lock(&dev->dma_lock); - - /* No more allocations after first buffer-using ioctl. */ - if (dev->buf_use != 0) { - spin_unlock(&dev->dma_lock); - return EBUSY; - } - /* No more than one allocation per order */ - if (dev->dma->bufs[order].buf_count != 0) { - spin_unlock(&dev->dma_lock); - return ENOMEM; - } - - ret = drm_do_addbufs_agp(dev, request); - - spin_unlock(&dev->dma_lock); - - return ret; -} - -int drm_addbufs_sg(struct drm_device *dev, struct drm_buf_desc *request) -{ - int order, ret; - - if (!DRM_SUSER(DRM_CURPROC)) - return EACCES; - - if (request->count < 0 || request->count > 4096) - return EINVAL; - - order = drm_order(request->size); - if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) - return EINVAL; - - spin_lock(&dev->dma_lock); - - /* No more allocations after first buffer-using ioctl. */ - if (dev->buf_use != 0) { - spin_unlock(&dev->dma_lock); - return EBUSY; - } - /* No more than one allocation per order */ - if (dev->dma->bufs[order].buf_count != 0) { - spin_unlock(&dev->dma_lock); - return ENOMEM; - } - - ret = drm_do_addbufs_sg(dev, request); - - spin_unlock(&dev->dma_lock); - - return ret; -} - -int drm_addbufs_pci(struct drm_device *dev, struct drm_buf_desc *request) -{ - int order, ret; - - if (!DRM_SUSER(DRM_CURPROC)) - return EACCES; - - if (request->count < 0 || request->count > 4096) - return EINVAL; - - order = drm_order(request->size); - if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) - return EINVAL; - - spin_lock(&dev->dma_lock); - - /* No more allocations after first buffer-using ioctl. */ - if (dev->buf_use != 0) { - spin_unlock(&dev->dma_lock); - return EBUSY; - } - /* No more than one allocation per order */ - if (dev->dma->bufs[order].buf_count != 0) { - spin_unlock(&dev->dma_lock); - return ENOMEM; - } - - ret = drm_do_addbufs_pci(dev, request); - - spin_unlock(&dev->dma_lock); - - return ret; -} - -int drm_addbufs(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - struct drm_buf_desc *request = data; - int err; - - if (request->flags & _DRM_AGP_BUFFER) - err = drm_addbufs_agp(dev, request); - else if (request->flags & _DRM_SG_BUFFER) - err = drm_addbufs_sg(dev, request); - else - err = drm_addbufs_pci(dev, request); - - return err; -} - -int drm_infobufs(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_device_dma_t *dma = dev->dma; - struct drm_buf_info *request = data; - int i; - int count; - int retcode = 0; - - spin_lock(&dev->dma_lock); - ++dev->buf_use; /* Can't allocate more after this call */ - spin_unlock(&dev->dma_lock); - - for (i = 0, count = 0; i < DRM_MAX_ORDER + 1; i++) { - if (dma->bufs[i].buf_count) - ++count; - } - - DRM_DEBUG("count = %d\n", count); - - if (request->count >= count) { - for (i = 0, count = 0; i < DRM_MAX_ORDER + 1; i++) { - if (dma->bufs[i].buf_count) { - struct drm_buf_desc from; - - from.count = dma->bufs[i].buf_count; - from.size = dma->bufs[i].buf_size; - from.low_mark = dma->bufs[i].freelist.low_mark; - from.high_mark = dma->bufs[i].freelist.high_mark; - - if (DRM_COPY_TO_USER(&request->list[count], &from, - sizeof(struct drm_buf_desc)) != 0) { - retcode = EFAULT; - break; - } - - DRM_DEBUG("%d %d %d %d %d\n", - i, dma->bufs[i].buf_count, - dma->bufs[i].buf_size, - dma->bufs[i].freelist.low_mark, - dma->bufs[i].freelist.high_mark); - ++count; - } - } - } - request->count = count; - - return retcode; -} - -int drm_markbufs(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_device_dma_t *dma = dev->dma; - struct drm_buf_desc *request = data; - int order; - - DRM_DEBUG("%d, %d, %d\n", - request->size, request->low_mark, request->high_mark); - - - order = drm_order(request->size); - if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER || - request->low_mark < 0 || request->high_mark < 0) { - return EINVAL; - } - - spin_lock(&dev->dma_lock); - if (request->low_mark > dma->bufs[order].buf_count || - request->high_mark > dma->bufs[order].buf_count) { - spin_unlock(&dev->dma_lock); - return EINVAL; - } - - dma->bufs[order].freelist.low_mark = request->low_mark; - dma->bufs[order].freelist.high_mark = request->high_mark; - spin_unlock(&dev->dma_lock); - - return 0; -} - -int drm_freebufs(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_device_dma_t *dma = dev->dma; - struct drm_buf_free *request = data; - int i; - int idx; - drm_buf_t *buf; - int retcode = 0; - - DRM_DEBUG("%d\n", request->count); - - spin_lock(&dev->dma_lock); - for (i = 0; i < request->count; i++) { - if (DRM_COPY_FROM_USER(&idx, &request->list[i], sizeof(idx))) { - retcode = EFAULT; - break; - } - if (idx < 0 || idx >= dma->buf_count) { - DRM_ERROR("Index %d (of %d max)\n", - idx, dma->buf_count - 1); - retcode = EINVAL; - break; - } - buf = dma->buflist[idx]; - if (buf->file_priv != file_priv) { - DRM_ERROR("Process %d freeing buffer not owned\n", - DRM_CURRENTPID); - retcode = EINVAL; - break; - } - drm_free_buffer(dev, buf); - } - spin_unlock(&dev->dma_lock); - - return retcode; -} - -int drm_mapbufs(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_device_dma_t *dma = dev->dma; - int retcode = 0; - const int zero = 0; - vm_offset_t address; - struct vmspace *vms; - vm_ooffset_t foff; - vm_size_t size; - vm_offset_t vaddr; - struct drm_buf_map *request = data; - int i; - - vms = DRM_CURPROC->td_proc->p_vmspace; - - spin_lock(&dev->dma_lock); - dev->buf_use++; /* Can't allocate more after this call */ - spin_unlock(&dev->dma_lock); - - if (request->count < dma->buf_count) - goto done; - - if ((drm_core_has_AGP(dev) && (dma->flags & _DRM_DMA_USE_AGP)) || - (drm_core_check_feature(dev, DRIVER_SG) && - (dma->flags & _DRM_DMA_USE_SG))) { - drm_local_map_t *map = dev->agp_buffer_map; - - if (map == NULL) { - retcode = EINVAL; - goto done; - } - size = round_page(map->size); - foff = (unsigned long)map->handle; - } else { - size = round_page(dma->byte_count), - foff = 0; - } - - vaddr = round_page((vm_offset_t)vms->vm_daddr + MAXDSIZ); - retcode = vm_mmap(&vms->vm_map, &vaddr, size, PROT_READ | PROT_WRITE, - VM_PROT_ALL, MAP_SHARED | MAP_NOSYNC, - SLIST_FIRST(&dev->devnode->si_hlist), foff); - if (retcode) - goto done; - - request->virtual = (void *)vaddr; - - for (i = 0; i < dma->buf_count; i++) { - if (DRM_COPY_TO_USER(&request->list[i].idx, - &dma->buflist[i]->idx, sizeof(request->list[0].idx))) { - retcode = EFAULT; - goto done; - } - if (DRM_COPY_TO_USER(&request->list[i].total, - &dma->buflist[i]->total, sizeof(request->list[0].total))) { - retcode = EFAULT; - goto done; - } - if (DRM_COPY_TO_USER(&request->list[i].used, &zero, - sizeof(zero))) { - retcode = EFAULT; - goto done; - } - address = vaddr + dma->buflist[i]->offset; /* *** */ - if (DRM_COPY_TO_USER(&request->list[i].address, &address, - sizeof(address))) { - retcode = EFAULT; - goto done; - } - } - - done: - request->count = dma->buf_count; - - DRM_DEBUG("%d buffers, retcode = %d\n", request->count, retcode); - - return retcode; -} - -/* - * Compute order. Can be made faster. - */ -int drm_order(unsigned long size) -{ - int order; - - if (size == 0) - return 0; - - order = flsl(size) - 1; - if (size & ~(1ul << order)) - ++order; - - return order; -} diff --git a/sys/dev/drm2/drm_context.c b/sys/dev/drm2/drm_context.c deleted file mode 100644 index d714e8c34d..0000000000 --- a/sys/dev/drm2/drm_context.c +++ /dev/null @@ -1,310 +0,0 @@ -/*- - * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * 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, 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS 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. - * - * Authors: - * Rickard E. (Rik) Faith - * Gareth Hughes - * - * $FreeBSD: src/sys/dev/drm2/drm_context.c,v 1.1 2012/05/22 11:07:44 kib Exp $ - */ - -/** @file drm_context.c - * Implementation of the context management ioctls. - */ - -#include - -/* ================================================================ - * Context bitmap support - */ - -void drm_ctxbitmap_free(struct drm_device *dev, int ctx_handle) -{ - if (ctx_handle < 0 || ctx_handle >= DRM_MAX_CTXBITMAP || - dev->ctx_bitmap == NULL) { - DRM_ERROR("Attempt to free invalid context handle: %d\n", - ctx_handle); - return; - } - - DRM_LOCK(dev); - clear_bit(ctx_handle, dev->ctx_bitmap); - dev->context_sareas[ctx_handle] = NULL; - DRM_UNLOCK(dev); - return; -} - -int drm_ctxbitmap_next(struct drm_device *dev) -{ - int bit; - - if (dev->ctx_bitmap == NULL) - return -1; - - DRM_LOCK(dev); - bit = find_first_zero_bit(dev->ctx_bitmap, DRM_MAX_CTXBITMAP); - if (bit >= DRM_MAX_CTXBITMAP) { - DRM_UNLOCK(dev); - return -1; - } - - set_bit(bit, dev->ctx_bitmap); - DRM_DEBUG("bit : %d\n", bit); - if ((bit+1) > dev->max_context) { - drm_local_map_t **ctx_sareas; - int max_ctx = (bit+1); - - ctx_sareas = krealloc(dev->context_sareas, - max_ctx * sizeof(*dev->context_sareas), - DRM_MEM_SAREA, M_NOWAIT); - if (ctx_sareas == NULL) { - clear_bit(bit, dev->ctx_bitmap); - DRM_DEBUG("failed to allocate bit : %d\n", bit); - DRM_UNLOCK(dev); - return -1; - } - dev->max_context = max_ctx; - dev->context_sareas = ctx_sareas; - dev->context_sareas[bit] = NULL; - } - DRM_UNLOCK(dev); - return bit; -} - -int drm_ctxbitmap_init(struct drm_device *dev) -{ - int i; - int temp; - - DRM_LOCK(dev); - dev->ctx_bitmap = kmalloc(PAGE_SIZE, DRM_MEM_CTXBITMAP, - M_NOWAIT | M_ZERO); - if (dev->ctx_bitmap == NULL) { - DRM_UNLOCK(dev); - return ENOMEM; - } - dev->context_sareas = NULL; - dev->max_context = -1; - DRM_UNLOCK(dev); - - for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) { - temp = drm_ctxbitmap_next(dev); - DRM_DEBUG("drm_ctxbitmap_init : %d\n", temp); - } - - return 0; -} - -void drm_ctxbitmap_cleanup(struct drm_device *dev) -{ - DRM_LOCK(dev); - if (dev->context_sareas != NULL) - drm_free(dev->context_sareas, DRM_MEM_SAREA); - drm_free(dev->ctx_bitmap, DRM_MEM_CTXBITMAP); - DRM_UNLOCK(dev); -} - -/* ================================================================ - * Per Context SAREA Support - */ - -int drm_getsareactx(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_ctx_priv_map *request = data; - drm_local_map_t *map; - - DRM_LOCK(dev); - if (dev->max_context < 0 || - request->ctx_id >= (unsigned) dev->max_context) { - DRM_UNLOCK(dev); - return EINVAL; - } - - map = dev->context_sareas[request->ctx_id]; - DRM_UNLOCK(dev); - - request->handle = (void *)map->handle; - - return 0; -} - -int drm_setsareactx(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_ctx_priv_map *request = data; - drm_local_map_t *map = NULL; - - DRM_LOCK(dev); - TAILQ_FOREACH(map, &dev->maplist, link) { - if (map->handle == request->handle) { - if (dev->max_context < 0) - goto bad; - if (request->ctx_id >= (unsigned) dev->max_context) - goto bad; - dev->context_sareas[request->ctx_id] = map; - DRM_UNLOCK(dev); - return 0; - } - } - -bad: - DRM_UNLOCK(dev); - return EINVAL; -} - -/* ================================================================ - * The actual DRM context handling routines - */ - -int drm_context_switch(struct drm_device *dev, int old, int new) -{ - if (test_and_set_bit(0, &dev->context_flag)) { - DRM_ERROR("Reentering -- FIXME\n"); - return EBUSY; - } - - DRM_DEBUG("Context switch from %d to %d\n", old, new); - - if (new == dev->last_context) { - clear_bit(0, &dev->context_flag); - return 0; - } - - return 0; -} - -int drm_context_switch_complete(struct drm_device *dev, int new) -{ - dev->last_context = new; /* PRE/POST: This is the _only_ writer. */ - - if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { - DRM_ERROR("Lock isn't held after context switch\n"); - } - - /* If a context switch is ever initiated - when the kernel holds the lock, release - that lock here. */ - clear_bit(0, &dev->context_flag); - - return 0; -} - -int drm_resctx(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - struct drm_ctx_res *res = data; - struct drm_ctx ctx; - int i; - - if (res->count >= DRM_RESERVED_CONTEXTS) { - bzero(&ctx, sizeof(ctx)); - for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) { - ctx.handle = i; - if (DRM_COPY_TO_USER(&res->contexts[i], - &ctx, sizeof(ctx))) - return EFAULT; - } - } - res->count = DRM_RESERVED_CONTEXTS; - - return 0; -} - -int drm_addctx(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - struct drm_ctx *ctx = data; - - ctx->handle = drm_ctxbitmap_next(dev); - if (ctx->handle == DRM_KERNEL_CONTEXT) { - /* Skip kernel's context and get a new one. */ - ctx->handle = drm_ctxbitmap_next(dev); - } - DRM_DEBUG("%d\n", ctx->handle); - if (ctx->handle == -1) { - DRM_DEBUG("Not enough free contexts.\n"); - /* Should this return -EBUSY instead? */ - return ENOMEM; - } - - if (dev->driver->context_ctor && ctx->handle != DRM_KERNEL_CONTEXT) { - DRM_LOCK(dev); - dev->driver->context_ctor(dev, ctx->handle); - DRM_UNLOCK(dev); - } - - return 0; -} - -int drm_modctx(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - /* This does nothing */ - return 0; -} - -int drm_getctx(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - struct drm_ctx *ctx = data; - - /* This is 0, because we don't handle any context flags */ - ctx->flags = 0; - - return 0; -} - -int drm_switchctx(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_ctx *ctx = data; - - DRM_DEBUG("%d\n", ctx->handle); - return drm_context_switch(dev, dev->last_context, ctx->handle); -} - -int drm_newctx(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - struct drm_ctx *ctx = data; - - DRM_DEBUG("%d\n", ctx->handle); - drm_context_switch_complete(dev, ctx->handle); - - return 0; -} - -int drm_rmctx(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - struct drm_ctx *ctx = data; - - DRM_DEBUG("%d\n", ctx->handle); - if (ctx->handle != DRM_KERNEL_CONTEXT) { - if (dev->driver->context_dtor) { - DRM_LOCK(dev); - dev->driver->context_dtor(dev, ctx->handle); - DRM_UNLOCK(dev); - } - - drm_ctxbitmap_free(dev, ctx->handle); - } - - return 0; -} diff --git a/sys/dev/drm2/drm_dma.c b/sys/dev/drm2/drm_dma.c deleted file mode 100644 index 406b0fff7e..0000000000 --- a/sys/dev/drm2/drm_dma.c +++ /dev/null @@ -1,137 +0,0 @@ -/*- - * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * 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, 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS 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. - * - * Authors: - * Rickard E. (Rik) Faith - * Gareth Hughes - * - * $FreeBSD: src/sys/dev/drm2/drm_dma.c,v 1.1 2012/05/22 11:07:44 kib Exp $ - */ - -/** @file drm_dma.c - * Support code for DMA buffer management. - * - * The implementation used to be significantly more complicated, but the - * complexity has been moved into the drivers as different buffer management - * schemes evolved. - */ - -#include - -int drm_dma_setup(struct drm_device *dev) -{ - - dev->dma = kmalloc(sizeof(*dev->dma), DRM_MEM_DRIVER, M_NOWAIT | M_ZERO); - if (dev->dma == NULL) - return ENOMEM; - - spin_init(&dev->dma_lock); - - return 0; -} - -void drm_dma_takedown(struct drm_device *dev) -{ - drm_device_dma_t *dma = dev->dma; - int i, j; - - if (dma == NULL) - return; - - /* Clear dma buffers */ - for (i = 0; i <= DRM_MAX_ORDER; i++) { - if (dma->bufs[i].seg_count) { - DRM_DEBUG("order %d: buf_count = %d," - " seg_count = %d\n", i, dma->bufs[i].buf_count, - dma->bufs[i].seg_count); - for (j = 0; j < dma->bufs[i].seg_count; j++) { - drm_pci_free(dev, dma->bufs[i].seglist[j]); - } - drm_free(dma->bufs[i].seglist, DRM_MEM_SEGS); - } - - if (dma->bufs[i].buf_count) { - for (j = 0; j < dma->bufs[i].buf_count; j++) { - drm_free(dma->bufs[i].buflist[j].dev_private, - DRM_MEM_BUFS); - } - drm_free(dma->bufs[i].buflist, DRM_MEM_BUFS); - } - } - - drm_free(dma->buflist, DRM_MEM_BUFS); - drm_free(dma->pagelist, DRM_MEM_PAGES); - drm_free(dev->dma, DRM_MEM_DRIVER); - dev->dma = NULL; - spin_uninit(&dev->dma_lock); -} - - -void drm_free_buffer(struct drm_device *dev, drm_buf_t *buf) -{ - if (!buf) - return; - - buf->pending = 0; - buf->file_priv= NULL; - buf->used = 0; -} - -void drm_reclaim_buffers(struct drm_device *dev, struct drm_file *file_priv) -{ - drm_device_dma_t *dma = dev->dma; - int i; - - if (!dma) - return; - - for (i = 0; i < dma->buf_count; i++) { - if (dma->buflist[i]->file_priv == file_priv) { - switch (dma->buflist[i]->list) { - case DRM_LIST_NONE: - drm_free_buffer(dev, dma->buflist[i]); - break; - case DRM_LIST_WAIT: - dma->buflist[i]->list = DRM_LIST_RECLAIM; - break; - default: - /* Buffer already on hardware. */ - break; - } - } - } -} - -/* Call into the driver-specific DMA handler */ -int drm_dma(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - - if (dev->driver->dma_ioctl) { - /* shared code returns -errno */ - return -dev->driver->dma_ioctl(dev, data, file_priv); - } else { - DRM_DEBUG("DMA ioctl on driver with no dma handler\n"); - return EINVAL; - } -} diff --git a/sys/dev/drm2/drm_drawable.c b/sys/dev/drm2/drm_drawable.c deleted file mode 100644 index 3c4639166e..0000000000 --- a/sys/dev/drm2/drm_drawable.c +++ /dev/null @@ -1,173 +0,0 @@ -/*- - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * 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, 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS 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. - * - * Authors: - * Rickard E. (Rik) Faith - * Gareth Hughes - * - * $FreeBSD: src/sys/dev/drm2/drm_drawable.c,v 1.1 2012/05/22 11:07:44 kib Exp $ - */ - -/** @file drm_drawable.c - * This file implements ioctls to store information along with DRM drawables, - * such as the current set of cliprects for vblank-synced buffer swaps. - */ - -#include - -struct bsd_drm_drawable_info { - struct drm_drawable_info info; - int handle; - RB_ENTRY(bsd_drm_drawable_info) tree; -}; - -static int -drm_drawable_compare(struct bsd_drm_drawable_info *a, - struct bsd_drm_drawable_info *b) -{ - if (a->handle > b->handle) - return 1; - if (a->handle < b->handle) - return -1; - return 0; -} - -RB_PROTOTYPE_STATIC(drawable_tree, bsd_drm_drawable_info, tree, - drm_drawable_compare); -RB_GENERATE_STATIC(drawable_tree, bsd_drm_drawable_info, tree, - drm_drawable_compare); - -struct drm_drawable_info * -drm_get_drawable_info(struct drm_device *dev, int handle) -{ - struct bsd_drm_drawable_info find, *result; - - find.handle = handle; - result = RB_FIND(drawable_tree, &dev->drw_head, &find); - - return &result->info; -} - -int drm_adddraw(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - struct drm_draw *draw = data; - struct bsd_drm_drawable_info *info; - - info = kmalloc(sizeof(struct bsd_drm_drawable_info), DRM_MEM_DRAWABLE, - M_NOWAIT | M_ZERO); - if (info == NULL) - return ENOMEM; - - info->handle = alloc_unr(dev->drw_unrhdr); - spin_lock(&dev->drw_lock); - RB_INSERT(drawable_tree, &dev->drw_head, info); - draw->handle = info->handle; - spin_unlock(&dev->drw_lock); - - DRM_DEBUG("%d\n", draw->handle); - - return 0; -} - -int drm_rmdraw(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - struct drm_draw *draw = (struct drm_draw *)data; - struct drm_drawable_info *info; - - spin_lock(&dev->drw_lock); - info = drm_get_drawable_info(dev, draw->handle); - if (info != NULL) { - RB_REMOVE(drawable_tree, &dev->drw_head, - (struct bsd_drm_drawable_info *)info); - spin_unlock(&dev->drw_lock); - free_unr(dev->drw_unrhdr, draw->handle); - drm_free(info->rects, DRM_MEM_DRAWABLE); - drm_free(info, DRM_MEM_DRAWABLE); - return 0; - } else { - spin_unlock(&dev->drw_lock); - return EINVAL; - } -} - -int drm_update_draw(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_drawable_info *info; - struct drm_update_draw *update = (struct drm_update_draw *)data; - int ret; - - info = drm_get_drawable_info(dev, update->handle); - if (info == NULL) - return EINVAL; - - switch (update->type) { - case DRM_DRAWABLE_CLIPRECTS: - spin_lock(&dev->drw_lock); - if (update->num != info->num_rects) { - drm_free(info->rects, DRM_MEM_DRAWABLE); - info->rects = NULL; - info->num_rects = 0; - } - if (update->num == 0) { - spin_unlock(&dev->drw_lock); - return 0; - } - if (info->rects == NULL) { - info->rects = kmalloc(sizeof(*info->rects) * - update->num, DRM_MEM_DRAWABLE, M_NOWAIT); - if (info->rects == NULL) { - spin_unlock(&dev->drw_lock); - return ENOMEM; - } - info->num_rects = update->num; - } - /* For some reason the pointer arg is unsigned long long. */ - ret = copyin((void *)(intptr_t)update->data, info->rects, - sizeof(*info->rects) * info->num_rects); - spin_unlock(&dev->drw_lock); - return ret; - default: - return EINVAL; - } -} - -void drm_drawable_free_all(struct drm_device *dev) -{ - struct bsd_drm_drawable_info *info, *next; - - spin_lock(&dev->drw_lock); - for (info = RB_MIN(drawable_tree, &dev->drw_head); - info != NULL ; info = next) { - next = RB_NEXT(drawable_tree, &dev->drw_head, info); - RB_REMOVE(drawable_tree, &dev->drw_head, - (struct bsd_drm_drawable_info *)info); - spin_unlock(&dev->drw_lock); - free_unr(dev->drw_unrhdr, info->handle); - drm_free(info->info.rects, DRM_MEM_DRAWABLE); - drm_free(info, DRM_MEM_DRAWABLE); - spin_lock(&dev->drw_lock); - } - spin_unlock(&dev->drw_lock); -} diff --git a/sys/dev/drm2/drm_drv.c b/sys/dev/drm2/drm_drv.c deleted file mode 100644 index f093b04083..0000000000 --- a/sys/dev/drm2/drm_drv.c +++ /dev/null @@ -1,1069 +0,0 @@ -/*- - * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * 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, 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS 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. - * - * Authors: - * Rickard E. (Rik) Faith - * Gareth Hughes - * - * $FreeBSD: head/sys/dev/drm2/drm_drv.c 247835 2013-03-05 09:49:34Z kib $ - */ - -/** @file drm_drv.c - * The catch-all file for DRM device support, including module setup/teardown, - * open/close, and ioctl dispatch. - */ - - -#include -#include -#include -#include -#include -#include - -#ifdef DRM_DEBUG_DEFAULT_ON -int drm_debug_flag = (DRM_DEBUGBITS_DEBUG | DRM_DEBUGBITS_KMS | - DRM_DEBUGBITS_FAILED_IOCTL); -#else -int drm_debug_flag = 0; -#endif -int drm_notyet_flag = 0; - -unsigned int drm_vblank_offdelay = 5000; /* Default to 5000 msecs. */ -unsigned int drm_timestamp_precision = 20; /* Default to 20 usecs. */ - -static int drm_load(struct drm_device *dev); -static void drm_unload(struct drm_device *dev); -static drm_pci_id_list_t *drm_find_description(int vendor, int device, - drm_pci_id_list_t *idlist); - -#define DRIVER_SOFTC(unit) \ - ((struct drm_device *)devclass_get_softc(drm_devclass, unit)) - -static int -drm_modevent(module_t mod, int type, void *data) -{ - - switch (type) { - case MOD_LOAD: - TUNABLE_INT_FETCH("drm.debug", &drm_debug_flag); - TUNABLE_INT_FETCH("drm.notyet", &drm_notyet_flag); - break; - } - return (0); -} - -static moduledata_t drm_mod = { - "drmn", - drm_modevent, - 0 -}; -DECLARE_MODULE(drmn, drm_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST); -MODULE_VERSION(drmn, 1); -MODULE_DEPEND(drmn, agp, 1, 1, 1); -MODULE_DEPEND(drmn, pci, 1, 1, 1); -MODULE_DEPEND(drmn, iicbus, 1, 1, 1); - -static drm_ioctl_desc_t drm_ioctls[256] = { - DRM_IOCTL_DEF(DRM_IOCTL_VERSION, drm_version, 0), - DRM_IOCTL_DEF(DRM_IOCTL_GET_UNIQUE, drm_getunique, 0), - DRM_IOCTL_DEF(DRM_IOCTL_GET_MAGIC, drm_getmagic, 0), - DRM_IOCTL_DEF(DRM_IOCTL_IRQ_BUSID, drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_GET_MAP, drm_getmap, 0), - DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT, drm_getclient, 0), - DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS, drm_getstats, 0), - DRM_IOCTL_DEF(DRM_IOCTL_GET_CAP, drm_getcap, DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER|DRM_ROOT_ONLY), - - DRM_IOCTL_DEF(DRM_IOCTL_SET_UNIQUE, drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_BLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_UNBLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_AUTH_MAGIC, drm_authmagic, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - - DRM_IOCTL_DEF(DRM_IOCTL_ADD_MAP, drm_addmap_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_RM_MAP, drm_rmmap_ioctl, DRM_AUTH), - - DRM_IOCTL_DEF(DRM_IOCTL_SET_SAREA_CTX, drm_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_GET_SAREA_CTX, drm_getsareactx, DRM_AUTH), - - DRM_IOCTL_DEF(DRM_IOCTL_SET_MASTER, drm_setmaster_ioctl, DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_DROP_MASTER, drm_dropmaster_ioctl, DRM_ROOT_ONLY), - - DRM_IOCTL_DEF(DRM_IOCTL_ADD_CTX, drm_addctx, DRM_AUTH|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_RM_CTX, drm_rmctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_MOD_CTX, drm_modctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_GET_CTX, drm_getctx, DRM_AUTH), - DRM_IOCTL_DEF(DRM_IOCTL_SWITCH_CTX, drm_switchctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_NEW_CTX, drm_newctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_RES_CTX, drm_resctx, DRM_AUTH), - - DRM_IOCTL_DEF(DRM_IOCTL_ADD_DRAW, drm_adddraw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_RM_DRAW, drm_rmdraw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - - DRM_IOCTL_DEF(DRM_IOCTL_LOCK, drm_lock, DRM_AUTH), - DRM_IOCTL_DEF(DRM_IOCTL_UNLOCK, drm_unlock, DRM_AUTH), - - DRM_IOCTL_DEF(DRM_IOCTL_FINISH, drm_noop, DRM_AUTH), - - DRM_IOCTL_DEF(DRM_IOCTL_ADD_BUFS, drm_addbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_MARK_BUFS, drm_markbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_INFO_BUFS, drm_infobufs, DRM_AUTH), - DRM_IOCTL_DEF(DRM_IOCTL_MAP_BUFS, drm_mapbufs, DRM_AUTH), - DRM_IOCTL_DEF(DRM_IOCTL_FREE_BUFS, drm_freebufs, DRM_AUTH), - DRM_IOCTL_DEF(DRM_IOCTL_DMA, drm_dma, DRM_AUTH), - - DRM_IOCTL_DEF(DRM_IOCTL_CONTROL, drm_control, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - - DRM_IOCTL_DEF(DRM_IOCTL_AGP_ACQUIRE, drm_agp_acquire_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_AGP_RELEASE, drm_agp_release_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_AGP_ENABLE, drm_agp_enable_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_AGP_INFO, drm_agp_info_ioctl, DRM_AUTH), - DRM_IOCTL_DEF(DRM_IOCTL_AGP_ALLOC, drm_agp_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_AGP_FREE, drm_agp_free_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_AGP_BIND, drm_agp_bind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_AGP_UNBIND, drm_agp_unbind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - - DRM_IOCTL_DEF(DRM_IOCTL_SG_ALLOC, drm_sg_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_SG_FREE, drm_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_modeset_ctl, 0), - DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_update_draw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - - DRM_IOCTL_DEF(DRM_IOCTL_GEM_CLOSE, drm_gem_close_ioctl, DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH|DRM_UNLOCKED), - - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANE, drm_mode_getplane, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPLANE, drm_mode_setplane, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR, drm_mode_cursor_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETGAMMA, drm_mode_gamma_get_ioctl, DRM_MASTER|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETGAMMA, drm_mode_gamma_set_ioctl, DRM_MASTER|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETENCODER, drm_mode_getencoder, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCONNECTOR, drm_mode_getconnector, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_mode_attachmode_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_mode_detachmode_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, DRM_MASTER | DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPROPERTY, drm_mode_connector_property_set_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB2, drm_mode_addfb2, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_PAGE_FLIP, drm_mode_page_flip_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_DIRTYFB, drm_mode_dirtyfb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_DUMB, drm_mode_create_dumb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_MAP_DUMB, drm_mode_mmap_dumb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_DESTROY_DUMB, drm_mode_destroy_dumb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), -}; - -static struct dev_ops drm_cdevsw = { - { "drm", 0, D_TRACKCLOSE }, - .d_open = drm_open, - .d_close = drm_close, - .d_read = drm_read, - .d_ioctl = drm_ioctl, - .d_kqfilter = drm_kqfilter, - .d_mmap = drm_mmap, - .d_mmap_single = drm_mmap_single, -}; - -static int drm_msi = 1; /* Enable by default. */ -TUNABLE_INT("hw.drm.msi", &drm_msi); -SYSCTL_NODE(_hw, OID_AUTO, drm, CTLFLAG_RW, NULL, "DRM device"); -SYSCTL_INT(_hw_drm, OID_AUTO, msi, CTLFLAG_RD, &drm_msi, 1, - "Enable MSI interrupts for drm devices"); - -static struct drm_msi_blacklist_entry drm_msi_blacklist[] = { - {0x8086, 0x2772}, /* Intel i945G */ \ - {0x8086, 0x27A2}, /* Intel i945GM */ \ - {0x8086, 0x27AE}, /* Intel i945GME */ \ - {0, 0} -}; - -static int drm_msi_is_blacklisted(int vendor, int device) -{ - int i = 0; - - for (i = 0; drm_msi_blacklist[i].vendor != 0; i++) { - if ((drm_msi_blacklist[i].vendor == vendor) && - (drm_msi_blacklist[i].device == device)) { - return 1; - } - } - - return 0; -} - -int drm_probe(device_t kdev, drm_pci_id_list_t *idlist) -{ - drm_pci_id_list_t *id_entry; - int vendor, device; - - vendor = pci_get_vendor(kdev); - device = pci_get_device(kdev); - - if (pci_get_class(kdev) != PCIC_DISPLAY) - return ENXIO; - - id_entry = drm_find_description(vendor, device, idlist); - if (id_entry != NULL) { - if (!device_get_desc(kdev)) { - DRM_DEBUG("desc : %s\n", device_get_desc(kdev)); - device_set_desc(kdev, id_entry->name); - } - return 0; - } - - return ENXIO; -} - -int drm_attach(device_t kdev, drm_pci_id_list_t *idlist) -{ - struct drm_device *dev; - drm_pci_id_list_t *id_entry; - int unit, msicount; - int rid = 0; - - unit = device_get_unit(kdev); - dev = device_get_softc(kdev); - - if (!strcmp(device_get_name(kdev), "drmsub")) - dev->device = device_get_parent(kdev); - else - dev->device = kdev; - - dev->devnode = make_dev(&drm_cdevsw, unit, DRM_DEV_UID, DRM_DEV_GID, - DRM_DEV_MODE, "dri/card%d", unit); - - dev->pci_domain = pci_get_domain(dev->device); - dev->pci_bus = pci_get_bus(dev->device); - dev->pci_slot = pci_get_slot(dev->device); - dev->pci_func = pci_get_function(dev->device); - - dev->pci_vendor = pci_get_vendor(dev->device); - dev->pci_device = pci_get_device(dev->device); - - if (drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) { - if (drm_msi && - !drm_msi_is_blacklisted(dev->pci_vendor, dev->pci_device)) { - msicount = pci_msi_count(dev->device); - DRM_DEBUG("MSI count = %d\n", msicount); - if (msicount > 1) - msicount = 1; - - if (pci_alloc_msi(dev->device, &rid, msicount, -1) == 0) { - DRM_INFO("MSI enabled %d message(s)\n", - msicount); - dev->msi_enabled = 1; - dev->irqrid = rid; - } - } - - dev->irqr = bus_alloc_resource_any(dev->device, SYS_RES_IRQ, - &dev->irqrid, RF_SHAREABLE); - if (!dev->irqr) { - return (ENOENT); - } - - dev->irq = (int) rman_get_start(dev->irqr); - } - - lockinit(&dev->dev_lock, "drmdev", 0, LK_CANRECURSE); - lwkt_serialize_init(&dev->irq_lock); - lockinit(&dev->vbl_lock, "drmvbl", 0, LK_CANRECURSE); - spin_init(&dev->drw_lock); - lockinit(&dev->event_lock, "drmev", 0, LK_CANRECURSE); - lockinit(&dev->dev_struct_lock, "drmslk", 0, LK_CANRECURSE); - - id_entry = drm_find_description(dev->pci_vendor, - dev->pci_device, idlist); - dev->id_entry = id_entry; - - return drm_load(dev); -} - -int drm_detach(device_t kdev) -{ - struct drm_device *dev; - - dev = device_get_softc(kdev); - drm_unload(dev); - if (dev->irqr) { - bus_release_resource(dev->device, SYS_RES_IRQ, dev->irqrid, - dev->irqr); - if (dev->msi_enabled) { - pci_release_msi(dev->device); - DRM_INFO("MSI released\n"); - } - } - return (0); -} - -#ifndef DRM_DEV_NAME -#define DRM_DEV_NAME "drm" -#endif - -devclass_t drm_devclass; - -drm_pci_id_list_t *drm_find_description(int vendor, int device, - drm_pci_id_list_t *idlist) -{ - int i = 0; - - for (i = 0; idlist[i].vendor != 0; i++) { - if ((idlist[i].vendor == vendor) && - ((idlist[i].device == device) || - (idlist[i].device == 0))) { - return &idlist[i]; - } - } - return NULL; -} - -static int drm_firstopen(struct drm_device *dev) -{ - drm_local_map_t *map; - int i; - - DRM_LOCK_ASSERT(dev); - - /* prebuild the SAREA */ - i = drm_addmap(dev, 0, SAREA_MAX, _DRM_SHM, - _DRM_CONTAINS_LOCK, &map); - if (i != 0) - return i; - - if (dev->driver->firstopen) - dev->driver->firstopen(dev); - - dev->buf_use = 0; - - if (drm_core_check_feature(dev, DRIVER_HAVE_DMA)) { - i = drm_dma_setup(dev); - if (i != 0) - return i; - } - - for (i = 0; i < DRM_HASH_SIZE; i++) { - dev->magiclist[i].head = NULL; - dev->magiclist[i].tail = NULL; - } - - dev->lock.lock_queue = 0; - if (!drm_core_check_feature(dev, DRIVER_MODESET)) - dev->irq_enabled = 0; - dev->context_flag = 0; - dev->last_context = 0; - dev->if_version = 0; - - dev->buf_sigio = NULL; - - DRM_DEBUG("\n"); - - return 0; -} - -static int drm_lastclose(struct drm_device *dev) -{ - drm_magic_entry_t *pt, *next; - drm_local_map_t *map, *mapsave; - int i; - - DRM_LOCK_ASSERT(dev); - - DRM_DEBUG("\n"); - - if (dev->driver->lastclose != NULL) - dev->driver->lastclose(dev); - - if (!drm_core_check_feature(dev, DRIVER_MODESET) && dev->irq_enabled) - drm_irq_uninstall(dev); - - if (dev->unique) { - drm_free(dev->unique, DRM_MEM_DRIVER); - dev->unique = NULL; - dev->unique_len = 0; - } - /* Clear pid list */ - for (i = 0; i < DRM_HASH_SIZE; i++) { - for (pt = dev->magiclist[i].head; pt; pt = next) { - next = pt->next; - drm_free(pt, DRM_MEM_MAGIC); - } - dev->magiclist[i].head = dev->magiclist[i].tail = NULL; - } - - DRM_UNLOCK(dev); - drm_drawable_free_all(dev); - DRM_LOCK(dev); - - /* Clear AGP information */ - if (dev->agp) { - drm_agp_mem_t *entry; - drm_agp_mem_t *nexte; - - /* Remove AGP resources, but leave dev->agp intact until - * drm_unload is called. - */ - for (entry = dev->agp->memory; entry; entry = nexte) { - nexte = entry->next; - if (entry->bound) - drm_agp_unbind_memory(entry->handle); - drm_agp_free_memory(entry->handle); - drm_free(entry, DRM_MEM_AGPLISTS); - } - dev->agp->memory = NULL; - - if (dev->agp->acquired) - drm_agp_release(dev); - - dev->agp->acquired = 0; - dev->agp->enabled = 0; - } - if (dev->sg != NULL) { - drm_sg_cleanup(dev->sg); - dev->sg = NULL; - } - -#if defined(__DragonFly__) - TAILQ_FOREACH_MUTABLE(map, &dev->maplist, link, mapsave) { -#else - TAILQ_FOREACH_SAFE(map, &dev->maplist, link, mapsave) { -#endif - if (!(map->flags & _DRM_DRIVER)) - drm_rmmap(dev, map); - } - - drm_dma_takedown(dev); - if (dev->lock.hw_lock) { - dev->lock.hw_lock = NULL; /* SHM removed */ - dev->lock.file_priv = NULL; - DRM_WAKEUP_INT((void *)&dev->lock.lock_queue); - } - - return 0; -} - -static int drm_load(struct drm_device *dev) -{ - int i, retcode; - - DRM_DEBUG("\n"); - - TAILQ_INIT(&dev->maplist); - dev->map_unrhdr = new_unrhdr(1, ((1 << DRM_MAP_HANDLE_BITS) - 1), NULL); - if (dev->map_unrhdr == NULL) { - DRM_ERROR("Couldn't allocate map number allocator\n"); - return EINVAL; - } - - - drm_mem_init(); - drm_sysctl_init(dev); - TAILQ_INIT(&dev->files); - - dev->counters = 6; - dev->types[0] = _DRM_STAT_LOCK; - dev->types[1] = _DRM_STAT_OPENS; - dev->types[2] = _DRM_STAT_CLOSES; - dev->types[3] = _DRM_STAT_IOCTLS; - dev->types[4] = _DRM_STAT_LOCKS; - dev->types[5] = _DRM_STAT_UNLOCKS; - - for (i = 0; i < DRM_ARRAY_SIZE(dev->counts); i++) - atomic_set(&dev->counts[i], 0); - - INIT_LIST_HEAD(&dev->vblank_event_list); - - if (drm_core_has_AGP(dev)) { - if (drm_device_is_agp(dev)) - dev->agp = drm_agp_init(); - if (drm_core_check_feature(dev, DRIVER_REQUIRE_AGP) && - dev->agp == NULL) { - DRM_ERROR("Card isn't AGP, or couldn't initialize " - "AGP.\n"); - retcode = ENOMEM; - goto error; - } - if (dev->agp != NULL && dev->agp->info.ai_aperture_base != 0) { - if (drm_mtrr_add(dev->agp->info.ai_aperture_base, - dev->agp->info.ai_aperture_size, DRM_MTRR_WC) == 0) - dev->agp->mtrr = 1; - } - } - - retcode = drm_ctxbitmap_init(dev); - if (retcode != 0) { - DRM_ERROR("Cannot allocate memory for context bitmap.\n"); - goto error; - } - - dev->drw_unrhdr = new_unrhdr(1, INT_MAX, NULL); - if (dev->drw_unrhdr == NULL) { - DRM_ERROR("Couldn't allocate drawable number allocator\n"); - retcode = ENOMEM; - goto error; - } - - if (dev->driver->driver_features & DRIVER_GEM) { - retcode = drm_gem_init(dev); - if (retcode != 0) { - DRM_ERROR("Cannot initialize graphics execution " - "manager (GEM)\n"); - goto error1; - } - } - - if (dev->driver->load != NULL) { - DRM_LOCK(dev); - /* Shared code returns -errno. */ - retcode = -dev->driver->load(dev, - dev->id_entry->driver_private); - if (pci_enable_busmaster(dev->device)) - DRM_ERROR("Request to enable bus-master failed.\n"); - DRM_UNLOCK(dev); - if (retcode != 0) - goto error; - } - - DRM_INFO("Initialized %s %d.%d.%d %s\n", - dev->driver->name, - dev->driver->major, - dev->driver->minor, - dev->driver->patchlevel, - dev->driver->date); - - return 0; - -error1: - delete_unrhdr(dev->drw_unrhdr); -error: - drm_sysctl_cleanup(dev); - DRM_LOCK(dev); - drm_lastclose(dev); - DRM_UNLOCK(dev); - if (dev->devnode != NULL) - destroy_dev(dev->devnode); - - spin_uninit(&dev->drw_lock); - lockuninit(&dev->vbl_lock); - lockuninit(&dev->dev_lock); - lockuninit(&dev->event_lock); - lockuninit(&dev->dev_struct_lock); - - return retcode; -} - -static void drm_unload(struct drm_device *dev) -{ - int i; - - DRM_DEBUG("\n"); - - drm_sysctl_cleanup(dev); - if (dev->devnode != NULL) - destroy_dev(dev->devnode); - - drm_ctxbitmap_cleanup(dev); - - if (dev->driver->driver_features & DRIVER_GEM) - drm_gem_destroy(dev); - - if (dev->agp && dev->agp->mtrr) { - int __unused retcode; - - retcode = drm_mtrr_del(0, dev->agp->info.ai_aperture_base, - dev->agp->info.ai_aperture_size, DRM_MTRR_WC); - DRM_DEBUG("mtrr_del = %d", retcode); - } - - drm_vblank_cleanup(dev); - - DRM_LOCK(dev); - drm_lastclose(dev); - DRM_UNLOCK(dev); - - /* Clean up PCI resources allocated by drm_bufs.c. We're not really - * worried about resource consumption while the DRM is inactive (between - * lastclose and firstopen or unload) because these aren't actually - * taking up KVA, just keeping the PCI resource allocated. - */ - for (i = 0; i < DRM_MAX_PCI_RESOURCE; i++) { - if (dev->pcir[i] == NULL) - continue; - bus_release_resource(dev->device, SYS_RES_MEMORY, - dev->pcirid[i], dev->pcir[i]); - dev->pcir[i] = NULL; - } - - if (dev->agp) { - drm_free(dev->agp, DRM_MEM_AGPLISTS); - dev->agp = NULL; - } - - if (dev->driver->unload != NULL) { - DRM_LOCK(dev); - dev->driver->unload(dev); - DRM_UNLOCK(dev); - } - - delete_unrhdr(dev->drw_unrhdr); - delete_unrhdr(dev->map_unrhdr); - - drm_mem_uninit(); - - if (pci_disable_busmaster(dev->device)) - DRM_ERROR("Request to disable bus-master failed.\n"); - - spin_uninit(&dev->drw_lock); - lockuninit(&dev->vbl_lock); - lockuninit(&dev->dev_lock); - lockuninit(&dev->event_lock); - lockuninit(&dev->dev_struct_lock); -} - -int drm_version(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - struct drm_version *version = data; - int len; - -#define DRM_COPY( name, value ) \ - len = strlen( value ); \ - if ( len > name##_len ) len = name##_len; \ - name##_len = strlen( value ); \ - if ( len && name ) { \ - if ( DRM_COPY_TO_USER( name, value, len ) ) \ - return EFAULT; \ - } - - version->version_major = dev->driver->major; - version->version_minor = dev->driver->minor; - version->version_patchlevel = dev->driver->patchlevel; - - DRM_COPY(version->name, dev->driver->name); - DRM_COPY(version->date, dev->driver->date); - DRM_COPY(version->desc, dev->driver->desc); - - return 0; -} - -int -/* drm_open(struct cdev *kdev, int flags, int fmt, DRM_STRUCTPROC *p) */ -drm_open(struct dev_open_args *ap) -{ - struct cdev *kdev = ap->a_head.a_dev; - int flags = ap->a_oflags; - int fmt = 0; - struct thread *p = curthread; - struct drm_device *dev; - int retcode; - - dev = DRIVER_SOFTC(minor(kdev)); - if (dev == NULL) - return (ENXIO); - - DRM_DEBUG("open_count = %d\n", dev->open_count); - - retcode = drm_open_helper(kdev, flags, fmt, p, dev); - - if (retcode == 0) { - atomic_inc(&dev->counts[_DRM_STAT_OPENS]); - DRM_LOCK(dev); - device_busy(dev->device); - if (!dev->open_count++) - retcode = drm_firstopen(dev); - DRM_UNLOCK(dev); - } - - DRM_DEBUG("return %d\n", retcode); - - return (retcode); -} - -int drm_close(struct dev_close_args *ap) -{ - struct cdev *kdev = ap->a_head.a_dev; - struct drm_file *file_priv; - struct drm_device *dev; - int retcode = 0; - - dev = DRIVER_SOFTC(minor(kdev)); - file_priv = drm_find_file_by_proc(dev, curthread); - - DRM_DEBUG("open_count = %d\n", dev->open_count); - - DRM_LOCK(dev); - - if (dev->driver->preclose != NULL) - dev->driver->preclose(dev, file_priv); - - /* ======================================================== - * Begin inline drm_release - */ - - DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n", - DRM_CURRENTPID, (long)dev->device, dev->open_count); - - if (dev->driver->driver_features & DRIVER_GEM) - drm_gem_release(dev, file_priv); - - if (dev->lock.hw_lock && _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) - && dev->lock.file_priv == file_priv) { - DRM_DEBUG("Process %d dead, freeing lock for context %d\n", - DRM_CURRENTPID, - _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); - if (dev->driver->reclaim_buffers_locked != NULL) - dev->driver->reclaim_buffers_locked(dev, file_priv); - - drm_lock_free(&dev->lock, - _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); - - /* FIXME: may require heavy-handed reset of - hardware at this point, possibly - processed via a callback to the X - server. */ - } else if (dev->driver->reclaim_buffers_locked != NULL && - dev->lock.hw_lock != NULL) { - /* The lock is required to reclaim buffers */ - for (;;) { - if (!dev->lock.hw_lock) { - /* Device has been unregistered */ - retcode = EINTR; - break; - } - if (drm_lock_take(&dev->lock, DRM_KERNEL_CONTEXT)) { - dev->lock.file_priv = file_priv; - dev->lock.lock_time = jiffies; - atomic_inc(&dev->counts[_DRM_STAT_LOCKS]); - break; /* Got lock */ - } - /* Contention */ - retcode = DRM_LOCK_SLEEP(dev, &dev->lock.lock_queue, - PCATCH, "drmlk2", 0); - if (retcode) - break; - } - if (retcode == 0) { - dev->driver->reclaim_buffers_locked(dev, file_priv); - drm_lock_free(&dev->lock, DRM_KERNEL_CONTEXT); - } - } - - if (drm_core_check_feature(dev, DRIVER_HAVE_DMA) && - !dev->driver->reclaim_buffers_locked) - drm_reclaim_buffers(dev, file_priv); - - funsetown(&dev->buf_sigio); - - if (dev->driver->postclose != NULL) - dev->driver->postclose(dev, file_priv); - TAILQ_REMOVE(&dev->files, file_priv, link); - drm_free(file_priv, DRM_MEM_FILES); - - /* ======================================================== - * End inline drm_release - */ - - atomic_inc(&dev->counts[_DRM_STAT_CLOSES]); - device_unbusy(dev->device); - if (--dev->open_count == 0) { - retcode = drm_lastclose(dev); - } - - DRM_UNLOCK(dev); - - return (0); -} - -/* drm_ioctl is called whenever a process performs an ioctl on /dev/drm. - */ -int drm_ioctl(struct dev_ioctl_args *ap) -{ - struct cdev *kdev = ap->a_head.a_dev; - u_long cmd = ap->a_cmd; - caddr_t data = ap->a_data; - struct thread *p = curthread; - struct drm_device *dev = drm_get_device_from_kdev(kdev); - int retcode = 0; - drm_ioctl_desc_t *ioctl; - int (*func)(struct drm_device *dev, void *data, struct drm_file *file_priv); - int nr = DRM_IOCTL_NR(cmd); - int is_driver_ioctl = 0; - struct drm_file *file_priv; - - file_priv = drm_find_file_by_proc(dev, p); - - atomic_inc(&dev->counts[_DRM_STAT_IOCTLS]); - ++file_priv->ioctl_count; - - DRM_DEBUG("pid=%d, cmd=0x%02lx, nr=0x%02x, dev 0x%lx, auth=%d\n", - DRM_CURRENTPID, cmd, nr, (long)dev->device, - file_priv->authenticated); - - switch (cmd) { - case FIONBIO: - case FIOASYNC: - return 0; - - case FIOSETOWN: - return fsetown(*(int *)data, &dev->buf_sigio); - - case FIOGETOWN: - *(int *) data = fgetown(&dev->buf_sigio); - return 0; - } - - if (IOCGROUP(cmd) != DRM_IOCTL_BASE) { - DRM_DEBUG("Bad ioctl group 0x%x\n", (int)IOCGROUP(cmd)); - return EINVAL; - } - - ioctl = &drm_ioctls[nr]; - /* It's not a core DRM ioctl, try driver-specific. */ - if (ioctl->func == NULL && nr >= DRM_COMMAND_BASE) { - /* The array entries begin at DRM_COMMAND_BASE ioctl nr */ - nr -= DRM_COMMAND_BASE; - if (nr > dev->driver->max_ioctl) { - DRM_DEBUG("Bad driver ioctl number, 0x%x (of 0x%x)\n", - nr, dev->driver->max_ioctl); - return EINVAL; - } - ioctl = &dev->driver->ioctls[nr]; - is_driver_ioctl = 1; - } - func = ioctl->func; - - if (func == NULL) { - DRM_DEBUG("no function\n"); - return EINVAL; - } - - if (((ioctl->flags & DRM_ROOT_ONLY) && !DRM_SUSER(p)) || - ((ioctl->flags & DRM_AUTH) && !file_priv->authenticated) || - ((ioctl->flags & DRM_MASTER) && !file_priv->master)) - return EACCES; - - if (is_driver_ioctl) { - if ((ioctl->flags & DRM_UNLOCKED) == 0) - DRM_LOCK(dev); - /* shared code returns -errno */ - retcode = -func(dev, data, file_priv); - if ((ioctl->flags & DRM_UNLOCKED) == 0) - DRM_UNLOCK(dev); - } else { - retcode = func(dev, data, file_priv); - } - - if (retcode != 0) - DRM_DEBUG(" returning %d\n", retcode); - if (retcode != 0 && - (drm_debug_flag & DRM_DEBUGBITS_FAILED_IOCTL) != 0) { - kprintf( -"pid %d, cmd 0x%02lx, nr 0x%02x/%1d, dev 0x%lx, auth %d, res %d\n", - DRM_CURRENTPID, cmd, nr, is_driver_ioctl, (long)dev->device, - file_priv->authenticated, retcode); - } - - return retcode; -} - -drm_local_map_t *drm_getsarea(struct drm_device *dev) -{ - drm_local_map_t *map; - - DRM_LOCK_ASSERT(dev); - TAILQ_FOREACH(map, &dev->maplist, link) { - if (map->type == _DRM_SHM && (map->flags & _DRM_CONTAINS_LOCK)) - return map; - } - - return NULL; -} - -int -drm_add_busid_modesetting(struct drm_device *dev, struct sysctl_ctx_list *ctx, - struct sysctl_oid *top) -{ - struct sysctl_oid *oid; - - ksnprintf(dev->busid_str, sizeof(dev->busid_str), - "pci:%04x:%02x:%02x.%d", dev->pci_domain, dev->pci_bus, - dev->pci_slot, dev->pci_func); - oid = SYSCTL_ADD_STRING(ctx, SYSCTL_CHILDREN(top), OID_AUTO, "busid", - CTLFLAG_RD, dev->busid_str, 0, NULL); - if (oid == NULL) - return (ENOMEM); - dev->modesetting = (dev->driver->driver_features & DRIVER_MODESET) != 0; - oid = SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(top), OID_AUTO, - "modesetting", CTLFLAG_RD, &dev->modesetting, 0, NULL); - if (oid == NULL) - return (ENOMEM); - - return (0); -} - -int -drm_mmap_single(struct dev_mmap_single_args *ap) -{ - struct drm_device *dev; - struct cdev *kdev = ap->a_head.a_dev; - vm_ooffset_t *offset = ap->a_offset; - vm_size_t size = ap->a_size; - struct vm_object **obj_res = ap->a_object; - int nprot = ap->a_nprot; - - dev = drm_get_device_from_kdev(kdev); - if ((dev->driver->driver_features & DRIVER_GEM) != 0) { - return (drm_gem_mmap_single(dev, offset, size, obj_res, nprot)); - } else if (dev->drm_ttm_bo != NULL) { - return (ttm_bo_mmap_single(dev->drm_ttm_bo, offset, size, - obj_res, nprot)); - } else { - return (ENODEV); - } -} - -#if DRM_LINUX - -#include - -MODULE_DEPEND(DRIVER_NAME, linux, 1, 1, 1); - -#define LINUX_IOCTL_DRM_MIN 0x6400 -#define LINUX_IOCTL_DRM_MAX 0x64ff - -static linux_ioctl_function_t drm_linux_ioctl; -static struct linux_ioctl_handler drm_handler = {drm_linux_ioctl, - LINUX_IOCTL_DRM_MIN, LINUX_IOCTL_DRM_MAX}; - -SYSINIT(drm_register, SI_SUB_KLD, SI_ORDER_MIDDLE, - linux_ioctl_register_handler, &drm_handler); -SYSUNINIT(drm_unregister, SI_SUB_KLD, SI_ORDER_MIDDLE, - linux_ioctl_unregister_handler, &drm_handler); - -/* The bits for in/out are switched on Linux */ -#define LINUX_IOC_IN IOC_OUT -#define LINUX_IOC_OUT IOC_IN - -static int -drm_linux_ioctl(DRM_STRUCTPROC *p, struct linux_ioctl_args* args) -{ - int error; - int cmd = args->cmd; - - args->cmd &= ~(LINUX_IOC_IN | LINUX_IOC_OUT); - if (cmd & LINUX_IOC_IN) - args->cmd |= IOC_IN; - if (cmd & LINUX_IOC_OUT) - args->cmd |= IOC_OUT; - - error = ioctl(p, (struct ioctl_args *)args); - - return error; -} -#endif /* DRM_LINUX */ - -/* - * Check if dmi_system_id structure matches system DMI data - */ -static bool -dmi_found(const struct dmi_system_id *dsi) -{ - int i, slot; - bool found = false; - char *sys_vendor, *board_vendor, *product_name, *board_name; - - sys_vendor = kgetenv("smbios.system.maker"); - board_vendor = kgetenv("smbios.planar.maker"); - product_name = kgetenv("smbios.system.product"); - board_name = kgetenv("smbios.planar.product"); - - for (i = 0; i < NELEM(dsi->matches); i++) { - slot = dsi->matches[i].slot; - switch (slot) { - case DMI_NONE: - break; - case DMI_SYS_VENDOR: - if (sys_vendor != NULL && - !strcmp(sys_vendor, dsi->matches[i].substr)) - break; - else - goto done; - case DMI_BOARD_VENDOR: - if (board_vendor != NULL && - !strcmp(board_vendor, dsi->matches[i].substr)) - break; - else - goto done; - case DMI_PRODUCT_NAME: - if (product_name != NULL && - !strcmp(product_name, dsi->matches[i].substr)) - break; - else - goto done; - case DMI_BOARD_NAME: - if (board_name != NULL && - !strcmp(board_name, dsi->matches[i].substr)) - break; - else - goto done; - default: - goto done; - } - } - found = true; - -done: - if (sys_vendor != NULL) - kfreeenv(sys_vendor); - if (board_vendor != NULL) - kfreeenv(board_vendor); - if (product_name != NULL) - kfreeenv(product_name); - if (board_name != NULL) - kfreeenv(board_name); - - return found; -} - -bool -dmi_check_system(const struct dmi_system_id *sysid) -{ - const struct dmi_system_id *dsi; - int num = 0; - - for (dsi = sysid; dsi->matches[0].slot != 0 ; dsi++) { - if (dmi_found(dsi)) { - num++; - if (dsi->callback && dsi->callback(dsi)) - break; - } - } - return (num); -} - diff --git a/sys/dev/drm2/drm_fops.c b/sys/dev/drm2/drm_fops.c deleted file mode 100644 index 63956f536a..0000000000 --- a/sys/dev/drm2/drm_fops.c +++ /dev/null @@ -1,259 +0,0 @@ -/*- - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * 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, 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS 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. - * - * Authors: - * Rickard E. (Rik) Faith - * Daryll Strauss - * Gareth Hughes - * - * $FreeBSD: src/sys/dev/drm2/drm_fops.c,v 1.1 2012/05/22 11:07:44 kib Exp $ - */ - -/** @file drm_fops.c - * Support code for dealing with the file privates associated with each - * open of the DRM device. - */ - -#include -#include -#include - -struct drm_file *drm_find_file_by_proc(struct drm_device *dev, DRM_STRUCTPROC *p) -{ - uid_t uid = p->td_proc->p_ucred->cr_svuid; - pid_t pid = p->td_proc->p_pid; - struct drm_file *priv; - - TAILQ_FOREACH(priv, &dev->files, link) - if (priv->pid == pid && priv->uid == uid) - return priv; - return NULL; -} - -/* drm_open_helper is called whenever a process opens /dev/drm. */ -int drm_open_helper(struct cdev *kdev, int flags, int fmt, DRM_STRUCTPROC *p, - struct drm_device *dev) -{ - struct drm_file *priv; - int retcode; - - if (flags & O_EXCL) - return EBUSY; /* No exclusive opens */ - dev->flags = flags; - - DRM_DEBUG("pid = %d, device = %s\n", DRM_CURRENTPID, devtoname(kdev)); - - priv = kmalloc(sizeof(*priv), DRM_MEM_FILES, M_NOWAIT | M_ZERO); - if (priv == NULL) { - return ENOMEM; - } - -#if 0 - /* FIXME */ - retcode = devfs_set_cdevpriv(priv, drm_close); - if (retcode != 0) { - drm_free(priv, DRM_MEM_FILES); - return retcode; - } -#endif - - DRM_LOCK(dev); - priv->dev = dev; - priv->uid = p->td_ucred->cr_svuid; - priv->pid = p->td_proc->p_pid; - priv->ioctl_count = 0; - - /* for compatibility root is always authenticated */ - priv->authenticated = DRM_SUSER(p); - - INIT_LIST_HEAD(&priv->fbs); - INIT_LIST_HEAD(&priv->event_list); - priv->event_space = 4096; /* set aside 4k for event buffer */ - - if (dev->driver->driver_features & DRIVER_GEM) - drm_gem_open(dev, priv); - - if (dev->driver->open) { - /* shared code returns -errno */ - retcode = -dev->driver->open(dev, priv); - if (retcode != 0) { -/* FIXME */ -/* devfs_clear_cdevpriv(); */ - drm_free(priv, DRM_MEM_FILES); - DRM_UNLOCK(dev); - return retcode; - } - } - - /* first opener automatically becomes master */ - priv->master = TAILQ_EMPTY(&dev->files); - - TAILQ_INSERT_TAIL(&dev->files, priv, link); - DRM_UNLOCK(dev); - kdev->si_drv1 = dev; - return 0; -} - -#if 0 -static bool -drm_dequeue_event(struct drm_device *dev, struct drm_file *file_priv, - struct uio *uio, struct drm_pending_event **out) -{ - struct drm_pending_event *e; - - if (list_empty(&file_priv->event_list)) - return (false); - e = list_first_entry(&file_priv->event_list, - struct drm_pending_event, link); - if (e->event->length > uio->uio_resid) - return (false); - - file_priv->event_space += e->event->length; - list_del(&e->link); - *out = e; - return (true); -} -#endif - -int -/* drm_read(struct cdev *kdev, struct uio *uio, int ioflag) */ -drm_read(struct dev_read_args *ap) -{ - kprintf("drm_read(): not implemented\n"); -#if 0 - struct cdev *kdev = ap->a_head.a_dev; - struct uio *uio = ap->a_uio; - int ioflag = ap->a_ioflag; - struct drm_file *file_priv; - struct drm_device *dev; - struct drm_pending_event *e; - int error; - - /* FIXME */ -/* error = devfs_get_cdevpriv((void **)&file_priv); */ - if (error != 0) { - DRM_ERROR("can't find authenticator\n"); - return (EINVAL); - } - dev = drm_get_device_from_kdev(kdev); - lockmgr(&dev->event_lock, LK_EXCLUSIVE); - while (list_empty(&file_priv->event_list)) { - if ((ioflag & O_NONBLOCK) != 0) { - error = EAGAIN; - goto out; - } - error = lksleep(&file_priv->event_space, &dev->event_lock, - PCATCH, "drmrea", 0); - if (error != 0) - goto out; - } - while (drm_dequeue_event(dev, file_priv, uio, &e)) { - lockmgr(&dev->event_lock, LK_RELEASE); - error = uiomove(e->event, e->event->length, uio); - e->destroy(e); - if (error != 0) - return (error); - lockmgr(&dev->event_lock, LK_EXCLUSIVE); - } -out: - lockmgr(&dev->event_lock, LK_RELEASE); - return (error); -#endif - return 0; -} - -void -drm_event_wakeup(struct drm_pending_event *e) -{ - struct drm_file *file_priv; - struct drm_device *dev; - - file_priv = e->file_priv; - dev = file_priv->dev; - KKASSERT(lockstatus(&dev->event_lock, curthread) != 0); - - wakeup(&file_priv->event_space); -// selwakeup(&file_priv->event_poll); /* XXX */ -} - -static int -drmfilt(struct knote *kn, long hint) -{ - return (0); -} - -static void -drmfilt_detach(struct knote *kn) {} - -static struct filterops drmfiltops = - { FILTEROP_ISFD, NULL, drmfilt_detach, drmfilt }; - -int -drm_kqfilter(struct dev_kqfilter_args *ap) -{ - struct knote *kn = ap->a_kn; - - ap->a_result = 0; - - switch (kn->kn_filter) { - case EVFILT_READ: - case EVFILT_WRITE: - kn->kn_fop = &drmfiltops; - break; - default: - ap->a_result = EOPNOTSUPP; - return (0); - } - - return (0); -} - -#if 0 /* XXX: poll kqueue */ -int -drm_poll(struct cdev *kdev, int events, struct thread *td) - struct drm_file *file_priv; - struct drm_device *dev; - int error, revents; - - /* FIXME */ -/* error = devfs_get_cdevpriv((void **)&file_priv);*/ - if (error != 0) { - DRM_ERROR("can't find authenticator\n"); - return (EINVAL); - } - dev = drm_get_device_from_kdev(kdev); - - revents = 0; - lockmgr(&dev->event_lock, LK_EXCLUSIVE); - if ((events & (POLLIN | POLLRDNORM)) != 0) { - if (list_empty(&file_priv->event_list)) { - selrecord(td, &file_priv->event_poll); - } else { - revents |= events & (POLLIN | POLLRDNORM); - } - } - lockmgr(&dev->event_lock, LK_RELEASE); - return (revents); -} -#endif diff --git a/sys/dev/drm2/drm_hashtab.c b/sys/dev/drm2/drm_hashtab.c deleted file mode 100644 index 2d4fec1257..0000000000 --- a/sys/dev/drm2/drm_hashtab.c +++ /dev/null @@ -1,178 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND. USA. - * 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 - * THE COPYRIGHT HOLDERS, AUTHORS 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. - * - * - * $FreeBSD: src/sys/dev/drm2/drm_hashtab.c,v 1.1 2012/05/22 11:07:44 kib Exp $ - **************************************************************************/ - -/* - * Simple open hash tab implementation. - * - * Authors: - * Thomas Hellström - */ - -#include -#include - -#include - -int drm_ht_create(struct drm_open_hash *ht, unsigned int order) -{ - ht->size = 1 << order; - ht->order = order; - ht->table = NULL; - ht->table = hashinit(ht->size, DRM_MEM_HASHTAB, &ht->mask); - if (!ht->table) { - DRM_ERROR("Out of memory for hash table\n"); - return -ENOMEM; - } - return 0; -} - -void drm_ht_verbose_list(struct drm_open_hash *ht, unsigned long key) -{ - struct drm_hash_item *entry; - struct drm_hash_item_list *h_list; - unsigned int hashed_key; - int count = 0; - - hashed_key = hash32_buf(&key, sizeof(key), ht->order); - DRM_DEBUG("Key is 0x%08lx, Hashed key is 0x%08x\n", key, hashed_key); - h_list = &ht->table[hashed_key & ht->mask]; - LIST_FOREACH(entry, h_list, head) - DRM_DEBUG("count %d, key: 0x%08lx\n", count++, entry->key); -} - -static struct drm_hash_item * -drm_ht_find_key(struct drm_open_hash *ht, unsigned long key) -{ - struct drm_hash_item *entry; - struct drm_hash_item_list *h_list; - unsigned int hashed_key; - - hashed_key = hash32_buf(&key, sizeof(key), ht->order); - h_list = &ht->table[hashed_key & ht->mask]; - LIST_FOREACH(entry, h_list, head) { - if (entry->key == key) - return entry; - if (entry->key > key) - break; - } - return NULL; -} - - -int drm_ht_insert_item(struct drm_open_hash *ht, struct drm_hash_item *item) -{ - struct drm_hash_item *entry, *parent; - struct drm_hash_item_list *h_list; - unsigned int hashed_key; - unsigned long key = item->key; - - hashed_key = hash32_buf(&key, sizeof(key), ht->order); - h_list = &ht->table[hashed_key & ht->mask]; - parent = NULL; - LIST_FOREACH(entry, h_list, head) { - if (entry->key == key) - return -EINVAL; - if (entry->key > key) - break; - parent = entry; - } - if (parent) { - LIST_INSERT_AFTER(parent, item, head); - } else { - LIST_INSERT_HEAD(h_list, item, head); - } - return 0; -} - -/* - * Just insert an item and return any "bits" bit key that hasn't been - * used before. - */ -int drm_ht_just_insert_please(struct drm_open_hash *ht, struct drm_hash_item *item, - unsigned long seed, int bits, int shift, - unsigned long add) -{ - int ret; - unsigned long mask = (1 << bits) - 1; - unsigned long first, unshifted_key = 0; - - unshifted_key = hash32_buf(&seed, sizeof(seed), unshifted_key); - first = unshifted_key; - do { - item->key = (unshifted_key << shift) + add; - ret = drm_ht_insert_item(ht, item); - if (ret) - unshifted_key = (unshifted_key + 1) & mask; - } while(ret && (unshifted_key != first)); - - if (ret) { - DRM_ERROR("Available key bit space exhausted\n"); - return -EINVAL; - } - return 0; -} - -int drm_ht_find_item(struct drm_open_hash *ht, unsigned long key, - struct drm_hash_item **item) -{ - struct drm_hash_item *entry; - - entry = drm_ht_find_key(ht, key); - if (!entry) - return -EINVAL; - - *item = entry; - return 0; -} - -int drm_ht_remove_key(struct drm_open_hash *ht, unsigned long key) -{ - struct drm_hash_item *entry; - - entry = drm_ht_find_key(ht, key); - if (entry) { - LIST_REMOVE(entry, head); - return 0; - } - return -EINVAL; -} - -int drm_ht_remove_item(struct drm_open_hash *ht, struct drm_hash_item *item) -{ - LIST_REMOVE(item, head); - return 0; -} - -void drm_ht_remove(struct drm_open_hash *ht) -{ - if (ht->table) { - hashdestroy(ht->table, DRM_MEM_HASHTAB, ht->mask); - ht->table = NULL; - } -} diff --git a/sys/dev/drm2/drm_hashtab.h b/sys/dev/drm2/drm_hashtab.h deleted file mode 100644 index 13342e21b7..0000000000 --- a/sys/dev/drm2/drm_hashtab.h +++ /dev/null @@ -1,66 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismack, ND. USA. - * 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 - * THE COPYRIGHT HOLDERS, AUTHORS 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. - * - * - * $FreeBSD: src/sys/dev/drm2/drm_hashtab.h,v 1.1 2012/05/22 11:07:44 kib Exp $ - **************************************************************************/ - -/* - * Simple open hash tab implementation. - * - * Authors: - * Thomas Hellström - */ - -#ifndef DRM_HASHTAB_H -#define DRM_HASHTAB_H - -#define drm_hash_entry(_ptr, _type, _member) container_of(_ptr, _type, _member) - -struct drm_hash_item { - LIST_ENTRY(drm_hash_item) head; - unsigned long key; -}; - -struct drm_open_hash { - LIST_HEAD(drm_hash_item_list, drm_hash_item) *table; - unsigned int size; - unsigned int order; - unsigned long mask; -}; - -extern int drm_ht_create(struct drm_open_hash *ht, unsigned int order); -extern int drm_ht_insert_item(struct drm_open_hash *ht, struct drm_hash_item *item); -extern int drm_ht_just_insert_please(struct drm_open_hash *ht, struct drm_hash_item *item, - unsigned long seed, int bits, int shift, - unsigned long add); -extern int drm_ht_find_item(struct drm_open_hash *ht, unsigned long key, struct drm_hash_item **item); - -extern void drm_ht_verbose_list(struct drm_open_hash *ht, unsigned long key); -extern int drm_ht_remove_key(struct drm_open_hash *ht, unsigned long key); -extern int drm_ht_remove_item(struct drm_open_hash *ht, struct drm_hash_item *item); -extern void drm_ht_remove(struct drm_open_hash *ht); - -#endif diff --git a/sys/dev/drm2/drm_internal.h b/sys/dev/drm2/drm_internal.h deleted file mode 100644 index 26e6c572ea..0000000000 --- a/sys/dev/drm2/drm_internal.h +++ /dev/null @@ -1,42 +0,0 @@ -/*- - * Copyright 2007 Red Hat, Inc - * 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, 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS 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. - * - * $FreeBSD: src/sys/dev/drm2/drm_internal.h,v 1.1 2012/05/22 11:07:44 kib Exp $ - */ - -/* This header file holds function prototypes and data types that are - * internal to the drm (not exported to user space) but shared across - * drivers and platforms */ - -#ifndef __DRM_INTERNAL_H__ -#define __DRM_INTERNAL_H__ - -/** - * Drawable information. - */ -struct drm_drawable_info { - unsigned int num_rects; - struct drm_clip_rect *rects; -}; - -#endif diff --git a/sys/dev/drm2/drm_ioctl.c b/sys/dev/drm2/drm_ioctl.c deleted file mode 100644 index 3db77d2af5..0000000000 --- a/sys/dev/drm2/drm_ioctl.c +++ /dev/null @@ -1,318 +0,0 @@ -/*- - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * 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, 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS 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. - * - * Authors: - * Rickard E. (Rik) Faith - * Gareth Hughes - * - * $FreeBSD: src/sys/dev/drm2/drm_ioctl.c,v 1.1 2012/05/22 11:07:44 kib Exp $ - */ - -/** @file drm_ioctl.c - * Varios minor DRM ioctls not applicable to other files, such as versioning - * information and reporting DRM information to userland. - */ - -#include - -/* - * Beginning in revision 1.1 of the DRM interface, getunique will return - * a unique in the form pci:oooo:bb:dd.f (o=domain, b=bus, d=device, f=function) - * before setunique has been called. The format for the bus-specific part of - * the unique is not defined for any other bus. - */ -int drm_getunique(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_unique *u = data; - - if (u->unique_len >= dev->unique_len) { - if (DRM_COPY_TO_USER(u->unique, dev->unique, dev->unique_len)) - return EFAULT; - } - u->unique_len = dev->unique_len; - - return 0; -} - -/* Deprecated in DRM version 1.1, and will return EBUSY when setversion has - * requested version 1.1 or greater. - */ -int drm_setunique(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_unique *u = data; - int domain, bus, slot, func, ret; - char *busid; - - /* Check and copy in the submitted Bus ID */ - if (!u->unique_len || u->unique_len > 1024) - return EINVAL; - - busid = kmalloc(u->unique_len + 1, DRM_MEM_DRIVER, M_WAITOK); - if (busid == NULL) - return ENOMEM; - - if (DRM_COPY_FROM_USER(busid, u->unique, u->unique_len)) { - drm_free(busid, DRM_MEM_DRIVER); - return EFAULT; - } - busid[u->unique_len] = '\0'; - - /* Return error if the busid submitted doesn't match the device's actual - * busid. - */ - ret = ksscanf(busid, "PCI:%d:%d:%d", &bus, &slot, &func); - if (ret != 3) { - drm_free(busid, DRM_MEM_DRIVER); - return EINVAL; - } - domain = bus >> 8; - bus &= 0xff; - - if ((domain != dev->pci_domain) || - (bus != dev->pci_bus) || - (slot != dev->pci_slot) || - (func != dev->pci_func)) { - drm_free(busid, DRM_MEM_DRIVER); - return EINVAL; - } - - /* Actually set the device's busid now. */ - DRM_LOCK(dev); - if (dev->unique_len || dev->unique) { - DRM_UNLOCK(dev); - return EBUSY; - } - - dev->unique_len = u->unique_len; - dev->unique = busid; - DRM_UNLOCK(dev); - - return 0; -} - - -static int -drm_set_busid(struct drm_device *dev) -{ - - DRM_LOCK(dev); - - if (dev->unique != NULL) { - DRM_UNLOCK(dev); - return EBUSY; - } - - dev->unique_len = 20; - dev->unique = kmalloc(dev->unique_len + 1, DRM_MEM_DRIVER, M_NOWAIT); - if (dev->unique == NULL) { - DRM_UNLOCK(dev); - return ENOMEM; - } - - ksnprintf(dev->unique, dev->unique_len, "pci:%04x:%02x:%02x.%1x", - dev->pci_domain, dev->pci_bus, dev->pci_slot, dev->pci_func); - - DRM_UNLOCK(dev); - - return 0; -} - -int drm_getmap(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - struct drm_map *map = data; - drm_local_map_t *mapinlist; - int idx; - int i = 0; - - idx = map->offset; - - DRM_LOCK(dev); - if (idx < 0) { - DRM_UNLOCK(dev); - return EINVAL; - } - - TAILQ_FOREACH(mapinlist, &dev->maplist, link) { - if (i == idx) { - map->offset = mapinlist->offset; - map->size = mapinlist->size; - map->type = mapinlist->type; - map->flags = mapinlist->flags; - map->handle = mapinlist->handle; - map->mtrr = mapinlist->mtrr; - break; - } - i++; - } - - DRM_UNLOCK(dev); - - if (mapinlist == NULL) - return EINVAL; - - return 0; -} - -int drm_getclient(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_client *client = data; - struct drm_file *pt; - int idx; - int i = 0; - - idx = client->idx; - DRM_LOCK(dev); - TAILQ_FOREACH(pt, &dev->files, link) { - if (i == idx) { - client->auth = pt->authenticated; - client->pid = pt->pid; - client->uid = pt->uid; - client->magic = pt->magic; - client->iocs = pt->ioctl_count; - DRM_UNLOCK(dev); - return 0; - } - i++; - } - DRM_UNLOCK(dev); - - return EINVAL; -} - -int drm_getstats(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - struct drm_stats *stats = data; - int i; - - memset(stats, 0, sizeof(struct drm_stats)); - - DRM_LOCK(dev); - - for (i = 0; i < dev->counters; i++) { - if (dev->types[i] == _DRM_STAT_LOCK) - stats->data[i].value = - (dev->lock.hw_lock ? dev->lock.hw_lock->lock : 0); - else - stats->data[i].value = atomic_read(&dev->counts[i]); - stats->data[i].type = dev->types[i]; - } - - stats->count = dev->counters; - - DRM_UNLOCK(dev); - - return 0; -} - -int drm_getcap(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - struct drm_get_cap *req = data; - - req->value = 0; - switch (req->capability) { - case DRM_CAP_DUMB_BUFFER: - if (dev->driver->dumb_create) - req->value = 1; - break; - case DRM_CAP_VBLANK_HIGH_CRTC: - req->value = 1; - break; - case DRM_CAP_DUMB_PREFERRED_DEPTH: - req->value = dev->mode_config.preferred_depth; - break; - case DRM_CAP_DUMB_PREFER_SHADOW: - req->value = dev->mode_config.prefer_shadow; - break; - default: - return EINVAL; - } - return 0; -} - - -#define DRM_IF_MAJOR 1 -#define DRM_IF_MINOR 2 - -int drm_setversion(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_set_version *sv = data; - struct drm_set_version ver; - int if_version; - - /* Save the incoming data, and set the response before continuing - * any further. - */ - ver = *sv; - sv->drm_di_major = DRM_IF_MAJOR; - sv->drm_di_minor = DRM_IF_MINOR; - sv->drm_dd_major = dev->driver->major; - sv->drm_dd_minor = dev->driver->minor; - - DRM_DEBUG("ver.drm_di_major %d ver.drm_di_minor %d " - "ver.drm_dd_major %d ver.drm_dd_minor %d\n", - ver.drm_di_major, ver.drm_di_minor, ver.drm_dd_major, - ver.drm_dd_minor); - DRM_DEBUG("sv->drm_di_major %d sv->drm_di_minor %d " - "sv->drm_dd_major %d sv->drm_dd_minor %d\n", - sv->drm_di_major, sv->drm_di_minor, sv->drm_dd_major, - sv->drm_dd_minor); - - if (ver.drm_di_major != -1) { - if (ver.drm_di_major != DRM_IF_MAJOR || - ver.drm_di_minor < 0 || ver.drm_di_minor > DRM_IF_MINOR) { - return EINVAL; - } - if_version = DRM_IF_VERSION(ver.drm_di_major, - ver.drm_dd_minor); - dev->if_version = DRM_MAX(if_version, dev->if_version); - if (ver.drm_di_minor >= 1) { - /* - * Version 1.1 includes tying of DRM to specific device - */ - drm_set_busid(dev); - } - } - - if (ver.drm_dd_major != -1) { - if (ver.drm_dd_major != dev->driver->major || - ver.drm_dd_minor < 0 || - ver.drm_dd_minor > dev->driver->minor) - { - return EINVAL; - } - } - - return 0; -} - - -int drm_noop(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - DRM_DEBUG("\n"); - return 0; -} diff --git a/sys/dev/drm2/drm_irq.c b/sys/dev/drm2/drm_irq.c deleted file mode 100644 index e8feb51262..0000000000 --- a/sys/dev/drm2/drm_irq.c +++ /dev/null @@ -1,1221 +0,0 @@ -/*- - * Copyright 2003 Eric Anholt - * 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, 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL - * ERIC ANHOLT 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. - * - * Authors: - * Eric Anholt - * - * $FreeBSD: src/sys/dev/drm2/drm_irq.c,v 1.1 2012/05/22 11:07:44 kib Exp $ - */ - -/** @file drm_irq.c - * Support code for handling setup/teardown of interrupt handlers and - * handing interrupt handlers off to the drivers. - */ - -#include -#include - -MALLOC_DEFINE(DRM_MEM_VBLANK, "drm_vblank", "DRM VBLANK Handling Data"); - -/* Access macro for slots in vblank timestamp ringbuffer. */ -#define vblanktimestamp(dev, crtc, count) ( \ - (dev)->_vblank_time[(crtc) * DRM_VBLANKTIME_RBSIZE + \ - ((count) % DRM_VBLANKTIME_RBSIZE)]) - -/* Retry timestamp calculation up to 3 times to satisfy - * drm_timestamp_precision before giving up. - */ -#define DRM_TIMESTAMP_MAXRETRIES 3 - -/* Threshold in nanoseconds for detection of redundant - * vblank irq in drm_handle_vblank(). 1 msec should be ok. - */ -#define DRM_REDUNDANT_VBLIRQ_THRESH_NS 1000000 - -int drm_irq_by_busid(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_irq_busid *irq = data; - - if ((irq->busnum >> 8) != dev->pci_domain || - (irq->busnum & 0xff) != dev->pci_bus || - irq->devnum != dev->pci_slot || - irq->funcnum != dev->pci_func) - return EINVAL; - - irq->irq = dev->irq; - - DRM_DEBUG("%d:%d:%d => IRQ %d\n", - irq->busnum, irq->devnum, irq->funcnum, irq->irq); - - return 0; -} - -int -drm_irq_install(struct drm_device *dev) -{ - int retcode; - - if (dev->irq == 0 || dev->dev_private == NULL) - return (EINVAL); - - DRM_DEBUG("irq=%d\n", dev->irq); - - DRM_LOCK(dev); - if (dev->irq_enabled) { - DRM_UNLOCK(dev); - return EBUSY; - } - dev->irq_enabled = 1; - - dev->context_flag = 0; - - /* Before installing handler */ - if (dev->driver->irq_preinstall) - dev->driver->irq_preinstall(dev); - DRM_UNLOCK(dev); - - /* Install handler */ - retcode = bus_setup_intr(dev->device, dev->irqr, INTR_MPSAFE, - dev->driver->irq_handler, dev, &dev->irqh, &dev->irq_lock); - if (retcode != 0) - goto err; - - /* After installing handler */ - DRM_LOCK(dev); - if (dev->driver->irq_postinstall) - dev->driver->irq_postinstall(dev); - DRM_UNLOCK(dev); - - return (0); -err: - device_printf(dev->device, "Error setting interrupt: %d\n", retcode); - dev->irq_enabled = 0; - - return (retcode); -} - -int drm_irq_uninstall(struct drm_device *dev) -{ - int i; - - if (!dev->irq_enabled) - return EINVAL; - - dev->irq_enabled = 0; - - /* - * Wake up any waiters so they don't hang. - */ - if (dev->num_crtcs) { - lockmgr(&dev->vbl_lock, LK_EXCLUSIVE); - for (i = 0; i < dev->num_crtcs; i++) { - wakeup(&dev->_vblank_count[i]); - dev->vblank_enabled[i] = 0; - dev->last_vblank[i] = - dev->driver->get_vblank_counter(dev, i); - } - lockmgr(&dev->vbl_lock, LK_RELEASE); - } - - DRM_DEBUG("irq=%d\n", dev->irq); - - if (dev->driver->irq_uninstall) - dev->driver->irq_uninstall(dev); - - DRM_UNLOCK(dev); - bus_teardown_intr(dev->device, dev->irqr, dev->irqh); - DRM_LOCK(dev); - - return 0; -} - -int drm_control(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - struct drm_control *ctl = data; - int err; - - switch (ctl->func) { - case DRM_INST_HANDLER: - /* Handle drivers whose DRM used to require IRQ setup but the - * no longer does. - */ - if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) - return 0; - if (drm_core_check_feature(dev, DRIVER_MODESET)) - return 0; - if (dev->if_version < DRM_IF_VERSION(1, 2) && - ctl->irq != dev->irq) - return EINVAL; - return drm_irq_install(dev); - case DRM_UNINST_HANDLER: - if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) - return 0; - if (drm_core_check_feature(dev, DRIVER_MODESET)) - return 0; - DRM_LOCK(dev); - err = drm_irq_uninstall(dev); - DRM_UNLOCK(dev); - return err; - default: - return EINVAL; - } -} - -#define NSEC_PER_USEC 1000L -#define NSEC_PER_SEC 1000000000L - -int64_t -timeval_to_ns(const struct timeval *tv) -{ - return ((int64_t)tv->tv_sec * NSEC_PER_SEC) + - tv->tv_usec * NSEC_PER_USEC; -} - -struct timeval -ns_to_timeval(const int64_t nsec) -{ - struct timeval tv; - uint32_t rem; - - if (nsec == 0) { - tv.tv_sec = 0; - tv.tv_usec = 0; - return (tv); - } - - tv.tv_sec = nsec / NSEC_PER_SEC; - rem = nsec % NSEC_PER_SEC; - if (rem < 0) { - tv.tv_sec--; - rem += NSEC_PER_SEC; - } - tv.tv_usec = rem / 1000; - return (tv); -} - -/* - * Clear vblank timestamp buffer for a crtc. - */ -static void clear_vblank_timestamps(struct drm_device *dev, int crtc) -{ - memset(&dev->_vblank_time[crtc * DRM_VBLANKTIME_RBSIZE], 0, - DRM_VBLANKTIME_RBSIZE * sizeof(struct timeval)); -} - -static int64_t -abs64(int64_t x) -{ - - return (x < 0 ? -x : x); -} - -/* - * Disable vblank irq's on crtc, make sure that last vblank count - * of hardware and corresponding consistent software vblank counter - * are preserved, even if there are any spurious vblank irq's after - * disable. - */ -static void vblank_disable_and_save(struct drm_device *dev, int crtc) -{ - u32 vblcount; - int64_t diff_ns; - int vblrc; - struct timeval tvblank; - - /* Prevent vblank irq processing while disabling vblank irqs, - * so no updates of timestamps or count can happen after we've - * disabled. Needed to prevent races in case of delayed irq's. - */ - lockmgr(&dev->vblank_time_lock, LK_EXCLUSIVE); - - dev->driver->disable_vblank(dev, crtc); - dev->vblank_enabled[crtc] = 0; - - /* No further vblank irq's will be processed after - * this point. Get current hardware vblank count and - * vblank timestamp, repeat until they are consistent. - * - * FIXME: There is still a race condition here and in - * drm_update_vblank_count() which can cause off-by-one - * reinitialization of software vblank counter. If gpu - * vblank counter doesn't increment exactly at the leading - * edge of a vblank interval, then we can lose 1 count if - * we happen to execute between start of vblank and the - * delayed gpu counter increment. - */ - do { - dev->last_vblank[crtc] = dev->driver->get_vblank_counter(dev, crtc); - vblrc = drm_get_last_vbltimestamp(dev, crtc, &tvblank, 0); - } while (dev->last_vblank[crtc] != dev->driver->get_vblank_counter(dev, crtc)); - - /* Compute time difference to stored timestamp of last vblank - * as updated by last invocation of drm_handle_vblank() in vblank irq. - */ - vblcount = atomic_read(&dev->_vblank_count[crtc]); - diff_ns = timeval_to_ns(&tvblank) - - timeval_to_ns(&vblanktimestamp(dev, crtc, vblcount)); - - /* If there is at least 1 msec difference between the last stored - * timestamp and tvblank, then we are currently executing our - * disable inside a new vblank interval, the tvblank timestamp - * corresponds to this new vblank interval and the irq handler - * for this vblank didn't run yet and won't run due to our disable. - * Therefore we need to do the job of drm_handle_vblank() and - * increment the vblank counter by one to account for this vblank. - * - * Skip this step if there isn't any high precision timestamp - * available. In that case we can't account for this and just - * hope for the best. - */ - if ((vblrc > 0) && (abs64(diff_ns) > 1000000)) { - atomic_inc(&dev->_vblank_count[crtc]); - } - - /* Invalidate all timestamps while vblank irq's are off. */ - clear_vblank_timestamps(dev, crtc); - - lockmgr(&dev->vblank_time_lock, LK_RELEASE); -} - -static void vblank_disable_fn(void * arg) -{ - struct drm_device *dev = (struct drm_device *)arg; - int i; - - if (!dev->vblank_disable_allowed) - return; - - for (i = 0; i < dev->num_crtcs; i++) { - lockmgr(&dev->vbl_lock, LK_EXCLUSIVE); - if (atomic_read(&dev->vblank_refcount[i]) == 0 && - dev->vblank_enabled[i]) { - DRM_DEBUG("disabling vblank on crtc %d\n", i); - vblank_disable_and_save(dev, i); - } - lockmgr(&dev->vbl_lock, LK_RELEASE); - } -} - -void drm_vblank_cleanup(struct drm_device *dev) -{ - /* Bail if the driver didn't call drm_vblank_init() */ - if (dev->num_crtcs == 0) - return; - - callout_stop(&dev->vblank_disable_callout); - - vblank_disable_fn(dev); - - drm_free(dev->_vblank_count, DRM_MEM_VBLANK); - drm_free(dev->vblank_refcount, DRM_MEM_VBLANK); - drm_free(dev->vblank_enabled, DRM_MEM_VBLANK); - drm_free(dev->last_vblank, DRM_MEM_VBLANK); - drm_free(dev->last_vblank_wait, DRM_MEM_VBLANK); - drm_free(dev->vblank_inmodeset, DRM_MEM_VBLANK); - drm_free(dev->_vblank_time, DRM_MEM_VBLANK); - - dev->num_crtcs = 0; -} - -int drm_vblank_init(struct drm_device *dev, int num_crtcs) -{ - int i; - - callout_init_mp(&dev->vblank_disable_callout); -#if 0 - mtx_init(&dev->vbl_lock, "drmvbl", NULL, MTX_DEF); -#endif - lockinit(&dev->vblank_time_lock, "drmvtl", 0, LK_CANRECURSE); - - dev->num_crtcs = num_crtcs; - - dev->_vblank_count = kmalloc(sizeof(atomic_t) * num_crtcs, - DRM_MEM_VBLANK, M_WAITOK); - dev->vblank_refcount = kmalloc(sizeof(atomic_t) * num_crtcs, - DRM_MEM_VBLANK, M_WAITOK); - dev->vblank_enabled = kmalloc(num_crtcs * sizeof(int), - DRM_MEM_VBLANK, M_WAITOK | M_ZERO); - dev->last_vblank = kmalloc(num_crtcs * sizeof(u32), - DRM_MEM_VBLANK, M_WAITOK | M_ZERO); - dev->last_vblank_wait = kmalloc(num_crtcs * sizeof(u32), - DRM_MEM_VBLANK, M_WAITOK | M_ZERO); - dev->vblank_inmodeset = kmalloc(num_crtcs * sizeof(int), - DRM_MEM_VBLANK, M_WAITOK | M_ZERO); - dev->_vblank_time = kmalloc(num_crtcs * DRM_VBLANKTIME_RBSIZE * - sizeof(struct timeval), DRM_MEM_VBLANK, M_WAITOK | M_ZERO); - DRM_INFO("Supports vblank timestamp caching Rev 1 (10.10.2010).\n"); - - /* Driver specific high-precision vblank timestamping supported? */ - if (dev->driver->get_vblank_timestamp) - DRM_INFO("Driver supports precise vblank timestamp query.\n"); - else - DRM_INFO("No driver support for vblank timestamp query.\n"); - - /* Zero per-crtc vblank stuff */ - for (i = 0; i < num_crtcs; i++) { - atomic_set(&dev->_vblank_count[i], 0); - atomic_set(&dev->vblank_refcount[i], 0); - } - - dev->vblank_disable_allowed = 0; - return 0; -} - -void -drm_calc_timestamping_constants(struct drm_crtc *crtc) -{ - int64_t linedur_ns = 0, pixeldur_ns = 0, framedur_ns = 0; - uint64_t dotclock; - - /* Dot clock in Hz: */ - dotclock = (uint64_t) crtc->hwmode.clock * 1000; - - /* Fields of interlaced scanout modes are only halve a frame duration. - * Double the dotclock to get halve the frame-/line-/pixelduration. - */ - if (crtc->hwmode.flags & DRM_MODE_FLAG_INTERLACE) - dotclock *= 2; - - /* Valid dotclock? */ - if (dotclock > 0) { - /* Convert scanline length in pixels and video dot clock to - * line duration, frame duration and pixel duration in - * nanoseconds: - */ - pixeldur_ns = (int64_t)1000000000 / dotclock; - linedur_ns = ((uint64_t)crtc->hwmode.crtc_htotal * - 1000000000) / dotclock; - framedur_ns = (int64_t)crtc->hwmode.crtc_vtotal * linedur_ns; - } else - DRM_ERROR("crtc %d: Can't calculate constants, dotclock = 0!\n", - crtc->base.id); - - crtc->pixeldur_ns = pixeldur_ns; - crtc->linedur_ns = linedur_ns; - crtc->framedur_ns = framedur_ns; - - DRM_DEBUG("crtc %d: hwmode: htotal %d, vtotal %d, vdisplay %d\n", - crtc->base.id, crtc->hwmode.crtc_htotal, - crtc->hwmode.crtc_vtotal, crtc->hwmode.crtc_vdisplay); - DRM_DEBUG("crtc %d: clock %d kHz framedur %d linedur %d, pixeldur %d\n", - crtc->base.id, (int) dotclock/1000, (int) framedur_ns, - (int) linedur_ns, (int) pixeldur_ns); -} - -/** - * drm_calc_vbltimestamp_from_scanoutpos - helper routine for kms - * drivers. Implements calculation of exact vblank timestamps from - * given drm_display_mode timings and current video scanout position - * of a crtc. This can be called from within get_vblank_timestamp() - * implementation of a kms driver to implement the actual timestamping. - * - * Should return timestamps conforming to the OML_sync_control OpenML - * extension specification. The timestamp corresponds to the end of - * the vblank interval, aka start of scanout of topmost-leftmost display - * pixel in the following video frame. - * - * Requires support for optional dev->driver->get_scanout_position() - * in kms driver, plus a bit of setup code to provide a drm_display_mode - * that corresponds to the true scanout timing. - * - * The current implementation only handles standard video modes. It - * returns as no operation if a doublescan or interlaced video mode is - * active. Higher level code is expected to handle this. - * - * @dev: DRM device. - * @crtc: Which crtc's vblank timestamp to retrieve. - * @max_error: Desired maximum allowable error in timestamps (nanosecs). - * On return contains true maximum error of timestamp. - * @vblank_time: Pointer to struct timeval which should receive the timestamp. - * @flags: Flags to pass to driver: - * 0 = Default. - * DRM_CALLED_FROM_VBLIRQ = If function is called from vbl irq handler. - * @refcrtc: drm_crtc* of crtc which defines scanout timing. - * - * Returns negative value on error, failure or if not supported in current - * video mode: - * - * -EINVAL - Invalid crtc. - * -EAGAIN - Temporary unavailable, e.g., called before initial modeset. - * -ENOTSUPP - Function not supported in current display mode. - * -EIO - Failed, e.g., due to failed scanout position query. - * - * Returns or'ed positive status flags on success: - * - * DRM_VBLANKTIME_SCANOUTPOS_METHOD - Signal this method used for timestamping. - * DRM_VBLANKTIME_INVBL - Timestamp taken while scanout was in vblank interval. - * - */ -int -drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc, - int *max_error, struct timeval *vblank_time, unsigned flags, - struct drm_crtc *refcrtc) -{ - struct timeval stime, raw_time; - struct drm_display_mode *mode; - int vbl_status, vtotal, vdisplay; - int vpos, hpos, i; - int64_t framedur_ns, linedur_ns, pixeldur_ns, delta_ns, duration_ns; - bool invbl; - - if (crtc < 0 || crtc >= dev->num_crtcs) { - DRM_ERROR("Invalid crtc %d\n", crtc); - return -EINVAL; - } - - /* Scanout position query not supported? Should not happen. */ - if (!dev->driver->get_scanout_position) { - DRM_ERROR("Called from driver w/o get_scanout_position()!?\n"); - return -EIO; - } - - mode = &refcrtc->hwmode; - vtotal = mode->crtc_vtotal; - vdisplay = mode->crtc_vdisplay; - - /* Durations of frames, lines, pixels in nanoseconds. */ - framedur_ns = refcrtc->framedur_ns; - linedur_ns = refcrtc->linedur_ns; - pixeldur_ns = refcrtc->pixeldur_ns; - - /* If mode timing undefined, just return as no-op: - * Happens during initial modesetting of a crtc. - */ - if (vtotal <= 0 || vdisplay <= 0 || framedur_ns == 0) { - DRM_DEBUG("crtc %d: Noop due to uninitialized mode.\n", crtc); - return -EAGAIN; - } - - /* Get current scanout position with system timestamp. - * Repeat query up to DRM_TIMESTAMP_MAXRETRIES times - * if single query takes longer than max_error nanoseconds. - * - * This guarantees a tight bound on maximum error if - * code gets preempted or delayed for some reason. - */ - for (i = 0; i < DRM_TIMESTAMP_MAXRETRIES; i++) { - /* Disable preemption to make it very likely to - * succeed in the first iteration. - */ - crit_enter(); - - /* Get system timestamp before query. */ - getmicrouptime(&stime); - - /* Get vertical and horizontal scanout pos. vpos, hpos. */ - vbl_status = dev->driver->get_scanout_position(dev, crtc, &vpos, &hpos); - - /* Get system timestamp after query. */ - getmicrouptime(&raw_time); - - crit_exit(); - - /* Return as no-op if scanout query unsupported or failed. */ - if (!(vbl_status & DRM_SCANOUTPOS_VALID)) { - DRM_DEBUG("crtc %d : scanoutpos query failed [%d].\n", - crtc, vbl_status); - return -EIO; - } - - duration_ns = timeval_to_ns(&raw_time) - timeval_to_ns(&stime); - - /* Accept result with < max_error nsecs timing uncertainty. */ - if (duration_ns <= (int64_t) *max_error) - break; - } - - /* Noisy system timing? */ - if (i == DRM_TIMESTAMP_MAXRETRIES) { - DRM_DEBUG("crtc %d: Noisy timestamp %d us > %d us [%d reps].\n", - crtc, (int) duration_ns/1000, *max_error/1000, i); - } - - /* Return upper bound of timestamp precision error. */ - *max_error = (int) duration_ns; - - /* Check if in vblank area: - * vpos is >=0 in video scanout area, but negative - * within vblank area, counting down the number of lines until - * start of scanout. - */ - invbl = vbl_status & DRM_SCANOUTPOS_INVBL; - - /* Convert scanout position into elapsed time at raw_time query - * since start of scanout at first display scanline. delta_ns - * can be negative if start of scanout hasn't happened yet. - */ - delta_ns = (int64_t)vpos * linedur_ns + (int64_t)hpos * pixeldur_ns; - - /* Is vpos outside nominal vblank area, but less than - * 1/100 of a frame height away from start of vblank? - * If so, assume this isn't a massively delayed vblank - * interrupt, but a vblank interrupt that fired a few - * microseconds before true start of vblank. Compensate - * by adding a full frame duration to the final timestamp. - * Happens, e.g., on ATI R500, R600. - * - * We only do this if DRM_CALLED_FROM_VBLIRQ. - */ - if ((flags & DRM_CALLED_FROM_VBLIRQ) && !invbl && - ((vdisplay - vpos) < vtotal / 100)) { - delta_ns = delta_ns - framedur_ns; - - /* Signal this correction as "applied". */ - vbl_status |= 0x8; - } - - /* Subtract time delta from raw timestamp to get final - * vblank_time timestamp for end of vblank. - */ - *vblank_time = ns_to_timeval(timeval_to_ns(&raw_time) - delta_ns); - - DRM_DEBUG("crtc %d : v %d p(%d,%d)@ %jd.%jd -> %jd.%jd [e %d us, %d rep]\n", - crtc, (int)vbl_status, hpos, vpos, (uintmax_t)raw_time.tv_sec, - (uintmax_t)raw_time.tv_usec, (uintmax_t)vblank_time->tv_sec, - (uintmax_t)vblank_time->tv_usec, (int)duration_ns/1000, i); - - vbl_status = DRM_VBLANKTIME_SCANOUTPOS_METHOD; - if (invbl) - vbl_status |= DRM_VBLANKTIME_INVBL; - - return vbl_status; -} - -/** - * drm_get_last_vbltimestamp - retrieve raw timestamp for the most recent - * vblank interval. - * - * @dev: DRM device - * @crtc: which crtc's vblank timestamp to retrieve - * @tvblank: Pointer to target struct timeval which should receive the timestamp - * @flags: Flags to pass to driver: - * 0 = Default. - * DRM_CALLED_FROM_VBLIRQ = If function is called from vbl irq handler. - * - * Fetches the system timestamp corresponding to the time of the most recent - * vblank interval on specified crtc. May call into kms-driver to - * compute the timestamp with a high-precision GPU specific method. - * - * Returns zero if timestamp originates from uncorrected do_gettimeofday() - * call, i.e., it isn't very precisely locked to the true vblank. - * - * Returns non-zero if timestamp is considered to be very precise. - */ -u32 drm_get_last_vbltimestamp(struct drm_device *dev, int crtc, - struct timeval *tvblank, unsigned flags) -{ - int ret = 0; - - /* Define requested maximum error on timestamps (nanoseconds). */ - int max_error = (int) drm_timestamp_precision * 1000; - - /* Query driver if possible and precision timestamping enabled. */ - if (dev->driver->get_vblank_timestamp && (max_error > 0)) { - ret = dev->driver->get_vblank_timestamp(dev, crtc, &max_error, - tvblank, flags); - if (ret > 0) - return (u32) ret; - } - - /* GPU high precision timestamp query unsupported or failed. - * Return gettimeofday timestamp as best estimate. - */ - microtime(tvblank); - - return 0; -} - -/** - * drm_vblank_count - retrieve "cooked" vblank counter value - * @dev: DRM device - * @crtc: which counter to retrieve - * - * Fetches the "cooked" vblank count value that represents the number of - * vblank events since the system was booted, including lost events due to - * modesetting activity. - */ -u32 drm_vblank_count(struct drm_device *dev, int crtc) -{ - return atomic_read(&dev->_vblank_count[crtc]); -} - -/** - * drm_vblank_count_and_time - retrieve "cooked" vblank counter value - * and the system timestamp corresponding to that vblank counter value. - * - * @dev: DRM device - * @crtc: which counter to retrieve - * @vblanktime: Pointer to struct timeval to receive the vblank timestamp. - * - * Fetches the "cooked" vblank count value that represents the number of - * vblank events since the system was booted, including lost events due to - * modesetting activity. Returns corresponding system timestamp of the time - * of the vblank interval that corresponds to the current value vblank counter - * value. - */ -u32 drm_vblank_count_and_time(struct drm_device *dev, int crtc, - struct timeval *vblanktime) -{ - u32 cur_vblank; - - /* Read timestamp from slot of _vblank_time ringbuffer - * that corresponds to current vblank count. Retry if - * count has incremented during readout. This works like - * a seqlock. - */ - do { - cur_vblank = atomic_read(&dev->_vblank_count[crtc]); - *vblanktime = vblanktimestamp(dev, crtc, cur_vblank); - cpu_lfence(); - } while (cur_vblank != atomic_read(&dev->_vblank_count[crtc])); - - return cur_vblank; -} - -/** - * drm_update_vblank_count - update the master vblank counter - * @dev: DRM device - * @crtc: counter to update - * - * Call back into the driver to update the appropriate vblank counter - * (specified by @crtc). Deal with wraparound, if it occurred, and - * update the last read value so we can deal with wraparound on the next - * call if necessary. - * - * Only necessary when going from off->on, to account for frames we - * didn't get an interrupt for. - * - * Note: caller must hold dev->vbl_lock since this reads & writes - * device vblank fields. - */ -static void drm_update_vblank_count(struct drm_device *dev, int crtc) -{ - u32 cur_vblank, diff, tslot, rc; - struct timeval t_vblank; - - /* - * Interrupts were disabled prior to this call, so deal with counter - * wrap if needed. - * NOTE! It's possible we lost a full dev->max_vblank_count events - * here if the register is small or we had vblank interrupts off for - * a long time. - * - * We repeat the hardware vblank counter & timestamp query until - * we get consistent results. This to prevent races between gpu - * updating its hardware counter while we are retrieving the - * corresponding vblank timestamp. - */ - do { - cur_vblank = dev->driver->get_vblank_counter(dev, crtc); - rc = drm_get_last_vbltimestamp(dev, crtc, &t_vblank, 0); - } while (cur_vblank != dev->driver->get_vblank_counter(dev, crtc)); - - /* Deal with counter wrap */ - diff = cur_vblank - dev->last_vblank[crtc]; - if (cur_vblank < dev->last_vblank[crtc]) { - diff += dev->max_vblank_count; - - DRM_DEBUG("last_vblank[%d]=0x%x, cur_vblank=0x%x => diff=0x%x\n", - crtc, dev->last_vblank[crtc], cur_vblank, diff); - } - - DRM_DEBUG("enabling vblank interrupts on crtc %d, missed %d\n", - crtc, diff); - - /* Reinitialize corresponding vblank timestamp if high-precision query - * available. Skip this step if query unsupported or failed. Will - * reinitialize delayed at next vblank interrupt in that case. - */ - if (rc) { - tslot = atomic_read(&dev->_vblank_count[crtc]) + diff; - vblanktimestamp(dev, crtc, tslot) = t_vblank; - } - - atomic_add(diff, &dev->_vblank_count[crtc]); -} - -/** - * drm_vblank_get - get a reference count on vblank events - * @dev: DRM device - * @crtc: which CRTC to own - * - * Acquire a reference count on vblank events to avoid having them disabled - * while in use. - * - * RETURNS - * Zero on success, nonzero on failure. - */ -int drm_vblank_get(struct drm_device *dev, int crtc) -{ - int ret = 0; - - lockmgr(&dev->vbl_lock, LK_EXCLUSIVE); - /* Going from 0->1 means we have to enable interrupts again */ - if (atomic_fetchadd_int(&dev->vblank_refcount[crtc], 1) == 0) { - lockmgr(&dev->vblank_time_lock, LK_EXCLUSIVE); - if (!dev->vblank_enabled[crtc]) { - /* Enable vblank irqs under vblank_time_lock protection. - * All vblank count & timestamp updates are held off - * until we are done reinitializing master counter and - * timestamps. Filtercode in drm_handle_vblank() will - * prevent double-accounting of same vblank interval. - */ - ret = -dev->driver->enable_vblank(dev, crtc); - DRM_DEBUG("enabling vblank on crtc %d, ret: %d\n", - crtc, ret); - if (ret) - atomic_dec(&dev->vblank_refcount[crtc]); - else { - dev->vblank_enabled[crtc] = 1; - drm_update_vblank_count(dev, crtc); - } - } - lockmgr(&dev->vblank_time_lock, LK_RELEASE); - } else { - if (!dev->vblank_enabled[crtc]) { - atomic_dec(&dev->vblank_refcount[crtc]); - ret = EINVAL; - } - } - lockmgr(&dev->vbl_lock, LK_RELEASE); - - return ret; -} - -/** - * drm_vblank_put - give up ownership of vblank events - * @dev: DRM device - * @crtc: which counter to give up - * - * Release ownership of a given vblank counter, turning off interrupts - * if possible. Disable interrupts after drm_vblank_offdelay milliseconds. - */ -void drm_vblank_put(struct drm_device *dev, int crtc) -{ - KASSERT(atomic_read(&dev->vblank_refcount[crtc]) != 0, - ("Too many drm_vblank_put for crtc %d", crtc)); - - /* Last user schedules interrupt disable */ - if (atomic_fetchadd_int(&dev->vblank_refcount[crtc], -1) == 1 && - (drm_vblank_offdelay > 0)) - callout_reset(&dev->vblank_disable_callout, - (drm_vblank_offdelay * DRM_HZ) / 1000, - vblank_disable_fn, dev); -} - -void drm_vblank_off(struct drm_device *dev, int crtc) -{ - struct drm_pending_vblank_event *e, *t; - struct timeval now; - unsigned int seq; - - lockmgr(&dev->vbl_lock, LK_EXCLUSIVE); - vblank_disable_and_save(dev, crtc); - lockmgr(&dev->event_lock, LK_EXCLUSIVE); - wakeup(&dev->_vblank_count[crtc]); - - /* Send any queued vblank events, lest the natives grow disquiet */ - seq = drm_vblank_count_and_time(dev, crtc, &now); - list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) { - if (e->pipe != crtc) - continue; - DRM_DEBUG("Sending premature vblank event on disable: \ - wanted %d, current %d\n", - e->event.sequence, seq); - - e->event.sequence = seq; - e->event.tv_sec = now.tv_sec; - e->event.tv_usec = now.tv_usec; - drm_vblank_put(dev, e->pipe); - list_move_tail(&e->base.link, &e->base.file_priv->event_list); - drm_event_wakeup(&e->base); - } - - lockmgr(&dev->event_lock, LK_RELEASE); - lockmgr(&dev->vbl_lock, LK_RELEASE); -} - -/** - * drm_vblank_pre_modeset - account for vblanks across mode sets - * @dev: DRM device - * @crtc: CRTC in question - * @post: post or pre mode set? - * - * Account for vblank events across mode setting events, which will likely - * reset the hardware frame counter. - */ -void drm_vblank_pre_modeset(struct drm_device *dev, int crtc) -{ - /* vblank is not initialized (IRQ not installed ?) */ - if (!dev->num_crtcs) - return; - /* - * To avoid all the problems that might happen if interrupts - * were enabled/disabled around or between these calls, we just - * have the kernel take a reference on the CRTC (just once though - * to avoid corrupting the count if multiple, mismatch calls occur), - * so that interrupts remain enabled in the interim. - */ - if (!dev->vblank_inmodeset[crtc]) { - dev->vblank_inmodeset[crtc] = 0x1; - if (drm_vblank_get(dev, crtc) == 0) - dev->vblank_inmodeset[crtc] |= 0x2; - } -} - -void drm_vblank_post_modeset(struct drm_device *dev, int crtc) -{ - - if (dev->vblank_inmodeset[crtc]) { - lockmgr(&dev->vbl_lock, LK_EXCLUSIVE); - dev->vblank_disable_allowed = 1; - lockmgr(&dev->vbl_lock, LK_RELEASE); - - if (dev->vblank_inmodeset[crtc] & 0x2) - drm_vblank_put(dev, crtc); - - dev->vblank_inmodeset[crtc] = 0; - } -} - -/** - * drm_modeset_ctl - handle vblank event counter changes across mode switch - * @DRM_IOCTL_ARGS: standard ioctl arguments - * - * Applications should call the %_DRM_PRE_MODESET and %_DRM_POST_MODESET - * ioctls around modesetting so that any lost vblank events are accounted for. - * - * Generally the counter will reset across mode sets. If interrupts are - * enabled around this call, we don't have to do anything since the counter - * will have already been incremented. - */ -int drm_modeset_ctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_modeset_ctl *modeset = data; - int ret = 0; - unsigned int crtc; - - /* If drm_vblank_init() hasn't been called yet, just no-op */ - if (!dev->num_crtcs) - goto out; - - crtc = modeset->crtc; - if (crtc >= dev->num_crtcs) { - ret = -EINVAL; - goto out; - } - - switch (modeset->cmd) { - case _DRM_PRE_MODESET: - drm_vblank_pre_modeset(dev, crtc); - break; - case _DRM_POST_MODESET: - drm_vblank_post_modeset(dev, crtc); - break; - default: - ret = -EINVAL; - break; - } - -out: - return ret; -} - -static void -drm_vblank_event_destroy(struct drm_pending_event *e) -{ - - drm_free(e, DRM_MEM_VBLANK); -} - -static int drm_queue_vblank_event(struct drm_device *dev, int pipe, - union drm_wait_vblank *vblwait, - struct drm_file *file_priv) -{ - struct drm_pending_vblank_event *e; - struct timeval now; - unsigned int seq; - int ret; - - e = kmalloc(sizeof *e, DRM_MEM_VBLANK, M_WAITOK | M_ZERO); - - e->pipe = pipe; - e->base.pid = curproc->p_pid; - e->event.base.type = DRM_EVENT_VBLANK; - e->event.base.length = sizeof e->event; - e->event.user_data = vblwait->request.signal; - e->base.event = &e->event.base; - e->base.file_priv = file_priv; - e->base.destroy = drm_vblank_event_destroy; - - lockmgr(&dev->event_lock, LK_EXCLUSIVE); - - if (file_priv->event_space < sizeof e->event) { - ret = EBUSY; - goto err_unlock; - } - - file_priv->event_space -= sizeof e->event; - seq = drm_vblank_count_and_time(dev, pipe, &now); - - if ((vblwait->request.type & _DRM_VBLANK_NEXTONMISS) && - (seq - vblwait->request.sequence) <= (1 << 23)) { - vblwait->request.sequence = seq + 1; - vblwait->reply.sequence = vblwait->request.sequence; - } - - DRM_DEBUG("event on vblank count %d, current %d, crtc %d\n", - vblwait->request.sequence, seq, pipe); - - e->event.sequence = vblwait->request.sequence; - if ((seq - vblwait->request.sequence) <= (1 << 23)) { - e->event.sequence = seq; - e->event.tv_sec = now.tv_sec; - e->event.tv_usec = now.tv_usec; - drm_vblank_put(dev, pipe); - list_add_tail(&e->base.link, &e->base.file_priv->event_list); - drm_event_wakeup(&e->base); - vblwait->reply.sequence = seq; - } else { - /* drm_handle_vblank_events will call drm_vblank_put */ - list_add_tail(&e->base.link, &dev->vblank_event_list); - vblwait->reply.sequence = vblwait->request.sequence; - } - - lockmgr(&dev->event_lock, LK_RELEASE); - - return 0; - -err_unlock: - lockmgr(&dev->event_lock, LK_RELEASE); - drm_free(e, DRM_MEM_VBLANK); - drm_vblank_put(dev, pipe); - return ret; -} - -/** - * Wait for VBLANK. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param data user argument, pointing to a drm_wait_vblank structure. - * \return zero on success or a negative number on failure. - * - * This function enables the vblank interrupt on the pipe requested, then - * sleeps waiting for the requested sequence number to occur, and drops - * the vblank interrupt refcount afterwards. (vblank irq disable follows that - * after a timeout with no further vblank waits scheduled). - */ -int drm_wait_vblank(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - union drm_wait_vblank *vblwait = data; - int ret = 0; - unsigned int flags, seq, crtc, high_crtc; - - if (/*(!drm_dev_to_irq(dev)) || */(!dev->irq_enabled)) - return (EINVAL); - - if (vblwait->request.type & _DRM_VBLANK_SIGNAL) - return (EINVAL); - - if (vblwait->request.type & - ~(_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK | - _DRM_VBLANK_HIGH_CRTC_MASK)) { - DRM_ERROR("Unsupported type value 0x%x, supported mask 0x%x\n", - vblwait->request.type, - (_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK | - _DRM_VBLANK_HIGH_CRTC_MASK)); - return (EINVAL); - } - - flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK; - high_crtc = (vblwait->request.type & _DRM_VBLANK_HIGH_CRTC_MASK); - if (high_crtc) - crtc = high_crtc >> _DRM_VBLANK_HIGH_CRTC_SHIFT; - else - crtc = flags & _DRM_VBLANK_SECONDARY ? 1 : 0; - if (crtc >= dev->num_crtcs) - return (EINVAL); - - ret = drm_vblank_get(dev, crtc); - if (ret) { - DRM_DEBUG("failed to acquire vblank counter, %d\n", ret); - return (ret); - } - seq = drm_vblank_count(dev, crtc); - - switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) { - case _DRM_VBLANK_RELATIVE: - vblwait->request.sequence += seq; - vblwait->request.type &= ~_DRM_VBLANK_RELATIVE; - case _DRM_VBLANK_ABSOLUTE: - break; - default: - ret = (EINVAL); - goto done; - } - - if (flags & _DRM_VBLANK_EVENT) { - /* must hold on to the vblank ref until the event fires - * drm_vblank_put will be called asynchronously - */ - return drm_queue_vblank_event(dev, crtc, vblwait, file_priv); - } - - if ((flags & _DRM_VBLANK_NEXTONMISS) && - (seq - vblwait->request.sequence) <= (1<<23)) { - vblwait->request.sequence = seq + 1; - } - - dev->last_vblank_wait[crtc] = vblwait->request.sequence; - lockmgr(&dev->vblank_time_lock, LK_EXCLUSIVE); - while (((drm_vblank_count(dev, crtc) - vblwait->request.sequence) > - (1 << 23)) && dev->irq_enabled) { - /* - * The wakeups from the drm_irq_uninstall() and - * drm_vblank_off() may be lost there since vbl_lock - * is not held. Then, the timeout will wake us; the 3 - * seconds delay should not be a problem for - * application when crtc is disabled or irq - * uninstalled anyway. - */ - ret = lksleep(&dev->_vblank_count[crtc], &dev->vblank_time_lock, - PCATCH, "drmvbl", 3 * hz); - if (ret != 0) - break; - } - lockmgr(&dev->vblank_time_lock, LK_RELEASE); - if (ret != EINTR) { - struct timeval now; - long reply_seq; - - reply_seq = drm_vblank_count_and_time(dev, crtc, &now); - vblwait->reply.sequence = reply_seq; - vblwait->reply.tval_sec = now.tv_sec; - vblwait->reply.tval_usec = now.tv_usec; - } - -done: - drm_vblank_put(dev, crtc); - return ret; -} - -void drm_handle_vblank_events(struct drm_device *dev, int crtc) -{ - struct drm_pending_vblank_event *e, *t; - struct timeval now; - unsigned int seq; - - seq = drm_vblank_count_and_time(dev, crtc, &now); - - lockmgr(&dev->event_lock, LK_EXCLUSIVE); - - list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) { - if (e->pipe != crtc) - continue; - if ((seq - e->event.sequence) > (1<<23)) - continue; - - e->event.sequence = seq; - e->event.tv_sec = now.tv_sec; - e->event.tv_usec = now.tv_usec; - drm_vblank_put(dev, e->pipe); - list_move_tail(&e->base.link, &e->base.file_priv->event_list); - drm_event_wakeup(&e->base); - } - - lockmgr(&dev->event_lock, LK_RELEASE); -} - -/** - * drm_handle_vblank - handle a vblank event - * @dev: DRM device - * @crtc: where this event occurred - * - * Drivers should call this routine in their vblank interrupt handlers to - * update the vblank counter and send any signals that may be pending. - */ -bool drm_handle_vblank(struct drm_device *dev, int crtc) -{ - u32 vblcount; - int64_t diff_ns; - struct timeval tvblank; - - if (!dev->num_crtcs) - return false; - - /* Need timestamp lock to prevent concurrent execution with - * vblank enable/disable, as this would cause inconsistent - * or corrupted timestamps and vblank counts. - */ - lockmgr(&dev->vblank_time_lock, LK_EXCLUSIVE); - - /* Vblank irq handling disabled. Nothing to do. */ - if (!dev->vblank_enabled[crtc]) { - lockmgr(&dev->vblank_time_lock, LK_RELEASE); - return false; - } - - /* Fetch corresponding timestamp for this vblank interval from - * driver and store it in proper slot of timestamp ringbuffer. - */ - - /* Get current timestamp and count. */ - vblcount = atomic_read(&dev->_vblank_count[crtc]); - drm_get_last_vbltimestamp(dev, crtc, &tvblank, DRM_CALLED_FROM_VBLIRQ); - - /* Compute time difference to timestamp of last vblank */ - diff_ns = timeval_to_ns(&tvblank) - - timeval_to_ns(&vblanktimestamp(dev, crtc, vblcount)); - - /* Update vblank timestamp and count if at least - * DRM_REDUNDANT_VBLIRQ_THRESH_NS nanoseconds - * difference between last stored timestamp and current - * timestamp. A smaller difference means basically - * identical timestamps. Happens if this vblank has - * been already processed and this is a redundant call, - * e.g., due to spurious vblank interrupts. We need to - * ignore those for accounting. - */ - if (abs64(diff_ns) > DRM_REDUNDANT_VBLIRQ_THRESH_NS) { - /* Store new timestamp in ringbuffer. */ - vblanktimestamp(dev, crtc, vblcount + 1) = tvblank; - - /* Increment cooked vblank count. This also atomically commits - * the timestamp computed above. - */ - atomic_inc(&dev->_vblank_count[crtc]); - } else { - DRM_DEBUG("crtc %d: Redundant vblirq ignored. diff_ns = %d\n", - crtc, (int) diff_ns); - } - - wakeup(&dev->_vblank_count[crtc]); - drm_handle_vblank_events(dev, crtc); - - lockmgr(&dev->vblank_time_lock, LK_RELEASE); - return true; -} diff --git a/sys/dev/drm2/drm_linux_list.h b/sys/dev/drm2/drm_linux_list.h deleted file mode 100644 index 86fdfe7663..0000000000 --- a/sys/dev/drm2/drm_linux_list.h +++ /dev/null @@ -1,175 +0,0 @@ -/* drm_linux_list.h -- linux list functions for the BSDs. - * Created: Mon Apr 7 14:30:16 1999 by anholt@FreeBSD.org - */ -/*- - * Copyright 2003 Eric Anholt - * 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, 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS 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. - * - * Authors: - * Eric Anholt - * - * $FreeBSD: src/sys/dev/drm2/drm_linux_list.h,v 1.1 2012/05/22 11:07:44 kib Exp $ - */ - -#ifndef _DRM_LINUX_LIST_H_ -#define _DRM_LINUX_LIST_H_ - -struct list_head { - struct list_head *next, *prev; -}; - -#define list_entry(ptr, type, member) container_of(ptr,type,member) -#define hlist_entry(ptr, type, member) container_of(ptr,type,member) - -static __inline__ void -INIT_LIST_HEAD(struct list_head *head) { - (head)->next = head; - (head)->prev = head; -} - -#define LIST_HEAD_INIT(name) { &(name), &(name) } - -#define DRM_LIST_HEAD(name) \ - struct list_head name = LIST_HEAD_INIT(name) - -static __inline__ int -list_empty(const struct list_head *head) { - return (head)->next == head; -} - -static __inline__ void -list_add(struct list_head *new, struct list_head *head) { - (head)->next->prev = new; - (new)->next = (head)->next; - (new)->prev = head; - (head)->next = new; -} - -static __inline__ void -list_add_tail(struct list_head *entry, struct list_head *head) { - (entry)->prev = (head)->prev; - (entry)->next = head; - (head)->prev->next = entry; - (head)->prev = entry; -} - -static __inline__ void -list_del(struct list_head *entry) { - (entry)->next->prev = (entry)->prev; - (entry)->prev->next = (entry)->next; -} - -static inline void list_replace(struct list_head *old, - struct list_head *new) -{ - new->next = old->next; - new->next->prev = new; - new->prev = old->prev; - new->prev->next = new; -} - -static inline void list_move(struct list_head *list, struct list_head *head) -{ - list_del(list); - list_add(list, head); -} - -static inline void list_move_tail(struct list_head *list, - struct list_head *head) -{ - list_del(list); - list_add_tail(list, head); -} - -static __inline__ void -list_del_init(struct list_head *entry) { - (entry)->next->prev = (entry)->prev; - (entry)->prev->next = (entry)->next; - INIT_LIST_HEAD(entry); -} - -#define list_for_each(entry, head) \ - for (entry = (head)->next; entry != head; entry = (entry)->next) - -#define list_for_each_prev(entry, head) \ - for (entry = (head)->prev; entry != (head); \ - entry = entry->prev) - -#define list_for_each_safe(entry, temp, head) \ - for (entry = (head)->next, temp = (entry)->next; \ - entry != head; \ - entry = temp, temp = entry->next) - -#define list_for_each_entry(pos, head, member) \ - for (pos = list_entry((head)->next, __typeof(*pos), member); \ - &pos->member != (head); \ - pos = list_entry(pos->member.next, __typeof(*pos), member)) - -#define list_for_each_entry_continue_reverse(pos, head, member) \ - for (pos = list_entry(pos->member.prev, __typeof(*pos), member); \ - &pos->member != (head); \ - pos = list_entry(pos->member.prev, __typeof(*pos), member)) - -/** - * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry - * @pos: the type * to use as a loop cursor. - * @n: another type * to use as temporary storage - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry_safe(pos, n, head, member) \ - for (pos = list_entry((head)->next, __typeof(*pos), member), \ - n = list_entry(pos->member.next, __typeof(*pos), member); \ - &pos->member != (head); \ - pos = n, n = list_entry(n->member.next, __typeof(*n), member)) - -#define list_first_entry(ptr, type, member) \ - list_entry((ptr)->next, type, member) - - -static inline void -__list_splice(const struct list_head *list, struct list_head *prev, - struct list_head *next) -{ - struct list_head *first = list->next; - struct list_head *last = list->prev; - - first->prev = prev; - prev->next = first; - - last->next = next; - next->prev = last; -} - -static inline void -list_splice(const struct list_head *list, struct list_head *head) -{ - if (list_empty(list)) - return; - - __list_splice(list, head, head->next); -} - -void drm_list_sort(void *priv, struct list_head *head, int (*cmp)(void *priv, - struct list_head *a, struct list_head *b)); - -#endif /* _DRM_LINUX_LIST_H_ */ diff --git a/sys/dev/drm2/drm_lock.c b/sys/dev/drm2/drm_lock.c deleted file mode 100644 index b9f3c66ae3..0000000000 --- a/sys/dev/drm2/drm_lock.c +++ /dev/null @@ -1,197 +0,0 @@ -/*- - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * 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, 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS 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. - * - * Authors: - * Rickard E. (Rik) Faith - * Gareth Hughes - * - * $FreeBSD: src/sys/dev/drm2/drm_lock.c,v 1.1 2012/05/22 11:07:44 kib Exp $ - */ - -/** @file drm_lock.c - * Implementation of the ioctls and other support code for dealing with the - * hardware lock. - * - * The DRM hardware lock is a shared structure between the kernel and userland. - * - * On uncontended access where the new context was the last context, the - * client may take the lock without dropping down into the kernel, using atomic - * compare-and-set. - * - * If the client finds during compare-and-set that it was not the last owner - * of the lock, it calls the DRM lock ioctl, which may sleep waiting for the - * lock, and may have side-effects of kernel-managed context switching. - * - * When the client releases the lock, if the lock is marked as being contended - * by another client, then the DRM unlock ioctl is called so that the - * contending client may be woken up. - */ - -#include - -int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - struct drm_lock *lock = data; - int ret = 0; - - if (lock->context == DRM_KERNEL_CONTEXT) { - DRM_ERROR("Process %d using kernel context %d\n", - DRM_CURRENTPID, lock->context); - return EINVAL; - } - - DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n", - lock->context, DRM_CURRENTPID, dev->lock.hw_lock->lock, - lock->flags); - - if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE) && - lock->context < 0) - return EINVAL; - - DRM_LOCK(dev); - for (;;) { - if (drm_lock_take(&dev->lock, lock->context)) { - dev->lock.file_priv = file_priv; - dev->lock.lock_time = jiffies; - atomic_inc(&dev->counts[_DRM_STAT_LOCKS]); - break; /* Got lock */ - } - - /* Contention */ - ret = DRM_LOCK_SLEEP(dev, &dev->lock.lock_queue, - PCATCH, "drmlk2", 0); - if (ret != 0) - break; - } - DRM_UNLOCK(dev); - - if (ret == ERESTART) - DRM_DEBUG("restarting syscall\n"); - else - DRM_DEBUG("%d %s\n", lock->context, - ret ? "interrupted" : "has lock"); - - if (ret != 0) - return ret; - - /* XXX: Add signal blocking here */ - - if (dev->driver->dma_quiescent != NULL && - (lock->flags & _DRM_LOCK_QUIESCENT)) - dev->driver->dma_quiescent(dev); - - return 0; -} - -int drm_unlock(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - struct drm_lock *lock = data; - - DRM_DEBUG("%d (pid %d) requests unlock (0x%08x), flags = 0x%08x\n", - lock->context, DRM_CURRENTPID, dev->lock.hw_lock->lock, - lock->flags); - - if (lock->context == DRM_KERNEL_CONTEXT) { - DRM_ERROR("Process %d using kernel context %d\n", - DRM_CURRENTPID, lock->context); - return EINVAL; - } - - atomic_inc(&dev->counts[_DRM_STAT_UNLOCKS]); - - DRM_LOCK(dev); - drm_lock_transfer(&dev->lock, DRM_KERNEL_CONTEXT); - - if (drm_lock_free(&dev->lock, DRM_KERNEL_CONTEXT)) { - DRM_ERROR("\n"); - } - DRM_UNLOCK(dev); - - return 0; -} - -int drm_lock_take(struct drm_lock_data *lock_data, unsigned int context) -{ - volatile unsigned int *lock = &lock_data->hw_lock->lock; - unsigned int old, new; - - do { - old = *lock; - if (old & _DRM_LOCK_HELD) - new = old | _DRM_LOCK_CONT; - else - new = context | _DRM_LOCK_HELD; - } while (!atomic_cmpset_int(lock, old, new)); - - if (_DRM_LOCKING_CONTEXT(old) == context) { - if (old & _DRM_LOCK_HELD) { - if (context != DRM_KERNEL_CONTEXT) { - DRM_ERROR("%d holds heavyweight lock\n", - context); - } - return 0; - } - } - if (new == (context | _DRM_LOCK_HELD)) { - /* Have lock */ - return 1; - } - return 0; -} - -/* This takes a lock forcibly and hands it to context. Should ONLY be used - inside *_unlock to give lock to kernel before calling *_dma_schedule. */ -int drm_lock_transfer(struct drm_lock_data *lock_data, unsigned int context) -{ - volatile unsigned int *lock = &lock_data->hw_lock->lock; - unsigned int old, new; - - lock_data->file_priv = NULL; - do { - old = *lock; - new = context | _DRM_LOCK_HELD; - } while (!atomic_cmpset_int(lock, old, new)); - - return 1; -} - -int drm_lock_free(struct drm_lock_data *lock_data, unsigned int context) -{ - volatile unsigned int *lock = &lock_data->hw_lock->lock; - unsigned int old, new; - - lock_data->file_priv = NULL; - do { - old = *lock; - new = 0; - } while (!atomic_cmpset_int(lock, old, new)); - - if (_DRM_LOCK_IS_HELD(old) && _DRM_LOCKING_CONTEXT(old) != context) { - DRM_ERROR("%d freed heavyweight lock held by %d\n", - context, _DRM_LOCKING_CONTEXT(old)); - return 1; - } - DRM_WAKEUP_INT((void *)&lock_data->lock_queue); - return 0; -} diff --git a/sys/dev/drm2/drm_memory.c b/sys/dev/drm2/drm_memory.c deleted file mode 100644 index 1f1acb7f65..0000000000 --- a/sys/dev/drm2/drm_memory.c +++ /dev/null @@ -1,121 +0,0 @@ -/*- - *Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. - * - * Portions of this software were developed by Konstantin Belousov - * under sponsorship from the FreeBSD Foundation. - * - * 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS 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. - * - * Authors: - * Rickard E. (Rik) Faith - * Gareth Hughes - * - * $FreeBSD: src/sys/dev/drm2/drm_memory.c,v 1.1 2012/05/22 11:07:44 kib Exp $ - */ - -/** @file drm_memory.c - * Wrappers for kernel memory allocation routines, and MTRR management support. - * - * This file previously implemented a memory consumption tracking system using - * the "area" argument for various different types of allocations, but that - * has been stripped out for now. - */ - -#include - -MALLOC_DEFINE(DRM_MEM_DMA, "drm_dma", "DRM DMA Data Structures"); -MALLOC_DEFINE(DRM_MEM_SAREA, "drm_sarea", "DRM SAREA Data Structures"); -MALLOC_DEFINE(DRM_MEM_DRIVER, "drm_driver", "DRM DRIVER Data Structures"); -MALLOC_DEFINE(DRM_MEM_MAGIC, "drm_magic", "DRM MAGIC Data Structures"); -MALLOC_DEFINE(DRM_MEM_MAPS, "drm_maps", "DRM MAP Data Structures"); -MALLOC_DEFINE(DRM_MEM_BUFS, "drm_bufs", "DRM BUFFER Data Structures"); -MALLOC_DEFINE(DRM_MEM_SEGS, "drm_segs", "DRM SEGMENTS Data Structures"); -MALLOC_DEFINE(DRM_MEM_PAGES, "drm_pages", "DRM PAGES Data Structures"); -MALLOC_DEFINE(DRM_MEM_FILES, "drm_files", "DRM FILE Data Structures"); -MALLOC_DEFINE(DRM_MEM_BUFLISTS, "drm_buflists", "DRM BUFLISTS Data Structures"); -MALLOC_DEFINE(DRM_MEM_AGPLISTS, "drm_agplists", "DRM AGPLISTS Data Structures"); -MALLOC_DEFINE(DRM_MEM_CTXBITMAP, "drm_ctxbitmap", - "DRM CTXBITMAP Data Structures"); -MALLOC_DEFINE(DRM_MEM_SGLISTS, "drm_sglists", "DRM SGLISTS Data Structures"); -MALLOC_DEFINE(DRM_MEM_DRAWABLE, "drm_drawable", "DRM DRAWABLE Data Structures"); -MALLOC_DEFINE(DRM_MEM_MM, "drm_sman", "DRM MEMORY MANAGER Data Structures"); -MALLOC_DEFINE(DRM_MEM_HASHTAB, "drm_hashtab", "DRM HASHTABLE Data Structures"); -MALLOC_DEFINE(DRM_MEM_KMS, "drm_kms", "DRM KMS Data Structures"); - -void drm_mem_init(void) -{ -} - -void drm_mem_uninit(void) -{ -} - -void *drm_ioremap_wc(struct drm_device *dev, drm_local_map_t *map) -{ - return pmap_mapdev_attr(map->offset, map->size, VM_MEMATTR_WRITE_COMBINING); -} - -void *drm_ioremap(struct drm_device *dev, drm_local_map_t *map) -{ - return pmap_mapdev(map->offset, map->size); -} - -void drm_ioremapfree(drm_local_map_t *map) -{ - pmap_unmapdev((vm_offset_t) map->virtual, map->size); -} - -int -drm_mtrr_add(unsigned long offset, size_t size, int flags) -{ - int act; - struct mem_range_desc mrdesc; - - mrdesc.mr_base = offset; - mrdesc.mr_len = size; - mrdesc.mr_flags = flags; - act = MEMRANGE_SET_UPDATE; - strlcpy(mrdesc.mr_owner, "drm", sizeof(mrdesc.mr_owner)); - return mem_range_attr_set(&mrdesc, &act); -} - -int -drm_mtrr_del(int __unused handle, unsigned long offset, size_t size, int flags) -{ - int act; - struct mem_range_desc mrdesc; - - mrdesc.mr_base = offset; - mrdesc.mr_len = size; - mrdesc.mr_flags = flags; - act = MEMRANGE_SET_REMOVE; - strlcpy(mrdesc.mr_owner, "drm", sizeof(mrdesc.mr_owner)); - return mem_range_attr_set(&mrdesc, &act); -} - -void -drm_clflush_pages(vm_page_t *pages, unsigned long num_pages) -{ - - pmap_invalidate_cache_pages(pages, num_pages); -} diff --git a/sys/dev/drm2/drm_mm.c b/sys/dev/drm2/drm_mm.c deleted file mode 100644 index 5ff1b5e484..0000000000 --- a/sys/dev/drm2/drm_mm.c +++ /dev/null @@ -1,597 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA. - * 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 - * THE COPYRIGHT HOLDERS, AUTHORS 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. - * - * $FreeBSD: head/sys/dev/drm2/drm_mm.c 247833 2013-03-05 09:07:58Z kib $ - **************************************************************************/ - -/* - * Generic simple memory manager implementation. Intended to be used as a base - * class implementation for more advanced memory managers. - * - * Note that the algorithm used is quite simple and there might be substantial - * performance gains if a smarter free list is implemented. Currently it is just an - * unordered stack of free regions. This could easily be improved if an RB-tree - * is used instead. At least if we expect heavy fragmentation. - * - * Aligned allocations can also see improvement. - * - * Authors: - * Thomas Hellström - */ - -#include -#include - -#define MM_UNUSED_TARGET 4 - -static struct drm_mm_node *drm_mm_kmalloc(struct drm_mm *mm, int atomic) -{ - struct drm_mm_node *child; - - child = kmalloc(sizeof(*child), DRM_MEM_MM, M_ZERO | - (atomic ? M_NOWAIT : M_WAITOK)); - - if (unlikely(child == NULL)) { - spin_lock(&mm->unused_spin); - if (list_empty(&mm->unused_nodes)) - child = NULL; - else { - child = - list_entry(mm->unused_nodes.next, - struct drm_mm_node, node_list); - list_del(&child->node_list); - --mm->num_unused; - } - spin_unlock(&mm->unused_spin); - } - return child; -} - -int drm_mm_pre_get(struct drm_mm *mm) -{ - struct drm_mm_node *node; - - spin_lock(&mm->unused_spin); - while (mm->num_unused < MM_UNUSED_TARGET) { - spin_unlock(&mm->unused_spin); - node = kmalloc(sizeof(*node), DRM_MEM_MM, M_WAITOK); - spin_lock(&mm->unused_spin); - - if (unlikely(node == NULL)) { - int ret = (mm->num_unused < 2) ? -ENOMEM : 0; - spin_unlock(&mm->unused_spin); - return ret; - } - ++mm->num_unused; - list_add_tail(&node->node_list, &mm->unused_nodes); - } - spin_unlock(&mm->unused_spin); - return 0; -} - -static inline unsigned long drm_mm_hole_node_start(struct drm_mm_node *hole_node) -{ - return hole_node->start + hole_node->size; -} - -static inline unsigned long drm_mm_hole_node_end(struct drm_mm_node *hole_node) -{ - struct drm_mm_node *next_node = - list_entry(hole_node->node_list.next, struct drm_mm_node, - node_list); - - return next_node->start; -} - -static void drm_mm_insert_helper(struct drm_mm_node *hole_node, - struct drm_mm_node *node, - unsigned long size, unsigned alignment) -{ - struct drm_mm *mm = hole_node->mm; - unsigned long tmp = 0, wasted = 0; - unsigned long hole_start = drm_mm_hole_node_start(hole_node); - unsigned long hole_end = drm_mm_hole_node_end(hole_node); - - KASSERT(hole_node->hole_follows && !node->allocated, ("hole_node")); - - if (alignment) - tmp = hole_start % alignment; - - if (!tmp) { - hole_node->hole_follows = 0; - list_del_init(&hole_node->hole_stack); - } else - wasted = alignment - tmp; - - node->start = hole_start + wasted; - node->size = size; - node->mm = mm; - node->allocated = 1; - - INIT_LIST_HEAD(&node->hole_stack); - list_add(&node->node_list, &hole_node->node_list); - - KASSERT(node->start + node->size <= hole_end, ("hole pos")); - - if (node->start + node->size < hole_end) { - list_add(&node->hole_stack, &mm->hole_stack); - node->hole_follows = 1; - } else { - node->hole_follows = 0; - } -} - -struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *hole_node, - unsigned long size, - unsigned alignment, - int atomic) -{ - struct drm_mm_node *node; - - node = drm_mm_kmalloc(hole_node->mm, atomic); - if (unlikely(node == NULL)) - return NULL; - - drm_mm_insert_helper(hole_node, node, size, alignment); - - return node; -} - -int drm_mm_insert_node(struct drm_mm *mm, struct drm_mm_node *node, - unsigned long size, unsigned alignment) -{ - struct drm_mm_node *hole_node; - - hole_node = drm_mm_search_free(mm, size, alignment, 0); - if (!hole_node) - return -ENOSPC; - - drm_mm_insert_helper(hole_node, node, size, alignment); - - return 0; -} - -static void drm_mm_insert_helper_range(struct drm_mm_node *hole_node, - struct drm_mm_node *node, - unsigned long size, unsigned alignment, - unsigned long start, unsigned long end) -{ - struct drm_mm *mm = hole_node->mm; - unsigned long tmp = 0, wasted = 0; - unsigned long hole_start = drm_mm_hole_node_start(hole_node); - unsigned long hole_end = drm_mm_hole_node_end(hole_node); - - KASSERT(hole_node->hole_follows && !node->allocated, ("hole_node")); - - if (hole_start < start) - wasted += start - hole_start; - if (alignment) - tmp = (hole_start + wasted) % alignment; - - if (tmp) - wasted += alignment - tmp; - - if (!wasted) { - hole_node->hole_follows = 0; - list_del_init(&hole_node->hole_stack); - } - - node->start = hole_start + wasted; - node->size = size; - node->mm = mm; - node->allocated = 1; - - INIT_LIST_HEAD(&node->hole_stack); - list_add(&node->node_list, &hole_node->node_list); - - KASSERT(node->start + node->size <= hole_end, ("hole_end")); - KASSERT(node->start + node->size <= end, ("end")); - - if (node->start + node->size < hole_end) { - list_add(&node->hole_stack, &mm->hole_stack); - node->hole_follows = 1; - } else { - node->hole_follows = 0; - } -} - -struct drm_mm_node *drm_mm_get_block_range_generic(struct drm_mm_node *hole_node, - unsigned long size, - unsigned alignment, - unsigned long start, - unsigned long end, - int atomic) -{ - struct drm_mm_node *node; - - node = drm_mm_kmalloc(hole_node->mm, atomic); - if (unlikely(node == NULL)) - return NULL; - - drm_mm_insert_helper_range(hole_node, node, size, alignment, - start, end); - - return node; -} - -int drm_mm_insert_node_in_range(struct drm_mm *mm, struct drm_mm_node *node, - unsigned long size, unsigned alignment, - unsigned long start, unsigned long end) -{ - struct drm_mm_node *hole_node; - - hole_node = drm_mm_search_free_in_range(mm, size, alignment, - start, end, 0); - if (!hole_node) - return -ENOSPC; - - drm_mm_insert_helper_range(hole_node, node, size, alignment, - start, end); - - return 0; -} - -void drm_mm_remove_node(struct drm_mm_node *node) -{ - struct drm_mm *mm = node->mm; - struct drm_mm_node *prev_node; - - KASSERT(!node->scanned_block && !node->scanned_prev_free - && !node->scanned_next_free, ("node")); - - prev_node = - list_entry(node->node_list.prev, struct drm_mm_node, node_list); - - if (node->hole_follows) { - KASSERT(drm_mm_hole_node_start(node) - != drm_mm_hole_node_end(node), ("hole_follows")); - list_del(&node->hole_stack); - } else - KASSERT(drm_mm_hole_node_start(node) - == drm_mm_hole_node_end(node), ("!hole_follows")); - - if (!prev_node->hole_follows) { - prev_node->hole_follows = 1; - list_add(&prev_node->hole_stack, &mm->hole_stack); - } else - list_move(&prev_node->hole_stack, &mm->hole_stack); - - list_del(&node->node_list); - node->allocated = 0; -} - -/* - * Put a block. Merge with the previous and / or next block if they are free. - * Otherwise add to the free stack. - */ - -void drm_mm_put_block(struct drm_mm_node *node) -{ - struct drm_mm *mm = node->mm; - - drm_mm_remove_node(node); - - spin_lock(&mm->unused_spin); - if (mm->num_unused < MM_UNUSED_TARGET) { - list_add(&node->node_list, &mm->unused_nodes); - ++mm->num_unused; - } else - drm_free(node, DRM_MEM_MM); - spin_unlock(&mm->unused_spin); -} - -static int check_free_hole(unsigned long start, unsigned long end, - unsigned long size, unsigned alignment) -{ - unsigned wasted = 0; - - if (end - start < size) - return 0; - - if (alignment) { - unsigned tmp = start % alignment; - if (tmp) - wasted = alignment - tmp; - } - - if (end >= start + size + wasted) { - return 1; - } - - return 0; -} - - -struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm, - unsigned long size, - unsigned alignment, int best_match) -{ - struct drm_mm_node *entry; - struct drm_mm_node *best; - unsigned long best_size; - - best = NULL; - best_size = ~0UL; - - list_for_each_entry(entry, &mm->hole_stack, hole_stack) { - KASSERT(entry->hole_follows, ("hole_follows")); - if (!check_free_hole(drm_mm_hole_node_start(entry), - drm_mm_hole_node_end(entry), - size, alignment)) - continue; - - if (!best_match) - return entry; - - if (entry->size < best_size) { - best = entry; - best_size = entry->size; - } - } - - return best; -} - -struct drm_mm_node *drm_mm_search_free_in_range(const struct drm_mm *mm, - unsigned long size, - unsigned alignment, - unsigned long start, - unsigned long end, - int best_match) -{ - struct drm_mm_node *entry; - struct drm_mm_node *best; - unsigned long best_size; - - KASSERT(!mm->scanned_blocks, ("scanned")); - - best = NULL; - best_size = ~0UL; - - list_for_each_entry(entry, &mm->hole_stack, hole_stack) { - unsigned long adj_start = drm_mm_hole_node_start(entry) < start ? - start : drm_mm_hole_node_start(entry); - unsigned long adj_end = drm_mm_hole_node_end(entry) > end ? - end : drm_mm_hole_node_end(entry); - - KASSERT(entry->hole_follows, ("hole_follows")); - if (!check_free_hole(adj_start, adj_end, size, alignment)) - continue; - - if (!best_match) - return entry; - - if (entry->size < best_size) { - best = entry; - best_size = entry->size; - } - } - - return best; -} - -void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new) -{ - list_replace(&old->node_list, &new->node_list); - list_replace(&old->hole_stack, &new->hole_stack); - new->hole_follows = old->hole_follows; - new->mm = old->mm; - new->start = old->start; - new->size = old->size; - - old->allocated = 0; - new->allocated = 1; -} - -void drm_mm_init_scan(struct drm_mm *mm, unsigned long size, - unsigned alignment) -{ - mm->scan_alignment = alignment; - mm->scan_size = size; - mm->scanned_blocks = 0; - mm->scan_hit_start = 0; - mm->scan_hit_size = 0; - mm->scan_check_range = 0; - mm->prev_scanned_node = NULL; -} - -void drm_mm_init_scan_with_range(struct drm_mm *mm, unsigned long size, - unsigned alignment, - unsigned long start, - unsigned long end) -{ - mm->scan_alignment = alignment; - mm->scan_size = size; - mm->scanned_blocks = 0; - mm->scan_hit_start = 0; - mm->scan_hit_size = 0; - mm->scan_start = start; - mm->scan_end = end; - mm->scan_check_range = 1; - mm->prev_scanned_node = NULL; -} - -int drm_mm_scan_add_block(struct drm_mm_node *node) -{ - struct drm_mm *mm = node->mm; - struct drm_mm_node *prev_node; - unsigned long hole_start, hole_end; - unsigned long adj_start; - unsigned long adj_end; - - mm->scanned_blocks++; - - KASSERT(!node->scanned_block, ("node->scanned_block")); - node->scanned_block = 1; - - prev_node = list_entry(node->node_list.prev, struct drm_mm_node, - node_list); - - node->scanned_preceeds_hole = prev_node->hole_follows; - prev_node->hole_follows = 1; - list_del(&node->node_list); - node->node_list.prev = &prev_node->node_list; - node->node_list.next = &mm->prev_scanned_node->node_list; - mm->prev_scanned_node = node; - - hole_start = drm_mm_hole_node_start(prev_node); - hole_end = drm_mm_hole_node_end(prev_node); - if (mm->scan_check_range) { - adj_start = hole_start < mm->scan_start ? - mm->scan_start : hole_start; - adj_end = hole_end > mm->scan_end ? - mm->scan_end : hole_end; - } else { - adj_start = hole_start; - adj_end = hole_end; - } - - if (check_free_hole(adj_start , adj_end, - mm->scan_size, mm->scan_alignment)) { - mm->scan_hit_start = hole_start; - mm->scan_hit_size = hole_end; - - return 1; - } - - return 0; -} - -int drm_mm_scan_remove_block(struct drm_mm_node *node) -{ - struct drm_mm *mm = node->mm; - struct drm_mm_node *prev_node; - - mm->scanned_blocks--; - - KASSERT(node->scanned_block, ("scanned_block")); - node->scanned_block = 0; - - prev_node = list_entry(node->node_list.prev, struct drm_mm_node, - node_list); - - prev_node->hole_follows = node->scanned_preceeds_hole; - INIT_LIST_HEAD(&node->node_list); - list_add(&node->node_list, &prev_node->node_list); - - /* Only need to check for containement because start&size for the - * complete resulting free block (not just the desired part) is - * stored. */ - if (node->start >= mm->scan_hit_start && - node->start + node->size - <= mm->scan_hit_start + mm->scan_hit_size) { - return 1; - } - - return 0; -} - -int drm_mm_clean(struct drm_mm * mm) -{ - struct list_head *head = &mm->head_node.node_list; - - return (head->next->next == head); -} - -int drm_mm_init(struct drm_mm * mm, unsigned long start, unsigned long size) -{ - INIT_LIST_HEAD(&mm->hole_stack); - INIT_LIST_HEAD(&mm->unused_nodes); - mm->num_unused = 0; - mm->scanned_blocks = 0; - spin_init(&mm->unused_spin); - - INIT_LIST_HEAD(&mm->head_node.node_list); - INIT_LIST_HEAD(&mm->head_node.hole_stack); - mm->head_node.hole_follows = 1; - mm->head_node.scanned_block = 0; - mm->head_node.scanned_prev_free = 0; - mm->head_node.scanned_next_free = 0; - mm->head_node.mm = mm; - mm->head_node.start = start + size; - mm->head_node.size = start - mm->head_node.start; - list_add_tail(&mm->head_node.hole_stack, &mm->hole_stack); - - return 0; -} - -void drm_mm_takedown(struct drm_mm * mm) -{ - struct drm_mm_node *entry, *next; - - if (!list_empty(&mm->head_node.node_list)) { - DRM_ERROR("Memory manager not clean. Delaying takedown\n"); - return; - } - - spin_lock(&mm->unused_spin); - list_for_each_entry_safe(entry, next, &mm->unused_nodes, node_list) { - list_del(&entry->node_list); - drm_free(entry, DRM_MEM_MM); - --mm->num_unused; - } - spin_unlock(&mm->unused_spin); - - spin_uninit(&mm->unused_spin); - - KASSERT(mm->num_unused == 0, ("num_unused != 0")); -} - -void drm_mm_debug_table(struct drm_mm *mm, const char *prefix) -{ - struct drm_mm_node *entry; - unsigned long total_used = 0, total_free = 0, total = 0; - unsigned long hole_start, hole_end, hole_size; - - hole_start = drm_mm_hole_node_start(&mm->head_node); - hole_end = drm_mm_hole_node_end(&mm->head_node); - hole_size = hole_end - hole_start; - if (hole_size) - kprintf("%s 0x%08lx-0x%08lx: %8lu: free\n", - prefix, hole_start, hole_end, - hole_size); - total_free += hole_size; - - drm_mm_for_each_node(entry, mm) { - kprintf("%s 0x%08lx-0x%08lx: %8lu: used\n", - prefix, entry->start, entry->start + entry->size, - entry->size); - total_used += entry->size; - - if (entry->hole_follows) { - hole_start = drm_mm_hole_node_start(entry); - hole_end = drm_mm_hole_node_end(entry); - hole_size = hole_end - hole_start; - kprintf("%s 0x%08lx-0x%08lx: %8lu: free\n", - prefix, hole_start, hole_end, - hole_size); - total_free += hole_size; - } - } - total = total_free + total_used; - - kprintf("%s total: %lu, used %lu free %lu\n", prefix, total, - total_used, total_free); -} diff --git a/sys/dev/drm2/drm_mm.h b/sys/dev/drm2/drm_mm.h deleted file mode 100644 index cbdfe11186..0000000000 --- a/sys/dev/drm2/drm_mm.h +++ /dev/null @@ -1,186 +0,0 @@ -/************************************************************************** - * - * Copyright 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX. USA. - * 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 - * THE COPYRIGHT HOLDERS, AUTHORS 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. - * - * - * $FreeBSD: head/sys/dev/drm2/drm_mm.h 247833 2013-03-05 09:07:58Z kib $ - **************************************************************************/ - -/* - * Authors: - * Thomas Hellstrom - */ - -#ifndef _DRM_MM_H_ -#define _DRM_MM_H_ - -#include -#include - -struct drm_mm_node { - struct list_head node_list; - struct list_head hole_stack; - unsigned hole_follows : 1; - unsigned scanned_block : 1; - unsigned scanned_prev_free : 1; - unsigned scanned_next_free : 1; - unsigned scanned_preceeds_hole : 1; - unsigned allocated : 1; - unsigned long start; - unsigned long size; - struct drm_mm *mm; - void *private; -}; - -struct drm_mm { - struct list_head hole_stack; - struct drm_mm_node head_node; - struct list_head unused_nodes; - int num_unused; - struct spinlock unused_spin; - unsigned int scan_check_range : 1; - unsigned scan_alignment; - unsigned long scan_size; - unsigned long scan_hit_start; - unsigned scan_hit_size; - unsigned scanned_blocks; - unsigned long scan_start; - unsigned long scan_end; - struct drm_mm_node *prev_scanned_node; -}; - -static inline bool drm_mm_node_allocated(struct drm_mm_node *node) -{ - return node->allocated; -} - -static inline bool drm_mm_initialized(struct drm_mm *mm) -{ - return (mm->hole_stack.next != NULL); -} -#define drm_mm_for_each_node(entry, mm) list_for_each_entry(entry, \ - &(mm)->head_node.node_list, \ - node_list) -#define drm_mm_for_each_scanned_node_reverse(entry, n, mm) \ - for (entry = (mm)->prev_scanned_node, \ - next = entry ? list_entry(entry->node_list.next, \ - struct drm_mm_node, node_list) : NULL; \ - entry != NULL; entry = next, \ - next = entry ? list_entry(entry->node_list.next, \ - struct drm_mm_node, node_list) : NULL) - -/* - * Basic range manager support (drm_mm.c) - */ -extern struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *node, - unsigned long size, - unsigned alignment, - int atomic); -extern struct drm_mm_node *drm_mm_get_block_range_generic( - struct drm_mm_node *node, - unsigned long size, - unsigned alignment, - unsigned long start, - unsigned long end, - int atomic); -static inline struct drm_mm_node *drm_mm_get_block(struct drm_mm_node *parent, - unsigned long size, - unsigned alignment) -{ - return drm_mm_get_block_generic(parent, size, alignment, 0); -} -static inline struct drm_mm_node *drm_mm_get_block_atomic(struct drm_mm_node *parent, - unsigned long size, - unsigned alignment) -{ - return drm_mm_get_block_generic(parent, size, alignment, 1); -} -static inline struct drm_mm_node *drm_mm_get_block_range( - struct drm_mm_node *parent, - unsigned long size, - unsigned alignment, - unsigned long start, - unsigned long end) -{ - return drm_mm_get_block_range_generic(parent, size, alignment, - start, end, 0); -} -static inline struct drm_mm_node *drm_mm_get_block_atomic_range( - struct drm_mm_node *parent, - unsigned long size, - unsigned alignment, - unsigned long start, - unsigned long end) -{ - return drm_mm_get_block_range_generic(parent, size, alignment, - start, end, 1); -} -extern int drm_mm_insert_node(struct drm_mm *mm, struct drm_mm_node *node, - unsigned long size, unsigned alignment); -extern int drm_mm_insert_node_in_range(struct drm_mm *mm, - struct drm_mm_node *node, - unsigned long size, unsigned alignment, - unsigned long start, unsigned long end); -extern void drm_mm_put_block(struct drm_mm_node *cur); -extern void drm_mm_remove_node(struct drm_mm_node *node); -extern void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new); -extern struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm, - unsigned long size, - unsigned alignment, - int best_match); -extern struct drm_mm_node *drm_mm_search_free_in_range( - const struct drm_mm *mm, - unsigned long size, - unsigned alignment, - unsigned long start, - unsigned long end, - int best_match); -extern int drm_mm_init(struct drm_mm *mm, unsigned long start, - unsigned long size); -extern void drm_mm_takedown(struct drm_mm *mm); -extern int drm_mm_clean(struct drm_mm *mm); -extern unsigned long drm_mm_tail_space(struct drm_mm *mm); -extern int drm_mm_remove_space_from_tail(struct drm_mm *mm, - unsigned long size); -extern int drm_mm_add_space_to_tail(struct drm_mm *mm, - unsigned long size, int atomic); -extern int drm_mm_pre_get(struct drm_mm *mm); - -static inline struct drm_mm *drm_get_mm(struct drm_mm_node *block) -{ - return block->mm; -} - -void drm_mm_init_scan(struct drm_mm *mm, unsigned long size, - unsigned alignment); -void drm_mm_init_scan_with_range(struct drm_mm *mm, unsigned long size, - unsigned alignment, - unsigned long start, - unsigned long end); -int drm_mm_scan_add_block(struct drm_mm_node *node); -int drm_mm_scan_remove_block(struct drm_mm_node *node); - -void drm_mm_debug_table(struct drm_mm *mm, const char *prefix); - -#endif diff --git a/sys/dev/drm2/drm_pci.c b/sys/dev/drm2/drm_pci.c deleted file mode 100644 index 700c99a39c..0000000000 --- a/sys/dev/drm2/drm_pci.c +++ /dev/null @@ -1,125 +0,0 @@ -/*- - * Copyright 2003 Eric Anholt. - * 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, 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHOR 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. - * - * $FreeBSD: src/sys/dev/drm2/drm_pci.c,v 1.1 2012/05/22 11:07:44 kib Exp $ - */ - -/** - * \file drm_pci.h - * \brief PCI consistent, DMA-accessible memory allocation. - * - * \author Eric Anholt - */ - -#include - -/**********************************************************************/ -/** \name PCI memory */ -/*@{*/ - -static void -drm_pci_busdma_callback(void *arg, bus_dma_segment_t *segs, int nsegs, int error) -{ - drm_dma_handle_t *dmah = arg; - - if (error != 0) - return; - - KASSERT(nsegs == 1, ("drm_pci_busdma_callback: bad dma segment count")); - dmah->busaddr = segs[0].ds_addr; -} - -/** - * \brief Allocate a physically contiguous DMA-accessible consistent - * memory block. - */ -drm_dma_handle_t * -drm_pci_alloc(struct drm_device *dev, size_t size, - size_t align, dma_addr_t maxaddr) -{ - drm_dma_handle_t *dmah; - int ret; - - /* Need power-of-two alignment, so fail the allocation if it isn't. */ - if ((align & (align - 1)) != 0) { - DRM_ERROR("drm_pci_alloc with non-power-of-two alignment %d\n", - (int)align); - return NULL; - } - - dmah = kmalloc(sizeof(drm_dma_handle_t), DRM_MEM_DMA, M_ZERO | M_NOWAIT); - if (dmah == NULL) - return NULL; - - /* Make sure we aren't holding mutexes here */ -/* FIXME: Is it ok to remove the next 3 lines ? */ -/* mtx_assert(&dev->dma_lock, MA_NOTOWNED); - if (mtx_owned(&dev->dma_lock)) - DRM_ERROR("called while holding dma_lock\n"); */ - - ret = bus_dma_tag_create(NULL, align, 0, /* tag, align, boundary */ - maxaddr, BUS_SPACE_MAXADDR, /* lowaddr, highaddr */ - NULL, NULL, /* filtfunc, filtfuncargs */ - size, 1, size, /* maxsize, nsegs, maxsegsize */ - 0, /* flags */ - &dmah->tag); - if (ret != 0) { - drm_free(dmah, DRM_MEM_DMA); - return NULL; - } - - ret = bus_dmamem_alloc(dmah->tag, &dmah->vaddr, - BUS_DMA_WAITOK | BUS_DMA_ZERO | BUS_DMA_NOCACHE, &dmah->map); - if (ret != 0) { - bus_dma_tag_destroy(dmah->tag); - drm_free(dmah, DRM_MEM_DMA); - return NULL; - } - - ret = bus_dmamap_load(dmah->tag, dmah->map, dmah->vaddr, size, - drm_pci_busdma_callback, dmah, BUS_DMA_NOWAIT); - if (ret != 0) { - bus_dmamem_free(dmah->tag, dmah->vaddr, dmah->map); - bus_dma_tag_destroy(dmah->tag); - drm_free(dmah, DRM_MEM_DMA); - return NULL; - } - - return dmah; -} - -/** - * \brief Free a DMA-accessible consistent memory block. - */ -void -drm_pci_free(struct drm_device *dev, drm_dma_handle_t *dmah) -{ - if (dmah == NULL) - return; - - bus_dmamem_free(dmah->tag, dmah->vaddr, dmah->map); - bus_dma_tag_destroy(dmah->tag); - - drm_free(dmah, DRM_MEM_DMA); -} - -/*@}*/ diff --git a/sys/dev/drm2/drm_pciids.h b/sys/dev/drm2/drm_pciids.h deleted file mode 100644 index 810172611c..0000000000 --- a/sys/dev/drm2/drm_pciids.h +++ /dev/null @@ -1,770 +0,0 @@ -/* - * $FreeBSD: src/sys/dev/drm2/drm_pciids.h,v 1.1 2012/05/22 11:07:44 kib Exp $ - */ -/* - This file is auto-generated from the drm_pciids.txt in the DRM CVS - Please contact dri-devel@lists.sf.net to add new cards to this list -*/ -#define radeon_PCI_IDS \ - {0x1002, 0x3150, CHIP_RV380|RADEON_IS_MOBILITY, "ATI Radeon Mobility X600 M24"}, \ - {0x1002, 0x3152, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Radeon Mobility X300 M24"}, \ - {0x1002, 0x3154, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI FireGL M24 GL"}, \ - {0x1002, 0x3E50, CHIP_RV380|RADEON_NEW_MEMMAP, "ATI Radeon RV380 X600"}, \ - {0x1002, 0x3E54, CHIP_RV380|RADEON_NEW_MEMMAP, "ATI FireGL V3200 RV380"}, \ - {0x1002, 0x4136, CHIP_RS100|RADEON_IS_IGP, "ATI Radeon RS100 IGP 320"}, \ - {0x1002, 0x4137, CHIP_RS200|RADEON_IS_IGP, "ATI Radeon RS200 IGP 340"}, \ - {0x1002, 0x4144, CHIP_R300, "ATI Radeon AD 9500"}, \ - {0x1002, 0x4145, CHIP_R300, "ATI Radeon AE 9700 Pro"}, \ - {0x1002, 0x4146, CHIP_R300, "ATI Radeon AF R300 9600TX"}, \ - {0x1002, 0x4147, CHIP_R300, "ATI FireGL AG Z1"}, \ - {0x1002, 0x4148, CHIP_R350, "ATI Radeon AH 9800 SE"}, \ - {0x1002, 0x4149, CHIP_R350, "ATI Radeon AI 9800"}, \ - {0x1002, 0x414A, CHIP_R350, "ATI Radeon AJ 9800"}, \ - {0x1002, 0x414B, CHIP_R350, "ATI FireGL AK X2"}, \ - {0x1002, 0x4150, CHIP_RV350, "ATI Radeon AP 9600"}, \ - {0x1002, 0x4151, CHIP_RV350, "ATI Radeon AQ 9600 SE"}, \ - {0x1002, 0x4152, CHIP_RV350, "ATI Radeon AR 9600 XT"}, \ - {0x1002, 0x4153, CHIP_RV350, "ATI Radeon AS 9550"}, \ - {0x1002, 0x4154, CHIP_RV350, "ATI FireGL AT T2"}, \ - {0x1002, 0x4155, CHIP_RV350, "ATI Radeon 9650"}, \ - {0x1002, 0x4156, CHIP_RV350, "ATI FireGL AV RV360 T2"}, \ - {0x1002, 0x4237, CHIP_RS200|RADEON_IS_IGP, "ATI Radeon RS250 IGP"}, \ - {0x1002, 0x4242, CHIP_R200, "ATI Radeon BB R200 AIW 8500DV"}, \ - {0x1002, 0x4243, CHIP_R200, "ATI Radeon BC R200"}, \ - {0x1002, 0x4336, CHIP_RS100|RADEON_IS_IGP|RADEON_IS_MOBILITY, "ATI Radeon RS100 Mobility U1"}, \ - {0x1002, 0x4337, CHIP_RS200|RADEON_IS_IGP|RADEON_IS_MOBILITY, "ATI Radeon RS200 Mobility IGP 340M"}, \ - {0x1002, 0x4437, CHIP_RS200|RADEON_IS_IGP|RADEON_IS_MOBILITY, "ATI Radeon RS250 Mobility IGP"}, \ - {0x1002, 0x4966, CHIP_RV250, "ATI Radeon If RV250 9000"}, \ - {0x1002, 0x4967, CHIP_RV250, "ATI Radeon Ig RV250 9000"}, \ - {0x1002, 0x4A48, CHIP_R420|RADEON_NEW_MEMMAP, "ATI Radeon JH R420 X800"}, \ - {0x1002, 0x4A49, CHIP_R420|RADEON_NEW_MEMMAP, "ATI Radeon JI R420 X800 Pro"}, \ - {0x1002, 0x4A4A, CHIP_R420|RADEON_NEW_MEMMAP, "ATI Radeon JJ R420 X800 SE"}, \ - {0x1002, 0x4A4B, CHIP_R420|RADEON_NEW_MEMMAP, "ATI Radeon JK R420 X800 XT"}, \ - {0x1002, 0x4A4C, CHIP_R420|RADEON_NEW_MEMMAP, "ATI Radeon JL R420 X800"}, \ - {0x1002, 0x4A4D, CHIP_R420|RADEON_NEW_MEMMAP, "ATI FireGL JM X3-256"}, \ - {0x1002, 0x4A4E, CHIP_R420|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Radeon JN R420 Mobility M18"}, \ - {0x1002, 0x4A4F, CHIP_R420|RADEON_NEW_MEMMAP, "ATI Radeon JO R420 X800 SE"}, \ - {0x1002, 0x4A50, CHIP_R420|RADEON_NEW_MEMMAP, "ATI Radeon JP R420 X800 XT PE"}, \ - {0x1002, 0x4A54, CHIP_R420|RADEON_NEW_MEMMAP, "ATI Radeon JT R420 AIW X800 VE"}, \ - {0x1002, 0x4B49, CHIP_R420|RADEON_NEW_MEMMAP, "ATI Radeon R481 X850 XT"}, \ - {0x1002, 0x4B4A, CHIP_R420|RADEON_NEW_MEMMAP, "ATI Radeon R481 X850 SE"}, \ - {0x1002, 0x4B4B, CHIP_R420|RADEON_NEW_MEMMAP, "ATI Radeon R481 X850 Pro"}, \ - {0x1002, 0x4B4C, CHIP_R420|RADEON_NEW_MEMMAP, "ATI Radeon R481 X850 XT PE"}, \ - {0x1002, 0x4C57, CHIP_RV200|RADEON_IS_MOBILITY, "ATI Radeon LW RV200 Mobility 7500 M7"}, \ - {0x1002, 0x4C58, CHIP_RV200|RADEON_IS_MOBILITY, "ATI Radeon LX RV200 Mobility FireGL 7800 M7"}, \ - {0x1002, 0x4C59, CHIP_RV100|RADEON_IS_MOBILITY, "ATI Radeon LY RV100 Mobility M6"}, \ - {0x1002, 0x4C5A, CHIP_RV100|RADEON_IS_MOBILITY, "ATI Radeon LZ RV100 Mobility M6"}, \ - {0x1002, 0x4C64, CHIP_RV250|RADEON_IS_MOBILITY, "ATI Radeon Ld RV250 Mobility 9000 M9"}, \ - {0x1002, 0x4C66, CHIP_RV250, "ATI Radeon Lf RV250 Mobility 9000 M9 / FireMV 2400 PCI"}, \ - {0x1002, 0x4C67, CHIP_RV250|RADEON_IS_MOBILITY, "ATI Radeon Lg RV250 Mobility 9000 M9"}, \ - {0x1002, 0x4E44, CHIP_R300, "ATI Radeon ND R300 9700 Pro"}, \ - {0x1002, 0x4E45, CHIP_R300, "ATI Radeon NE R300 9500 Pro / 9700"}, \ - {0x1002, 0x4E46, CHIP_R300, "ATI Radeon NF R300 9600TX"}, \ - {0x1002, 0x4E47, CHIP_R300, "ATI Radeon NG R300 FireGL X1"}, \ - {0x1002, 0x4E48, CHIP_R350, "ATI Radeon NH R350 9800 Pro"}, \ - {0x1002, 0x4E49, CHIP_R350, "ATI Radeon NI R350 9800"}, \ - {0x1002, 0x4E4A, CHIP_R350, "ATI Radeon NJ R360 9800 XT"}, \ - {0x1002, 0x4E4B, CHIP_R350, "ATI FireGL NK X2"}, \ - {0x1002, 0x4E50, CHIP_RV350|RADEON_IS_MOBILITY, "ATI Radeon RV350 Mobility 9600 M10 NP"}, \ - {0x1002, 0x4E51, CHIP_RV350|RADEON_IS_MOBILITY, "ATI Radeon RV350 Mobility 9600 M10 NQ"}, \ - {0x1002, 0x4E52, CHIP_RV350|RADEON_IS_MOBILITY, "ATI Radeon RV350 Mobility 9600 M11 NR"}, \ - {0x1002, 0x4E53, CHIP_RV350|RADEON_IS_MOBILITY, "ATI Radeon RV350 Mobility 9600 M10 NS"}, \ - {0x1002, 0x4E54, CHIP_RV350|RADEON_IS_MOBILITY, "ATI FireGL T2/T2e"}, \ - {0x1002, 0x4E56, CHIP_RV350|RADEON_IS_MOBILITY, "ATI Radeon Mobility 9550"}, \ - {0x1002, 0x5144, CHIP_R100|RADEON_SINGLE_CRTC, "ATI Radeon QD R100"}, \ - {0x1002, 0x5145, CHIP_R100|RADEON_SINGLE_CRTC, "ATI Radeon QE R100"}, \ - {0x1002, 0x5146, CHIP_R100|RADEON_SINGLE_CRTC, "ATI Radeon QF R100"}, \ - {0x1002, 0x5147, CHIP_R100|RADEON_SINGLE_CRTC, "ATI Radeon QG R100"}, \ - {0x1002, 0x5148, CHIP_R200, "ATI Radeon QH R200 8500"}, \ - {0x1002, 0x514C, CHIP_R200, "ATI Radeon QL R200 8500 LE"}, \ - {0x1002, 0x514D, CHIP_R200, "ATI Radeon QM R200 9100"}, \ - {0x1002, 0x5157, CHIP_RV200, "ATI Radeon QW RV200 7500"}, \ - {0x1002, 0x5158, CHIP_RV200, "ATI Radeon QX RV200 7500"}, \ - {0x1002, 0x5159, CHIP_RV100, "ATI Radeon QY RV100 7000/VE"}, \ - {0x1002, 0x515A, CHIP_RV100, "ATI Radeon QZ RV100 7000/VE"}, \ - {0x1002, 0x515E, CHIP_RV100, "ATI ES1000 RN50"}, \ - {0x1002, 0x5460, CHIP_RV380|RADEON_IS_MOBILITY, "ATI Radeon Mobility X300 M22"}, \ - {0x1002, 0x5462, CHIP_RV380|RADEON_IS_MOBILITY, "ATI Radeon Mobility X600 SE M24C"}, \ - {0x1002, 0x5464, CHIP_RV380|RADEON_IS_MOBILITY, "ATI FireGL M22 GL 5464"}, \ - {0x1002, 0x5548, CHIP_R423|RADEON_NEW_MEMMAP, "ATI Radeon R423 X800"}, \ - {0x1002, 0x5549, CHIP_R423|RADEON_NEW_MEMMAP, "ATI Radeon R423 X800 Pro"}, \ - {0x1002, 0x554A, CHIP_R423|RADEON_NEW_MEMMAP, "ATI Radeon R423 X800 XT PE"}, \ - {0x1002, 0x554B, CHIP_R423|RADEON_NEW_MEMMAP, "ATI Radeon R423 X800 SE"}, \ - {0x1002, 0x554C, CHIP_R423|RADEON_NEW_MEMMAP, "ATI Radeon R430 X800 XTP"}, \ - {0x1002, 0x554D, CHIP_R423|RADEON_NEW_MEMMAP, "ATI Radeon R430 X800 XL"}, \ - {0x1002, 0x554E, CHIP_R423|RADEON_NEW_MEMMAP, "ATI Radeon R430 X800 SE"}, \ - {0x1002, 0x554F, CHIP_R423|RADEON_NEW_MEMMAP, "ATI Radeon R430 X800"}, \ - {0x1002, 0x5550, CHIP_R423|RADEON_NEW_MEMMAP, "ATI FireGL V7100 R423"}, \ - {0x1002, 0x5551, CHIP_R423|RADEON_NEW_MEMMAP, "ATI FireGL V5100 R423 UQ"}, \ - {0x1002, 0x5552, CHIP_R423|RADEON_NEW_MEMMAP, "ATI FireGL unknown R423 UR"}, \ - {0x1002, 0x5554, CHIP_R423|RADEON_NEW_MEMMAP, "ATI FireGL unknown R423 UT"}, \ - {0x1002, 0x564A, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility FireGL V5000 M26"}, \ - {0x1002, 0x564B, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility FireGL V5000 M26"}, \ - {0x1002, 0x564F, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Radeon Mobility X700 XL M26"}, \ - {0x1002, 0x5652, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Radeon Mobility X700 M26"}, \ - {0x1002, 0x5653, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Radeon Mobility X700 M26"}, \ - {0x1002, 0x5657, CHIP_RV410|RADEON_NEW_MEMMAP, "ATI Radeon X550XTX"}, \ - {0x1002, 0x5834, CHIP_RS300|RADEON_IS_IGP, "ATI Radeon RS300 9100 IGP"}, \ - {0x1002, 0x5835, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY, "ATI Radeon RS300 Mobility IGP"}, \ - {0x1002, 0x5954, CHIP_RS480|RADEON_IS_IGP|RADEON_IS_IGPGART, "ATI RS480 XPRESS 200G"}, \ - {0x1002, 0x5955, CHIP_RS480|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART, "ATI Radeon XPRESS 200M 5955"}, \ - {0x1002, 0x5974, CHIP_RS480|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART, "ATI Radeon RS482 XPRESS 200"}, \ - {0x1002, 0x5975, CHIP_RS480|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART, "ATI Radeon RS485 XPRESS 1100 IGP"}, \ - {0x1002, 0x5960, CHIP_RV280, "ATI Radeon RV280 9250"}, \ - {0x1002, 0x5961, CHIP_RV280, "ATI Radeon RV280 9200"}, \ - {0x1002, 0x5962, CHIP_RV280, "ATI Radeon RV280 9200"}, \ - {0x1002, 0x5964, CHIP_RV280, "ATI Radeon RV280 9200 SE"}, \ - {0x1002, 0x5965, CHIP_RV280, "ATI FireMV 2200 PCI"}, \ - {0x1002, 0x5969, CHIP_RV100, "ATI ES1000 RN50"}, \ - {0x1002, 0x5a41, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_IGPGART, "ATI Radeon XPRESS 200 5A41 (PCIE)"}, \ - {0x1002, 0x5a42, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART, "ATI Radeon XPRESS 200M 5A42 (PCIE)"}, \ - {0x1002, 0x5a61, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_IGPGART, "ATI Radeon RC410 XPRESS 200"}, \ - {0x1002, 0x5a62, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART, "ATI Radeon RC410 XPRESS 200M"}, \ - {0x1002, 0x5b60, CHIP_RV380|RADEON_NEW_MEMMAP, "ATI Radeon RV370 X300 SE"}, \ - {0x1002, 0x5b62, CHIP_RV380|RADEON_NEW_MEMMAP, "ATI Radeon RV370 X600 Pro"}, \ - {0x1002, 0x5b63, CHIP_RV380|RADEON_NEW_MEMMAP, "ATI Radeon RV370 X550"}, \ - {0x1002, 0x5b64, CHIP_RV380|RADEON_NEW_MEMMAP, "ATI FireGL V3100 (RV370) 5B64"}, \ - {0x1002, 0x5b65, CHIP_RV380|RADEON_NEW_MEMMAP, "ATI FireMV 2200 PCIE (RV370) 5B65"}, \ - {0x1002, 0x5c61, CHIP_RV280|RADEON_IS_MOBILITY, "ATI Radeon RV280 Mobility"}, \ - {0x1002, 0x5c63, CHIP_RV280|RADEON_IS_MOBILITY, "ATI Radeon RV280 Mobility"}, \ - {0x1002, 0x5d48, CHIP_R423|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon X800 XT M28"}, \ - {0x1002, 0x5d49, CHIP_R423|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility FireGL V5100 M28"}, \ - {0x1002, 0x5d4a, CHIP_R423|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon X800 M28"}, \ - {0x1002, 0x5d4c, CHIP_R423|RADEON_NEW_MEMMAP, "ATI Radeon R480 X850"}, \ - {0x1002, 0x5d4d, CHIP_R423|RADEON_NEW_MEMMAP, "ATI Radeon R480 X850 XT PE"}, \ - {0x1002, 0x5d4e, CHIP_R423|RADEON_NEW_MEMMAP, "ATI Radeon R480 X850 SE"}, \ - {0x1002, 0x5d4f, CHIP_R423|RADEON_NEW_MEMMAP, "ATI Radeon R480 X850 Pro"}, \ - {0x1002, 0x5d50, CHIP_R423|RADEON_NEW_MEMMAP, "ATI unknown Radeon / FireGL R480"}, \ - {0x1002, 0x5d52, CHIP_R423|RADEON_NEW_MEMMAP, "ATI Radeon R480 X850 XT"}, \ - {0x1002, 0x5d57, CHIP_R423|RADEON_NEW_MEMMAP, "ATI Radeon R423 X800 XT"}, \ - {0x1002, 0x5e48, CHIP_RV410|RADEON_NEW_MEMMAP, "ATI FireGL V5000 RV410"}, \ - {0x1002, 0x5e4a, CHIP_RV410|RADEON_NEW_MEMMAP, "ATI Radeon RV410 X700 XT"}, \ - {0x1002, 0x5e4b, CHIP_RV410|RADEON_NEW_MEMMAP, "ATI Radeon RV410 X700 Pro"}, \ - {0x1002, 0x5e4c, CHIP_RV410|RADEON_NEW_MEMMAP, "ATI Radeon RV410 X700 SE"}, \ - {0x1002, 0x5e4d, CHIP_RV410|RADEON_NEW_MEMMAP, "ATI Radeon RV410 X700"}, \ - {0x1002, 0x5e4f, CHIP_RV410|RADEON_NEW_MEMMAP, "ATI Radeon RV410 X700 SE"}, \ - {0x1002, 0x7100, CHIP_R520|RADEON_NEW_MEMMAP, "ATI Radeon X1800"}, \ - {0x1002, 0x7101, CHIP_R520|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon X1800 XT"}, \ - {0x1002, 0x7102, CHIP_R520|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon X1800"}, \ - {0x1002, 0x7103, CHIP_R520|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility FireGL V7200"}, \ - {0x1002, 0x7104, CHIP_R520|RADEON_NEW_MEMMAP, "ATI FireGL V7200"}, \ - {0x1002, 0x7105, CHIP_R520|RADEON_NEW_MEMMAP, "ATI FireGL V5300"}, \ - {0x1002, 0x7106, CHIP_R520|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility FireGL V7100"}, \ - {0x1002, 0x7108, CHIP_R520|RADEON_NEW_MEMMAP, "ATI Radeon X1800"}, \ - {0x1002, 0x7109, CHIP_R520|RADEON_NEW_MEMMAP, "ATI Radeon X1800"}, \ - {0x1002, 0x710A, CHIP_R520|RADEON_NEW_MEMMAP, "ATI Radeon X1800"}, \ - {0x1002, 0x710B, CHIP_R520|RADEON_NEW_MEMMAP, "ATI Radeon X1800"}, \ - {0x1002, 0x710C, CHIP_R520|RADEON_NEW_MEMMAP, "ATI Radeon X1800"}, \ - {0x1002, 0x710E, CHIP_R520|RADEON_NEW_MEMMAP, "ATI FireGL V7300"}, \ - {0x1002, 0x710F, CHIP_R520|RADEON_NEW_MEMMAP, "ATI FireGL V7350"}, \ - {0x1002, 0x7140, CHIP_RV515|RADEON_NEW_MEMMAP, "ATI Radeon X1600"}, \ - {0x1002, 0x7141, CHIP_RV515|RADEON_NEW_MEMMAP, "ATI RV505"}, \ - {0x1002, 0x7142, CHIP_RV515|RADEON_NEW_MEMMAP, "ATI Radeon X1300/X1550"}, \ - {0x1002, 0x7143, CHIP_RV515|RADEON_NEW_MEMMAP, "ATI Radeon X1550"}, \ - {0x1002, 0x7144, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI M54-GL"}, \ - {0x1002, 0x7145, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon X1400"}, \ - {0x1002, 0x7146, CHIP_RV515|RADEON_NEW_MEMMAP, "ATI Radeon X1300/X1550"}, \ - {0x1002, 0x7147, CHIP_RV515|RADEON_NEW_MEMMAP, "ATI Radeon X1550 64-bit"}, \ - {0x1002, 0x7149, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon X1300"}, \ - {0x1002, 0x714A, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon X1300"}, \ - {0x1002, 0x714B, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon X1300"}, \ - {0x1002, 0x714C, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon X1300"}, \ - {0x1002, 0x714D, CHIP_RV515|RADEON_NEW_MEMMAP, "ATI Radeon X1300"}, \ - {0x1002, 0x714E, CHIP_RV515|RADEON_NEW_MEMMAP, "ATI Radeon X1300"}, \ - {0x1002, 0x714F, CHIP_RV515|RADEON_NEW_MEMMAP, "ATI RV505"}, \ - {0x1002, 0x7151, CHIP_RV515|RADEON_NEW_MEMMAP, "ATI RV505"}, \ - {0x1002, 0x7152, CHIP_RV515|RADEON_NEW_MEMMAP, "ATI FireGL V3300"}, \ - {0x1002, 0x7153, CHIP_RV515|RADEON_NEW_MEMMAP, "ATI FireGL V3350"}, \ - {0x1002, 0x715E, CHIP_RV515|RADEON_NEW_MEMMAP, "ATI Radeon X1300"}, \ - {0x1002, 0x715F, CHIP_RV515|RADEON_NEW_MEMMAP, "ATI Radeon X1550 64-bit"}, \ - {0x1002, 0x7180, CHIP_RV515|RADEON_NEW_MEMMAP, "ATI Radeon X1300/X1550"}, \ - {0x1002, 0x7181, CHIP_RV515|RADEON_NEW_MEMMAP, "ATI Radeon X1600"}, \ - {0x1002, 0x7183, CHIP_RV515|RADEON_NEW_MEMMAP, "ATI Radeon X1300/X1550"}, \ - {0x1002, 0x7186, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon X1450"}, \ - {0x1002, 0x7187, CHIP_RV515|RADEON_NEW_MEMMAP, "ATI Radeon X1300/X1550"}, \ - {0x1002, 0x7188, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon X2300"}, \ - {0x1002, 0x718A, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon X2300"}, \ - {0x1002, 0x718B, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon X1350"}, \ - {0x1002, 0x718C, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon X1350"}, \ - {0x1002, 0x718D, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon X1450"}, \ - {0x1002, 0x718F, CHIP_RV515|RADEON_NEW_MEMMAP, "ATI Radeon X1300"}, \ - {0x1002, 0x7193, CHIP_RV515|RADEON_NEW_MEMMAP, "ATI Radeon X1550"}, \ - {0x1002, 0x7196, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon X1350"}, \ - {0x1002, 0x719B, CHIP_RV515|RADEON_NEW_MEMMAP, "ATI FireMV 2250"}, \ - {0x1002, 0x719F, CHIP_RV515|RADEON_NEW_MEMMAP, "ATI Radeon X1550 64-bit"}, \ - {0x1002, 0x71C0, CHIP_RV530|RADEON_NEW_MEMMAP, "ATI Radeon X1600"}, \ - {0x1002, 0x71C1, CHIP_RV530|RADEON_NEW_MEMMAP, "ATI Radeon X1650"}, \ - {0x1002, 0x71C2, CHIP_RV530|RADEON_NEW_MEMMAP, "ATI Radeon X1600"}, \ - {0x1002, 0x71C3, CHIP_RV530|RADEON_NEW_MEMMAP, "ATI Radeon X1600"}, \ - {0x1002, 0x71C4, CHIP_RV530|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility FireGL V5200"}, \ - {0x1002, 0x71C5, CHIP_RV530|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon X1600"}, \ - {0x1002, 0x71C6, CHIP_RV530|RADEON_NEW_MEMMAP, "ATI Radeon X1650"}, \ - {0x1002, 0x71C7, CHIP_RV530|RADEON_NEW_MEMMAP, "ATI Radeon X1650"}, \ - {0x1002, 0x71CD, CHIP_RV530|RADEON_NEW_MEMMAP, "ATI Radeon X1600"}, \ - {0x1002, 0x71CE, CHIP_RV530|RADEON_NEW_MEMMAP, "ATI Radeon X1300 XT/X1600 Pro"}, \ - {0x1002, 0x71D2, CHIP_RV530|RADEON_NEW_MEMMAP, "ATI FireGL V3400"}, \ - {0x1002, 0x71D4, CHIP_RV530|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility FireGL V5250"}, \ - {0x1002, 0x71D5, CHIP_RV530|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon X1700"}, \ - {0x1002, 0x71D6, CHIP_RV530|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon X1700 XT"}, \ - {0x1002, 0x71DA, CHIP_RV530|RADEON_NEW_MEMMAP, "ATI FireGL V5200"}, \ - {0x1002, 0x71DE, CHIP_RV530|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon X1700"}, \ - {0x1002, 0x7200, CHIP_RV515|RADEON_NEW_MEMMAP, "ATI Radeon X2300HD"}, \ - {0x1002, 0x7210, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 2300"}, \ - {0x1002, 0x7211, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 2300"}, \ - {0x1002, 0x7240, CHIP_R580|RADEON_NEW_MEMMAP, "ATI Radeon X1950"}, \ - {0x1002, 0x7243, CHIP_R580|RADEON_NEW_MEMMAP, "ATI Radeon X1900"}, \ - {0x1002, 0x7244, CHIP_R580|RADEON_NEW_MEMMAP, "ATI Radeon X1950"}, \ - {0x1002, 0x7245, CHIP_R580|RADEON_NEW_MEMMAP, "ATI Radeon X1900"}, \ - {0x1002, 0x7246, CHIP_R580|RADEON_NEW_MEMMAP, "ATI Radeon X1900"}, \ - {0x1002, 0x7247, CHIP_R580|RADEON_NEW_MEMMAP, "ATI Radeon X1900"}, \ - {0x1002, 0x7248, CHIP_R580|RADEON_NEW_MEMMAP, "ATI Radeon X1900"}, \ - {0x1002, 0x7249, CHIP_R580|RADEON_NEW_MEMMAP, "ATI Radeon X1900"}, \ - {0x1002, 0x724A, CHIP_R580|RADEON_NEW_MEMMAP, "ATI Radeon X1900"}, \ - {0x1002, 0x724B, CHIP_R580|RADEON_NEW_MEMMAP, "ATI Radeon X1900"}, \ - {0x1002, 0x724C, CHIP_R580|RADEON_NEW_MEMMAP, "ATI Radeon X1900"}, \ - {0x1002, 0x724D, CHIP_R580|RADEON_NEW_MEMMAP, "ATI Radeon X1900"}, \ - {0x1002, 0x724E, CHIP_R580|RADEON_NEW_MEMMAP, "ATI AMD Stream Processor"}, \ - {0x1002, 0x724F, CHIP_R580|RADEON_NEW_MEMMAP, "ATI Radeon X1900"}, \ - {0x1002, 0x7280, CHIP_RV570|RADEON_NEW_MEMMAP, "ATI Radeon X1950"}, \ - {0x1002, 0x7281, CHIP_RV560|RADEON_NEW_MEMMAP, "ATI RV560"}, \ - {0x1002, 0x7283, CHIP_RV560|RADEON_NEW_MEMMAP, "ATI RV560"}, \ - {0x1002, 0x7284, CHIP_R580|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon X1900"}, \ - {0x1002, 0x7287, CHIP_RV560|RADEON_NEW_MEMMAP, "ATI RV560"}, \ - {0x1002, 0x7288, CHIP_RV570|RADEON_NEW_MEMMAP, "ATI Radeon X1950 GT"}, \ - {0x1002, 0x7289, CHIP_RV570|RADEON_NEW_MEMMAP, "ATI RV570"}, \ - {0x1002, 0x728B, CHIP_RV570|RADEON_NEW_MEMMAP, "ATI RV570"}, \ - {0x1002, 0x728C, CHIP_RV570|RADEON_NEW_MEMMAP, "ATI ATI FireGL V7400"}, \ - {0x1002, 0x7290, CHIP_RV560|RADEON_NEW_MEMMAP, "ATI RV560"}, \ - {0x1002, 0x7291, CHIP_RV560|RADEON_NEW_MEMMAP, "ATI Radeon X1650"}, \ - {0x1002, 0x7293, CHIP_RV560|RADEON_NEW_MEMMAP, "ATI Radeon X1650"}, \ - {0x1002, 0x7297, CHIP_RV560|RADEON_NEW_MEMMAP, "ATI RV560"}, \ - {0x1002, 0x7834, CHIP_RS300|RADEON_IS_IGP|RADEON_NEW_MEMMAP, "ATI Radeon RS350 9000/9100 IGP"}, \ - {0x1002, 0x7835, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Radeon RS350 Mobility IGP"}, \ - {0x1002, 0x793f, CHIP_RS600|RADEON_IS_IGP|RADEON_NEW_MEMMAP, "ATI Radeon X1200"}, \ - {0x1002, 0x7941, CHIP_RS600|RADEON_IS_IGP|RADEON_NEW_MEMMAP, "ATI Radeon X1200"}, \ - {0x1002, 0x7942, CHIP_RS600|RADEON_IS_IGP|RADEON_NEW_MEMMAP, "ATI Radeon X1200"}, \ - {0x1002, 0x791e, CHIP_RS690|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART, "ATI Radeon RS690 X1250 IGP"}, \ - {0x1002, 0x791f, CHIP_RS690|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART, "ATI Radeon RS690 X1270 IGP"}, \ - {0x1002, 0x796c, CHIP_RS740|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART, "ATI Radeon RS740 HD2100 IGP"}, \ - {0x1002, 0x796d, CHIP_RS740|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART, "ATI Radeon RS740 HD2100 IGP"}, \ - {0x1002, 0x796e, CHIP_RS740|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART, "ATI Radeon RS740 HD2100 IGP"}, \ - {0x1002, 0x796f, CHIP_RS740|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART, "ATI Radeon RS740 HD2100 IGP"}, \ - {0x1002, 0x9400, CHIP_R600|RADEON_NEW_MEMMAP, "ATI Radeon HD 2900 XT"}, \ - {0x1002, 0x9401, CHIP_R600|RADEON_NEW_MEMMAP, "ATI Radeon HD 2900 XT"}, \ - {0x1002, 0x9402, CHIP_R600|RADEON_NEW_MEMMAP, "ATI Radeon HD 2900 XT"}, \ - {0x1002, 0x9403, CHIP_R600|RADEON_NEW_MEMMAP, "ATI Radeon HD 2900 Pro"}, \ - {0x1002, 0x9405, CHIP_R600|RADEON_NEW_MEMMAP, "ATI Radeon HD 2900 GT"}, \ - {0x1002, 0x940A, CHIP_R600|RADEON_NEW_MEMMAP, "ATI FireGL V8650"}, \ - {0x1002, 0x940B, CHIP_R600|RADEON_NEW_MEMMAP, "ATI FireGL V8600"}, \ - {0x1002, 0x940F, CHIP_R600|RADEON_NEW_MEMMAP, "ATI FireGL V7600"}, \ - {0x1002, 0x94A0, CHIP_RV740|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 4830"}, \ - {0x1002, 0x94A1, CHIP_RV740|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 4850"}, \ - {0x1002, 0x94A3, CHIP_RV740|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI FirePro M7740"}, \ - {0x1002, 0x94B1, CHIP_RV740|RADEON_NEW_MEMMAP, "ATI RV740"}, \ - {0x1002, 0x94B3, CHIP_RV740|RADEON_NEW_MEMMAP, "ATI Radeon HD 4770"}, \ - {0x1002, 0x94B4, CHIP_RV740|RADEON_NEW_MEMMAP, "ATI Radeon HD 4700 Series"}, \ - {0x1002, 0x94B5, CHIP_RV740|RADEON_NEW_MEMMAP, "ATI Radeon HD 4770"}, \ - {0x1002, 0x94B9, CHIP_RV740|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI FirePro M5750"}, \ - {0x1002, 0x94C0, CHIP_RV610|RADEON_NEW_MEMMAP, "RV610"}, \ - {0x1002, 0x94C1, CHIP_RV610|RADEON_NEW_MEMMAP, "Radeon HD 2400 XT"}, \ - {0x1002, 0x94C3, CHIP_RV610|RADEON_NEW_MEMMAP, "Radeon HD 2400 Pro"}, \ - {0x1002, 0x94C4, CHIP_RV610|RADEON_NEW_MEMMAP, "Radeon HD 2400 PRO AGP"}, \ - {0x1002, 0x94C5, CHIP_RV610|RADEON_NEW_MEMMAP, "FireGL V4000"}, \ - {0x1002, 0x94C6, CHIP_RV610|RADEON_NEW_MEMMAP, "RV610"}, \ - {0x1002, 0x94C7, CHIP_RV610|RADEON_NEW_MEMMAP, "ATI Radeon HD 2350"}, \ - {0x1002, 0x94C8, CHIP_RV610|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 2400 XT"}, \ - {0x1002, 0x94C9, CHIP_RV610|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 2400"}, \ - {0x1002, 0x94CB, CHIP_RV610|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI RADEON E2400"}, \ - {0x1002, 0x94CC, CHIP_RV610|RADEON_NEW_MEMMAP, "ATI RV610"}, \ - {0x1002, 0x94CD, CHIP_RV610|RADEON_NEW_MEMMAP, "ATI FireMV 2260"}, \ - {0x1002, 0x9500, CHIP_RV670|RADEON_NEW_MEMMAP, "ATI RV670"}, \ - {0x1002, 0x9501, CHIP_RV670|RADEON_NEW_MEMMAP, "ATI Radeon HD3870"}, \ - {0x1002, 0x9504, CHIP_RV670|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 3850"}, \ - {0x1002, 0x9505, CHIP_RV670|RADEON_NEW_MEMMAP, "ATI Radeon HD3850"}, \ - {0x1002, 0x9506, CHIP_RV670|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 3850 X2"}, \ - {0x1002, 0x9507, CHIP_RV670|RADEON_NEW_MEMMAP, "ATI RV670"}, \ - {0x1002, 0x9508, CHIP_RV670|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 3870"}, \ - {0x1002, 0x9509, CHIP_RV670|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 3870 X2"}, \ - {0x1002, 0x950F, CHIP_RV670|RADEON_NEW_MEMMAP, "ATI Radeon HD3870 X2"}, \ - {0x1002, 0x9511, CHIP_RV670|RADEON_NEW_MEMMAP, "ATI FireGL V7700"}, \ - {0x1002, 0x9515, CHIP_RV670|RADEON_NEW_MEMMAP, "ATI Radeon HD3850"}, \ - {0x1002, 0x9517, CHIP_RV670|RADEON_NEW_MEMMAP, "ATI Radeon HD3690"}, \ - {0x1002, 0x9519, CHIP_RV670|RADEON_NEW_MEMMAP, "AMD Firestream 9170"}, \ - {0x1002, 0x9580, CHIP_RV630|RADEON_NEW_MEMMAP, "ATI RV630"}, \ - {0x1002, 0x9581, CHIP_RV630|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 2600"}, \ - {0x1002, 0x9583, CHIP_RV630|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 2600 XT"}, \ - {0x1002, 0x9586, CHIP_RV630|RADEON_NEW_MEMMAP, "ATI Radeon HD 2600 XT AGP"}, \ - {0x1002, 0x9587, CHIP_RV630|RADEON_NEW_MEMMAP, "ATI Radeon HD 2600 Pro AGP"}, \ - {0x1002, 0x9588, CHIP_RV630|RADEON_NEW_MEMMAP, "ATI Radeon HD 2600 XT"}, \ - {0x1002, 0x9589, CHIP_RV630|RADEON_NEW_MEMMAP, "ATI Radeon HD 2600 Pro"}, \ - {0x1002, 0x958A, CHIP_RV630|RADEON_NEW_MEMMAP, "ATI Gemini RV630"}, \ - {0x1002, 0x958B, CHIP_RV630|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Gemini Mobility Radeon HD 2600 XT"}, \ - {0x1002, 0x958C, CHIP_RV630|RADEON_NEW_MEMMAP, "ATI FireGL V5600"}, \ - {0x1002, 0x958D, CHIP_RV630|RADEON_NEW_MEMMAP, "ATI FireGL V3600"}, \ - {0x1002, 0x958E, CHIP_RV630|RADEON_NEW_MEMMAP, "ATI Radeon HD 2600 LE"}, \ - {0x1002, 0x958F, CHIP_RV630|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility FireGL Graphics Processor"}, \ - {0x1002, 0x95C0, CHIP_RV620|RADEON_NEW_MEMMAP, "ATI Radeon HD 3470"}, \ - {0x1002, 0x95C5, CHIP_RV620|RADEON_NEW_MEMMAP, "ATI Radeon HD 3450"}, \ - {0x1002, 0x95C6, CHIP_RV620|RADEON_NEW_MEMMAP, "ATI Radeon HD 3450"}, \ - {0x1002, 0x95C7, CHIP_RV620|RADEON_NEW_MEMMAP, "ATI Radeon HD 3430"}, \ - {0x1002, 0x95C9, CHIP_RV620|RADEON_NEW_MEMMAP, "ATI Radeon HD 3450"}, \ - {0x1002, 0x95C2, CHIP_RV620|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 3430"}, \ - {0x1002, 0x95C4, CHIP_RV620|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 3400 Series"}, \ - {0x1002, 0x95CC, CHIP_RV620|RADEON_NEW_MEMMAP, "ATI FirePro V3700"}, \ - {0x1002, 0x95CD, CHIP_RV620|RADEON_NEW_MEMMAP, "ATI FireMV 2450"}, \ - {0x1002, 0x95CE, CHIP_RV620|RADEON_NEW_MEMMAP, "ATI FireMV 2260"}, \ - {0x1002, 0x95CF, CHIP_RV620|RADEON_NEW_MEMMAP, "ATI FireMV 2260"}, \ - {0x1002, 0x9590, CHIP_RV635|RADEON_NEW_MEMMAP, "ATI ATI Radeon HD 3600 Series"}, \ - {0x1002, 0x9596, CHIP_RV635|RADEON_NEW_MEMMAP, "ATI ATI Radeon HD 3650 AGP"}, \ - {0x1002, 0x9597, CHIP_RV635|RADEON_NEW_MEMMAP, "ATI ATI Radeon HD 3600 PRO"}, \ - {0x1002, 0x9598, CHIP_RV635|RADEON_NEW_MEMMAP, "ATI ATI Radeon HD 3600 XT"}, \ - {0x1002, 0x9599, CHIP_RV635|RADEON_NEW_MEMMAP, "ATI ATI Radeon HD 3600 PRO"}, \ - {0x1002, 0x9591, CHIP_RV635|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 3650"}, \ - {0x1002, 0x9593, CHIP_RV635|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 3670"}, \ - {0x1002, 0x9595, CHIP_RV635|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility FireGL V5700"}, \ - {0x1002, 0x959B, CHIP_RV635|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility FireGL V5725"}, \ - {0x1002, 0x9610, CHIP_RS780|RADEON_NEW_MEMMAP|RADEON_IS_IGP, "ATI Radeon HD 3200 Graphics"}, \ - {0x1002, 0x9611, CHIP_RS780|RADEON_NEW_MEMMAP|RADEON_IS_IGP, "ATI Radeon 3100 Graphics"}, \ - {0x1002, 0x9612, CHIP_RS780|RADEON_NEW_MEMMAP|RADEON_IS_IGP, "ATI Radeon HD 3200 Graphics"}, \ - {0x1002, 0x9613, CHIP_RS780|RADEON_NEW_MEMMAP|RADEON_IS_IGP, "ATI Radeon 3100 Graphics"}, \ - {0x1002, 0x9614, CHIP_RS780|RADEON_NEW_MEMMAP|RADEON_IS_IGP, "ATI Radeon 3300 Graphics"}, \ - {0x1002, 0x9615, CHIP_RS780|RADEON_NEW_MEMMAP|RADEON_IS_IGP, "ATI Radeon 3200 Graphics"}, \ - {0x1002, 0x9616, CHIP_RS780|RADEON_NEW_MEMMAP|RADEON_IS_IGP, "ATI Radeon 3000 Graphics"}, \ - {0x1002, 0x9710, CHIP_RS880|RADEON_NEW_MEMMAP|RADEON_IS_IGP, "ATI Radeon HD 4200"}, \ - {0x1002, 0x9711, CHIP_RS880|RADEON_NEW_MEMMAP|RADEON_IS_IGP, "ATI Radeon 4100"}, \ - {0x1002, 0x9712, CHIP_RS880|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP, "ATI Mobility Radeon HD 4200"}, \ - {0x1002, 0x9713, CHIP_RS880|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP, "ATI Mobility Radeon 4100"}, \ - {0x1002, 0x9714, CHIP_RS880|RADEON_NEW_MEMMAP|RADEON_IS_IGP, "ATI RS880"}, \ - {0x1002, 0x9715, CHIP_RS880|RADEON_NEW_MEMMAP|RADEON_IS_IGP, "ATI Radeon HD 4250"}, \ - {0x1002, 0x9440, CHIP_RV770|RADEON_NEW_MEMMAP, "ATI Radeon 4800 Series"}, \ - {0x1002, 0x9441, CHIP_RV770|RADEON_NEW_MEMMAP, "ATI Radeon 4870 X2"}, \ - {0x1002, 0x9442, CHIP_RV770|RADEON_NEW_MEMMAP, "ATI Radeon 4800 Series"}, \ - {0x1002, 0x9443, CHIP_RV770|RADEON_NEW_MEMMAP, "ATI Radeon 4850 X2"}, \ - {0x1002, 0x944C, CHIP_RV770|RADEON_NEW_MEMMAP, "ATI Radeon 4800 Series"}, \ - {0x1002, 0x9450, CHIP_RV770|RADEON_NEW_MEMMAP, "AMD FireStream 9270"}, \ - {0x1002, 0x9452, CHIP_RV770|RADEON_NEW_MEMMAP, "AMD FireStream 9250"}, \ - {0x1002, 0x9444, CHIP_RV770|RADEON_NEW_MEMMAP, "ATI FirePro V8750 (FireGL)"}, \ - {0x1002, 0x9446, CHIP_RV770|RADEON_NEW_MEMMAP, "ATI FirePro V7760 (FireGL)"}, \ - {0x1002, 0x9456, CHIP_RV770|RADEON_NEW_MEMMAP, "ATI FirePro V8700 (FireGL)"}, \ - {0x1002, 0x944E, CHIP_RV770|RADEON_NEW_MEMMAP, "ATI FirePro RV770"}, \ - {0x1002, 0x944A, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 4850"}, \ - {0x1002, 0x944B, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 4850 X2"}, \ - {0x1002, 0x945A, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 4870"}, \ - {0x1002, 0x945B, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon M98"}, \ - {0x1002, 0x9460, CHIP_RV770|RADEON_NEW_MEMMAP, "ATI Radeon 4800 Series"}, \ - {0x1002, 0x9462, CHIP_RV770|RADEON_NEW_MEMMAP, "ATI Radeon 4800 Series"}, \ - {0x1002, 0x946A, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI FirePro M7750"}, \ - {0x1002, 0x946B, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI M98"}, \ - {0x1002, 0x947A, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI M98"}, \ - {0x1002, 0x947B, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI M98"}, \ - {0x1002, 0x9487, CHIP_RV730|RADEON_NEW_MEMMAP, "ATI Radeon RV730 (AGP)"}, \ - {0x1002, 0x948F, CHIP_RV730|RADEON_NEW_MEMMAP, "ATI Radeon RV730 (AGP)"}, \ - {0x1002, 0x9490, CHIP_RV730|RADEON_NEW_MEMMAP, "ATI Radeon HD 4670"}, \ - {0x1002, 0x9495, CHIP_RV730|RADEON_NEW_MEMMAP, "ATI Radeon HD 4600 Series"}, \ - {0x1002, 0x9498, CHIP_RV730|RADEON_NEW_MEMMAP, "ATI Radeon HD 4650"}, \ - {0x1002, 0x9480, CHIP_RV730|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 4650"}, \ - {0x1002, 0x9488, CHIP_RV730|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 4670"}, \ - {0x1002, 0x9489, CHIP_RV730|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI FirePro M5750"}, \ - {0x1002, 0x9491, CHIP_RV730|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI RADEON E4600"}, \ - {0x1002, 0x949C, CHIP_RV730|RADEON_NEW_MEMMAP, "ATI FirePro V7750 (FireGL)"}, \ - {0x1002, 0x949E, CHIP_RV730|RADEON_NEW_MEMMAP, "ATI FirePro V5700 (FireGL)"}, \ - {0x1002, 0x949F, CHIP_RV730|RADEON_NEW_MEMMAP, "ATI FirePro V3750 (FireGL)"}, \ - {0x1002, 0x9540, CHIP_RV710|RADEON_NEW_MEMMAP, "ATI Radeon HD 4550"}, \ - {0x1002, 0x9541, CHIP_RV710|RADEON_NEW_MEMMAP, "ATI Radeon RV710"}, \ - {0x1002, 0x9542, CHIP_RV710|RADEON_NEW_MEMMAP, "ATI Radeon RV710"}, \ - {0x1002, 0x954E, CHIP_RV710|RADEON_NEW_MEMMAP, "ATI Radeon RV710"}, \ - {0x1002, 0x954F, CHIP_RV710|RADEON_NEW_MEMMAP, "ATI Radeon HD 4350"}, \ - {0x1002, 0x9552, CHIP_RV710|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon 4300 Series"}, \ - {0x1002, 0x9553, CHIP_RV710|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon 4500 Series"}, \ - {0x1002, 0x9555, CHIP_RV710|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon 4500 Series"}, \ - {0x1002, 0x9557, CHIP_RV710|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI FirePro RG220"}, \ - {0, 0, 0, NULL} - -#define r128_PCI_IDS \ - {0x1002, 0x4c45, 0, "ATI Rage 128 Mobility LE (PCI)"}, \ - {0x1002, 0x4c46, 0, "ATI Rage 128 Mobility LF (AGP)"}, \ - {0x1002, 0x4d46, 0, "ATI Rage 128 Mobility MF (AGP)"}, \ - {0x1002, 0x4d4c, 0, "ATI Rage 128 Mobility ML (AGP)"}, \ - {0x1002, 0x5041, 0, "ATI Rage 128 Pro PA (PCI)"}, \ - {0x1002, 0x5042, 0, "ATI Rage 128 Pro PB (AGP)"}, \ - {0x1002, 0x5043, 0, "ATI Rage 128 Pro PC (AGP)"}, \ - {0x1002, 0x5044, 0, "ATI Rage 128 Pro PD (PCI)"}, \ - {0x1002, 0x5045, 0, "ATI Rage 128 Pro PE (AGP)"}, \ - {0x1002, 0x5046, 0, "ATI Rage 128 Pro PF (AGP)"}, \ - {0x1002, 0x5047, 0, "ATI Rage 128 Pro PG (PCI)"}, \ - {0x1002, 0x5048, 0, "ATI Rage 128 Pro PH (AGP)"}, \ - {0x1002, 0x5049, 0, "ATI Rage 128 Pro PI (AGP)"}, \ - {0x1002, 0x504A, 0, "ATI Rage 128 Pro PJ (PCI)"}, \ - {0x1002, 0x504B, 0, "ATI Rage 128 Pro PK (AGP)"}, \ - {0x1002, 0x504C, 0, "ATI Rage 128 Pro PL (AGP)"}, \ - {0x1002, 0x504D, 0, "ATI Rage 128 Pro PM (PCI)"}, \ - {0x1002, 0x504E, 0, "ATI Rage 128 Pro PN (AGP)"}, \ - {0x1002, 0x504F, 0, "ATI Rage 128 Pro PO (AGP)"}, \ - {0x1002, 0x5050, 0, "ATI Rage 128 Pro PP (PCI)"}, \ - {0x1002, 0x5051, 0, "ATI Rage 128 Pro PQ (AGP)"}, \ - {0x1002, 0x5052, 0, "ATI Rage 128 Pro PR (PCI)"}, \ - {0x1002, 0x5053, 0, "ATI Rage 128 Pro PS (PCI)"}, \ - {0x1002, 0x5054, 0, "ATI Rage 128 Pro PT (AGP)"}, \ - {0x1002, 0x5055, 0, "ATI Rage 128 Pro PU (AGP)"}, \ - {0x1002, 0x5056, 0, "ATI Rage 128 Pro PV (PCI)"}, \ - {0x1002, 0x5057, 0, "ATI Rage 128 Pro PW (AGP)"}, \ - {0x1002, 0x5058, 0, "ATI Rage 128 Pro PX (AGP)"}, \ - {0x1002, 0x5245, 0, "ATI Rage 128 RE (PCI)"}, \ - {0x1002, 0x5246, 0, "ATI Rage 128 RF (AGP)"}, \ - {0x1002, 0x5247, 0, "ATI Rage 128 RG (AGP)"}, \ - {0x1002, 0x524b, 0, "ATI Rage 128 RK (PCI)"}, \ - {0x1002, 0x524c, 0, "ATI Rage 128 RL (AGP)"}, \ - {0x1002, 0x534d, 0, "ATI Rage 128 SM (AGP)"}, \ - {0x1002, 0x5446, 0, "ATI Rage 128 Pro Ultra TF (AGP)"}, \ - {0x1002, 0x544C, 0, "ATI Rage 128 Pro Ultra TL (AGP)"}, \ - {0x1002, 0x5452, 0, "ATI Rage 128 Pro Ultra TR (AGP)"}, \ - {0, 0, 0, NULL} - -#define mga_PCI_IDS \ - {0x102b, 0x0520, MGA_CARD_TYPE_G200, "Matrox G200 (PCI)"}, \ - {0x102b, 0x0521, MGA_CARD_TYPE_G200, "Matrox G200 (AGP)"}, \ - {0x102b, 0x0525, MGA_CARD_TYPE_G400, "Matrox G400/G450 (AGP)"}, \ - {0x102b, 0x2527, MGA_CARD_TYPE_G550, "Matrox G550 (AGP)"}, \ - {0, 0, 0, NULL} - -#define mach64_PCI_IDS \ - {0x1002, 0x4749, 0, "3D Rage Pro"}, \ - {0x1002, 0x4750, 0, "3D Rage Pro 215GP"}, \ - {0x1002, 0x4751, 0, "3D Rage Pro 215GQ"}, \ - {0x1002, 0x4742, 0, "3D Rage Pro AGP 1X/2X"}, \ - {0x1002, 0x4744, 0, "3D Rage Pro AGP 1X"}, \ - {0x1002, 0x4c49, 0, "3D Rage LT Pro"}, \ - {0x1002, 0x4c50, 0, "3D Rage LT Pro"}, \ - {0x1002, 0x4c51, 0, "3D Rage LT Pro"}, \ - {0x1002, 0x4c42, 0, "3D Rage LT Pro AGP-133"}, \ - {0x1002, 0x4c44, 0, "3D Rage LT Pro AGP-66"}, \ - {0x1002, 0x474c, 0, "Rage XC"}, \ - {0x1002, 0x474f, 0, "Rage XL"}, \ - {0x1002, 0x4752, 0, "Rage XL"}, \ - {0x1002, 0x4753, 0, "Rage XC"}, \ - {0x1002, 0x474d, 0, "Rage XL AGP 2X"}, \ - {0x1002, 0x474e, 0, "Rage XC AGP"}, \ - {0x1002, 0x4c52, 0, "Rage Mobility P/M"}, \ - {0x1002, 0x4c53, 0, "Rage Mobility L"}, \ - {0x1002, 0x4c4d, 0, "Rage Mobility P/M AGP 2X"}, \ - {0x1002, 0x4c4e, 0, "Rage Mobility L AGP 2X"}, \ - {0, 0, 0, NULL} - -#define sis_PCI_IDS \ - {0x1039, 0x0300, 0, "SiS 300/305"}, \ - {0x1039, 0x5300, 0, "SiS 540"}, \ - {0x1039, 0x6300, 0, "SiS 630"}, \ - {0x1039, 0x6330, SIS_CHIP_315, "SiS 661"}, \ - {0x1039, 0x7300, 0, "SiS 730"}, \ - {0x18CA, 0x0040, SIS_CHIP_315, "Volari V3XT/V5/V8"}, \ - {0x18CA, 0x0042, SIS_CHIP_315, "Volari Unknown"}, \ - {0, 0, 0, NULL} - -#define tdfx_PCI_IDS \ - {0x121a, 0x0003, 0, "3dfx Voodoo Banshee"}, \ - {0x121a, 0x0004, 0, "3dfx Voodoo3 2000"}, \ - {0x121a, 0x0005, 0, "3dfx Voodoo3 3000"}, \ - {0x121a, 0x0007, 0, "3dfx Voodoo4 4500"}, \ - {0x121a, 0x0009, 0, "3dfx Voodoo5 5500"}, \ - {0x121a, 0x000b, 0, "3dfx Voodoo4 4200"}, \ - {0, 0, 0, NULL} - -#define viadrv_PCI_IDS \ - {0x1106, 0x3022, 0, "VIA CLE266 3022"}, \ - {0x1106, 0x3118, VIA_PRO_GROUP_A, "VIA CN400 / PM8X0"}, \ - {0x1106, 0x3122, 0, "VIA CLE266"}, \ - {0x1106, 0x7205, 0, "VIA KM400"}, \ - {0x1106, 0x3108, 0, "VIA K8M800"}, \ - {0x1106, 0x3344, 0, "VIA CN700 / VM800 / P4M800Pro"}, \ - {0x1106, 0x3343, 0, "VIA P4M890"}, \ - {0x1106, 0x3230, VIA_DX9_0, "VIA K8M890"}, \ - {0x1106, 0x3157, VIA_PRO_GROUP_A, "VIA CX700"}, \ - {0x1106, 0x3371, VIA_DX9_0, "VIA P4M900 / VN896"}, \ - {0, 0, 0, NULL} - -#define i810_PCI_IDS \ - {0x8086, 0x7121, 0, "Intel i810 GMCH"}, \ - {0x8086, 0x7123, 0, "Intel i810-DC100 GMCH"}, \ - {0x8086, 0x7125, 0, "Intel i810E GMCH"}, \ - {0x8086, 0x1132, 0, "Intel i815 GMCH"}, \ - {0, 0, 0, NULL} - -#define i830_PCI_IDS \ - {0x8086, 0x3577, 0, "Intel i830M GMCH"}, \ - {0x8086, 0x2562, 0, "Intel i845G GMCH"}, \ - {0x8086, 0x3582, 0, "Intel i852GM/i855GM GMCH"}, \ - {0x8086, 0x2572, 0, "Intel i865G GMCH"}, \ - {0, 0, 0, NULL} - -#define gamma_PCI_IDS \ - {0x3d3d, 0x0008, 0, "3DLabs GLINT Gamma G1"}, \ - {0, 0, 0, NULL} - -#define savage_PCI_IDS \ - {0x5333, 0x8a20, S3_SAVAGE3D, "Savage 3D"}, \ - {0x5333, 0x8a21, S3_SAVAGE3D, "Savage 3D/MV"}, \ - {0x5333, 0x8a22, S3_SAVAGE4, "Savage4"}, \ - {0x5333, 0x8a23, S3_SAVAGE4, "Savage4"}, \ - {0x5333, 0x8c10, S3_SAVAGE_MX, "Savage/MX-MV"}, \ - {0x5333, 0x8c11, S3_SAVAGE_MX, "Savage/MX"}, \ - {0x5333, 0x8c12, S3_SAVAGE_MX, "Savage/IX-MV"}, \ - {0x5333, 0x8c13, S3_SAVAGE_MX, "Savage/IX"}, \ - {0x5333, 0x8c22, S3_SUPERSAVAGE, "SuperSavage MX/128"}, \ - {0x5333, 0x8c24, S3_SUPERSAVAGE, "SuperSavage MX/64"}, \ - {0x5333, 0x8c26, S3_SUPERSAVAGE, "SuperSavage MX/64C"}, \ - {0x5333, 0x8c2a, S3_SUPERSAVAGE, "SuperSavage IX/128 SDR"}, \ - {0x5333, 0x8c2b, S3_SUPERSAVAGE, "SuperSavage IX/128 DDR"}, \ - {0x5333, 0x8c2c, S3_SUPERSAVAGE, "SuperSavage IX/64 SDR"}, \ - {0x5333, 0x8c2d, S3_SUPERSAVAGE, "SuperSavage IX/64 DDR"}, \ - {0x5333, 0x8c2e, S3_SUPERSAVAGE, "SuperSavage IX/C SDR"}, \ - {0x5333, 0x8c2f, S3_SUPERSAVAGE, "SuperSavage IX/C DDR"}, \ - {0x5333, 0x8a25, S3_PROSAVAGE, "ProSavage PM133"}, \ - {0x5333, 0x8a26, S3_PROSAVAGE, "ProSavage KM133"}, \ - {0x5333, 0x8d01, S3_TWISTER, "ProSavage Twister PN133"}, \ - {0x5333, 0x8d02, S3_TWISTER, "ProSavage Twister KN133"}, \ - {0x5333, 0x8d03, S3_PROSAVAGEDDR, "ProSavage DDR"}, \ - {0x5333, 0x8d04, S3_PROSAVAGEDDR, "ProSavage DDR-K"}, \ - {0, 0, 0, NULL} - -#define ffb_PCI_IDS \ - {0, 0, 0, NULL} - -#define i915_PCI_IDS \ - {0x8086, 0x3577, CHIP_I8XX, "Intel i830M GMCH"}, \ - {0x8086, 0x2562, CHIP_I8XX, "Intel i845G GMCH"}, \ - {0x8086, 0x3582, CHIP_I8XX, "Intel i852GM/i855GM GMCH"}, \ - {0x8086, 0x358e, CHIP_I8XX, "Intel i852GM/i855GM GMCH"}, \ - {0x8086, 0x2572, CHIP_I8XX, "Intel i865G GMCH"}, \ - {0x8086, 0x2582, CHIP_I9XX|CHIP_I915, "Intel i915G"}, \ - {0x8086, 0x258a, CHIP_I9XX|CHIP_I915, "Intel E7221 (i915)"}, \ - {0x8086, 0x2592, CHIP_I9XX|CHIP_I915, "Intel i915GM"}, \ - {0x8086, 0x2772, CHIP_I9XX|CHIP_I915, "Intel i945G"}, \ - {0x8086, 0x27A2, CHIP_I9XX|CHIP_I915, "Intel i945GM"}, \ - {0x8086, 0x27AE, CHIP_I9XX|CHIP_I915, "Intel i945GME"}, \ - {0x8086, 0x2972, CHIP_I9XX|CHIP_I965, "Intel i946GZ"}, \ - {0x8086, 0x2982, CHIP_I9XX|CHIP_I965, "Intel i965G"}, \ - {0x8086, 0x2992, CHIP_I9XX|CHIP_I965, "Intel i965Q"}, \ - {0x8086, 0x29A2, CHIP_I9XX|CHIP_I965, "Intel i965G"}, \ - {0x8086, 0x29B2, CHIP_I9XX|CHIP_I915, "Intel Q35"}, \ - {0x8086, 0x29C2, CHIP_I9XX|CHIP_I915, "Intel G33"}, \ - {0x8086, 0x29D2, CHIP_I9XX|CHIP_I915, "Intel Q33"}, \ - {0x8086, 0x2A02, CHIP_I9XX|CHIP_I965, "Intel i965GM"}, \ - {0x8086, 0x2A12, CHIP_I9XX|CHIP_I965, "Intel i965GME/GLE"}, \ - {0x8086, 0x2A42, CHIP_I9XX|CHIP_I965, "Mobile Intel® GM45 Express Chipset"}, \ - {0x8086, 0x2E02, CHIP_I9XX|CHIP_I965, "Intel Eaglelake"}, \ - {0x8086, 0x2E12, CHIP_I9XX|CHIP_I965, "Intel Q45/Q43"}, \ - {0x8086, 0x2E22, CHIP_I9XX|CHIP_I965, "Intel G45/G43"}, \ - {0x8086, 0x2E32, CHIP_I9XX|CHIP_I965, "Intel G41"}, \ - {0x8086, 0x2e42, CHIP_I9XX|CHIP_I915, "Intel G43 ?"}, \ - {0x8086, 0x2e92, CHIP_I9XX|CHIP_I915, "Intel G43 ?"}, \ - {0x8086, 0x0042, CHIP_I9XX|CHIP_I915, "Intel IronLake"}, \ - {0x8086, 0x0046, CHIP_I9XX|CHIP_I915, "Intel IronLake"}, \ - {0x8086, 0x0102, CHIP_I9XX|CHIP_I915, "Intel SandyBridge"}, \ - {0x8086, 0x0112, CHIP_I9XX|CHIP_I915, "Intel SandyBridge"}, \ - {0x8086, 0x0122, CHIP_I9XX|CHIP_I915, "Intel SandyBridge"}, \ - {0x8086, 0x0106, CHIP_I9XX|CHIP_I915, "Intel SandyBridge (M)"}, \ - {0x8086, 0x0116, CHIP_I9XX|CHIP_I915, "Intel SandyBridge (M)"}, \ - {0x8086, 0x0126, CHIP_I9XX|CHIP_I915, "Intel SandyBridge (M)"}, \ - {0x8086, 0x010A, CHIP_I9XX|CHIP_I915, "Intel SandyBridge (M)"}, \ - {0x8086, 0x0152, CHIP_I9XX|CHIP_I915, "Intel IvyBridge"}, \ - {0x8086, 0x0162, CHIP_I9XX|CHIP_I915, "Intel IvyBridge"}, \ - {0x8086, 0x0156, CHIP_I9XX|CHIP_I915, "Intel IvyBridge (M)"}, \ - {0x8086, 0x0166, CHIP_I9XX|CHIP_I915, "Intel IvyBridge (M)"}, \ - {0x8086, 0x015A, CHIP_I9XX|CHIP_I915, "Intel IvyBridge (S)"}, \ - {0x8086, 0x016A, CHIP_I9XX|CHIP_I915, "Intel IvyBridge (S)"}, \ - {0x8086, 0xA001, CHIP_I9XX|CHIP_I965, "Intel Pineview"}, \ - {0x8086, 0xA011, CHIP_I9XX|CHIP_I965, "Intel Pineview (M)"}, \ - {0, 0, 0, NULL} - -#define imagine_PCI_IDS \ - {0x105d, 0x2309, IMAGINE_128, "Imagine 128"}, \ - {0x105d, 0x2339, IMAGINE_128_2, "Imagine 128-II"}, \ - {0x105d, 0x493d, IMAGINE_T2R, "Ticket to Ride"}, \ - {0x105d, 0x5348, IMAGINE_REV4, "Revolution IV"}, \ - {0, 0, 0, NULL} - -#define nv_PCI_IDS \ - {0x10DE, 0x0020, NV04, "NVidia RIVA TNT"}, \ - {0x10DE, 0x0028, NV04, "NVidia RIVA TNT2"}, \ - {0x10DE, 0x002A, NV04, "NVidia Unknown TNT2"}, \ - {0x10DE, 0x002C, NV04, "NVidia Vanta"}, \ - {0x10DE, 0x0029, NV04, "NVidia RIVA TNT2 Ultra"}, \ - {0x10DE, 0x002D, NV04, "NVidia RIVA TNT2 Model 64"}, \ - {0x10DE, 0x00A0, NV04, "NVidia Aladdin TNT2"}, \ - {0x10DE, 0x0100, NV10, "NVidia GeForce 256"}, \ - {0x10DE, 0x0101, NV10, "NVidia GeForce DDR"}, \ - {0x10DE, 0x0103, NV10, "NVidia Quadro"}, \ - {0x10DE, 0x0110, NV10, "NVidia GeForce2 MX/MX 400"}, \ - {0x10DE, 0x0111, NV10, "NVidia GeForce2 MX 100/200"}, \ - {0x10DE, 0x0112, NV10, "NVidia GeForce2 Go"}, \ - {0x10DE, 0x0113, NV10, "NVidia Quadro2 MXR/EX/Go"}, \ - {0x10DE, 0x0150, NV10, "NVidia GeForce2 GTS"}, \ - {0x10DE, 0x0151, NV10, "NVidia GeForce2 Ti"}, \ - {0x10DE, 0x0152, NV10, "NVidia GeForce2 Ultra"}, \ - {0x10DE, 0x0153, NV10, "NVidia Quadro2 Pro"}, \ - {0x10DE, 0x0170, NV10, "NVidia GeForce4 MX 460"}, \ - {0x10DE, 0x0171, NV10, "NVidia GeForce4 MX 440"}, \ - {0x10DE, 0x0172, NV10, "NVidia GeForce4 MX 420"}, \ - {0x10DE, 0x0173, NV10, "NVidia GeForce4 MX 440-SE"}, \ - {0x10DE, 0x0174, NV10, "NVidia GeForce4 440 Go"}, \ - {0x10DE, 0x0175, NV10, "NVidia GeForce4 420 Go"}, \ - {0x10DE, 0x0176, NV10, "NVidia GeForce4 420 Go 32M"}, \ - {0x10DE, 0x0177, NV10, "NVidia GeForce4 460 Go"}, \ - {0x10DE, 0x0178, NV10, "NVidia Quadro4 550 XGL"}, \ - {0x10DE, 0x0179, NV10, "NVidia GeForce4"}, \ - {0x10DE, 0x017A, NV10, "NVidia Quadro4 NVS"}, \ - {0x10DE, 0x017C, NV10, "NVidia Quadro4 500 GoGL"}, \ - {0x10DE, 0x017D, NV10, "NVidia GeForce4 410 Go 16M"}, \ - {0x10DE, 0x0181, NV10, "NVidia GeForce4 MX 440 with AGP8X"}, \ - {0x10DE, 0x0182, NV10, "NVidia GeForce4 MX 440SE with AGP8X"}, \ - {0x10DE, 0x0183, NV10, "NVidia GeForce4 MX 420 with AGP8X"}, \ - {0x10DE, 0x0185, NV10, "NVidia GeForce4 MX 4000"}, \ - {0x10DE, 0x0186, NV10, "NVidia GeForce4 448 Go"}, \ - {0x10DE, 0x0187, NV10, "NVidia GeForce4 488 Go"}, \ - {0x10DE, 0x0188, NV10, "NVidia Quadro4 580 XGL"}, \ - {0x10DE, 0x0189, NV10, "NVidia GeForce4 MX with AGP8X (Mac)"}, \ - {0x10DE, 0x018A, NV10, "NVidia Quadro4 280 NVS"}, \ - {0x10DE, 0x018B, NV10, "NVidia Quadro4 380 XGL"}, \ - {0x10DE, 0x018C, NV10, "NVidia Quadro NVS 50 PCI"}, \ - {0x10DE, 0x018D, NV10, "NVidia GeForce4 448 Go"}, \ - {0x10DE, 0x01A0, NV10, "NVidia GeForce2 Integrated GPU"}, \ - {0x10DE, 0x01F0, NV10, "NVidia GeForce4 MX Integrated GPU"}, \ - {0x10DE, 0x0200, NV20, "NVidia GeForce3"}, \ - {0x10DE, 0x0201, NV20, "NVidia GeForce3 Ti 200"}, \ - {0x10DE, 0x0202, NV20, "NVidia GeForce3 Ti 500"}, \ - {0x10DE, 0x0203, NV20, "NVidia Quadro DCC"}, \ - {0x10DE, 0x0250, NV20, "NVidia GeForce4 Ti 4600"}, \ - {0x10DE, 0x0251, NV20, "NVidia GeForce4 Ti 4400"}, \ - {0x10DE, 0x0252, NV20, "NVidia 0x0252"}, \ - {0x10DE, 0x0253, NV20, "NVidia GeForce4 Ti 4200"}, \ - {0x10DE, 0x0258, NV20, "NVidia Quadro4 900 XGL"}, \ - {0x10DE, 0x0259, NV20, "NVidia Quadro4 750 XGL"}, \ - {0x10DE, 0x025B, NV20, "NVidia Quadro4 700 XGL"}, \ - {0x10DE, 0x0280, NV20, "NVidia GeForce4 Ti 4800"}, \ - {0x10DE, 0x0281, NV20, "NVidia GeForce4 Ti 4200 with AGP8X"}, \ - {0x10DE, 0x0282, NV20, "NVidia GeForce4 Ti 4800 SE"}, \ - {0x10DE, 0x0286, NV20, "NVidia GeForce4 4200 Go"}, \ - {0x10DE, 0x028C, NV20, "NVidia Quadro4 700 GoGL"}, \ - {0x10DE, 0x0288, NV20, "NVidia Quadro4 980 XGL"}, \ - {0x10DE, 0x0289, NV20, "NVidia Quadro4 780 XGL"}, \ - {0x10DE, 0x0301, NV30, "NVidia GeForce FX 5800 Ultra"}, \ - {0x10DE, 0x0302, NV30, "NVidia GeForce FX 5800"}, \ - {0x10DE, 0x0308, NV30, "NVidia Quadro FX 2000"}, \ - {0x10DE, 0x0309, NV30, "NVidia Quadro FX 1000"}, \ - {0x10DE, 0x0311, NV30, "NVidia GeForce FX 5600 Ultra"}, \ - {0x10DE, 0x0312, NV30, "NVidia GeForce FX 5600"}, \ - {0x10DE, 0x0313, NV30, "NVidia 0x0313"}, \ - {0x10DE, 0x0314, NV30, "NVidia GeForce FX 5600SE"}, \ - {0x10DE, 0x0316, NV30, "NVidia 0x0316"}, \ - {0x10DE, 0x0317, NV30, "NVidia 0x0317"}, \ - {0x10DE, 0x031A, NV30, "NVidia GeForce FX Go5600"}, \ - {0x10DE, 0x031B, NV30, "NVidia GeForce FX Go5650"}, \ - {0x10DE, 0x031C, NV30, "NVidia Quadro FX Go700"}, \ - {0x10DE, 0x031D, NV30, "NVidia 0x031D"}, \ - {0x10DE, 0x031E, NV30, "NVidia 0x031E"}, \ - {0x10DE, 0x031F, NV30, "NVidia 0x031F"}, \ - {0x10DE, 0x0320, NV30, "NVidia GeForce FX 5200"}, \ - {0x10DE, 0x0321, NV30, "NVidia GeForce FX 5200 Ultra"}, \ - {0x10DE, 0x0322, NV30, "NVidia GeForce FX 5200"}, \ - {0x10DE, 0x0323, NV30, "NVidia GeForce FX 5200SE"}, \ - {0x10DE, 0x0324, NV30, "NVidia GeForce FX Go5200"}, \ - {0x10DE, 0x0325, NV30, "NVidia GeForce FX Go5250"}, \ - {0x10DE, 0x0326, NV30, "NVidia GeForce FX 5500"}, \ - {0x10DE, 0x0327, NV30, "NVidia GeForce FX 5100"}, \ - {0x10DE, 0x0328, NV30, "NVidia GeForce FX Go5200 32M/64M"}, \ - {0x10DE, 0x0329, NV30, "NVidia GeForce FX 5200 (Mac)"}, \ - {0x10DE, 0x032A, NV30, "NVidia Quadro NVS 280 PCI"}, \ - {0x10DE, 0x032B, NV30, "NVidia Quadro FX 500/600 PCI"}, \ - {0x10DE, 0x032C, NV30, "NVidia GeForce FX Go53xx Series"}, \ - {0x10DE, 0x032D, NV30, "NVidia GeForce FX Go5100"}, \ - {0x10DE, 0x032F, NV30, "NVidia 0x032F"}, \ - {0x10DE, 0x0330, NV30, "NVidia GeForce FX 5900 Ultra"}, \ - {0x10DE, 0x0331, NV30, "NVidia GeForce FX 5900"}, \ - {0x10DE, 0x0332, NV30, "NVidia GeForce FX 5900XT"}, \ - {0x10DE, 0x0333, NV30, "NVidia GeForce FX 5950 Ultra"}, \ - {0x10DE, 0x033F, NV30, "NVidia Quadro FX 700"}, \ - {0x10DE, 0x0334, NV30, "NVidia GeForce FX 5900ZT"}, \ - {0x10DE, 0x0338, NV30, "NVidia Quadro FX 3000"}, \ - {0x10DE, 0x0341, NV30, "NVidia GeForce FX 5700 Ultra"}, \ - {0x10DE, 0x0342, NV30, "NVidia GeForce FX 5700"}, \ - {0x10DE, 0x0343, NV30, "NVidia GeForce FX 5700LE"}, \ - {0x10DE, 0x0344, NV30, "NVidia GeForce FX 5700VE"}, \ - {0x10DE, 0x0345, NV30, "NVidia 0x0345"}, \ - {0x10DE, 0x0347, NV30, "NVidia GeForce FX Go5700"}, \ - {0x10DE, 0x0348, NV30, "NVidia GeForce FX Go5700"}, \ - {0x10DE, 0x0349, NV30, "NVidia 0x0349"}, \ - {0x10DE, 0x034B, NV30, "NVidia 0x034B"}, \ - {0x10DE, 0x034C, NV30, "NVidia Quadro FX Go1000"}, \ - {0x10DE, 0x034E, NV30, "NVidia Quadro FX 1100"}, \ - {0x10DE, 0x034F, NV30, "NVidia 0x034F"}, \ - {0x10DE, 0x0040, NV40, "NVidia GeForce 6800 Ultra"}, \ - {0x10DE, 0x0041, NV40, "NVidia GeForce 6800"}, \ - {0x10DE, 0x0042, NV40, "NVidia GeForce 6800 LE"}, \ - {0x10DE, 0x0043, NV40, "NVidia 0x0043"}, \ - {0x10DE, 0x0045, NV40, "NVidia GeForce 6800 GT"}, \ - {0x10DE, 0x0046, NV40, "NVidia GeForce 6800 GT"}, \ - {0x10DE, 0x0049, NV40, "NVidia 0x0049"}, \ - {0x10DE, 0x004E, NV40, "NVidia Quadro FX 4000"}, \ - {0x10DE, 0x00C0, NV40, "NVidia 0x00C0"}, \ - {0x10DE, 0x00C1, NV40, "NVidia GeForce 6800"}, \ - {0x10DE, 0x00C2, NV40, "NVidia GeForce 6800 LE"}, \ - {0x10DE, 0x00C8, NV40, "NVidia GeForce Go 6800"}, \ - {0x10DE, 0x00C9, NV40, "NVidia GeForce Go 6800 Ultra"}, \ - {0x10DE, 0x00CC, NV40, "NVidia Quadro FX Go1400"}, \ - {0x10DE, 0x00CD, NV40, "NVidia Quadro FX 3450/4000 SDI"}, \ - {0x10DE, 0x00CE, NV40, "NVidia Quadro FX 1400"}, \ - {0x10de, 0x00f0, NV40, "Nvidia GeForce 6600 GT"}, \ - {0x10de, 0x00f1, NV40, "Nvidia GeForce 6600 GT"}, \ - {0x10DE, 0x0140, NV40, "NVidia GeForce 6600 GT"}, \ - {0x10DE, 0x0141, NV40, "NVidia GeForce 6600"}, \ - {0x10DE, 0x0142, NV40, "NVidia GeForce 6600 LE"}, \ - {0x10DE, 0x0143, NV40, "NVidia 0x0143"}, \ - {0x10DE, 0x0144, NV40, "NVidia GeForce Go 6600"}, \ - {0x10DE, 0x0145, NV40, "NVidia GeForce 6610 XL"}, \ - {0x10DE, 0x0146, NV40, "NVidia GeForce Go 6600 TE/6200 TE"}, \ - {0x10DE, 0x0147, NV40, "NVidia GeForce 6700 XL"}, \ - {0x10DE, 0x0148, NV40, "NVidia GeForce Go 6600"}, \ - {0x10DE, 0x0149, NV40, "NVidia GeForce Go 6600 GT"}, \ - {0x10DE, 0x014B, NV40, "NVidia 0x014B"}, \ - {0x10DE, 0x014C, NV40, "NVidia 0x014C"}, \ - {0x10DE, 0x014D, NV40, "NVidia 0x014D"}, \ - {0x10DE, 0x014E, NV40, "NVidia Quadro FX 540"}, \ - {0x10DE, 0x014F, NV40, "NVidia GeForce 6200"}, \ - {0x10DE, 0x0160, NV40, "NVidia 0x0160"}, \ - {0x10DE, 0x0161, NV40, "NVidia GeForce 6200 TurboCache(TM)"}, \ - {0x10DE, 0x0162, NV40, "NVidia GeForce 6200SE TurboCache(TM)"}, \ - {0x10DE, 0x0163, NV40, "NVidia 0x0163"}, \ - {0x10DE, 0x0164, NV40, "NVidia GeForce Go 6200"}, \ - {0x10DE, 0x0165, NV40, "NVidia Quadro NVS 285"}, \ - {0x10DE, 0x0166, NV40, "NVidia GeForce Go 6400"}, \ - {0x10DE, 0x0167, NV40, "NVidia GeForce Go 6200"}, \ - {0x10DE, 0x0168, NV40, "NVidia GeForce Go 6400"}, \ - {0x10DE, 0x0169, NV40, "NVidia 0x0169"}, \ - {0x10DE, 0x016B, NV40, "NVidia 0x016B"}, \ - {0x10DE, 0x016C, NV40, "NVidia 0x016C"}, \ - {0x10DE, 0x016D, NV40, "NVidia 0x016D"}, \ - {0x10DE, 0x016E, NV40, "NVidia 0x016E"}, \ - {0x10DE, 0x0210, NV40, "NVidia 0x0210"}, \ - {0x10DE, 0x0211, NV40, "NVidia GeForce 6800"}, \ - {0x10DE, 0x0212, NV40, "NVidia GeForce 6800 LE"}, \ - {0x10DE, 0x0215, NV40, "NVidia GeForce 6800 GT"}, \ - {0x10DE, 0x0220, NV40, "NVidia 0x0220"}, \ - {0x10DE, 0x0221, NV40, "NVidia GeForce 6200"}, \ - {0x10DE, 0x0222, NV40, "NVidia 0x0222"}, \ - {0x10DE, 0x0228, NV40, "NVidia 0x0228"}, \ - {0x10DE, 0x0090, NV40, "NVidia 0x0090"}, \ - {0x10DE, 0x0091, NV40, "NVidia GeForce 7800 GTX"}, \ - {0x10DE, 0x0092, NV40, "NVidia 0x0092"}, \ - {0x10DE, 0x0093, NV40, "NVidia 0x0093"}, \ - {0x10DE, 0x0094, NV40, "NVidia 0x0094"}, \ - {0x10DE, 0x0098, NV40, "NVidia 0x0098"}, \ - {0x10DE, 0x0099, NV40, "NVidia GeForce Go 7800 GTX"}, \ - {0x10DE, 0x009C, NV40, "NVidia 0x009C"}, \ - {0x10DE, 0x009D, NV40, "NVidia Quadro FX 4500"}, \ - {0x10DE, 0x009E, NV40, "NVidia 0x009E"}, \ - {0, 0, 0, NULL} - -#define xgi_PCI_IDS \ - {0x18ca, 0x2200, 0, "XP5"}, \ - {0x18ca, 0x0047, 0, "XP10 / XG47"}, \ - {0, 0, 0, NULL} diff --git a/sys/dev/drm2/drm_sarea.h b/sys/dev/drm2/drm_sarea.h deleted file mode 100644 index e1b4b2d489..0000000000 --- a/sys/dev/drm2/drm_sarea.h +++ /dev/null @@ -1,86 +0,0 @@ -/** - * \file drm_sarea.h - * \brief SAREA definitions - * - * \author Michel D�zer - */ - -/*- - * Copyright 2002 Tungsten Graphics, Inc., Cedar Park, Texas. - * 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, 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL - * TUNGSTEN GRAPHICS 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. - * - * $FreeBSD: src/sys/dev/drm2/drm_sarea.h,v 1.1 2012/05/22 11:07:44 kib Exp $ - */ - -#ifndef _DRM_SAREA_H_ -#define _DRM_SAREA_H_ - -#include - -/* SAREA area needs to be at least a page */ -#if defined(__alpha__) -#define SAREA_MAX 0x2000 -#elif defined(__ia64__) -#define SAREA_MAX 0x10000 /* 64kB */ -#else -/* Intel 830M driver needs at least 8k SAREA */ -#define SAREA_MAX 0x2000UL -#endif - -/** Maximum number of drawables in the SAREA */ -#define SAREA_MAX_DRAWABLES 256 - -#define SAREA_DRAWABLE_CLAIMED_ENTRY 0x80000000 - -/** SAREA drawable */ -struct drm_sarea_drawable { - unsigned int stamp; - unsigned int flags; -}; - -/** SAREA frame */ -struct drm_sarea_frame { - unsigned int x; - unsigned int y; - unsigned int width; - unsigned int height; - unsigned int fullscreen; -}; - -/** SAREA */ -struct drm_sarea { - /** first thing is always the DRM locking structure */ - struct drm_hw_lock lock; - /** \todo Use readers/writer lock for drm_sarea::drawable_lock */ - struct drm_hw_lock drawable_lock; - struct drm_sarea_drawable drawableTable[SAREA_MAX_DRAWABLES]; /**< drawables */ - struct drm_sarea_frame frame; /**< frame */ - drm_context_t dummy_context; -}; - -#ifndef __KERNEL__ -typedef struct drm_sarea_drawable drm_sarea_drawable_t; -typedef struct drm_sarea_frame drm_sarea_frame_t; -typedef struct drm_sarea drm_sarea_t; -#endif - -#endif /* _DRM_SAREA_H_ */ diff --git a/sys/dev/drm2/drm_scatter.c b/sys/dev/drm2/drm_scatter.c deleted file mode 100644 index cbdeebb2b2..0000000000 --- a/sys/dev/drm2/drm_scatter.c +++ /dev/null @@ -1,129 +0,0 @@ -/*- - * Copyright (c) 2009 Robert C. Noland III - * 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, 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT 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. - * - * $FreeBSD: src/sys/dev/drm2/drm_scatter.c,v 1.1 2012/05/22 11:07:44 kib Exp $ - */ - -/** @file drm_scatter.c - * Allocation of memory for scatter-gather mappings by the graphics chip. - * The memory allocated here is then made into an aperture in the card - * by mapping the pages into the GART. - */ - -#include - -int -drm_sg_alloc(struct drm_device *dev, struct drm_scatter_gather *request) -{ - struct drm_sg_mem *entry; - vm_size_t size; - vm_pindex_t pindex; - - if (dev->sg) - return EINVAL; - - DRM_DEBUG("request size=%ld\n", request->size); - - entry = kmalloc(sizeof(*entry), DRM_MEM_DRIVER, M_WAITOK | M_ZERO); - - size = round_page(request->size); - entry->pages = OFF_TO_IDX(size); - entry->busaddr = kmalloc(entry->pages * sizeof(*entry->busaddr), - DRM_MEM_SGLISTS, M_WAITOK | M_ZERO); - - entry->vaddr = kmem_alloc_attr(&kernel_map, size, M_WAITOK | M_ZERO, - 0, BUS_SPACE_MAXADDR_32BIT, VM_MEMATTR_WRITE_COMBINING); - if (entry->vaddr == 0) { - drm_sg_cleanup(entry); - return (ENOMEM); - } - - for(pindex = 0; pindex < entry->pages; pindex++) { - entry->busaddr[pindex] = - vtophys(entry->vaddr + IDX_TO_OFF(pindex)); - } - - DRM_LOCK(dev); - if (dev->sg) { - DRM_UNLOCK(dev); - drm_sg_cleanup(entry); - return (EINVAL); - } - dev->sg = entry; - DRM_UNLOCK(dev); - - request->handle = entry->vaddr; - - DRM_DEBUG("allocated %ju pages @ 0x%08jx, contents=%08lx\n", - entry->pages, (uintmax_t)entry->vaddr, - *(unsigned long *)entry->vaddr); - - return (0); -} - -int -drm_sg_alloc_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_scatter_gather *request = data; - - DRM_DEBUG("\n"); - - return (drm_sg_alloc(dev, request)); -} - -void -drm_sg_cleanup(struct drm_sg_mem *entry) -{ - if (entry == NULL) - return; - - if (entry->vaddr != 0) - kmem_free(&kernel_map, entry->vaddr, IDX_TO_OFF(entry->pages)); - - drm_free(entry->busaddr, DRM_MEM_SGLISTS); - drm_free(entry, DRM_MEM_DRIVER); - - return; -} - -int -drm_sg_free(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - struct drm_scatter_gather *request = data; - struct drm_sg_mem *entry; - - DRM_LOCK(dev); - entry = dev->sg; - dev->sg = NULL; - DRM_UNLOCK(dev); - - if (!entry || entry->vaddr != request->handle) - return (EINVAL); - - DRM_DEBUG("free 0x%jx\n", (uintmax_t)entry->vaddr); - - drm_sg_cleanup(entry); - - return (0); -} diff --git a/sys/dev/drm2/drm_sman.c b/sys/dev/drm2/drm_sman.c deleted file mode 100644 index 630703c6cb..0000000000 --- a/sys/dev/drm2/drm_sman.c +++ /dev/null @@ -1,349 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck., ND., USA. - * 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 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 - * THE COPYRIGHT HOLDERS, AUTHORS 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. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - * $FreeBSD: src/sys/dev/drm2/drm_sman.c,v 1.1 2012/05/22 11:07:44 kib Exp $ - **************************************************************************/ - -/* - * Simple memory manager interface that keeps track on allocate regions on a - * per "owner" basis. All regions associated with an "owner" can be released - * with a simple call. Typically if the "owner" exists. The owner is any - * "unsigned long" identifier. Can typically be a pointer to a file private - * struct or a context identifier. - * - * Authors: - * Thomas Hellström - */ - -#include -#include - -struct drm_owner_item { - struct drm_hash_item owner_hash; - struct list_head sman_list; - struct list_head mem_blocks; -}; - -void drm_sman_takedown(struct drm_sman * sman) -{ - drm_ht_remove(&sman->user_hash_tab); - drm_ht_remove(&sman->owner_hash_tab); - if (sman->mm) - drm_free(sman->mm, DRM_MEM_MM); -} - -int -drm_sman_init(struct drm_sman * sman, unsigned int num_managers, - unsigned int user_order, unsigned int owner_order) -{ - int ret = 0; - - sman->mm = (struct drm_sman_mm *) drm_calloc(num_managers, - sizeof(*sman->mm), DRM_MEM_MM); - if (!sman->mm) { - ret = -ENOMEM; - goto out; - } - sman->num_managers = num_managers; - INIT_LIST_HEAD(&sman->owner_items); - ret = drm_ht_create(&sman->owner_hash_tab, owner_order); - if (ret) - goto out1; - ret = drm_ht_create(&sman->user_hash_tab, user_order); - if (!ret) - goto out; - - drm_ht_remove(&sman->owner_hash_tab); -out1: - drm_free(sman->mm, DRM_MEM_MM); -out: - return ret; -} - -static void *drm_sman_mm_allocate(void *private, unsigned long size, - unsigned alignment) -{ - struct drm_mm *mm = (struct drm_mm *) private; - struct drm_mm_node *tmp; - - tmp = drm_mm_search_free(mm, size, alignment, 1); - if (!tmp) { - return NULL; - } - /* This could be non-atomic, but we are called from a locked path */ - tmp = drm_mm_get_block_atomic(tmp, size, alignment); - return tmp; -} - -static void drm_sman_mm_free(void *private, void *ref) -{ - struct drm_mm_node *node = (struct drm_mm_node *) ref; - - drm_mm_put_block(node); -} - -static void drm_sman_mm_destroy(void *private) -{ - struct drm_mm *mm = (struct drm_mm *) private; - drm_mm_takedown(mm); - drm_free(mm, DRM_MEM_MM); -} - -static unsigned long drm_sman_mm_offset(void *private, void *ref) -{ - struct drm_mm_node *node = (struct drm_mm_node *) ref; - return node->start; -} - -int -drm_sman_set_range(struct drm_sman * sman, unsigned int manager, - unsigned long start, unsigned long size) -{ - struct drm_sman_mm *sman_mm; - struct drm_mm *mm; - int ret; - - KASSERT(manager < sman->num_managers, ("Invalid manager")); - - sman_mm = &sman->mm[manager]; - mm = kmalloc(sizeof(*mm), DRM_MEM_MM, M_NOWAIT | M_ZERO); - if (!mm) { - return -ENOMEM; - } - sman_mm->private = mm; - ret = drm_mm_init(mm, start, size); - - if (ret) { - drm_free(mm, DRM_MEM_MM); - return ret; - } - - sman_mm->allocate = drm_sman_mm_allocate; - sman_mm->free = drm_sman_mm_free; - sman_mm->destroy = drm_sman_mm_destroy; - sman_mm->offset = drm_sman_mm_offset; - - return 0; -} - -int -drm_sman_set_manager(struct drm_sman * sman, unsigned int manager, - struct drm_sman_mm * allocator) -{ - KASSERT(manager < sman->num_managers, ("Invalid manager")); - sman->mm[manager] = *allocator; - - return 0; -} - -static struct drm_owner_item *drm_sman_get_owner_item(struct drm_sman * sman, - unsigned long owner) -{ - int ret; - struct drm_hash_item *owner_hash_item; - struct drm_owner_item *owner_item; - - ret = drm_ht_find_item(&sman->owner_hash_tab, owner, &owner_hash_item); - if (!ret) { - return drm_hash_entry(owner_hash_item, struct drm_owner_item, - owner_hash); - } - - owner_item = kmalloc(sizeof(*owner_item), DRM_MEM_MM, M_NOWAIT | M_ZERO); - if (!owner_item) - goto out; - - INIT_LIST_HEAD(&owner_item->mem_blocks); - owner_item->owner_hash.key = owner; - DRM_DEBUG("owner_item = %p, mem_blocks = %p\n", owner_item, &owner_item->mem_blocks); - if (drm_ht_insert_item(&sman->owner_hash_tab, &owner_item->owner_hash)) - goto out1; - - list_add_tail(&owner_item->sman_list, &sman->owner_items); - return owner_item; - -out1: - drm_free(owner_item, DRM_MEM_MM); -out: - return NULL; -} - -struct drm_memblock_item *drm_sman_alloc(struct drm_sman *sman, unsigned int manager, - unsigned long size, unsigned alignment, - unsigned long owner) -{ - void *tmp; - struct drm_sman_mm *sman_mm; - struct drm_owner_item *owner_item; - struct drm_memblock_item *memblock; - - KASSERT(manager < sman->num_managers, ("Invalid manager")); - - sman_mm = &sman->mm[manager]; - tmp = sman_mm->allocate(sman_mm->private, size, alignment); - if (!tmp) { - return NULL; - } - - memblock = kmalloc(sizeof(*memblock), DRM_MEM_MM, M_NOWAIT | M_ZERO); - DRM_DEBUG("allocated mem_block %p\n", memblock); - if (!memblock) - goto out; - - memblock->mm_info = tmp; - memblock->mm = sman_mm; - memblock->sman = sman; - INIT_LIST_HEAD(&memblock->owner_list); - - if (drm_ht_just_insert_please - (&sman->user_hash_tab, &memblock->user_hash, - (unsigned long)memblock, 32, 0, 0)) - goto out1; - - owner_item = drm_sman_get_owner_item(sman, owner); - if (!owner_item) - goto out2; - - DRM_DEBUG("owner_item = %p, mem_blocks = %p\n", owner_item, &owner_item->mem_blocks); - DRM_DEBUG("owner_list.prev = %p, mem_blocks.prev = %p\n", memblock->owner_list.prev, owner_item->mem_blocks.prev); - DRM_DEBUG("owner_list.next = %p, mem_blocks.next = %p\n", memblock->owner_list.next, owner_item->mem_blocks.next); - list_add_tail(&memblock->owner_list, &owner_item->mem_blocks); - - DRM_DEBUG("Complete\n"); - return memblock; - -out2: - drm_ht_remove_item(&sman->user_hash_tab, &memblock->user_hash); -out1: - drm_free(memblock, DRM_MEM_MM); -out: - sman_mm->free(sman_mm->private, tmp); - - return NULL; -} - -static void drm_sman_free(struct drm_memblock_item *item) -{ - struct drm_sman *sman = item->sman; - - list_del(&item->owner_list); - drm_ht_remove_item(&sman->user_hash_tab, &item->user_hash); - item->mm->free(item->mm->private, item->mm_info); - drm_free(item, DRM_MEM_MM); -} - -int drm_sman_free_key(struct drm_sman *sman, unsigned int key) -{ - struct drm_hash_item *hash_item; - struct drm_memblock_item *memblock_item; - - if (drm_ht_find_item(&sman->user_hash_tab, key, &hash_item)) - return -EINVAL; - - memblock_item = drm_hash_entry(hash_item, struct drm_memblock_item, - user_hash); - drm_sman_free(memblock_item); - return 0; -} - -static void drm_sman_remove_owner(struct drm_sman *sman, - struct drm_owner_item *owner_item) -{ - list_del(&owner_item->sman_list); - drm_ht_remove_item(&sman->owner_hash_tab, &owner_item->owner_hash); - drm_free(owner_item, DRM_MEM_MM); -} - -int drm_sman_owner_clean(struct drm_sman *sman, unsigned long owner) -{ - - struct drm_hash_item *hash_item; - struct drm_owner_item *owner_item; - - if (drm_ht_find_item(&sman->owner_hash_tab, owner, &hash_item)) { - return -1; - } - - owner_item = drm_hash_entry(hash_item, struct drm_owner_item, owner_hash); - DRM_DEBUG("cleaning owner_item %p\n", owner_item); - if (owner_item->mem_blocks.next == &owner_item->mem_blocks) { - drm_sman_remove_owner(sman, owner_item); - return -1; - } - - return 0; -} - -static void drm_sman_do_owner_cleanup(struct drm_sman *sman, - struct drm_owner_item *owner_item) -{ - struct drm_memblock_item *entry, *next; - - list_for_each_entry_safe(entry, next, &owner_item->mem_blocks, - owner_list) { - DRM_DEBUG("freeing mem_block %p\n", entry); - drm_sman_free(entry); - } - drm_sman_remove_owner(sman, owner_item); -} - -void drm_sman_owner_cleanup(struct drm_sman *sman, unsigned long owner) -{ - - struct drm_hash_item *hash_item; - struct drm_owner_item *owner_item; - - if (drm_ht_find_item(&sman->owner_hash_tab, owner, &hash_item)) { - - return; - } - - owner_item = drm_hash_entry(hash_item, struct drm_owner_item, owner_hash); - drm_sman_do_owner_cleanup(sman, owner_item); -} - -void drm_sman_cleanup(struct drm_sman *sman) -{ - struct drm_owner_item *entry, *next; - unsigned int i; - struct drm_sman_mm *sman_mm; - - DRM_DEBUG("sman = %p, owner_items = %p\n", - sman, &sman->owner_items); - list_for_each_entry_safe(entry, next, &sman->owner_items, sman_list) { - DRM_DEBUG("cleaning owner_item = %p\n", entry); - drm_sman_do_owner_cleanup(sman, entry); - } - if (sman->mm) { - for (i = 0; i < sman->num_managers; ++i) { - sman_mm = &sman->mm[i]; - if (sman_mm->private) { - sman_mm->destroy(sman_mm->private); - sman_mm->private = NULL; - } - } - } -} diff --git a/sys/dev/drm2/drm_sman.h b/sys/dev/drm2/drm_sman.h deleted file mode 100644 index eff88f2de7..0000000000 --- a/sys/dev/drm2/drm_sman.h +++ /dev/null @@ -1,178 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA. - * 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 - * THE COPYRIGHT HOLDERS, AUTHORS 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. - * - * $FreeBSD: src/sys/dev/drm2/drm_sman.h,v 1.1 2012/05/22 11:07:44 kib Exp $ - **************************************************************************/ - -/* - * Simple memory MANager interface that keeps track on allocate regions on a - * per "owner" basis. All regions associated with an "owner" can be released - * with a simple call. Typically if the "owner" exists. The owner is any - * "unsigned long" identifier. Can typically be a pointer to a file private - * struct or a context identifier. - * - * Authors: - * Thomas Hellström - */ - -#ifndef DRM_SMAN_H -#define DRM_SMAN_H - -#include -#include -#include - -/* - * A class that is an abstration of a simple memory allocator. - * The sman implementation provides a default such allocator - * using the drm_mm.c implementation. But the user can replace it. - * See the SiS implementation, which may use the SiS FB kernel module - * for memory management. - */ - -struct drm_sman_mm { - /* private info. If allocated, needs to be destroyed by the destroy - function */ - void *private; - - /* Allocate a memory block with given size and alignment. - Return an opaque reference to the memory block */ - - void *(*allocate) (void *private, unsigned long size, - unsigned alignment); - - /* Free a memory block. "ref" is the opaque reference that we got from - the "alloc" function */ - - void (*free) (void *private, void *ref); - - /* Free all resources associated with this allocator */ - - void (*destroy) (void *private); - - /* Return a memory offset from the opaque reference returned from the - "alloc" function */ - - unsigned long (*offset) (void *private, void *ref); -}; - -struct drm_memblock_item { - struct list_head owner_list; - struct drm_hash_item user_hash; - void *mm_info; - struct drm_sman_mm *mm; - struct drm_sman *sman; -}; - -struct drm_sman { - struct drm_sman_mm *mm; - int num_managers; - struct drm_open_hash owner_hash_tab; - struct drm_open_hash user_hash_tab; - struct list_head owner_items; -}; - -/* - * Take down a memory manager. This function should only be called after a - * successful init and after a call to drm_sman_cleanup. - */ - -extern void drm_sman_takedown(struct drm_sman * sman); - -/* - * Allocate structures for a manager. - * num_managers are the number of memory pools to manage. (VRAM, AGP, ....) - * user_order is the log2 of the number of buckets in the user hash table. - * set this to approximately log2 of the max number of memory regions - * that will be allocated for _all_ pools together. - * owner_order is the log2 of the number of buckets in the owner hash table. - * set this to approximately log2 of - * the number of client file connections that will - * be using the manager. - * - */ - -extern int drm_sman_init(struct drm_sman * sman, unsigned int num_managers, - unsigned int user_order, unsigned int owner_order); - -/* - * Initialize a drm_mm.c allocator. Should be called only once for each - * manager unless a customized allogator is used. - */ - -extern int drm_sman_set_range(struct drm_sman * sman, unsigned int manager, - unsigned long start, unsigned long size); - -/* - * Initialize a customized allocator for one of the managers. - * (See the SiS module). The object pointed to by "allocator" is copied, - * so it can be destroyed after this call. - */ - -extern int drm_sman_set_manager(struct drm_sman * sman, unsigned int mananger, - struct drm_sman_mm * allocator); - -/* - * Allocate a memory block. Aligment is not implemented yet. - */ - -extern struct drm_memblock_item *drm_sman_alloc(struct drm_sman * sman, - unsigned int manager, - unsigned long size, - unsigned alignment, - unsigned long owner); -/* - * Free a memory block identified by its user hash key. - */ - -extern int drm_sman_free_key(struct drm_sman * sman, unsigned int key); - -/* - * returns 1 iff there are no stale memory blocks associated with this owner. - * Typically called to determine if we need to idle the hardware and call - * drm_sman_owner_cleanup. If there are no stale memory blocks, it removes all - * resources associated with owner. - */ - -extern int drm_sman_owner_clean(struct drm_sman * sman, unsigned long owner); - -/* - * Frees all stale memory blocks associated with this owner. Note that this - * requires that the hardware is finished with all blocks, so the graphics engine - * should be idled before this call is made. This function also frees - * any resources associated with "owner" and should be called when owner - * is not going to be referenced anymore. - */ - -extern void drm_sman_owner_cleanup(struct drm_sman * sman, unsigned long owner); - -/* - * Frees all stale memory blocks associated with the memory manager. - * See idling above. - */ - -extern void drm_sman_cleanup(struct drm_sman * sman); - -#endif diff --git a/sys/dev/drm2/drm_sysctl.c b/sys/dev/drm2/drm_sysctl.c deleted file mode 100644 index d150d8981c..0000000000 --- a/sys/dev/drm2/drm_sysctl.c +++ /dev/null @@ -1,365 +0,0 @@ -/*- - * Copyright 2003 Eric Anholt - * 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, 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL - * ERIC ANHOLT 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. - * - * $FreeBSD: src/sys/dev/drm2/drm_sysctl.c,v 1.1 2012/05/22 11:07:44 kib Exp $ - */ - -/** @file drm_sysctl.c - * Implementation of various sysctls for controlling DRM behavior and reporting - * debug information. - */ - -#include -#include - -#include -#include -#include - -static int drm_name_info DRM_SYSCTL_HANDLER_ARGS; -static int drm_vm_info DRM_SYSCTL_HANDLER_ARGS; -static int drm_clients_info DRM_SYSCTL_HANDLER_ARGS; -static int drm_bufs_info DRM_SYSCTL_HANDLER_ARGS; -static int drm_vblank_info DRM_SYSCTL_HANDLER_ARGS; - -struct drm_sysctl_list { - const char *name; - int (*f) DRM_SYSCTL_HANDLER_ARGS; -} drm_sysctl_list[] = { - {"name", drm_name_info}, - {"vm", drm_vm_info}, - {"clients", drm_clients_info}, - {"bufs", drm_bufs_info}, - {"vblank", drm_vblank_info}, -}; -#define DRM_SYSCTL_ENTRIES (sizeof(drm_sysctl_list)/sizeof(drm_sysctl_list[0])) - -struct drm_sysctl_info { - struct sysctl_ctx_list ctx; - char name[2]; -}; - -int drm_sysctl_init(struct drm_device *dev) -{ - struct drm_sysctl_info *info; - struct sysctl_oid *oid; - struct sysctl_oid *top, *drioid; - int i; - - info = kmalloc(sizeof *info, DRM_MEM_DRIVER, M_WAITOK | M_ZERO); - dev->sysctl = info; - - /* Add the sysctl node for DRI if it doesn't already exist */ - drioid = SYSCTL_ADD_NODE(&info->ctx, &sysctl__hw_children, OID_AUTO, - "dri", CTLFLAG_RW, NULL, "DRI Graphics"); - if (!drioid) - return 1; - - /* Find the next free slot under hw.dri */ - i = 0; - SLIST_FOREACH(oid, SYSCTL_CHILDREN(drioid), oid_link) { - if (i <= oid->oid_arg2) - i = oid->oid_arg2 + 1; - } - if (i > 9) - return (1); - - dev->sysctl_node_idx = i; - /* Add the hw.dri.x for our device */ - info->name[0] = '0' + i; - info->name[1] = 0; - top = SYSCTL_ADD_NODE(&info->ctx, SYSCTL_CHILDREN(drioid), - OID_AUTO, info->name, CTLFLAG_RW, NULL, NULL); - if (!top) - return 1; - - for (i = 0; i < DRM_SYSCTL_ENTRIES; i++) { - oid = SYSCTL_ADD_OID(&info->ctx, - SYSCTL_CHILDREN(top), - OID_AUTO, - drm_sysctl_list[i].name, - CTLTYPE_STRING | CTLFLAG_RD, - dev, - 0, - drm_sysctl_list[i].f, - "A", - NULL); - if (!oid) - return 1; - } - SYSCTL_ADD_INT(&info->ctx, SYSCTL_CHILDREN(drioid), OID_AUTO, "debug", - CTLFLAG_RW, &drm_debug_flag, sizeof(drm_debug_flag), - "Enable debugging output"); - SYSCTL_ADD_INT(&info->ctx, SYSCTL_CHILDREN(drioid), OID_AUTO, "notyet", - CTLFLAG_RW, &drm_notyet_flag, sizeof(drm_debug_flag), - "Enable notyet reminders"); - - if (dev->driver->sysctl_init != NULL) - dev->driver->sysctl_init(dev, &info->ctx, top); - - SYSCTL_ADD_INT(&info->ctx, SYSCTL_CHILDREN(drioid), OID_AUTO, - "vblank_offdelay", CTLFLAG_RW, &drm_vblank_offdelay, - sizeof(drm_vblank_offdelay), - ""); - SYSCTL_ADD_INT(&info->ctx, SYSCTL_CHILDREN(drioid), OID_AUTO, - "timestamp_precision", CTLFLAG_RW, &drm_timestamp_precision, - sizeof(drm_timestamp_precision), - ""); - - return (0); -} - -int drm_sysctl_cleanup(struct drm_device *dev) -{ - int error; - - error = sysctl_ctx_free(&dev->sysctl->ctx); - drm_free(dev->sysctl, DRM_MEM_DRIVER); - dev->sysctl = NULL; - if (dev->driver->sysctl_cleanup != NULL) - dev->driver->sysctl_cleanup(dev); - - return (error); -} - -#define DRM_SYSCTL_PRINT(fmt, arg...) \ -do { \ - ksnprintf(buf, sizeof(buf), fmt, ##arg); \ - retcode = SYSCTL_OUT(req, buf, strlen(buf)); \ - if (retcode) \ - goto done; \ -} while (0) - -static int drm_name_info DRM_SYSCTL_HANDLER_ARGS -{ - struct drm_device *dev = arg1; - char buf[128]; - int retcode; - int hasunique = 0; - - DRM_SYSCTL_PRINT("%s 0x%x", dev->driver->name, dev2udev(dev->devnode)); - - DRM_LOCK(dev); - if (dev->unique) { - ksnprintf(buf, sizeof(buf), " %s", dev->unique); - hasunique = 1; - } - DRM_UNLOCK(dev); - - if (hasunique) - SYSCTL_OUT(req, buf, strlen(buf)); - - SYSCTL_OUT(req, "", 1); - -done: - return retcode; -} - -static int drm_vm_info DRM_SYSCTL_HANDLER_ARGS -{ - struct drm_device *dev = arg1; - drm_local_map_t *map, *tempmaps; - const char *types[] = { "FB", "REG", "SHM", "AGP", "SG" }; - const char *type, *yesno; - int i, mapcount; - char buf[128]; - int retcode; - - /* We can't hold the lock while doing SYSCTL_OUTs, so allocate a - * temporary copy of all the map entries and then SYSCTL_OUT that. - */ - DRM_LOCK(dev); - - mapcount = 0; - TAILQ_FOREACH(map, &dev->maplist, link) - mapcount++; - - tempmaps = kmalloc(sizeof(drm_local_map_t) * mapcount, DRM_MEM_DRIVER, - M_NOWAIT); - if (tempmaps == NULL) { - DRM_UNLOCK(dev); - return ENOMEM; - } - - i = 0; - TAILQ_FOREACH(map, &dev->maplist, link) - tempmaps[i++] = *map; - - DRM_UNLOCK(dev); - - DRM_SYSCTL_PRINT("\nslot offset size " - "type flags address handle mtrr\n"); - - for (i = 0; i < mapcount; i++) { - map = &tempmaps[i]; - - if (map->type < 0 || map->type > 4) - type = "??"; - else - type = types[map->type]; - - if (!map->mtrr) - yesno = "no"; - else - yesno = "yes"; - - DRM_SYSCTL_PRINT( - "%4d 0x%016lx 0x%08lx %4.4s 0x%02x 0x%016lx %6d %s\n", - i, map->offset, map->size, type, map->flags, - (unsigned long)map->virtual, - (unsigned int)((unsigned long)map->handle >> - DRM_MAP_HANDLE_SHIFT), yesno); - } - SYSCTL_OUT(req, "", 1); - -done: - drm_free(tempmaps, DRM_MEM_DRIVER); - return retcode; -} - -static int drm_bufs_info DRM_SYSCTL_HANDLER_ARGS -{ - struct drm_device *dev = arg1; - drm_device_dma_t *dma = dev->dma; - drm_device_dma_t tempdma; - int *templists; - int i; - char buf[128]; - int retcode; - - /* We can't hold the locks around DRM_SYSCTL_PRINT, so make a temporary - * copy of the whole structure and the relevant data from buflist. - */ - DRM_LOCK(dev); - if (dma == NULL) { - DRM_UNLOCK(dev); - return 0; - } - spin_lock(&dev->dma_lock); - tempdma = *dma; - templists = kmalloc(sizeof(int) * dma->buf_count, DRM_MEM_DRIVER, - M_NOWAIT); - for (i = 0; i < dma->buf_count; i++) - templists[i] = dma->buflist[i]->list; - dma = &tempdma; - spin_unlock(&dev->dma_lock); - DRM_UNLOCK(dev); - - DRM_SYSCTL_PRINT("\n o size count free segs pages kB\n"); - for (i = 0; i <= DRM_MAX_ORDER; i++) { - if (dma->bufs[i].buf_count) - DRM_SYSCTL_PRINT("%2d %8d %5d %5d %5d %5d %5d\n", - i, - dma->bufs[i].buf_size, - dma->bufs[i].buf_count, - atomic_read(&dma->bufs[i] - .freelist.count), - dma->bufs[i].seg_count, - dma->bufs[i].seg_count - *(1 << dma->bufs[i].page_order), - (dma->bufs[i].seg_count - * (1 << dma->bufs[i].page_order)) - * (int)PAGE_SIZE / 1024); - } - DRM_SYSCTL_PRINT("\n"); - for (i = 0; i < dma->buf_count; i++) { - if (i && !(i%32)) DRM_SYSCTL_PRINT("\n"); - DRM_SYSCTL_PRINT(" %d", templists[i]); - } - DRM_SYSCTL_PRINT("\n"); - - SYSCTL_OUT(req, "", 1); -done: - drm_free(templists, DRM_MEM_DRIVER); - return retcode; -} - -static int drm_clients_info DRM_SYSCTL_HANDLER_ARGS -{ - struct drm_device *dev = arg1; - struct drm_file *priv, *tempprivs; - char buf[128]; - int retcode; - int privcount, i; - - DRM_LOCK(dev); - - privcount = 0; - TAILQ_FOREACH(priv, &dev->files, link) - privcount++; - - tempprivs = kmalloc(sizeof(struct drm_file) * privcount, DRM_MEM_DRIVER, - M_NOWAIT); - if (tempprivs == NULL) { - DRM_UNLOCK(dev); - return ENOMEM; - } - i = 0; - TAILQ_FOREACH(priv, &dev->files, link) - tempprivs[i++] = *priv; - - DRM_UNLOCK(dev); - - DRM_SYSCTL_PRINT( - "\na dev pid uid magic ioctls\n"); - for (i = 0; i < privcount; i++) { - priv = &tempprivs[i]; - DRM_SYSCTL_PRINT("%c %-12s %5d %5d %10u %10lu\n", - priv->authenticated ? 'y' : 'n', - devtoname(priv->dev->devnode), - priv->pid, - priv->uid, - priv->magic, - priv->ioctl_count); - } - - SYSCTL_OUT(req, "", 1); -done: - drm_free(tempprivs, DRM_MEM_DRIVER); - return retcode; -} - -static int drm_vblank_info DRM_SYSCTL_HANDLER_ARGS -{ - struct drm_device *dev = arg1; - char buf[128]; - int retcode; - int i; - - DRM_SYSCTL_PRINT("\ncrtc ref count last enabled inmodeset\n"); - DRM_LOCK(dev); - if (dev->_vblank_count == NULL) - goto done; - for (i = 0 ; i < dev->num_crtcs ; i++) { - DRM_SYSCTL_PRINT(" %02d %02d %08d %08d %02d %02d\n", - i, dev->vblank_refcount[i], - dev->_vblank_count[i], - dev->last_vblank[i], - dev->vblank_enabled[i], - dev->vblank_inmodeset[i]); - } -done: - DRM_UNLOCK(dev); - - SYSCTL_OUT(req, "", -1); - return retcode; -} diff --git a/sys/dev/drm2/drm_vm.c b/sys/dev/drm2/drm_vm.c deleted file mode 100644 index f39616a554..0000000000 --- a/sys/dev/drm2/drm_vm.c +++ /dev/null @@ -1,229 +0,0 @@ -/*- - * Copyright 2003 Eric Anholt - * 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, 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL - * ERIC ANHOLT 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. - * - * $FreeBSD: head/sys/dev/drm2/drm_vm.c 235783 2012-05-22 11:07:44Z kib $" - */ - -/** @file drm_vm.c - * Support code for mmaping of DRM maps. - */ - -#include -#include -#include -#include -#include -#include - -int -drm_mmap(struct dev_mmap_args *ap) -/* - struct cdev *kdev, vm_ooffset_t offset, vm_paddr_t *paddr, - int prot, vm_memattr_t *memattr)*/ -{ - struct cdev *kdev = ap->a_head.a_dev; - vm_offset_t offset = ap->a_offset; - struct drm_device *dev = drm_get_device_from_kdev(kdev); - struct drm_file *file_priv = NULL; - drm_local_map_t *map; - enum drm_map_type type; - vm_paddr_t phys; - - /* d_mmap gets called twice, we can only reference file_priv during - * the first call. We need to assume that if error is EBADF the - * call was succesful and the client is authenticated. - */ - DRM_LOCK(dev); - file_priv = drm_find_file_by_proc(dev, curthread); - DRM_UNLOCK(dev); - - if (!file_priv) { - DRM_ERROR("Could not find authenticator!\n"); - return EINVAL; - } - - if (!file_priv->authenticated) - return EACCES; - - DRM_DEBUG("called with offset %016jx\n", (uintmax_t)offset); - if (dev->dma && offset < ptoa(dev->dma->page_count)) { - drm_device_dma_t *dma = dev->dma; - - spin_lock(&dev->dma_lock); - - if (dma->pagelist != NULL) { - unsigned long page = offset >> PAGE_SHIFT; - phys = dma->pagelist[page]; - - spin_unlock(&dev->dma_lock); - return 0; - } else { - spin_unlock(&dev->dma_lock); - return -1; - } - } - - /* A sequential search of a linked list is - fine here because: 1) there will only be - about 5-10 entries in the list and, 2) a - DRI client only has to do this mapping - once, so it doesn't have to be optimized - for performance, even if the list was a - bit longer. - */ - DRM_LOCK(dev); - TAILQ_FOREACH(map, &dev->maplist, link) { - if (offset >> DRM_MAP_HANDLE_SHIFT == - (unsigned long)map->handle >> DRM_MAP_HANDLE_SHIFT) - break; - } - - if (map == NULL) { - DRM_DEBUG("Can't find map, request offset = %016jx\n", - (uintmax_t)offset); - TAILQ_FOREACH(map, &dev->maplist, link) { - DRM_DEBUG("map offset = %016lx, handle = %016lx\n", - map->offset, (unsigned long)map->handle); - } - DRM_UNLOCK(dev); - return -1; - } - if (((map->flags & _DRM_RESTRICTED) && !DRM_SUSER(DRM_CURPROC))) { - DRM_UNLOCK(dev); - DRM_DEBUG("restricted map\n"); - return -1; - } - type = map->type; - DRM_UNLOCK(dev); - - offset = offset & ((1ULL << DRM_MAP_HANDLE_SHIFT) - 1); - - switch (type) { - case _DRM_FRAME_BUFFER: - case _DRM_AGP: -#if 0 /* XXX */ - memattr = VM_MEMATTR_WRITE_COMBINING; -#endif - /* FALLTHROUGH */ - case _DRM_REGISTERS: - phys = map->offset + offset; - break; - case _DRM_SCATTER_GATHER: -#if 0 /* XXX */ - memattr = VM_MEMATTR_WRITE_COMBINING; -#endif - /* FALLTHROUGH */ - case _DRM_CONSISTENT: - case _DRM_SHM: - phys = vtophys((char *)map->virtual + offset); - break; - default: - DRM_ERROR("bad map type %d\n", type); - return -1; /* This should never happen. */ - } - - ap->a_result = atop(phys); - return 0; -} - -/* XXX The following is just temporary hack to replace the - * vm_phys_fictitious functions available on FreeBSD - */ -#define VM_PHYS_FICTITIOUS_NSEGS 8 -static struct vm_phys_fictitious_seg { - vm_paddr_t start; - vm_paddr_t end; - vm_page_t first_page; -} vm_phys_fictitious_segs[VM_PHYS_FICTITIOUS_NSEGS]; -static struct mtx vm_phys_fictitious_reg_mtx = MTX_INITIALIZER; - -vm_page_t -vm_phys_fictitious_to_vm_page(vm_paddr_t pa) -{ - struct vm_phys_fictitious_seg *seg; - vm_page_t m; - int segind; - - m = NULL; - for (segind = 0; segind < VM_PHYS_FICTITIOUS_NSEGS; segind++) { - seg = &vm_phys_fictitious_segs[segind]; - if (pa >= seg->start && pa < seg->end) { - m = &seg->first_page[atop(pa - seg->start)]; - KASSERT((m->flags & PG_FICTITIOUS) != 0, - ("%p not fictitious", m)); - break; - } - } - return (m); -} - -static void page_init(vm_page_t m, vm_paddr_t paddr, int pat_mode) -{ - bzero(m, sizeof(*m)); - - pmap_page_init(m); - - //m->flags = PG_BUSY | PG_FICTITIOUS; - m->flags = PG_FICTITIOUS; - m->valid = VM_PAGE_BITS_ALL; - m->dirty = 0; - m->busy = 0; - m->queue = PQ_NONE; - m->object = NULL; - m->pat_mode = pat_mode; - - m->wire_count = 1; - m->hold_count = 0; - m->phys_addr = paddr; -} - -int -vm_phys_fictitious_reg_range(vm_paddr_t start, vm_paddr_t end, int pat_mode) -{ - struct vm_phys_fictitious_seg *seg; - vm_page_t fp; - long i, page_count; - int segind; - - page_count = (end - start) / PAGE_SIZE; - - fp = kmalloc(page_count * sizeof(struct vm_page), DRM_MEM_DRIVER, - M_WAITOK | M_ZERO); - - for (i = 0; i < page_count; i++) { - page_init(&fp[i], start + PAGE_SIZE * i, pat_mode); - } - mtx_lock(&vm_phys_fictitious_reg_mtx); - for (segind = 0; segind < VM_PHYS_FICTITIOUS_NSEGS; segind++) { - seg = &vm_phys_fictitious_segs[segind]; - if (seg->start == 0 && seg->end == 0) { - seg->start = start; - seg->end = end; - seg->first_page = fp; - mtx_unlock(&vm_phys_fictitious_reg_mtx); - return (0); - } - } - mtx_unlock(&vm_phys_fictitious_reg_mtx); - drm_free(fp, DRM_MEM_DRIVER); - return (EBUSY); -} diff --git a/sys/dev/drm2/drmn/Makefile b/sys/dev/drm2/drmn/Makefile deleted file mode 100644 index 0962a1a0e2..0000000000 --- a/sys/dev/drm2/drmn/Makefile +++ /dev/null @@ -1,48 +0,0 @@ -.PATH: ${.CURDIR}/.. ${.CURDIR}/../ttm -KMOD = drmn -SRCS = \ - drm_agpsupport.c \ - drm_auth.c \ - drm_bufs.c \ - drm_context.c \ - drm_crtc.c \ - drm_crtc_helper.c \ - drm_dma.c \ - drm_dp_iic_helper.c \ - drm_drawable.c \ - drm_drv.c \ - drm_edid.c \ - drm_fb_helper.c \ - drm_fops.c \ - drm_gem.c \ - drm_gem_names.c \ - drm_global.c \ - drm_hashtab.c \ - drm_ioctl.c \ - drm_irq.c \ - drm_linux_list_sort.c \ - drm_lock.c \ - drm_memory.c \ - drm_mm.c \ - drm_modes.c \ - drm_pci.c \ - drm_scatter.c \ - drm_sman.c \ - drm_stub.c \ - drm_sysctl.c \ - drm_vm.c \ - ttm_lock.c \ - ttm_object.c \ - ttm_tt.c \ - ttm_bo_util.c \ - ttm_bo.c \ - ttm_bo_manager.c \ - ttm_execbuf_util.c \ - ttm_memory.c \ - ttm_page_alloc.c \ - ttm_bo_vm.c - -SRCS += device_if.h bus_if.h pci_if.h device_if.h iicbus_if.h opt_drm.h \ - opt_ktr.h opt_vm.h - -.include -- 2.41.0