svn commit: r189180 - projects/jbuild/sys/dev/drm
John Birrell
jb at FreeBSD.org
Sat Feb 28 09:56:12 PST 2009
Author: jb
Date: Sat Feb 28 17:56:11 2009
New Revision: 189180
URL: http://svn.freebsd.org/changeset/base/189180
Log:
MFC
Added:
projects/jbuild/sys/dev/drm/i915_reg.h
- copied unchanged from r189173, head/sys/dev/drm/i915_reg.h
Modified:
projects/jbuild/sys/dev/drm/drmP.h
projects/jbuild/sys/dev/drm/drm_bufs.c
projects/jbuild/sys/dev/drm/drm_drv.c
projects/jbuild/sys/dev/drm/drm_irq.c
projects/jbuild/sys/dev/drm/drm_lock.c
projects/jbuild/sys/dev/drm/i915_dma.c
projects/jbuild/sys/dev/drm/i915_drv.c
projects/jbuild/sys/dev/drm/i915_drv.h
projects/jbuild/sys/dev/drm/i915_irq.c
projects/jbuild/sys/dev/drm/mach64_drv.c
projects/jbuild/sys/dev/drm/mach64_drv.h
projects/jbuild/sys/dev/drm/mach64_irq.c
projects/jbuild/sys/dev/drm/mga_dma.c
projects/jbuild/sys/dev/drm/mga_irq.c
projects/jbuild/sys/dev/drm/r128_drv.c
projects/jbuild/sys/dev/drm/r128_drv.h
projects/jbuild/sys/dev/drm/r128_irq.c
projects/jbuild/sys/dev/drm/radeon_cp.c
projects/jbuild/sys/dev/drm/radeon_irq.c
Modified: projects/jbuild/sys/dev/drm/drmP.h
==============================================================================
--- projects/jbuild/sys/dev/drm/drmP.h Sat Feb 28 17:55:32 2009 (r189179)
+++ projects/jbuild/sys/dev/drm/drmP.h Sat Feb 28 17:56:11 2009 (r189180)
@@ -63,7 +63,6 @@ struct drm_file;
#include <sys/signalvar.h>
#include <sys/poll.h>
#include <sys/tree.h>
-#include <sys/taskqueue.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <vm/vm_extern.h>
@@ -294,8 +293,8 @@ for ( ret = 0 ; !ret && !(condition) ; )
DRM_UNLOCK(); \
mtx_lock(&dev->irq_lock); \
if (!(condition)) \
- ret = -mtx_sleep(&(queue), &dev->irq_lock, \
- PZERO | PCATCH, "drmwtq", (timeout)); \
+ ret = -mtx_sleep(&(queue), &dev->irq_lock, \
+ PCATCH, "drmwtq", (timeout)); \
mtx_unlock(&dev->irq_lock); \
DRM_LOCK(); \
}
@@ -320,6 +319,12 @@ typedef struct drm_pci_id_list
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
@@ -628,7 +633,6 @@ struct drm_device {
struct mtx irq_lock; /* protects irq condition checks */
struct mtx dev_lock; /* protects everything else */
DRM_SPINTYPE drw_lock;
- DRM_SPINTYPE tsk_lock;
/* Usage Counters */
int open_count; /* Outstanding files open */
@@ -657,6 +661,7 @@ struct drm_device {
/* 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 */
@@ -695,9 +700,6 @@ struct drm_device {
struct unrhdr *drw_unrhdr;
/* RB tree of drawable infos */
RB_HEAD(drawable_tree, bsd_drm_drawable_info) drw_head;
-
- struct task locked_task;
- void (*locked_task_call)(struct drm_device *dev);
};
static __inline__ int drm_core_check_feature(struct drm_device *dev,
@@ -792,6 +794,7 @@ void drm_handle_vblank(struct drm_device
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_vbl_send_signals(struct drm_device *dev, int crtc);
@@ -899,8 +902,8 @@ int drm_addmap_ioctl(struct drm_device *
struct drm_file *file_priv);
int drm_rmmap_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
-int drm_addbufs_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,
@@ -918,8 +921,6 @@ int drm_control(struct drm_device *dev,
struct drm_file *file_priv);
int drm_wait_vblank(struct drm_device *dev, void *data,
struct drm_file *file_priv);
-void drm_locked_tasklet(struct drm_device *dev,
- void (*tasklet)(struct drm_device *dev));
/* AGP/GART support (drm_agpsupport.c) */
int drm_agp_acquire_ioctl(struct drm_device *dev, void *data,
Modified: projects/jbuild/sys/dev/drm/drm_bufs.c
==============================================================================
--- projects/jbuild/sys/dev/drm/drm_bufs.c Sat Feb 28 17:55:32 2009 (r189179)
+++ projects/jbuild/sys/dev/drm/drm_bufs.c Sat Feb 28 17:56:11 2009 (r189180)
@@ -880,8 +880,7 @@ int drm_addbufs_pci(struct drm_device *d
return ret;
}
-int drm_addbufs_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)
{
struct drm_buf_desc *request = data;
int err;
Modified: projects/jbuild/sys/dev/drm/drm_drv.c
==============================================================================
--- projects/jbuild/sys/dev/drm/drm_drv.c Sat Feb 28 17:55:32 2009 (r189179)
+++ projects/jbuild/sys/dev/drm/drm_drv.c Sat Feb 28 17:56:11 2009 (r189180)
@@ -82,7 +82,7 @@ static drm_ioctl_desc_t drm_ioctls[25
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_ADD_CTX, drm_addctx, DRM_AUTH|DRM_MASTER|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),
@@ -95,10 +95,11 @@ static drm_ioctl_desc_t drm_ioctls[25
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_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF(DRM_IOCTL_MARK_BUFS, drm_markbufs, DRM_AUTH|DRM_MASTER),
+ 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),
@@ -117,7 +118,6 @@ static drm_ioctl_desc_t drm_ioctls[25
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_MODESET_CTL, drm_modeset_ctl, 0),
DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_update_draw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
@@ -131,9 +131,33 @@ static struct cdevsw drm_cdevsw = {
.d_poll = drm_poll,
.d_mmap = drm_mmap,
.d_name = "drm",
- .d_flags = D_TRACKCLOSE | D_NEEDGIANT
+ .d_flags = D_TRACKCLOSE
};
+int drm_msi = 1; /* Enable by default. */
+TUNABLE_INT("hw.drm.msi", &drm_msi);
+
+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 dev, drm_pci_id_list_t *idlist)
{
drm_pci_id_list_t *id_entry;
@@ -169,7 +193,7 @@ int drm_attach(device_t nbdev, drm_pci_i
{
struct drm_device *dev;
drm_pci_id_list_t *id_entry;
- int unit;
+ int unit, msicount;
unit = device_get_unit(nbdev);
dev = device_get_softc(nbdev);
@@ -189,22 +213,67 @@ int drm_attach(device_t nbdev, drm_pci_i
DRM_DEV_MODE,
"dri/card%d", unit);
+#if __FreeBSD_version >= 700053
+ dev->pci_domain = pci_get_domain(dev->device);
+#else
+ dev->pci_domain = 0;
+#endif
+ 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_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, &msicount) == 0) {
+ DRM_INFO("MSI enabled %d message(s)\n", msicount);
+ dev->msi_enabled = 1;
+ dev->irqrid = 1;
+ }
+ }
+
+ 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);
+
mtx_init(&dev->dev_lock, "drmdev", NULL, MTX_DEF);
mtx_init(&dev->irq_lock, "drmirq", NULL, MTX_DEF);
mtx_init(&dev->vbl_lock, "drmvbl", NULL, MTX_DEF);
mtx_init(&dev->drw_lock, "drmdrw", NULL, MTX_DEF);
- mtx_init(&dev->tsk_lock, "drmtsk", NULL, MTX_DEF);
- id_entry = drm_find_description(pci_get_vendor(dev->device),
- pci_get_device(dev->device), idlist);
+ 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 dev)
+int drm_detach(device_t nbdev)
{
- drm_unload(device_get_softc(dev));
+ struct drm_device *dev;
+
+ dev = device_get_softc(nbdev);
+
+ drm_unload(dev);
+
+ 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;
}
@@ -353,19 +422,6 @@ static int drm_load(struct drm_device *d
DRM_DEBUG("\n");
- dev->irq = pci_get_irq(dev->device);
-#if __FreeBSD_version >= 700053
- dev->pci_domain = pci_get_domain(dev->device);
-#else
- dev->pci_domain = 0;
-#endif
- 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);
-
TAILQ_INIT(&dev->maplist);
drm_mem_init();
@@ -440,7 +496,6 @@ error:
DRM_UNLOCK();
destroy_dev(dev->devnode);
- mtx_destroy(&dev->tsk_lock);
mtx_destroy(&dev->drw_lock);
mtx_destroy(&dev->vbl_lock);
mtx_destroy(&dev->irq_lock);
@@ -468,6 +523,8 @@ static void drm_unload(struct drm_device
DRM_DEBUG("mtrr_del = %d", retcode);
}
+ drm_vblank_cleanup(dev);
+
DRM_LOCK();
drm_lastclose(dev);
DRM_UNLOCK();
@@ -503,14 +560,12 @@ static void drm_unload(struct drm_device
if (pci_disable_busmaster(dev->device))
DRM_ERROR("Request to disable bus-master failed.\n");
- mtx_destroy(&dev->tsk_lock);
mtx_destroy(&dev->drw_lock);
mtx_destroy(&dev->vbl_lock);
mtx_destroy(&dev->irq_lock);
mtx_destroy(&dev->dev_lock);
}
-
int drm_version(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
struct drm_version *version = data;
@@ -658,9 +713,7 @@ int drm_ioctl(struct cdev *kdev, u_long
int is_driver_ioctl = 0;
struct drm_file *file_priv;
- DRM_LOCK();
retcode = devfs_get_cdevpriv((void **)&file_priv);
- DRM_UNLOCK();
if (retcode != 0) {
DRM_ERROR("can't find authenticator\n");
return EINVAL;
Modified: projects/jbuild/sys/dev/drm/drm_irq.c
==============================================================================
--- projects/jbuild/sys/dev/drm/drm_irq.c Sat Feb 28 17:55:32 2009 (r189179)
+++ projects/jbuild/sys/dev/drm/drm_irq.c Sat Feb 28 17:56:11 2009 (r189180)
@@ -36,8 +36,6 @@ __FBSDID("$FreeBSD$");
#include "dev/drm/drmP.h"
#include "dev/drm/drm.h"
-static void drm_locked_task(void *context, int pending __unused);
-
int drm_irq_by_busid(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
@@ -98,7 +96,7 @@ static void vblank_disable_fn(void *arg)
}
}
-static void drm_vblank_cleanup(struct drm_device *dev)
+void drm_vblank_cleanup(struct drm_device *dev)
{
unsigned long irqflags;
@@ -174,13 +172,6 @@ int drm_irq_install(struct drm_device *d
DRM_UNLOCK();
/* Install handler */
- dev->irqrid = 0;
- dev->irqr = bus_alloc_resource_any(dev->device, SYS_RES_IRQ,
- &dev->irqrid, RF_SHAREABLE);
- if (!dev->irqr) {
- retcode = ENOENT;
- goto err;
- }
#if __FreeBSD_version >= 700031
retcode = bus_setup_intr(dev->device, dev->irqr,
INTR_TYPE_TTY | INTR_MPSAFE,
@@ -198,30 +189,21 @@ int drm_irq_install(struct drm_device *d
dev->driver->irq_postinstall(dev);
DRM_UNLOCK();
- TASK_INIT(&dev->locked_task, 0, drm_locked_task, dev);
return 0;
err:
DRM_LOCK();
dev->irq_enabled = 0;
- if (dev->irqrid != 0) {
- bus_release_resource(dev->device, SYS_RES_IRQ, dev->irqrid,
- dev->irqr);
- dev->irqrid = 0;
- }
DRM_UNLOCK();
+
return retcode;
}
int drm_irq_uninstall(struct drm_device *dev)
{
- int irqrid;
-
if (!dev->irq_enabled)
return EINVAL;
dev->irq_enabled = 0;
- irqrid = dev->irqrid;
- dev->irqrid = 0;
DRM_DEBUG("irq=%d\n", dev->irq);
@@ -229,11 +211,8 @@ int drm_irq_uninstall(struct drm_device
DRM_UNLOCK();
bus_teardown_intr(dev->device, dev->irqr, dev->irqh);
- bus_release_resource(dev->device, SYS_RES_IRQ, irqrid, dev->irqr);
DRM_LOCK();
- drm_vblank_cleanup(dev);
-
return 0;
}
@@ -304,6 +283,7 @@ int drm_vblank_get(struct drm_device *de
DRM_SPINLOCK_IRQSAVE(&dev->vbl_lock, irqflags);
/* Going from 0->1 means we have to enable interrupts again */
atomic_add_acq_int(&dev->vblank[crtc].refcount, 1);
+ DRM_DEBUG("vblank refcount = %d\n", dev->vblank[crtc].refcount);
if (dev->vblank[crtc].refcount == 1 &&
!dev->vblank[crtc].enabled) {
ret = dev->driver->enable_vblank(dev, crtc);
@@ -326,6 +306,7 @@ void drm_vblank_put(struct drm_device *d
DRM_SPINLOCK_IRQSAVE(&dev->vbl_lock, irqflags);
/* Last user schedules interrupt disable */
atomic_subtract_acq_int(&dev->vblank[crtc].refcount, 1);
+ DRM_DEBUG("vblank refcount = %d\n", dev->vblank[crtc].refcount);
if (dev->vblank[crtc].refcount == 0)
callout_reset(&dev->vblank_disable_timer, 5 * DRM_HZ,
(timeout_t *)vblank_disable_fn, (void *)dev);
@@ -388,8 +369,8 @@ out:
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;
- int flags, seq, crtc;
if (!dev->irq_enabled)
return EINVAL;
@@ -409,8 +390,10 @@ int drm_wait_vblank(struct drm_device *d
return EINVAL;
ret = drm_vblank_get(dev, crtc);
- if (ret)
+ if (ret) {
+ DRM_ERROR("failed to acquire vblank counter, %d\n", ret);
return ret;
+ }
seq = drm_vblank_count(dev, crtc);
switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) {
@@ -449,14 +432,20 @@ int drm_wait_vblank(struct drm_device *d
#endif
ret = EINVAL;
} else {
- DRM_LOCK();
- /* shared code returns -errno */
-
- DRM_WAIT_ON(ret, dev->vblank[crtc].queue, 3 * DRM_HZ,
- ((drm_vblank_count(dev, crtc)
- - vblwait->request.sequence) <= (1 << 23)));
- DRM_UNLOCK();
+ 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)) ; ) {
+ mtx_lock(&dev->irq_lock);
+ if (!((drm_vblank_count(dev, crtc) -
+ vblwait->request.sequence) <= (1 << 23)))
+ ret = mtx_sleep(&dev->vblank[crtc].queue,
+ &dev->irq_lock, PCATCH, "vblwtq",
+ 3 * DRM_HZ);
+ mtx_unlock(&dev->irq_lock);
+ }
+ DRM_DEBUG("return = %d\n", ret);
if (ret != EINTR) {
struct timeval now;
@@ -464,6 +453,10 @@ int drm_wait_vblank(struct drm_device *d
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\n",
+ vblwait->reply.sequence);
+ } else {
+ DRM_DEBUG("vblank wait interrupted by signal\n");
}
}
@@ -507,46 +500,3 @@ void drm_handle_vblank(struct drm_device
drm_vbl_send_signals(dev, crtc);
}
-static void drm_locked_task(void *context, int pending __unused)
-{
- struct drm_device *dev = context;
-
- DRM_SPINLOCK(&dev->tsk_lock);
-
- DRM_LOCK(); /* XXX drm_lock_take() should do it's own locking */
- if (dev->locked_task_call == NULL ||
- drm_lock_take(&dev->lock, DRM_KERNEL_CONTEXT) == 0) {
- DRM_UNLOCK();
- DRM_SPINUNLOCK(&dev->tsk_lock);
- return;
- }
-
- dev->lock.file_priv = NULL; /* kernel owned */
- dev->lock.lock_time = jiffies;
- atomic_inc(&dev->counts[_DRM_STAT_LOCKS]);
-
- DRM_UNLOCK();
-
- dev->locked_task_call(dev);
-
- drm_lock_free(&dev->lock, DRM_KERNEL_CONTEXT);
-
- dev->locked_task_call = NULL;
-
- DRM_SPINUNLOCK(&dev->tsk_lock);
-}
-
-void
-drm_locked_tasklet(struct drm_device *dev,
- void (*tasklet)(struct drm_device *dev))
-{
- DRM_SPINLOCK(&dev->tsk_lock);
- if (dev->locked_task_call != NULL) {
- DRM_SPINUNLOCK(&dev->tsk_lock);
- return;
- }
-
- dev->locked_task_call = tasklet;
- DRM_SPINUNLOCK(&dev->tsk_lock);
- taskqueue_enqueue(taskqueue_swi, &dev->locked_task);
-}
Modified: projects/jbuild/sys/dev/drm/drm_lock.c
==============================================================================
--- projects/jbuild/sys/dev/drm/drm_lock.c Sat Feb 28 17:55:32 2009 (r189179)
+++ projects/jbuild/sys/dev/drm/drm_lock.c Sat Feb 28 17:56:11 2009 (r189180)
@@ -115,13 +115,6 @@ int drm_unlock(struct drm_device *dev, v
return EINVAL;
}
- DRM_SPINLOCK(&dev->tsk_lock);
- if (dev->locked_task_call != NULL) {
- dev->locked_task_call(dev);
- dev->locked_task_call = NULL;
- }
- DRM_SPINUNLOCK(&dev->tsk_lock);
-
atomic_inc(&dev->counts[_DRM_STAT_UNLOCKS]);
DRM_LOCK();
Modified: projects/jbuild/sys/dev/drm/i915_dma.c
==============================================================================
--- projects/jbuild/sys/dev/drm/i915_dma.c Sat Feb 28 17:55:32 2009 (r189179)
+++ projects/jbuild/sys/dev/drm/i915_dma.c Sat Feb 28 17:56:11 2009 (r189180)
@@ -58,6 +58,9 @@ int i915_wait_ring(struct drm_device * d
if (ring->space >= n)
return 0;
+ if (dev_priv->sarea_priv)
+ dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
+
if (ring->head != last_head)
i = 0;
@@ -72,77 +75,53 @@ int i915_wait_ring(struct drm_device * d
return -EBUSY;
}
-int i915_init_hardware_status(struct drm_device *dev)
+/**
+ * Sets up the hardware status page for devices that need a physical address
+ * in the register.
+ */
+static int i915_init_phys_hws(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = dev->dev_private;
- drm_dma_handle_t *dmah;
/* Program Hardware Status Page */
-#ifdef __FreeBSD__
DRM_UNLOCK();
-#endif
- dmah = drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff);
-#ifdef __FreeBSD__
+ dev_priv->status_page_dmah =
+ drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff);
DRM_LOCK();
-#endif
- if (!dmah) {
+ if (!dev_priv->status_page_dmah) {
DRM_ERROR("Can not allocate hardware status page\n");
return -ENOMEM;
}
-
- dev_priv->status_page_dmah = dmah;
- dev_priv->hw_status_page = dmah->vaddr;
- dev_priv->dma_status_page = dmah->busaddr;
+ dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr;
+ dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr;
memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
- I915_WRITE(0x02080, dev_priv->dma_status_page);
+ I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
DRM_DEBUG("Enabled hardware status page\n");
return 0;
}
-void i915_free_hardware_status(struct drm_device *dev)
+/**
+ * Frees the hardware status page, whether it's a physical address or a virtual
+ * address set up by the X Server.
+ */
+static void i915_free_hws(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = dev->dev_private;
if (dev_priv->status_page_dmah) {
drm_pci_free(dev, dev_priv->status_page_dmah);
dev_priv->status_page_dmah = NULL;
- /* Need to rewrite hardware status page */
- I915_WRITE(0x02080, 0x1ffff000);
}
if (dev_priv->status_gfx_addr) {
dev_priv->status_gfx_addr = 0;
drm_core_ioremapfree(&dev_priv->hws_map, dev);
- I915_WRITE(0x02080, 0x1ffff000);
}
-}
-#if I915_RING_VALIDATE
-/**
- * Validate the cached ring tail value
- *
- * If the X server writes to the ring and DRM doesn't
- * reload the head and tail pointers, it will end up writing
- * data to the wrong place in the ring, causing havoc.
- */
-void i915_ring_validate(struct drm_device *dev, const char *func, int line)
-{
- drm_i915_private_t *dev_priv = dev->dev_private;
- drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
- u32 tail = I915_READ(PRB0_TAIL) & HEAD_ADDR;
- u32 head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
-
- if (tail != ring->tail) {
- DRM_ERROR("%s:%d head sw %x, hw %x. tail sw %x hw %x\n",
- func, line,
- ring->head, head, ring->tail, tail);
-#ifdef __linux__
- BUG_ON(1);
-#endif
- }
+ /* Need to rewrite hardware status page */
+ I915_WRITE(HWS_PGA, 0x1ffff000);
}
-#endif
void i915_kernel_lost_context(struct drm_device * dev)
{
@@ -154,6 +133,9 @@ void i915_kernel_lost_context(struct drm
ring->space = ring->head - (ring->tail + 8);
if (ring->space < 0)
ring->space += ring->Size;
+
+ if (ring->head == ring->tail && dev_priv->sarea_priv)
+ dev_priv->sarea_priv->perf_boxes |= I915_BOX_RING_EMPTY;
}
static int i915_dma_cleanup(struct drm_device * dev)
@@ -168,86 +150,22 @@ static int i915_dma_cleanup(struct drm_d
if (dev_priv->ring.virtual_start) {
drm_core_ioremapfree(&dev_priv->ring.map, dev);
- dev_priv->ring.virtual_start = 0;
- dev_priv->ring.map.handle = 0;
+ dev_priv->ring.virtual_start = NULL;
+ dev_priv->ring.map.handle = NULL;
dev_priv->ring.map.size = 0;
}
+ /* Clear the HWS virtual address at teardown */
if (I915_NEED_GFX_HWS(dev))
- i915_free_hardware_status(dev);
+ i915_free_hws(dev);
return 0;
}
-#if defined(I915_HAVE_BUFFER)
-#define DRI2_SAREA_BLOCK_TYPE(b) ((b) >> 16)
-#define DRI2_SAREA_BLOCK_SIZE(b) ((b) & 0xffff)
-#define DRI2_SAREA_BLOCK_NEXT(p) \
- ((void *) ((unsigned char *) (p) + \
- DRI2_SAREA_BLOCK_SIZE(*(unsigned int *) p)))
-
-#define DRI2_SAREA_BLOCK_END 0x0000
-#define DRI2_SAREA_BLOCK_LOCK 0x0001
-#define DRI2_SAREA_BLOCK_EVENT_BUFFER 0x0002
-
-static int
-setup_dri2_sarea(struct drm_device * dev,
- struct drm_file *file_priv,
- drm_i915_init_t * init)
+static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
{
drm_i915_private_t *dev_priv = dev->dev_private;
- int ret;
- unsigned int *p, *end, *next;
-
- mutex_lock(&dev->struct_mutex);
- dev_priv->sarea_bo =
- drm_lookup_buffer_object(file_priv,
- init->sarea_handle, 1);
- mutex_unlock(&dev->struct_mutex);
-
- if (!dev_priv->sarea_bo) {
- DRM_ERROR("did not find sarea bo\n");
- return -EINVAL;
- }
-
- ret = drm_bo_kmap(dev_priv->sarea_bo, 0,
- dev_priv->sarea_bo->num_pages,
- &dev_priv->sarea_kmap);
- if (ret) {
- DRM_ERROR("could not map sarea bo\n");
- return ret;
- }
- p = dev_priv->sarea_kmap.virtual;
- end = (void *) p + (dev_priv->sarea_bo->num_pages << PAGE_SHIFT);
- while (p < end && DRI2_SAREA_BLOCK_TYPE(*p) != DRI2_SAREA_BLOCK_END) {
- switch (DRI2_SAREA_BLOCK_TYPE(*p)) {
- case DRI2_SAREA_BLOCK_LOCK:
- dev->lock.hw_lock = (void *) (p + 1);
- dev->sigdata.lock = dev->lock.hw_lock;
- break;
- }
- next = DRI2_SAREA_BLOCK_NEXT(p);
- if (next <= p || end < next) {
- DRM_ERROR("malformed dri2 sarea: next is %p should be within %p-%p\n",
- next, p, end);
- return -EINVAL;
- }
- p = next;
- }
-
- return 0;
-}
-#endif
-
-static int i915_initialize(struct drm_device * dev,
- struct drm_file *file_priv,
- drm_i915_init_t * init)
-{
- drm_i915_private_t *dev_priv = dev->dev_private;
-#if defined(I915_HAVE_BUFFER)
- int ret;
-#endif
dev_priv->sarea = drm_getsarea(dev);
if (!dev_priv->sarea) {
DRM_ERROR("can not find sarea!\n");
@@ -255,20 +173,17 @@ static int i915_initialize(struct drm_de
return -EINVAL;
}
-#ifdef I915_HAVE_BUFFER
- dev_priv->max_validate_buffers = I915_MAX_VALIDATE_BUFFERS;
-#endif
-
- if (init->sarea_priv_offset)
- dev_priv->sarea_priv = (drm_i915_sarea_t *)
- ((u8 *) dev_priv->sarea->handle +
- init->sarea_priv_offset);
- else {
- /* No sarea_priv for you! */
- dev_priv->sarea_priv = NULL;
- }
+ dev_priv->sarea_priv = (drm_i915_sarea_t *)
+ ((u8 *) dev_priv->sarea->handle + init->sarea_priv_offset);
if (init->ring_size != 0) {
+ if (dev_priv->ring.ring_obj != NULL) {
+ i915_dma_cleanup(dev);
+ DRM_ERROR("Client tried to initialize ringbuffer in "
+ "GEM mode\n");
+ return -EINVAL;
+ }
+
dev_priv->ring.Size = init->ring_size;
dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
@@ -286,41 +201,20 @@ static int i915_initialize(struct drm_de
" ring buffer\n");
return -ENOMEM;
}
-
- dev_priv->ring.virtual_start = dev_priv->ring.map.handle;
}
- dev_priv->cpp = init->cpp;
-
- if (dev_priv->sarea_priv)
- dev_priv->sarea_priv->pf_current_page = 0;
+ dev_priv->ring.virtual_start = dev_priv->ring.map.handle;
- /* We are using separate values as placeholders for mechanisms for
- * private backbuffer/depthbuffer usage.
- */
+ dev_priv->cpp = init->cpp;
+ dev_priv->back_offset = init->back_offset;
+ dev_priv->front_offset = init->front_offset;
+ dev_priv->current_page = 0;
+ dev_priv->sarea_priv->pf_current_page = dev_priv->current_page;
/* Allow hardware batchbuffers unless told otherwise.
*/
dev_priv->allow_batchbuffer = 1;
- /* Enable vblank on pipe A for older X servers
- */
- dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A;
-
-#ifdef I915_HAVE_BUFFER
- mutex_init(&dev_priv->cmdbuf_mutex);
-#endif
-#if defined(I915_HAVE_BUFFER)
- if (init->func == I915_INIT_DMA2) {
- ret = setup_dri2_sarea(dev, file_priv, init);
- if (ret) {
- i915_dma_cleanup(dev);
- DRM_ERROR("could not set up dri2 sarea\n");
- return ret;
- }
- }
-#endif
-
return 0;
}
@@ -349,9 +243,9 @@ static int i915_dma_resume(struct drm_de
DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page);
if (dev_priv->status_gfx_addr != 0)
- I915_WRITE(0x02080, dev_priv->status_gfx_addr);
+ I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
else
- I915_WRITE(0x02080, dev_priv->dma_status_page);
+ I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
DRM_DEBUG("Enabled hardware status page\n");
return 0;
@@ -365,8 +259,7 @@ static int i915_dma_init(struct drm_devi
switch (init->func) {
case I915_INIT_DMA:
- case I915_INIT_DMA2:
- retcode = i915_initialize(dev, file_priv, init);
+ retcode = i915_initialize(dev, init);
break;
case I915_CLEANUP_DMA:
retcode = i915_dma_cleanup(dev);
@@ -541,55 +434,28 @@ int i915_emit_box(struct drm_device * de
* emit. For now, do it in both places:
*/
-void i915_emit_breadcrumb(struct drm_device *dev)
+static void i915_emit_breadcrumb(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = dev->dev_private;
RING_LOCALS;
- if (++dev_priv->counter > BREADCRUMB_MASK) {
- dev_priv->counter = 1;
- DRM_DEBUG("Breadcrumb counter wrapped around\n");
- }
-
+ dev_priv->counter++;
+ if (dev_priv->counter > 0x7FFFFFFFUL)
+ dev_priv->counter = 0;
if (dev_priv->sarea_priv)
dev_priv->sarea_priv->last_enqueue = dev_priv->counter;
BEGIN_LP_RING(4);
OUT_RING(MI_STORE_DWORD_INDEX);
- OUT_RING(5 << MI_STORE_DWORD_INDEX_SHIFT);
+ OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
OUT_RING(dev_priv->counter);
OUT_RING(0);
ADVANCE_LP_RING();
}
-
-int i915_emit_mi_flush(struct drm_device *dev, uint32_t flush)
-{
- drm_i915_private_t *dev_priv = dev->dev_private;
- uint32_t flush_cmd = MI_FLUSH;
- RING_LOCALS;
-
- flush_cmd |= flush;
-
- i915_kernel_lost_context(dev);
-
- BEGIN_LP_RING(4);
- OUT_RING(flush_cmd);
- OUT_RING(0);
- OUT_RING(0);
- OUT_RING(0);
- ADVANCE_LP_RING();
-
- return 0;
-}
-
-
static int i915_dispatch_cmdbuffer(struct drm_device * dev,
drm_i915_cmdbuffer_t * cmd)
{
-#ifdef I915_HAVE_FENCE
- drm_i915_private_t *dev_priv = dev->dev_private;
-#endif
int nbox = cmd->num_cliprects;
int i = 0, count, ret;
@@ -616,15 +482,11 @@ static int i915_dispatch_cmdbuffer(struc
}
i915_emit_breadcrumb(dev);
-#ifdef I915_HAVE_FENCE
- if (unlikely((dev_priv->counter & 0xFF) == 0))
- drm_fence_flush_old(dev, 0, dev_priv->counter);
-#endif
return 0;
}
-int i915_dispatch_batchbuffer(struct drm_device * dev,
- drm_i915_batchbuffer_t * batch)
+static int i915_dispatch_batchbuffer(struct drm_device * dev,
+ drm_i915_batchbuffer_t * batch)
{
drm_i915_private_t *dev_priv = dev->dev_private;
struct drm_clip_rect __user *boxes = batch->cliprects;
@@ -649,14 +511,7 @@ int i915_dispatch_batchbuffer(struct drm
return ret;
}
- if (IS_I830(dev) || IS_845G(dev)) {
- BEGIN_LP_RING(4);
- OUT_RING(MI_BATCH_BUFFER);
- OUT_RING(batch->start | MI_BATCH_NON_SECURE);
- OUT_RING(batch->start + batch->used - 4);
- OUT_RING(0);
- ADVANCE_LP_RING();
- } else {
+ if (!IS_I830(dev) && !IS_845G(dev)) {
BEGIN_LP_RING(2);
if (IS_I965G(dev)) {
OUT_RING(MI_BATCH_BUFFER_START | (2 << 6) | MI_BATCH_NON_SECURE_I965);
@@ -666,115 +521,90 @@ int i915_dispatch_batchbuffer(struct drm
OUT_RING(batch->start | MI_BATCH_NON_SECURE);
}
ADVANCE_LP_RING();
+ } else {
+ BEGIN_LP_RING(4);
+ OUT_RING(MI_BATCH_BUFFER);
+ OUT_RING(batch->start | MI_BATCH_NON_SECURE);
+ OUT_RING(batch->start + batch->used - 4);
+ OUT_RING(0);
+ ADVANCE_LP_RING();
}
}
i915_emit_breadcrumb(dev);
-#ifdef I915_HAVE_FENCE
- if (unlikely((dev_priv->counter & 0xFF) == 0))
- drm_fence_flush_old(dev, 0, dev_priv->counter);
-#endif
+
return 0;
}
-static void i915_do_dispatch_flip(struct drm_device * dev, int plane, int sync)
+static int i915_dispatch_flip(struct drm_device * dev)
{
drm_i915_private_t *dev_priv = dev->dev_private;
- u32 num_pages, current_page, next_page, dspbase;
- int shift = 2 * plane, x, y;
RING_LOCALS;
- /* Calculate display base offset */
- num_pages = dev_priv->sarea_priv->third_handle ? 3 : 2;
- current_page = (dev_priv->sarea_priv->pf_current_page >> shift) & 0x3;
- next_page = (current_page + 1) % num_pages;
+ if (!dev_priv->sarea_priv)
+ return -EINVAL;
- switch (next_page) {
- default:
- case 0:
- dspbase = dev_priv->sarea_priv->front_offset;
- break;
- case 1:
- dspbase = dev_priv->sarea_priv->back_offset;
- break;
- case 2:
- dspbase = dev_priv->sarea_priv->third_offset;
- break;
- }
+ DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n",
+ __func__,
+ dev_priv->current_page,
+ dev_priv->sarea_priv->pf_current_page);
+
+ i915_kernel_lost_context(dev);
- if (plane == 0) {
- x = dev_priv->sarea_priv->planeA_x;
- y = dev_priv->sarea_priv->planeA_y;
+ BEGIN_LP_RING(2);
+ OUT_RING(MI_FLUSH | MI_READ_FLUSH);
+ OUT_RING(0);
+ ADVANCE_LP_RING();
+
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-projects
mailing list