Merge commit 'origin/drm-gem' into ms-gem
Conflicts: linux-core/drmP.h linux-core/drm_drv.c linux-core/drm_stub.c linux-core/i915_drv.c linux-core/i915_gem.c shared-core/i915_drv.h shared-core/i915_irq.cmain
commit
3e02f7fd31
|
@ -109,11 +109,11 @@ struct _dri_bo_gem {
|
|||
int validate_index;
|
||||
|
||||
/**
|
||||
* Boolean whether set_domain to CPU is current
|
||||
* Set when set_domain has been called
|
||||
* Cleared when a batch has been submitted
|
||||
* Boolean whether we've started swrast
|
||||
* Set when the buffer has been mapped
|
||||
* Cleared when the buffer is unmapped
|
||||
*/
|
||||
int cpu_domain_set;
|
||||
int swrast;
|
||||
|
||||
/** Array passed to the DRM containing relocation information. */
|
||||
struct drm_i915_gem_relocation_entry *relocs;
|
||||
|
@ -485,25 +485,27 @@ dri_gem_bo_map(dri_bo *bo, int write_enable)
|
|||
bo_gem->virtual = (void *)(uintptr_t)mmap_arg.addr_ptr;
|
||||
}
|
||||
bo->virtual = bo_gem->virtual;
|
||||
bo_gem->swrast = 0;
|
||||
bo_gem->mapped = 1;
|
||||
DBG("bo_map: %d (%s) -> %p\n", bo_gem->gem_handle, bo_gem->name, bo_gem->virtual);
|
||||
}
|
||||
|
||||
if (!bo_gem->cpu_domain_set) {
|
||||
if (!bo_gem->swrast) {
|
||||
set_domain.handle = bo_gem->gem_handle;
|
||||
set_domain.read_domains = I915_GEM_DOMAIN_CPU;
|
||||
set_domain.write_domain = write_enable ? I915_GEM_DOMAIN_CPU : 0;
|
||||
if (write_enable)
|
||||
set_domain.write_domain = I915_GEM_DOMAIN_CPU;
|
||||
else
|
||||
set_domain.write_domain = 0;
|
||||
do {
|
||||
ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN,
|
||||
&set_domain);
|
||||
} while (ret == -1 && errno == EINTR);
|
||||
if (ret != 0) {
|
||||
fprintf (stderr, "%s:%d: Error setting memory domains %d (%08x %08x): %s .\n",
|
||||
__FILE__, __LINE__,
|
||||
bo_gem->gem_handle, set_domain.read_domains, set_domain.write_domain,
|
||||
strerror (errno));
|
||||
fprintf (stderr, "%s:%d: Error setting swrast %d: %s\n",
|
||||
__FILE__, __LINE__, bo_gem->gem_handle, strerror (errno));
|
||||
}
|
||||
bo_gem->cpu_domain_set = 1;
|
||||
bo_gem->swrast = 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -512,13 +514,24 @@ dri_gem_bo_map(dri_bo *bo, int write_enable)
|
|||
static int
|
||||
dri_gem_bo_unmap(dri_bo *bo)
|
||||
{
|
||||
dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bo->bufmgr;
|
||||
dri_bo_gem *bo_gem = (dri_bo_gem *)bo;
|
||||
struct drm_i915_gem_sw_finish sw_finish;
|
||||
int ret;
|
||||
|
||||
if (bo == NULL)
|
||||
return 0;
|
||||
|
||||
assert(bo_gem->mapped);
|
||||
|
||||
if (bo_gem->swrast) {
|
||||
sw_finish.handle = bo_gem->gem_handle;
|
||||
do {
|
||||
ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_SW_FINISH,
|
||||
&sw_finish);
|
||||
} while (ret == -1 && errno == EINTR);
|
||||
bo_gem->swrast = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -583,7 +596,7 @@ dri_gem_bo_wait_rendering(dri_bo *bo)
|
|||
int ret;
|
||||
|
||||
set_domain.handle = bo_gem->gem_handle;
|
||||
set_domain.read_domains = I915_GEM_DOMAIN_CPU;
|
||||
set_domain.read_domains = I915_GEM_DOMAIN_GTT;
|
||||
set_domain.write_domain = 0;
|
||||
ret = ioctl (bufmgr_gem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain);
|
||||
if (ret != 0) {
|
||||
|
@ -744,8 +757,8 @@ dri_gem_post_submit(dri_bo *batch_buf)
|
|||
dri_bo *bo = bufmgr_gem->exec_bos[i];
|
||||
dri_bo_gem *bo_gem = (dri_bo_gem *)bo;
|
||||
|
||||
/* Need to call set_domain on next bo_map */
|
||||
bo_gem->cpu_domain_set = 0;
|
||||
/* Need to call swrast on next bo_map */
|
||||
bo_gem->swrast = 0;
|
||||
|
||||
/* Disconnect the buffer from the validate list */
|
||||
bo_gem->validate_index = -1;
|
||||
|
|
|
@ -811,6 +811,10 @@ struct drm_driver {
|
|||
/* Master routines */
|
||||
int (*master_create)(struct drm_device *dev, struct drm_master *master);
|
||||
void (*master_destroy)(struct drm_device *dev, struct drm_master *master);
|
||||
|
||||
int (*proc_init)(struct drm_minor *minor);
|
||||
void (*proc_cleanup)(struct drm_minor *minor);
|
||||
|
||||
/**
|
||||
* Driver-specific constructor for drm_gem_objects, to set up
|
||||
* obj->driver_private.
|
||||
|
@ -1366,7 +1370,7 @@ extern void drm_put_master(struct drm_master *master);
|
|||
extern int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
|
||||
struct drm_driver *driver);
|
||||
extern int drm_put_dev(struct drm_device *dev);
|
||||
extern int drm_put_minor(struct drm_minor **minor);
|
||||
extern int drm_put_minor(struct drm_device *dev, struct drm_minor **p);
|
||||
extern unsigned int drm_debug; /* 1 to enable debug output */
|
||||
|
||||
extern struct class *drm_class;
|
||||
|
|
|
@ -353,7 +353,7 @@ static inline int kobject_uevent_env(struct kobject *kobj,
|
|||
#endif
|
||||
|
||||
|
||||
#if (defined(CONFIG_X86) && defined(CONFIG_X86_32) && defined(CONFIG_HIMEM))
|
||||
#if (defined(CONFIG_X86) && defined(CONFIG_X86_32) && defined(CONFIG_HIGHMEM))
|
||||
#define DRM_KMAP_ATOMIC_PROT_PFN
|
||||
extern void *kmap_atomic_prot_pfn(unsigned long pfn, enum km_type type,
|
||||
pgprot_t protection);
|
||||
|
|
|
@ -424,9 +424,10 @@ static void drm_cleanup(struct drm_device * dev)
|
|||
drm_memrange_takedown(&dev->offset_manager);
|
||||
drm_ht_remove(&dev->object_hash);
|
||||
|
||||
drm_put_minor(&dev->primary);
|
||||
drm_put_minor(dev, &dev->primary);
|
||||
if (drm_core_check_feature(dev, DRIVER_MODESET))
|
||||
drm_put_minor(&dev->control);
|
||||
drm_put_minor(dev, &dev->control);
|
||||
|
||||
if (drm_put_dev(dev))
|
||||
DRM_ERROR("Cannot unload module\n");
|
||||
}
|
||||
|
|
|
@ -309,6 +309,13 @@ static int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int t
|
|||
DRM_ERROR("DRM: Failed to initialize /proc/dri.\n");
|
||||
goto err_mem;
|
||||
}
|
||||
if (dev->driver->proc_init) {
|
||||
ret = dev->driver->proc_init(new_minor);
|
||||
if (ret) {
|
||||
DRM_ERROR("DRM: Driver failed to initialize /proc/dri.\n");
|
||||
goto err_mem;
|
||||
}
|
||||
}
|
||||
} else
|
||||
new_minor->dev_root = NULL;
|
||||
|
||||
|
@ -325,8 +332,11 @@ static int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int t
|
|||
|
||||
|
||||
err_g2:
|
||||
if (new_minor->type == DRM_MINOR_LEGACY)
|
||||
if (new_minor->type == DRM_MINOR_LEGACY) {
|
||||
if (dev->driver->proc_cleanup)
|
||||
dev->driver->proc_cleanup(new_minor);
|
||||
drm_proc_cleanup(new_minor, drm_proc_root);
|
||||
}
|
||||
err_mem:
|
||||
kfree(new_minor);
|
||||
err_idr:
|
||||
|
@ -398,10 +408,10 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
|
|||
|
||||
return 0;
|
||||
err_g5:
|
||||
drm_put_minor(&dev->primary);
|
||||
drm_put_minor(dev, &dev->primary);
|
||||
err_g4:
|
||||
if (drm_core_check_feature(dev, DRIVER_MODESET))
|
||||
drm_put_minor(&dev->control);
|
||||
drm_put_minor(dev, &dev->control);
|
||||
err_g3:
|
||||
if (!drm_fb_loaded)
|
||||
pci_disable_device(pdev);
|
||||
|
@ -452,13 +462,16 @@ int drm_put_dev(struct drm_device * dev)
|
|||
* last minor released.
|
||||
*
|
||||
*/
|
||||
int drm_put_minor(struct drm_minor **minor_p)
|
||||
int drm_put_minor(struct drm_device *dev, struct drm_minor **minor_p)
|
||||
{
|
||||
struct drm_minor *minor = *minor_p;
|
||||
DRM_DEBUG("release secondary minor %d\n", minor->index);
|
||||
|
||||
if (minor->type == DRM_MINOR_LEGACY)
|
||||
if (minor->type == DRM_MINOR_LEGACY) {
|
||||
if (dev->driver->proc_cleanup)
|
||||
dev->driver->proc_cleanup(minor);
|
||||
drm_proc_cleanup(minor, drm_proc_root);
|
||||
}
|
||||
drm_sysfs_device_remove(minor);
|
||||
|
||||
idr_remove(&drm_minors_idr, minor->index);
|
||||
|
|
|
@ -600,6 +600,8 @@ static struct drm_driver driver = {
|
|||
.get_reg_ofs = drm_core_get_reg_ofs,
|
||||
.master_create = i915_master_create,
|
||||
.master_destroy = i915_master_destroy,
|
||||
.proc_init = i915_gem_proc_init,
|
||||
.proc_cleanup = i915_gem_proc_cleanup,
|
||||
.ioctls = i915_ioctls,
|
||||
.gem_init_object = i915_gem_init_object,
|
||||
.gem_free_object = i915_gem_free_object,
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1093,6 +1093,7 @@ struct drm_ioctl_desc i915_ioctls[] = {
|
|||
DRM_IOCTL_DEF(DRM_I915_GEM_PWRITE, i915_gem_pwrite_ioctl, 0),
|
||||
DRM_IOCTL_DEF(DRM_I915_GEM_MMAP, i915_gem_mmap_ioctl, 0),
|
||||
DRM_IOCTL_DEF(DRM_I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, 0),
|
||||
DRM_IOCTL_DEF(DRM_I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, 0),
|
||||
};
|
||||
|
||||
int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
|
||||
|
|
|
@ -189,6 +189,7 @@ typedef struct drm_i915_sarea {
|
|||
#define DRM_I915_GEM_PWRITE 0x1d
|
||||
#define DRM_I915_GEM_MMAP 0x1e
|
||||
#define DRM_I915_GEM_SET_DOMAIN 0x1f
|
||||
#define DRM_I915_GEM_SW_FINISH 0x20
|
||||
|
||||
#define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
|
||||
#define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH)
|
||||
|
@ -221,6 +222,7 @@ typedef struct drm_i915_sarea {
|
|||
#define DRM_IOCTL_I915_GEM_PWRITE DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_PWRITE, struct drm_i915_gem_pwrite)
|
||||
#define DRM_IOCTL_I915_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MMAP, struct drm_i915_gem_mmap)
|
||||
#define DRM_IOCTL_I915_GEM_SET_DOMAIN DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_SET_DOMAIN, struct drm_i915_gem_set_domain)
|
||||
#define DRM_IOCTL_I915_GEM_SW_FINISH DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_SW_FINISH, struct drm_i915_gem_sw_finish)
|
||||
|
||||
/* Asynchronous page flipping:
|
||||
*/
|
||||
|
@ -505,6 +507,11 @@ struct drm_i915_gem_set_domain {
|
|||
uint32_t write_domain;
|
||||
};
|
||||
|
||||
struct drm_i915_gem_sw_finish {
|
||||
/** Handle for the object */
|
||||
uint32_t handle;
|
||||
};
|
||||
|
||||
struct drm_i915_gem_relocation_entry {
|
||||
/**
|
||||
* Handle of the buffer being pointed to by this relocation entry.
|
||||
|
@ -569,6 +576,8 @@ struct drm_i915_gem_relocation_entry {
|
|||
#define I915_GEM_DOMAIN_INSTRUCTION 0x00000010
|
||||
/** Vertex address cache */
|
||||
#define I915_GEM_DOMAIN_VERTEX 0x00000020
|
||||
/** GTT domain - aperture and scanout */
|
||||
#define I915_GEM_DOMAIN_GTT 0x00000040
|
||||
/** @} */
|
||||
|
||||
struct drm_i915_gem_exec_object {
|
||||
|
|
|
@ -134,7 +134,6 @@ struct drm_i915_private {
|
|||
|
||||
wait_queue_head_t irq_queue;
|
||||
atomic_t irq_received;
|
||||
atomic_t irq_emitted;
|
||||
|
||||
int tex_lru_log_granularity;
|
||||
int allow_batchbuffer;
|
||||
|
@ -235,15 +234,34 @@ struct drm_i915_private {
|
|||
|
||||
uint32_t next_gem_seqno;
|
||||
|
||||
/**
|
||||
* Flag if the X Server, and thus DRM, is not currently in
|
||||
* control of the device.
|
||||
*
|
||||
* This is set between LeaveVT and EnterVT. It needs to be
|
||||
* replaced with a semaphore. It also needs to be
|
||||
* transitioned away from for kernel modesetting.
|
||||
*/
|
||||
int suspended;
|
||||
/**
|
||||
* Waiting sequence number, if any
|
||||
*/
|
||||
uint32_t waiting_gem_seqno;
|
||||
|
||||
/**
|
||||
* Last seq seen at irq time
|
||||
*/
|
||||
uint32_t irq_gem_seqno;
|
||||
|
||||
/**
|
||||
* Flag if the X Server, and thus DRM, is not currently in
|
||||
* control of the device.
|
||||
*
|
||||
* This is set between LeaveVT and EnterVT. It needs to be
|
||||
* replaced with a semaphore. It also needs to be
|
||||
* transitioned away from for kernel modesetting.
|
||||
*/
|
||||
int suspended;
|
||||
|
||||
/**
|
||||
* Flag if the hardware appears to be wedged.
|
||||
*
|
||||
* This is set when attempts to idle the device timeout.
|
||||
* It prevents command submission from occuring and makes
|
||||
* every pending request fail
|
||||
*/
|
||||
int wedged;
|
||||
} mm;
|
||||
|
||||
struct work_struct user_interrupt_task;
|
||||
|
@ -369,6 +387,12 @@ struct drm_i915_gem_object {
|
|||
*/
|
||||
int active;
|
||||
|
||||
/**
|
||||
* This is set if the object has been written to since last bound
|
||||
* to the GTT
|
||||
*/
|
||||
int dirty;
|
||||
|
||||
/** AGP memory structure for our GTT binding. */
|
||||
DRM_AGP_MEM *agp_mem;
|
||||
|
||||
|
@ -521,6 +545,8 @@ int i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
|
|||
struct drm_file *file_priv);
|
||||
int i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv);
|
||||
int i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv);
|
||||
int i915_gem_execbuffer(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv);
|
||||
int i915_gem_pin_ioctl(struct drm_device *dev, void *data,
|
||||
|
@ -535,11 +561,14 @@ int i915_gem_entervt_ioctl(struct drm_device *dev, void *data,
|
|||
struct drm_file *file_priv);
|
||||
int i915_gem_leavevt_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv);
|
||||
int i915_gem_proc_init(struct drm_minor *minor);
|
||||
void i915_gem_proc_cleanup(struct drm_minor *minor);
|
||||
int i915_gem_init_object(struct drm_gem_object *obj);
|
||||
void i915_gem_free_object(struct drm_gem_object *obj);
|
||||
int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment);
|
||||
void i915_gem_object_unpin(struct drm_gem_object *obj);
|
||||
void i915_gem_lastclose(struct drm_device *dev);
|
||||
uint32_t i915_get_gem_seqno(struct drm_device *dev);
|
||||
void i915_gem_retire_requests(struct drm_device *dev);
|
||||
int i915_gem_init_ringbuffer(struct drm_device *dev);
|
||||
void i915_gem_cleanup_ringbuffer(struct drm_device *dev);
|
||||
|
|
|
@ -42,6 +42,26 @@
|
|||
I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | \
|
||||
I915_DISPLAY_PIPE_B_EVENT_INTERRUPT)
|
||||
|
||||
static inline void
|
||||
i915_enable_irq(struct drm_i915_private *dev_priv, uint32_t mask)
|
||||
{
|
||||
if ((dev_priv->irq_mask_reg & mask) != 0) {
|
||||
dev_priv->irq_mask_reg &= ~mask;
|
||||
I915_WRITE(IMR, dev_priv->irq_mask_reg);
|
||||
(void) I915_READ(IMR);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
i915_disable_irq(struct drm_i915_private *dev_priv, uint32_t mask)
|
||||
{
|
||||
if ((dev_priv->irq_mask_reg & mask) != mask) {
|
||||
dev_priv->irq_mask_reg |= mask;
|
||||
I915_WRITE(IMR, dev_priv->irq_mask_reg);
|
||||
(void) I915_READ(IMR);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* i915_get_pipe - return the the pipe associated with a given plane
|
||||
* @dev: DRM device
|
||||
|
@ -510,17 +530,27 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
|
|||
int hotplug = 0;
|
||||
int vblank = 0;
|
||||
|
||||
/* On i8xx/i915 hw the IIR and IER are 16bit on i9xx its 32bit */
|
||||
if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev))
|
||||
iir = I915_READ(IIR);
|
||||
else
|
||||
iir = I915_READ16(IIR);
|
||||
|
||||
if (dev->pdev->msi_enabled)
|
||||
I915_WRITE(IER, 0);
|
||||
|
||||
if (!iir)
|
||||
I915_WRITE(IMR, ~0);
|
||||
iir = I915_READ(IIR);
|
||||
#if 0
|
||||
DRM_DEBUG("flag=%08x\n", iir);
|
||||
#endif
|
||||
atomic_inc(&dev_priv->irq_received);
|
||||
if (iir == 0) {
|
||||
DRM_DEBUG ("iir 0x%08x im 0x%08x ie 0x%08x pipea 0x%08x pipeb 0x%08x\n",
|
||||
iir,
|
||||
I915_READ(IMR),
|
||||
I915_READ(IER),
|
||||
I915_READ(PIPEASTAT),
|
||||
I915_READ(PIPEBSTAT));
|
||||
if (dev->pdev->msi_enabled) {
|
||||
I915_WRITE(IMR,
|
||||
dev_priv->irq_mask_reg);
|
||||
(void) I915_READ(IMR);
|
||||
}
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear the PIPE(A|B)STAT regs before the IIR otherwise
|
||||
|
@ -528,46 +558,29 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
|
|||
*/
|
||||
if (iir & I915_DISPLAY_PIPE_A_EVENT_INTERRUPT) {
|
||||
pipea_stats = I915_READ(PIPEASTAT);
|
||||
if (pipea_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS|
|
||||
PIPE_VBLANK_INTERRUPT_STATUS))
|
||||
{
|
||||
vblank++;
|
||||
drm_handle_vblank(dev, i915_get_plane(dev, 0));
|
||||
}
|
||||
|
||||
/* This is a global event, and not a pipe A event */
|
||||
if (pipea_stats & PIPE_HOTPLUG_INTERRUPT_STATUS)
|
||||
hotplug = 1;
|
||||
|
||||
if (pipea_stats & PIPE_HOTPLUG_TV_INTERRUPT_STATUS) {
|
||||
hotplug = 1;
|
||||
/* Toggle hotplug detection to clear hotplug status */
|
||||
tvdac = I915_READ(TV_DAC);
|
||||
I915_WRITE(TV_DAC, tvdac & ~TVDAC_STATE_CHG_EN);
|
||||
I915_WRITE(TV_DAC, tvdac | TVDAC_STATE_CHG_EN);
|
||||
}
|
||||
|
||||
I915_WRITE(PIPEASTAT, pipea_stats);
|
||||
}
|
||||
|
||||
if (iir & I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) {
|
||||
pipeb_stats = I915_READ(PIPEBSTAT);
|
||||
if (pipeb_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS|
|
||||
PIPE_VBLANK_INTERRUPT_STATUS))
|
||||
{
|
||||
vblank++;
|
||||
drm_handle_vblank(dev, i915_get_plane(dev, 1));
|
||||
}
|
||||
I915_WRITE(PIPEBSTAT, pipeb_stats);
|
||||
}
|
||||
|
||||
/* Clear the generated interrupt */
|
||||
if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) {
|
||||
I915_WRITE(IIR, iir);
|
||||
(void) I915_READ(IIR);
|
||||
} else {
|
||||
I915_WRITE16(IIR, iir);
|
||||
(void) I915_READ16(IIR);
|
||||
I915_WRITE(IIR, iir);
|
||||
if (dev->pdev->msi_enabled)
|
||||
I915_WRITE(IMR, dev_priv->irq_mask_reg);
|
||||
(void) I915_READ(IIR); /* Flush posted writes */
|
||||
|
||||
/* This is a global event, and not a pipe A event */
|
||||
if (pipea_stats & PIPE_HOTPLUG_INTERRUPT_STATUS)
|
||||
hotplug = 1;
|
||||
|
||||
if (pipea_stats & PIPE_HOTPLUG_TV_INTERRUPT_STATUS) {
|
||||
hotplug = 1;
|
||||
/* Toggle hotplug detection to clear hotplug status */
|
||||
tvdac = I915_READ(TV_DAC);
|
||||
I915_WRITE(TV_DAC, tvdac & ~TVDAC_STATE_CHG_EN);
|
||||
I915_WRITE(TV_DAC, tvdac | TVDAC_STATE_CHG_EN);
|
||||
}
|
||||
|
||||
if (dev->primary->master) {
|
||||
|
@ -576,22 +589,25 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
|
|||
}
|
||||
|
||||
if (iir & I915_USER_INTERRUPT) {
|
||||
dev_priv->mm.irq_gem_seqno = i915_get_gem_seqno(dev);
|
||||
DRM_WAKEUP(&dev_priv->irq_queue);
|
||||
#ifdef I915_HAVE_FENCE
|
||||
i915_fence_handler(dev);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (pipea_stats & (I915_START_VBLANK_INTERRUPT_STATUS|
|
||||
I915_VBLANK_INTERRUPT_STATUS)) {
|
||||
vblank = 1;
|
||||
if (pipea_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS|
|
||||
PIPE_VBLANK_INTERRUPT_STATUS)) {
|
||||
vblank++;
|
||||
drm_handle_vblank(dev, i915_get_plane(dev, 0));
|
||||
}
|
||||
if (pipeb_stats & (I915_START_VBLANK_INTERRUPT_STATUS|
|
||||
I915_VBLANK_INTERRUPT_STATUS)) {
|
||||
vblank = 1;
|
||||
|
||||
if (pipeb_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS|
|
||||
PIPE_VBLANK_INTERRUPT_STATUS)) {
|
||||
vblank++;
|
||||
drm_handle_vblank(dev, i915_get_plane(dev, 1));
|
||||
}
|
||||
|
||||
if (vblank) {
|
||||
if (dev_priv->swaps_pending > 0)
|
||||
drm_locked_tasklet(dev, i915_vblank_tasklet);
|
||||
|
@ -616,9 +632,6 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
|
|||
i915_run_hotplug_tasklet(dev, temp2);
|
||||
}
|
||||
|
||||
if (dev->pdev->msi_enabled)
|
||||
I915_WRITE(IER, I915_INTERRUPT_ENABLE_MASK);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
|
@ -646,16 +659,9 @@ void i915_user_irq_on(struct drm_device *dev)
|
|||
struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
|
||||
|
||||
DRM_SPINLOCK(&dev_priv->user_irq_lock);
|
||||
if (dev_priv->irq_enabled && (++dev_priv->user_irq_refcount == 1)){
|
||||
dev_priv->irq_mask_reg &= ~I915_USER_INTERRUPT;
|
||||
if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev))
|
||||
I915_WRITE(IMR, dev_priv->irq_mask_reg);
|
||||
else
|
||||
I915_WRITE16(IMR, dev_priv->irq_mask_reg);
|
||||
I915_READ16(IMR);
|
||||
}
|
||||
if (dev_priv->irq_enabled && (++dev_priv->user_irq_refcount == 1))
|
||||
i915_enable_irq(dev_priv, I915_USER_INTERRUPT);
|
||||
DRM_SPINUNLOCK(&dev_priv->user_irq_lock);
|
||||
|
||||
}
|
||||
|
||||
void i915_user_irq_off(struct drm_device *dev)
|
||||
|
@ -664,14 +670,8 @@ void i915_user_irq_off(struct drm_device *dev)
|
|||
|
||||
DRM_SPINLOCK(&dev_priv->user_irq_lock);
|
||||
BUG_ON(dev_priv->irq_enabled && dev_priv->user_irq_refcount <= 0);
|
||||
if (dev_priv->irq_enabled && (--dev_priv->user_irq_refcount == 0)) {
|
||||
dev_priv->irq_mask_reg |= I915_USER_INTERRUPT;
|
||||
if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev))
|
||||
I915_WRITE(IMR, dev_priv->irq_mask_reg);
|
||||
else
|
||||
I915_WRITE16(IMR, dev_priv->irq_mask_reg);
|
||||
I915_READ16(IMR);
|
||||
}
|
||||
if (dev_priv->irq_enabled && (--dev_priv->user_irq_refcount == 0))
|
||||
i915_disable_irq(dev_priv, I915_USER_INTERRUPT);
|
||||
DRM_SPINUNLOCK(&dev_priv->user_irq_lock);
|
||||
}
|
||||
|
||||
|
@ -803,11 +803,7 @@ int i915_enable_vblank(struct drm_device *dev, int plane)
|
|||
}
|
||||
|
||||
DRM_SPINLOCK(&dev_priv->user_irq_lock);
|
||||
dev_priv->irq_mask_reg &= ~mask_reg;
|
||||
if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev))
|
||||
I915_WRITE(IMR, dev_priv->irq_mask_reg);
|
||||
else
|
||||
I915_WRITE16(IMR, dev_priv->irq_mask_reg);
|
||||
i915_enable_irq(dev_priv, mask_reg);
|
||||
DRM_SPINUNLOCK(&dev_priv->user_irq_lock);
|
||||
|
||||
return 0;
|
||||
|
@ -837,11 +833,7 @@ void i915_disable_vblank(struct drm_device *dev, int plane)
|
|||
}
|
||||
|
||||
DRM_SPINLOCK(&dev_priv->user_irq_lock);
|
||||
dev_priv->irq_mask_reg |= mask_reg;
|
||||
if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev))
|
||||
I915_WRITE(IMR, dev_priv->irq_mask_reg);
|
||||
else
|
||||
I915_WRITE16(IMR, dev_priv->irq_mask_reg);
|
||||
i915_disable_irq(dev_priv, mask_reg);
|
||||
DRM_SPINUNLOCK(&dev_priv->user_irq_lock);
|
||||
|
||||
if (pipestat_reg) {
|
||||
|
@ -862,8 +854,8 @@ void i915_enable_interrupt (struct drm_device *dev)
|
|||
{
|
||||
struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
|
||||
struct drm_connector *o;
|
||||
|
||||
dev_priv->irq_mask_reg &= ~I915_USER_INTERRUPT;
|
||||
|
||||
dev_priv->irq_mask_reg &= ~0;
|
||||
|
||||
if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) {
|
||||
if (dev->mode_config.num_connector)
|
||||
|
@ -925,14 +917,9 @@ void i915_enable_interrupt (struct drm_device *dev)
|
|||
}
|
||||
}
|
||||
|
||||
if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) {
|
||||
I915_WRITE(IMR, dev_priv->irq_mask_reg);
|
||||
I915_WRITE(IER, ~dev_priv->irq_mask_reg);
|
||||
} else {
|
||||
I915_WRITE16(IMR, dev_priv->irq_mask_reg);
|
||||
I915_WRITE16(IER, ~(u16)dev_priv->irq_mask_reg);
|
||||
}
|
||||
|
||||
I915_WRITE(IMR, dev_priv->irq_mask_reg);
|
||||
I915_WRITE(IER, I915_INTERRUPT_ENABLE_MASK);
|
||||
(void) I915_READ (IER);
|
||||
dev_priv->irq_enabled = 1;
|
||||
}
|
||||
|
||||
|
@ -964,17 +951,15 @@ int i915_vblank_pipe_get(struct drm_device *dev, void *data,
|
|||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct drm_i915_vblank_pipe *pipe = data;
|
||||
u16 flag;
|
||||
u32 flag = 0;
|
||||
|
||||
if (!dev_priv) {
|
||||
DRM_ERROR("called with no initialization\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev))
|
||||
flag = I915_READ(IER);
|
||||
else
|
||||
flag = I915_READ16(IER);
|
||||
if (dev_priv->irq_enabled)
|
||||
flag = ~dev_priv->irq_mask_reg;
|
||||
|
||||
pipe->pipe = 0;
|
||||
if (flag & I915_DISPLAY_PIPE_A_EVENT_INTERRUPT)
|
||||
|
@ -1158,19 +1143,12 @@ void i915_driver_irq_preinstall(struct drm_device * dev)
|
|||
tmp = I915_READ(PIPEBSTAT);
|
||||
I915_WRITE(PIPEBSTAT, tmp);
|
||||
|
||||
|
||||
I915_WRITE16(HWSTAM, 0xeffe);
|
||||
if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) {
|
||||
I915_WRITE(IMR, 0x0);
|
||||
I915_WRITE(IER, 0x0);
|
||||
tmp = I915_READ(IIR);
|
||||
I915_WRITE(IIR, tmp);
|
||||
} else {
|
||||
I915_WRITE16(IMR, 0x0);
|
||||
I915_WRITE16(IER, 0x0);
|
||||
tmp = I915_READ16(IIR);
|
||||
I915_WRITE16(IIR, tmp);
|
||||
}
|
||||
atomic_set(&dev_priv->irq_received, 0);
|
||||
I915_WRITE(HWSTAM, 0xffff);
|
||||
I915_WRITE(IER, 0x0);
|
||||
I915_WRITE(IMR, 0xffffffff);
|
||||
I915_WRITE(IIR, 0xffffffff);
|
||||
(void) I915_READ(IIR);
|
||||
}
|
||||
|
||||
int i915_driver_irq_postinstall(struct drm_device * dev)
|
||||
|
|
Loading…
Reference in New Issue