diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index d64c8854..1e17d9ed 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -109,6 +109,11 @@ static void i915_bmp_free(drm_device_t *dev) dev_priv->bmp = NULL; } + I915_WRITE(BMP_BUFFER, 0); + + dev_priv->irq_enable_reg &= ~HWB_OOM_FLAG; + I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); + DRM_INFO("BMP freed\n"); } @@ -800,6 +805,9 @@ static int i915_bmp_alloc(drm_device_t *dev) I915_WRITE(BMP_PUT, (i / 8) << BMP_OFFSET_SHIFT); I915_WRITE(BMP_GET, 0 << BMP_OFFSET_SHIFT); + dev_priv->irq_enable_reg |= HWB_OOM_FLAG; + I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); + I915_WRITE(BMP_BUFFER, dev_priv->bmp->busaddr | BMP_PAGE_SIZE_4K | ((BMP_SIZE / PAGE_SIZE - 1) << BMP_BUFFER_SIZE_SHIFT) | BMP_ENABLE); @@ -1586,15 +1594,21 @@ static int i915_hwz_init(drm_device_t *dev, struct drm_i915_hwz_init *init) static int i915_hwz(DRM_IOCTL_ARGS) { DRM_DEVICE; + drm_i915_private_t *dev_priv = dev->dev_private; drm_file_t *filp_priv; struct drm_i915_driver_file_fields *filp_i915priv; drm_i915_hwz_t hwz; - if (!dev->dev_private) { + if (!dev_priv) { DRM_ERROR("called with no initialization\n"); return DRM_ERR(EINVAL); } + if (dev_priv->hwb_oom) { + DRM_ERROR("HWB out of memory\n"); + return DRM_ERR(ENOMEM); + } + DRM_COPY_FROM_USER_IOCTL(hwz, (drm_i915_hwz_t __user *) data, sizeof(hwz)); diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index f7d0b3ca..dddd75a7 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -135,6 +135,8 @@ typedef struct drm_i915_private { drm_i915_vbl_swap_t vbl_swaps; unsigned int swaps_pending; + int hwb_oom; + drm_dma_handle_t *bmp, **bmp_pool; unsigned long priv1_addr; @@ -298,6 +300,11 @@ extern int i915_wait_ring(drm_i915_private_t *dev_priv, drm_i915_ring_buffer_t #define BB1_UNPROTECTED (0<<0) #define BB2_END_ADDR_MASK (~0x7) +#define USER_INT_FLAG (1<<1) +#define VSYNC_PIPEB_FLAG (1<<5) +#define VSYNC_PIPEA_FLAG (1<<7) +#define HWB_OOM_FLAG (1<<13) + #define I915REG_HWSTAM 0x02098 #define I915REG_INT_IDENTITY_R 0x020a4 #define I915REG_INT_MASK_R 0x020a8 diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index cae7eba3..c00d82c6 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -31,10 +31,6 @@ #include "i915_drm.h" #include "i915_drv.h" -#define USER_INT_FLAG (1<<1) -#define VSYNC_PIPEB_FLAG (1<<5) -#define VSYNC_PIPEA_FLAG (1<<7) - #define MAX_NOPID ((u32)~0) /** @@ -285,7 +281,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) pipeb_stats = I915_READ(I915REG_PIPEBSTAT); temp = I915_READ(I915REG_INT_IDENTITY_R); - temp &= (dev_priv->irq_enable_reg | USER_INT_FLAG); + temp &= (dev_priv->irq_enable_reg | USER_INT_FLAG | HWB_OOM_FLAG); #if 0 DRM_DEBUG("%s flag=%08x\n", __FUNCTION__, temp); @@ -335,6 +331,11 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) I915_VBLANK_CLEAR); } + if ((temp & HWB_OOM_FLAG) && !dev_priv->hwb_oom) { + DRM_ERROR("HWB out of memory\n"); + dev_priv->hwb_oom = TRUE; + } + return IRQ_HANDLED; }