Buffer object driver for via.
Some changes to buffer object driver callbacks.
Improve fence flushing.
drmFence *fence)
{
drm_fence_arg_t arg;
-
+
memset(&arg, 0, sizeof(arg));
+ arg.flags = flags;
arg.type = type;
arg.class = class;
arg.op = drm_fence_create;
ffb-objs := ffb_drv.o ffb_context.o
savage-objs := savage_drv.o savage_bci.o savage_state.o
via-objs := via_irq.o via_drv.o via_map.o via_mm.o via_dma.o via_verifier.o \
- via_video.o via_dmablit.o
-mach64-objs := mach64_drv.o mach64_dma.o mach64_irq.o mach64_state.o
+ via_video.o via_dmablit.o via_fence.o via_buffer.o
+mach64-objs := mach64_drv.o mach64_dma.o mach64_irq.o mach64_state.o
nv-objs := nv_drv.o
ifeq ($(CONFIG_COMPAT),y)
}
evict_mem = bo->mem;
- evict_mem.mask = dev->driver->bo_driver->evict_flags(dev, mem_type);
+ evict_mem.mask = dev->driver->bo_driver->evict_mask(bo);
ret = drm_bo_mem_space(bo, &evict_mem, no_wait);
if (ret) {
DRM_DEBUG("New flags 0x%08x, Old flags 0x%08x\n", bo->mem.mask,
bo->mem.flags);
ret =
- driver->fence_type(bo->mem.mask, &bo->fence_class, &bo->fence_type);
+ driver->fence_type(bo, &bo->fence_class, &bo->fence_type);
if (ret) {
DRM_ERROR("Driver did not support given buffer permissions\n");
return ret;
return ret;
}
-static int drm_bo_init_mm(drm_device_t * dev,
- unsigned type,
- unsigned long p_offset, unsigned long p_size)
+int drm_bo_init_mm(drm_device_t * dev,
+ unsigned type,
+ unsigned long p_offset, unsigned long p_size)
{
drm_buffer_manager_t *bm = &dev->bm;
int ret = -EINVAL;
return 0;
}
+EXPORT_SYMBOL(drm_bo_init_mm);
/*
* This is called from lastclose, so we don't need to bother about
}
+ fc->pending_flush &= ~type;
+ if (fc->pending_exe_flush && (type & DRM_FENCE_TYPE_EXE) &&
+ ((sequence - fc->exe_flush_sequence) < driver->wrap_diff))
+ fc->pending_exe_flush = 0;
+
if (wake) {
DRM_WAKEUP(&fc->fence_queue);
}
*/
list = &fc->ring;
- if (list->next == &fc->ring) {
+ if (list_empty(list)) {
return;
} else {
drm_fence_object_t *fence =
static int drm_fence_lazy_wait(drm_device_t *dev,
drm_fence_object_t *fence,
- int ignore_signals, uint32_t mask)
+ int ignore_signals,
+ uint32_t mask)
{
drm_fence_manager_t *fm = &dev->fm;
drm_fence_class_manager_t *fc = &fm->class[fence->class];
do {
DRM_WAIT_ON(ret, fc->fence_queue, 3 * DRM_HZ,
- fence_signaled(dev, fence, mask, 1));
+ fence_signaled(dev, fence, mask, 0));
if (time_after_eq(jiffies, _end))
break;
} while (ret == -EINTR && ignore_signals);
return ret;
}
}
- if (fence_signaled(dev, fence, mask, 0))
+ if (drm_fence_object_signaled(fence, mask))
return 0;
- DRM_ERROR("Busy wait\n");
/*
* Avoid kernel-space busy-waits.
*/
uint32_t num_mem_busy_prio;
drm_ttm_backend_t *(*create_ttm_backend_entry)
(struct drm_device * dev);
- int (*fence_type) (uint32_t flags, uint32_t * class, uint32_t * type);
+ int (*fence_type) (struct drm_buffer_object *bo, uint32_t * class, uint32_t * type);
int (*invalidate_caches) (struct drm_device * dev, uint32_t flags);
int (*init_mem_type) (struct drm_device * dev, uint32_t type,
drm_mem_type_manager_t * man);
- uint32_t(*evict_flags) (struct drm_device * dev, uint32_t type);
+ uint32_t(*evict_mask) (struct drm_buffer_object *bo);
int (*move) (struct drm_buffer_object * bo,
int evict, int no_wait, struct drm_bo_mem_reg * new_mem);
} drm_bo_driver_t;
return drm_agp_init_ttm(dev, NULL);
}
-int i915_fence_types(uint32_t buffer_flags, uint32_t * class, uint32_t * type)
+int i915_fence_types(drm_buffer_object_t *bo, uint32_t * class, uint32_t * type)
{
*class = 0;
- if (buffer_flags & (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE))
+ if (bo->mem.flags & (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE))
*type = 3;
else
*type = 1;
return 0;
}
-uint32_t i915_evict_flags(drm_device_t * dev, uint32_t type)
+uint32_t i915_evict_mask(drm_buffer_object_t *bo)
{
- switch (type) {
+ switch (bo->mem.mem_type) {
case DRM_BO_MEM_LOCAL:
case DRM_BO_MEM_TT:
return DRM_BO_FLAG_MEM_LOCAL;
.fence_type = i915_fence_types,
.invalidate_caches = i915_invalidate_caches,
.init_mem_type = i915_init_mem_type,
- .evict_flags = i915_evict_flags,
+ .evict_mask = i915_evict_mask,
.move = i915_move,
};
#endif
#ifdef I915_HAVE_BUFFER
/* i915_buffer.c */
extern drm_ttm_backend_t *i915_create_ttm_backend_entry(drm_device_t *dev);
-extern int i915_fence_types(uint32_t buffer_flags, uint32_t *class, uint32_t *type);
+extern int i915_fence_types(drm_buffer_object_t *bo, uint32_t *class, uint32_t *type);
extern int i915_invalidate_caches(drm_device_t *dev, uint32_t buffer_flags);
-extern int i915_init_mem_type(drm_device_t *dev, uint32_t type,
+extern int i915_init_mem_type(drm_device_t *dev, uint32_t type,
drm_mem_type_manager_t *man);
-extern uint32_t i915_evict_flags(drm_device_t *dev, uint32_t type);
+extern uint32_t i915_evict_mask(drm_buffer_object_t *bo);
extern int i915_move(drm_buffer_object_t *bo, int evict,
int no_wait, drm_bo_mem_reg_t *new_mem);
#include "via_drv.h"
#include "via_3d_reg.h"
-#define CMDBUF_ALIGNMENT_SIZE (0x100)
-#define CMDBUF_ALIGNMENT_MASK (0x0ff)
-
-/* defines for VIA 3D registers */
-#define VIA_REG_STATUS 0x400
-#define VIA_REG_TRANSET 0x43C
-#define VIA_REG_TRANSPACE 0x440
-
-/* VIA_REG_STATUS(0x400): Engine Status */
-#define VIA_CMD_RGTR_BUSY 0x00000080 /* Command Regulator is busy */
-#define VIA_2D_ENG_BUSY 0x00000001 /* 2D Engine is busy */
-#define VIA_3D_ENG_BUSY 0x00000002 /* 3D Engine is busy */
-#define VIA_VR_QUEUE_BUSY 0x00020000 /* Virtual Queue is busy */
-
#define SetReg2DAGP(nReg, nData) { \
*((uint32_t *)(vb)) = ((nReg) >> 2) | HALCYON_HEADER1; \
*((uint32_t *)(vb) + 1) = (nData); \
(VIA_MAX_CACHELINE_SIZE - 1)) & \
~(VIA_MAX_CACHELINE_SIZE - 1)) + \
VIA_MAX_CACHELINE_SIZE*(lockNo)))
-
-/* Each region is a minimum of 64k, and there are at most 64 of them.
- */
#define VIA_NR_TEX_REGIONS 64
-#define VIA_LOG_MIN_TEX_REGION_SIZE 16
+
#endif
-#define VIA_UPLOAD_TEX0IMAGE 0x1 /* handled clientside */
-#define VIA_UPLOAD_TEX1IMAGE 0x2 /* handled clientside */
-#define VIA_UPLOAD_CTX 0x4
-#define VIA_UPLOAD_BUFFERS 0x8
-#define VIA_UPLOAD_TEX0 0x10
-#define VIA_UPLOAD_TEX1 0x20
-#define VIA_UPLOAD_CLIPRECTS 0x40
-#define VIA_UPLOAD_ALL 0xff
+#define DRM_VIA_FENCE_TYPE_ACCEL 0x00000002
/* VIA specific ioctls */
#define DRM_VIA_ALLOCMEM 0x00
viadrv_PCI_IDS
};
+
+#ifdef VIA_HAVE_FENCE
+static drm_fence_driver_t via_fence_driver = {
+ .num_classes = 1,
+ .wrap_diff = (1 << 30),
+ .flush_diff = (1 << 20),
+ .sequence_mask = 0xffffffffU,
+ .lazy_capable = 1,
+ .emit = via_fence_emit_sequence,
+ .poke_flush = via_poke_flush,
+ .has_irq = via_fence_has_irq,
+};
+#endif
+#ifdef VIA_HAVE_BUFFER
+
+/**
+ * If there's no thrashing. This is the preferred memory type order.
+ */
+static uint32_t via_mem_prios[] = {DRM_BO_MEM_PRIV0, DRM_BO_MEM_VRAM, DRM_BO_MEM_TT, DRM_BO_MEM_LOCAL};
+
+/**
+ * If we have thrashing, most memory will be evicted to TT anyway, so we might as well
+ * just move the new buffer into TT from the start.
+ */
+static uint32_t via_busy_prios[] = {DRM_BO_MEM_TT, DRM_BO_MEM_PRIV0, DRM_BO_MEM_VRAM, DRM_BO_MEM_LOCAL};
+
+
+static drm_bo_driver_t via_bo_driver = {
+ .mem_type_prio = via_mem_prios,
+ .mem_busy_prio = via_busy_prios,
+ .num_mem_type_prio = ARRAY_SIZE(via_mem_prios),
+ .num_mem_busy_prio = ARRAY_SIZE(via_busy_prios),
+ .create_ttm_backend_entry = via_create_ttm_backend_entry,
+ .fence_type = via_fence_types,
+ .invalidate_caches = via_invalidate_caches,
+ .init_mem_type = via_init_mem_type,
+ .evict_mask = via_evict_mask,
+ .move = NULL,
+};
+#endif
+
static int probe(struct pci_dev *pdev, const struct pci_device_id *ent);
static struct drm_driver driver = {
.driver_features =
.probe = probe,
.remove = __devexit_p(drm_cleanup_pci),
},
-
+#ifdef VIA_HAVE_FENCE
+ .fence_driver = &via_fence_driver,
+#endif
+#ifdef VIA_HAVE_BUFFER
+ .bo_driver = &via_bo_driver,
+#endif
.name = DRIVER_NAME,
.desc = DRIVER_DESC,
.date = VIA_DRM_DRIVER_DATE,
#include "via_verifier.h"
+/*
+ * Registers go here.
+ */
+
+
+#define CMDBUF_ALIGNMENT_SIZE (0x100)
+#define CMDBUF_ALIGNMENT_MASK (0x0ff)
+
+/* defines for VIA 3D registers */
+#define VIA_REG_STATUS 0x400
+#define VIA_REG_TRANSET 0x43C
+#define VIA_REG_TRANSPACE 0x440
+
+/* VIA_REG_STATUS(0x400): Engine Status */
+#define VIA_CMD_RGTR_BUSY 0x00000080 /* Command Regulator is busy */
+#define VIA_2D_ENG_BUSY 0x00000001 /* 2D Engine is busy */
+#define VIA_3D_ENG_BUSY 0x00000002 /* 3D Engine is busy */
+#define VIA_VR_QUEUE_BUSY 0x00020000 /* Virtual Queue is busy */
+
+
+
#if defined(__linux__)
#include "via_dmablit.h"
*/
#define VIA_HAVE_DMABLIT 1
#define VIA_HAVE_CORE_MM 1
+#define VIA_HAVE_FENCE 1
+#define VIA_HAVE_BUFFER 1
#endif
#define VIA_PCI_BUF_SIZE 60000
drm_via_blitq_t blit_queues[VIA_NUM_BLIT_ENGINES];
#endif
uint32_t dma_diff;
+#ifdef VIA_HAVE_FENCE
+ spinlock_t fence_lock;
+ uint32_t emit_0_sequence;
+ int have_idlelock;
+ struct timer_list fence_timer;
+#endif
} drm_via_private_t;
enum via_family {
extern void via_init_dmablit(drm_device_t *dev);
#endif
+#ifdef VIA_HAVE_FENCE
+extern void via_fence_timer(unsigned long data);
+extern void via_poke_flush(drm_device_t * dev, uint32_t class);
+extern int via_fence_emit_sequence(drm_device_t * dev, uint32_t class,
+ uint32_t flags,
+ uint32_t * sequence,
+ uint32_t * native_type);
+extern int via_fence_has_irq(struct drm_device * dev, uint32_t class,
+ uint32_t flags);
+#endif
+
+#ifdef VIA_HAVE_BUFFER
+extern drm_ttm_backend_t *via_create_ttm_backend_entry(drm_device_t *dev);
+extern int via_fence_types(drm_buffer_object_t *bo, uint32_t *class, uint32_t *type);
+extern int via_invalidate_caches(drm_device_t *dev, uint32_t buffer_flags);
+extern int via_init_mem_type(drm_device_t *dev, uint32_t type,
+ drm_mem_type_manager_t *man);
+extern uint32_t via_evict_mask(drm_buffer_object_t *bo);
+extern int via_move(drm_buffer_object_t *bo, int evict,
+ int no_wait, drm_bo_mem_reg_t *new_mem);
+#endif
+
#endif
static int via_do_init_map(drm_device_t * dev, drm_via_init_t * init)
{
drm_via_private_t *dev_priv = dev->dev_private;
+ int ret = 0;
DRM_DEBUG("%s\n", __FUNCTION__);
#ifdef VIA_HAVE_DMABLIT
via_init_dmablit( dev );
#endif
+#ifdef VIA_HAVE_FENCE
+ dev_priv->emit_0_sequence = 0;
+ dev_priv->have_idlelock = 0;
+ spin_lock_init(&dev_priv->fence_lock);
+ init_timer(&dev_priv->fence_timer);
+ dev_priv->fence_timer.function = &via_fence_timer;
+ dev_priv->fence_timer.data = (unsigned long) dev;
+#endif /* VIA_HAVE_FENCE */
dev->dev_private = (void *)dev_priv;
- return 0;
+#ifdef VIA_HAVE_BUFFER
+ ret = drm_bo_driver_init(dev);
+ if (ret)
+ DRM_ERROR("Could not initialize buffer object driver.\n");
+#endif
+ return ret;
+
}
int via_do_cleanup_map(drm_device_t * dev)