svn commit: r195912 - in stable/7/sys: . contrib/pf dev/drm
Robert Noland
rnoland at FreeBSD.org
Mon Jul 27 16:05:52 UTC 2009
Author: rnoland
Date: Mon Jul 27 16:05:51 2009
New Revision: 195912
URL: http://svn.freebsd.org/changeset/base/195912
Log:
MFC r194741,194745-194746,194748-194749,194759,194960,194963,194965-194966,194969,194986,194996
This pulls in numerous vblank related fixes from HEAD.
Modified:
stable/7/sys/ (props changed)
stable/7/sys/contrib/pf/ (props changed)
stable/7/sys/dev/drm/drmP.h
stable/7/sys/dev/drm/drm_drv.c
stable/7/sys/dev/drm/drm_irq.c
stable/7/sys/dev/drm/drm_sysctl.c
stable/7/sys/dev/drm/i915_dma.c
stable/7/sys/dev/drm/i915_drv.c
stable/7/sys/dev/drm/i915_drv.h
stable/7/sys/dev/drm/i915_irq.c
stable/7/sys/dev/drm/radeon_cp.c
stable/7/sys/dev/drm/radeon_irq.c
Modified: stable/7/sys/dev/drm/drmP.h
==============================================================================
--- stable/7/sys/dev/drm/drmP.h Mon Jul 27 16:03:04 2009 (r195911)
+++ stable/7/sys/dev/drm/drmP.h Mon Jul 27 16:05:51 2009 (r195912)
@@ -502,19 +502,10 @@ typedef struct drm_local_map {
TAILQ_ENTRY(drm_local_map) link;
} drm_local_map_t;
-TAILQ_HEAD(drm_vbl_sig_list, drm_vbl_sig);
-typedef struct drm_vbl_sig {
- TAILQ_ENTRY(drm_vbl_sig) link;
- unsigned int sequence;
- int signo;
- int pid;
-} drm_vbl_sig_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) */
- struct drm_vbl_sig_list sigs; /* signal list to send on VBLANK */
atomic_t refcount; /* number of users of vblank interrupts */
u32 last; /* protected by dev->vbl_lock, used */
/* for wraparound handling */
@@ -684,7 +675,6 @@ struct drm_device {
int last_context; /* Last current context */
int vblank_disable_allowed;
- atomic_t vbl_signal_pending; /* number of signals pending on all crtcs */
struct callout vblank_disable_timer;
u32 max_vblank_count; /* size of vblank counter register */
struct drm_vblank_info *vblank; /* per crtc vblank info */
@@ -802,7 +792,6 @@ void drm_vblank_put(struct drm_device *d
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);
int drm_modeset_ctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
Modified: stable/7/sys/dev/drm/drm_drv.c
==============================================================================
--- stable/7/sys/dev/drm/drm_drv.c Mon Jul 27 16:03:04 2009 (r195911)
+++ stable/7/sys/dev/drm/drm_drv.c Mon Jul 27 16:05:51 2009 (r195912)
@@ -273,11 +273,14 @@ int drm_detach(device_t kdev)
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");
+ 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;
Modified: stable/7/sys/dev/drm/drm_irq.c
==============================================================================
--- stable/7/sys/dev/drm/drm_irq.c Mon Jul 27 16:03:04 2009 (r195911)
+++ stable/7/sys/dev/drm/drm_irq.c Mon Jul 27 16:05:51 2009 (r195912)
@@ -70,6 +70,9 @@ static void vblank_disable_fn(void *arg)
struct drm_device *dev = (struct drm_device *)arg;
int i;
+ /* Make sure that we are called with the lock held */
+ mtx_assert(&dev->vbl_lock, MA_OWNED);
+
if (callout_pending(&dev->vblank_disable_timer)) {
/* callout was reset */
return;
@@ -86,7 +89,7 @@ static void vblank_disable_fn(void *arg)
return;
for (i = 0; i < dev->num_crtcs; i++) {
- if (atomic_read(&dev->vblank[i].refcount) == 0 &&
+ 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 =
@@ -109,7 +112,9 @@ void drm_vblank_cleanup(struct drm_devic
callout_drain(&dev->vblank_disable_timer);
+ DRM_SPINLOCK(&dev->vbl_lock);
vblank_disable_fn((void *)dev);
+ DRM_SPINUNLOCK(&dev->vbl_lock);
free(dev->vblank, DRM_MEM_DRIVER);
@@ -121,7 +126,6 @@ int drm_vblank_init(struct drm_device *d
int i, ret = ENOMEM;
callout_init_mtx(&dev->vblank_disable_timer, &dev->vbl_lock, 0);
- atomic_set(&dev->vbl_signal_pending, 0);
dev->num_crtcs = num_crtcs;
dev->vblank = malloc(sizeof(struct drm_vblank_info) * num_crtcs,
@@ -132,14 +136,14 @@ int drm_vblank_init(struct drm_device *d
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);
- TAILQ_INIT(&dev->vblank[i].sigs);
- atomic_set(&dev->vblank[i].count, 0);
- atomic_set(&dev->vblank[i].refcount, 0);
+ dev->vblank[i].refcount = 0;
+ atomic_set_rel_32(&dev->vblank[i].count, 0);
}
-
dev->vblank_disable_allowed = 0;
+ DRM_SPINUNLOCK(&dev->vbl_lock);
return 0;
@@ -272,7 +276,7 @@ int drm_control(struct drm_device *dev,
u32 drm_vblank_count(struct drm_device *dev, int crtc)
{
- return atomic_read(&dev->vblank[crtc].count);
+ return atomic_load_acq_32(&dev->vblank[crtc].count);
}
static void drm_update_vblank_count(struct drm_device *dev, int crtc)
@@ -298,45 +302,48 @@ static void drm_update_vblank_count(stru
DRM_DEBUG("enabling vblank interrupts on crtc %d, missed %d\n",
crtc, diff);
- atomic_add(diff, &dev->vblank[crtc].count);
+ atomic_add_rel_32(&dev->vblank[crtc].count, diff);
}
int drm_vblank_get(struct drm_device *dev, int crtc)
{
int ret = 0;
- DRM_SPINLOCK(&dev->vbl_lock);
+ /* Make sure that we are called with the lock held */
+ mtx_assert(&dev->vbl_lock, MA_OWNED);
+
/* Going from 0->1 means we have to enable interrupts again */
- atomic_add_acq_int(&dev->vblank[crtc].refcount, 1);
- if (dev->vblank[crtc].refcount == 1 &&
+ 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)
- atomic_dec(&dev->vblank[crtc].refcount);
+ --dev->vblank[crtc].refcount;
else {
dev->vblank[crtc].enabled = 1;
drm_update_vblank_count(dev, crtc);
}
}
- DRM_SPINUNLOCK(&dev->vbl_lock);
+
+ if (dev->vblank[crtc].enabled)
+ dev->vblank[crtc].last =
+ dev->driver->get_vblank_counter(dev, crtc);
return ret;
}
void drm_vblank_put(struct drm_device *dev, int crtc)
{
- KASSERT(atomic_read(&dev->vblank[crtc].refcount) > 0,
+ /* Make sure that we are called with the lock held */
+ mtx_assert(&dev->vbl_lock, MA_OWNED);
+
+ KASSERT(dev->vblank[crtc].refcount > 0,
("invalid refcount"));
/* Last user schedules interrupt disable */
- atomic_subtract_acq_int(&dev->vblank[crtc].refcount, 1);
-
- DRM_SPINLOCK(&dev->vbl_lock);
- if (dev->vblank[crtc].refcount == 0)
+ if (--dev->vblank[crtc].refcount == 0)
callout_reset(&dev->vblank_disable_timer, 5 * DRM_HZ,
(timeout_t *)vblank_disable_fn, (void *)dev);
- DRM_SPINUNLOCK(&dev->vbl_lock);
}
int drm_modeset_ctl(struct drm_device *dev, void *data,
@@ -345,13 +352,11 @@ int drm_modeset_ctl(struct drm_device *d
struct drm_modeset_ctl *modeset = data;
int crtc, ret = 0;
- DRM_DEBUG("num_crtcs=%d\n", dev->num_crtcs);
/* If drm_vblank_init() hasn't been called yet, just no-op */
if (!dev->num_crtcs)
goto out;
crtc = modeset->crtc;
- DRM_DEBUG("crtc=%d\n", crtc);
if (crtc >= dev->num_crtcs) {
ret = EINVAL;
goto out;
@@ -366,25 +371,25 @@ int drm_modeset_ctl(struct drm_device *d
*/
switch (modeset->cmd) {
case _DRM_PRE_MODESET:
- DRM_DEBUG("pre-modeset\n");
+ 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);
break;
case _DRM_POST_MODESET:
- DRM_DEBUG("post-modeset\n");
+ DRM_DEBUG("post-modeset, crtc %d\n", crtc);
+ DRM_SPINLOCK(&dev->vbl_lock);
if (dev->vblank[crtc].inmodeset) {
- DRM_SPINLOCK(&dev->vbl_lock);
- dev->vblank_disable_allowed = 1;
- DRM_SPINUNLOCK(&dev->vbl_lock);
-
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);
break;
default:
ret = EINVAL;
@@ -418,7 +423,9 @@ int drm_wait_vblank(struct drm_device *d
if (crtc >= dev->num_crtcs)
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;
@@ -442,28 +449,11 @@ int drm_wait_vblank(struct drm_device *d
}
if (flags & _DRM_VBLANK_SIGNAL) {
-#if 0 /* disabled */
- drm_vbl_sig_t *vbl_sig = malloc(sizeof(drm_vbl_sig_t),
- DRM_MEM_DRIVER, M_NOWAIT | M_ZERO);
- if (vbl_sig == NULL)
- return ENOMEM;
-
- vbl_sig->sequence = vblwait->request.sequence;
- vbl_sig->signo = vblwait->request.signal;
- vbl_sig->pid = DRM_CURRENTPID;
-
- vblwait->reply.sequence = atomic_read(&dev->vbl_received);
-
- DRM_SPINLOCK(&dev->vbl_lock);
- TAILQ_INSERT_HEAD(&dev->vbl_sig_list, vbl_sig, link);
- DRM_SPINUNLOCK(&dev->vbl_lock);
- ret = 0;
-#endif
+ /* There have never been any consumers */
ret = EINVAL;
} else {
DRM_DEBUG("waiting on vblank count %d, crtc %d\n",
vblwait->request.sequence, crtc);
- dev->vblank[crtc].last = vblwait->request.sequence;
for ( ret = 0 ; !ret && !(((drm_vblank_count(dev, crtc) -
vblwait->request.sequence) <= (1 << 23)) ||
!dev->irq_enabled) ; ) {
@@ -473,7 +463,7 @@ int drm_wait_vblank(struct drm_device *d
!dev->irq_enabled))
ret = mtx_sleep(&dev->vblank[crtc].queue,
&dev->irq_lock, PCATCH, "vblwtq",
- 3 * DRM_HZ);
+ DRM_HZ);
mtx_unlock(&dev->irq_lock);
}
@@ -492,42 +482,16 @@ int drm_wait_vblank(struct drm_device *d
}
done:
+ DRM_SPINLOCK(&dev->vbl_lock);
drm_vblank_put(dev, crtc);
- return ret;
-}
-
-void drm_vbl_send_signals(struct drm_device *dev, int crtc)
-{
-}
-
-#if 0 /* disabled */
-void drm_vbl_send_signals(struct drm_device *dev, int crtc )
-{
- drm_vbl_sig_t *vbl_sig;
- unsigned int vbl_seq = atomic_read( &dev->vbl_received );
- struct proc *p;
-
- vbl_sig = TAILQ_FIRST(&dev->vbl_sig_list);
- while (vbl_sig != NULL) {
- drm_vbl_sig_t *next = TAILQ_NEXT(vbl_sig, link);
-
- if ((vbl_seq - vbl_sig->sequence) <= (1 << 23)) {
- p = pfind(vbl_sig->pid);
- if (p != NULL)
- psignal(p, vbl_sig->signo);
+ DRM_SPINUNLOCK(&dev->vbl_lock);
- TAILQ_REMOVE(&dev->vbl_sig_list, vbl_sig, link);
- DRM_FREE(vbl_sig,sizeof(*vbl_sig));
- }
- vbl_sig = next;
- }
+ return ret;
}
-#endif
void drm_handle_vblank(struct drm_device *dev, int crtc)
{
- atomic_inc(&dev->vblank[crtc].count);
+ atomic_add_rel_32(&dev->vblank[crtc].count, 1);
DRM_WAKEUP(&dev->vblank[crtc].queue);
- drm_vbl_send_signals(dev, crtc);
}
Modified: stable/7/sys/dev/drm/drm_sysctl.c
==============================================================================
--- stable/7/sys/dev/drm/drm_sysctl.c Mon Jul 27 16:03:04 2009 (r195911)
+++ stable/7/sys/dev/drm/drm_sysctl.c Mon Jul 27 16:05:51 2009 (r195912)
@@ -38,6 +38,7 @@ static int drm_name_info DRM_SYSCTL_H
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;
@@ -47,6 +48,7 @@ struct drm_sysctl_list {
{"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]))
@@ -313,3 +315,25 @@ done:
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");
+ 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));
+ }
+
+ SYSCTL_OUT(req, "", -1);
+done:
+ return retcode;
+}
Modified: stable/7/sys/dev/drm/i915_dma.c
==============================================================================
--- stable/7/sys/dev/drm/i915_dma.c Mon Jul 27 16:03:04 2009 (r195911)
+++ stable/7/sys/dev/drm/i915_dma.c Mon Jul 27 16:05:51 2009 (r195912)
@@ -644,18 +644,17 @@ static int i915_batchbuffer(struct drm_d
return -EFAULT;
}
}
- DRM_LOCK();
ret = i915_dispatch_batchbuffer(dev, batch);
- if (sarea_priv)
- sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
-
- DRM_UNLOCK();
if (batch->num_cliprects)
vsunlock(batch->cliprects, cliplen);
+
DRM_LOCK();
+ if (sarea_priv)
+ sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
+
return ret;
}
@@ -697,10 +696,9 @@ static int i915_cmdbuffer(struct drm_dev
return -EFAULT;
}
}
- DRM_LOCK();
ret = i915_dispatch_cmdbuffer(dev, cmdbuf);
- DRM_UNLOCK();
+
if (cmdbuf->num_cliprects) {
vsunlock(cmdbuf->buf, cmdbuf->sz);
vsunlock(cmdbuf->cliprects, cliplen);
Modified: stable/7/sys/dev/drm/i915_drv.c
==============================================================================
--- stable/7/sys/dev/drm/i915_drv.c Mon Jul 27 16:03:04 2009 (r195911)
+++ stable/7/sys/dev/drm/i915_drv.c Mon Jul 27 16:05:51 2009 (r195912)
@@ -52,7 +52,10 @@ static int i915_suspend(device_t kdev)
return -ENODEV;
}
+ DRM_LOCK();
+ DRM_DEBUG("starting suspend\n");
i915_save_state(dev);
+ DRM_UNLOCK();
return (bus_generic_suspend(kdev));
}
@@ -61,7 +64,10 @@ static int i915_resume(device_t kdev)
{
struct drm_device *dev = device_get_softc(kdev);
+ DRM_LOCK();
i915_restore_state(dev);
+ DRM_DEBUG("finished resume\n");
+ DRM_UNLOCK();
return (bus_generic_resume(kdev));
}
Modified: stable/7/sys/dev/drm/i915_drv.h
==============================================================================
--- stable/7/sys/dev/drm/i915_drv.h Mon Jul 27 16:03:04 2009 (r195911)
+++ stable/7/sys/dev/drm/i915_drv.h Mon Jul 27 16:05:51 2009 (r195912)
@@ -129,7 +129,6 @@ typedef struct drm_i915_private {
int page_flipping;
wait_queue_head_t irq_queue;
- atomic_t irq_received;
/** Protects user_irq_refcount and irq_mask_reg */
DRM_SPINTYPE user_irq_lock;
/** Refcount for i915_user_irq_get() versus i915_user_irq_put(). */
Modified: stable/7/sys/dev/drm/i915_irq.c
==============================================================================
--- stable/7/sys/dev/drm/i915_irq.c Mon Jul 27 16:03:04 2009 (r195911)
+++ stable/7/sys/dev/drm/i915_irq.c Mon Jul 27 16:05:51 2009 (r195912)
@@ -53,12 +53,6 @@ __FBSDID("$FreeBSD$");
#define I915_INTERRUPT_ENABLE_MASK (I915_INTERRUPT_ENABLE_FIX | \
I915_INTERRUPT_ENABLE_VAR)
-#define I915_PIPE_VBLANK_STATUS (PIPE_START_VBLANK_INTERRUPT_STATUS |\
- PIPE_VBLANK_INTERRUPT_STATUS)
-
-#define I915_PIPE_VBLANK_ENABLE (PIPE_START_VBLANK_INTERRUPT_ENABLE |\
- PIPE_VBLANK_INTERRUPT_ENABLE)
-
#define DRM_I915_VBLANK_PIPE_ALL (DRM_I915_VBLANK_PIPE_A | \
DRM_I915_VBLANK_PIPE_B)
@@ -154,7 +148,7 @@ u32 i915_get_vblank_counter(struct drm_d
low_frame = pipe ? PIPEBFRAMEPIXEL : PIPEAFRAMEPIXEL;
if (!i915_pipe_enabled(dev, pipe)) {
- DRM_ERROR("trying to get vblank count for disabled pipe %d\n", pipe);
+ DRM_DEBUG("trying to get vblank count for disabled pipe %d\n", pipe);
return 0;
}
@@ -183,7 +177,7 @@ u32 g45_get_vblank_counter(struct drm_de
int reg = pipe ? PIPEB_FRMCOUNT_GM45 : PIPEA_FRMCOUNT_GM45;
if (!i915_pipe_enabled(dev, pipe)) {
- DRM_ERROR("trying to get vblank count for disabled pipe %d\n", pipe);
+ DRM_DEBUG("trying to get vblank count for disabled pipe %d\n", pipe);
return 0;
}
@@ -200,12 +194,10 @@ irqreturn_t i915_driver_irq_handler(DRM_
u32 vblank_enable;
int irq_received;
- atomic_inc(&dev_priv->irq_received);
-
iir = I915_READ(IIR);
if (IS_I965G(dev)) {
- vblank_status = I915_START_VBLANK_INTERRUPT_STATUS;
+ vblank_status = PIPE_START_VBLANK_INTERRUPT_STATUS;
vblank_enable = PIPE_START_VBLANK_INTERRUPT_ENABLE;
} else {
vblank_status = I915_VBLANK_INTERRUPT_STATUS;
@@ -305,9 +297,12 @@ void i915_user_irq_get(struct drm_device
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ if (dev->irq_enabled == 0)
+ return;
+
DRM_DEBUG("\n");
DRM_SPINLOCK(&dev_priv->user_irq_lock);
- if (dev->irq_enabled && (++dev_priv->user_irq_refcount == 1))
+ if (++dev_priv->user_irq_refcount == 1)
i915_enable_irq(dev_priv, I915_USER_INTERRUPT);
DRM_SPINUNLOCK(&dev_priv->user_irq_lock);
}
@@ -316,12 +311,13 @@ void i915_user_irq_put(struct drm_device
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ if (dev->irq_enabled == 0)
+ return;
+
DRM_SPINLOCK(&dev_priv->user_irq_lock);
- if (dev->irq_enabled) {
- KASSERT(dev_priv->user_irq_refcount > 0, ("invalid refcount"));
- if (--dev_priv->user_irq_refcount == 0)
- i915_disable_irq(dev_priv, I915_USER_INTERRUPT);
- }
+ 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);
}
@@ -408,11 +404,8 @@ int i915_irq_wait(struct drm_device *dev
int i915_enable_vblank(struct drm_device *dev, int pipe)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
- int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
- u32 pipeconf;
- pipeconf = I915_READ(pipeconf_reg);
- if (!(pipeconf & PIPEACONF_ENABLE))
+ if (!i915_pipe_enabled(dev, pipe))
return -EINVAL;
DRM_SPINLOCK(&dev_priv->user_irq_lock);
@@ -500,8 +493,6 @@ void i915_driver_irq_preinstall(struct d
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
- atomic_set_int(&dev_priv->irq_received, 0);
-
I915_WRITE(HWSTAM, 0xeffe);
I915_WRITE(PIPEASTAT, 0);
I915_WRITE(PIPEBSTAT, 0);
@@ -519,9 +510,6 @@ int i915_driver_irq_postinstall(struct d
/* Unmask the interrupts that we always want on. */
dev_priv->irq_mask_reg = ~I915_INTERRUPT_ENABLE_FIX;
- dev_priv->pipestat[0] = 0;
- dev_priv->pipestat[1] = 0;
-
/* Disable pipe interrupt enables, clear pending pipe status */
I915_WRITE(PIPEASTAT, I915_READ(PIPEASTAT) & 0x8000ffff);
I915_WRITE(PIPEBSTAT, I915_READ(PIPEBSTAT) & 0x8000ffff);
@@ -531,6 +519,10 @@ int i915_driver_irq_postinstall(struct d
I915_WRITE(IER, I915_INTERRUPT_ENABLE_MASK);
I915_WRITE(IMR, dev_priv->irq_mask_reg);
+ I915_WRITE(PIPEASTAT, dev_priv->pipestat[0] |
+ (dev_priv->pipestat[0] >> 16));
+ I915_WRITE(PIPEBSTAT, dev_priv->pipestat[1] |
+ (dev_priv->pipestat[1] >> 16));
(void) I915_READ(IER);
return 0;
Modified: stable/7/sys/dev/drm/radeon_cp.c
==============================================================================
--- stable/7/sys/dev/drm/radeon_cp.c Mon Jul 27 16:03:04 2009 (r195911)
+++ stable/7/sys/dev/drm/radeon_cp.c Mon Jul 27 16:05:51 2009 (r195912)
@@ -2064,16 +2064,22 @@ int radeon_driver_load(struct drm_device
drm_get_resource_len(dev, 2), _DRM_REGISTERS,
_DRM_READ_ONLY | _DRM_DRIVER, &dev_priv->mmio);
if (ret != 0)
- return ret;
+ goto error;
ret = drm_vblank_init(dev, 2);
- if (ret) {
- radeon_driver_unload(dev);
- return ret;
- }
+ if (ret != 0)
+ goto error;
+
+ dev->max_vblank_count = 0x001fffff;
DRM_DEBUG("%s card detected\n",
- ((dev_priv->flags & RADEON_IS_AGP) ? "AGP" : (((dev_priv->flags & RADEON_IS_PCIE) ? "PCIE" : "PCI"))));
+ ((dev_priv->flags & RADEON_IS_AGP) ? "AGP" :
+ (((dev_priv->flags & RADEON_IS_PCIE) ? "PCIE" : "PCI"))));
+
+ return ret;
+
+error:
+ radeon_driver_unload(dev);
return ret;
}
Modified: stable/7/sys/dev/drm/radeon_irq.c
==============================================================================
--- stable/7/sys/dev/drm/radeon_irq.c Mon Jul 27 16:03:04 2009 (r195911)
+++ stable/7/sys/dev/drm/radeon_irq.c Mon Jul 27 16:05:51 2009 (r195912)
@@ -380,8 +380,6 @@ int radeon_driver_irq_postinstall(struct
atomic_set(&dev_priv->swi_emitted, 0);
DRM_INIT_WAITQUEUE(&dev_priv->swi_queue);
- dev->max_vblank_count = 0x001fffff;
-
radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1);
return 0;
More information about the svn-src-all
mailing list