Loading drivers/char/drm/radeon_cp.c +4 −0 Original line number Original line Diff line number Diff line Loading @@ -1420,6 +1420,10 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) return DRM_ERR(EINVAL); return DRM_ERR(EINVAL); } } /* Enable vblank on CRTC1 for older X servers */ dev_priv->vblank_crtc = DRM_RADEON_VBLANK_CRTC1; switch(init->func) { switch(init->func) { case RADEON_INIT_R200_CP: case RADEON_INIT_R200_CP: dev_priv->microcode_version = UCODE_R200; dev_priv->microcode_version = UCODE_R200; Loading drivers/char/drm/radeon_drm.h +5 −1 Original line number Original line Diff line number Diff line Loading @@ -655,6 +655,7 @@ typedef struct drm_radeon_indirect { #define RADEON_PARAM_GART_TEX_HANDLE 10 #define RADEON_PARAM_GART_TEX_HANDLE 10 #define RADEON_PARAM_SCRATCH_OFFSET 11 #define RADEON_PARAM_SCRATCH_OFFSET 11 #define RADEON_PARAM_CARD_TYPE 12 #define RADEON_PARAM_CARD_TYPE 12 #define RADEON_PARAM_VBLANK_CRTC 13 /* VBLANK CRTC */ typedef struct drm_radeon_getparam { typedef struct drm_radeon_getparam { int param; int param; Loading Loading @@ -708,7 +709,7 @@ typedef struct drm_radeon_setparam { #define RADEON_SETPARAM_PCIGART_LOCATION 3 /* PCI Gart Location */ #define RADEON_SETPARAM_PCIGART_LOCATION 3 /* PCI Gart Location */ #define RADEON_SETPARAM_NEW_MEMMAP 4 /* Use new memory map */ #define RADEON_SETPARAM_NEW_MEMMAP 4 /* Use new memory map */ #define RADEON_SETPARAM_PCIGART_TABLE_SIZE 5 /* PCI GART Table Size */ #define RADEON_SETPARAM_PCIGART_TABLE_SIZE 5 /* PCI GART Table Size */ #define RADEON_SETPARAM_VBLANK_CRTC 6 /* VBLANK CRTC */ /* 1.14: Clients can allocate/free a surface /* 1.14: Clients can allocate/free a surface */ */ typedef struct drm_radeon_surface_alloc { typedef struct drm_radeon_surface_alloc { Loading @@ -721,4 +722,7 @@ typedef struct drm_radeon_surface_free { unsigned int address; unsigned int address; } drm_radeon_surface_free_t; } drm_radeon_surface_free_t; #define DRM_RADEON_VBLANK_CRTC1 1 #define DRM_RADEON_VBLANK_CRTC2 2 #endif #endif drivers/char/drm/radeon_drv.c +2 −1 Original line number Original line Diff line number Diff line Loading @@ -60,7 +60,7 @@ static struct drm_driver driver = { .driver_features = .driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED | DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL, DRIVER_IRQ_VBL | DRIVER_IRQ_VBL2, .dev_priv_size = sizeof(drm_radeon_buf_priv_t), .dev_priv_size = sizeof(drm_radeon_buf_priv_t), .load = radeon_driver_load, .load = radeon_driver_load, .firstopen = radeon_driver_firstopen, .firstopen = radeon_driver_firstopen, Loading @@ -70,6 +70,7 @@ static struct drm_driver driver = { .lastclose = radeon_driver_lastclose, .lastclose = radeon_driver_lastclose, .unload = radeon_driver_unload, .unload = radeon_driver_unload, .vblank_wait = radeon_driver_vblank_wait, .vblank_wait = radeon_driver_vblank_wait, .vblank_wait2 = radeon_driver_vblank_wait2, .dri_library_name = dri_library_name, .dri_library_name = dri_library_name, .irq_preinstall = radeon_driver_irq_preinstall, .irq_preinstall = radeon_driver_irq_preinstall, .irq_postinstall = radeon_driver_irq_postinstall, .irq_postinstall = radeon_driver_irq_postinstall, Loading drivers/char/drm/radeon_drv.h +12 −1 Original line number Original line Diff line number Diff line Loading @@ -97,9 +97,10 @@ * new packet type) * new packet type) * 1.26- Add support for variable size PCI(E) gart aperture * 1.26- Add support for variable size PCI(E) gart aperture * 1.27- Add support for IGP GART * 1.27- Add support for IGP GART * 1.28- Add support for VBL on CRTC2 */ */ #define DRIVER_MAJOR 1 #define DRIVER_MAJOR 1 #define DRIVER_MINOR 27 #define DRIVER_MINOR 28 #define DRIVER_PATCHLEVEL 0 #define DRIVER_PATCHLEVEL 0 /* /* Loading Loading @@ -277,6 +278,9 @@ typedef struct drm_radeon_private { /* SW interrupt */ /* SW interrupt */ wait_queue_head_t swi_queue; wait_queue_head_t swi_queue; atomic_t swi_emitted; atomic_t swi_emitted; int vblank_crtc; uint32_t irq_enable_reg; int irq_enabled; struct radeon_surface surfaces[RADEON_MAX_SURFACES]; struct radeon_surface surfaces[RADEON_MAX_SURFACES]; struct radeon_virt_surface virt_surfaces[2 * RADEON_MAX_SURFACES]; struct radeon_virt_surface virt_surfaces[2 * RADEON_MAX_SURFACES]; Loading Loading @@ -356,10 +360,14 @@ extern int radeon_irq_wait(DRM_IOCTL_ARGS); extern void radeon_do_release(drm_device_t * dev); extern void radeon_do_release(drm_device_t * dev); extern int radeon_driver_vblank_wait(drm_device_t * dev, extern int radeon_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence); unsigned int *sequence); extern int radeon_driver_vblank_wait2(drm_device_t * dev, unsigned int *sequence); extern irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS); extern irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS); extern void radeon_driver_irq_preinstall(drm_device_t * dev); extern void radeon_driver_irq_preinstall(drm_device_t * dev); extern void radeon_driver_irq_postinstall(drm_device_t * dev); extern void radeon_driver_irq_postinstall(drm_device_t * dev); extern void radeon_driver_irq_uninstall(drm_device_t * dev); extern void radeon_driver_irq_uninstall(drm_device_t * dev); extern int radeon_vblank_crtc_get(drm_device_t *dev); extern int radeon_vblank_crtc_set(drm_device_t *dev, int64_t value); extern int radeon_driver_load(struct drm_device *dev, unsigned long flags); extern int radeon_driver_load(struct drm_device *dev, unsigned long flags); extern int radeon_driver_unload(struct drm_device *dev); extern int radeon_driver_unload(struct drm_device *dev); Loading Loading @@ -496,12 +504,15 @@ extern int r300_do_cp_cmdbuf(drm_device_t * dev, DRMFILE filp, #define RADEON_GEN_INT_CNTL 0x0040 #define RADEON_GEN_INT_CNTL 0x0040 # define RADEON_CRTC_VBLANK_MASK (1 << 0) # define RADEON_CRTC_VBLANK_MASK (1 << 0) # define RADEON_CRTC2_VBLANK_MASK (1 << 9) # define RADEON_GUI_IDLE_INT_ENABLE (1 << 19) # define RADEON_GUI_IDLE_INT_ENABLE (1 << 19) # define RADEON_SW_INT_ENABLE (1 << 25) # define RADEON_SW_INT_ENABLE (1 << 25) #define RADEON_GEN_INT_STATUS 0x0044 #define RADEON_GEN_INT_STATUS 0x0044 # define RADEON_CRTC_VBLANK_STAT (1 << 0) # define RADEON_CRTC_VBLANK_STAT (1 << 0) # define RADEON_CRTC_VBLANK_STAT_ACK (1 << 0) # define RADEON_CRTC_VBLANK_STAT_ACK (1 << 0) # define RADEON_CRTC2_VBLANK_STAT (1 << 9) # define RADEON_CRTC2_VBLANK_STAT_ACK (1 << 9) # define RADEON_GUI_IDLE_INT_TEST_ACK (1 << 19) # define RADEON_GUI_IDLE_INT_TEST_ACK (1 << 19) # define RADEON_SW_INT_TEST (1 << 25) # define RADEON_SW_INT_TEST (1 << 25) # define RADEON_SW_INT_TEST_ACK (1 << 25) # define RADEON_SW_INT_TEST_ACK (1 << 25) Loading drivers/char/drm/radeon_irq.c +95 −11 Original line number Original line Diff line number Diff line Loading @@ -73,18 +73,35 @@ irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS) * outside the DRM * outside the DRM */ */ stat = radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK | stat = radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK | RADEON_CRTC_VBLANK_STAT)); RADEON_CRTC_VBLANK_STAT | RADEON_CRTC2_VBLANK_STAT)); if (!stat) if (!stat) return IRQ_NONE; return IRQ_NONE; stat &= dev_priv->irq_enable_reg; /* SW interrupt */ /* SW interrupt */ if (stat & RADEON_SW_INT_TEST) { if (stat & RADEON_SW_INT_TEST) { DRM_WAKEUP(&dev_priv->swi_queue); DRM_WAKEUP(&dev_priv->swi_queue); } } /* VBLANK interrupt */ /* VBLANK interrupt */ if (stat & RADEON_CRTC_VBLANK_STAT) { if (stat & (RADEON_CRTC_VBLANK_STAT|RADEON_CRTC2_VBLANK_STAT)) { int vblank_crtc = dev_priv->vblank_crtc; if ((vblank_crtc & (DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) == (DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) { if (stat & RADEON_CRTC_VBLANK_STAT) atomic_inc(&dev->vbl_received); if (stat & RADEON_CRTC2_VBLANK_STAT) atomic_inc(&dev->vbl_received2); } else if (((stat & RADEON_CRTC_VBLANK_STAT) && (vblank_crtc & DRM_RADEON_VBLANK_CRTC1)) || ((stat & RADEON_CRTC2_VBLANK_STAT) && (vblank_crtc & DRM_RADEON_VBLANK_CRTC2))) atomic_inc(&dev->vbl_received); atomic_inc(&dev->vbl_received); DRM_WAKEUP(&dev->vbl_queue); DRM_WAKEUP(&dev->vbl_queue); drm_vbl_send_signals(dev); drm_vbl_send_signals(dev); } } Loading Loading @@ -127,19 +144,30 @@ static int radeon_wait_irq(drm_device_t * dev, int swi_nr) return ret; return ret; } } int radeon_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence) int radeon_driver_vblank_do_wait(drm_device_t * dev, unsigned int *sequence, int crtc) { { drm_radeon_private_t *dev_priv = drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; (drm_radeon_private_t *) dev->dev_private; unsigned int cur_vblank; unsigned int cur_vblank; int ret = 0; int ret = 0; int ack = 0; atomic_t *counter; if (!dev_priv) { if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __FUNCTION__); DRM_ERROR("%s called with no initialization\n", __FUNCTION__); return DRM_ERR(EINVAL); return DRM_ERR(EINVAL); } } radeon_acknowledge_irqs(dev_priv, RADEON_CRTC_VBLANK_STAT); if (crtc == DRM_RADEON_VBLANK_CRTC1) { counter = &dev->vbl_received; ack |= RADEON_CRTC_VBLANK_STAT; } else if (crtc == DRM_RADEON_VBLANK_CRTC2) { counter = &dev->vbl_received2; ack |= RADEON_CRTC2_VBLANK_STAT; } else return DRM_ERR(EINVAL); radeon_acknowledge_irqs(dev_priv, ack); dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; Loading @@ -148,7 +176,7 @@ int radeon_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence) * using vertical blanks... * using vertical blanks... */ */ DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, (((cur_vblank = atomic_read(&dev->vbl_received)) (((cur_vblank = atomic_read(counter)) - *sequence) <= (1 << 23))); - *sequence) <= (1 << 23))); *sequence = cur_vblank; *sequence = cur_vblank; Loading @@ -156,6 +184,16 @@ int radeon_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence) return ret; return ret; } } int radeon_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence) { return radeon_driver_vblank_do_wait(dev, sequence, DRM_RADEON_VBLANK_CRTC1); } int radeon_driver_vblank_wait2(drm_device_t *dev, unsigned int *sequence) { return radeon_driver_vblank_do_wait(dev, sequence, DRM_RADEON_VBLANK_CRTC2); } /* Needs the lock as it touches the ring. /* Needs the lock as it touches the ring. */ */ int radeon_irq_emit(DRM_IOCTL_ARGS) int radeon_irq_emit(DRM_IOCTL_ARGS) Loading Loading @@ -204,6 +242,21 @@ int radeon_irq_wait(DRM_IOCTL_ARGS) return radeon_wait_irq(dev, irqwait.irq_seq); return radeon_wait_irq(dev, irqwait.irq_seq); } } static void radeon_enable_interrupt(drm_device_t *dev) { drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; dev_priv->irq_enable_reg = RADEON_SW_INT_ENABLE; if (dev_priv->vblank_crtc & DRM_RADEON_VBLANK_CRTC1) dev_priv->irq_enable_reg |= RADEON_CRTC_VBLANK_MASK; if (dev_priv->vblank_crtc & DRM_RADEON_VBLANK_CRTC2) dev_priv->irq_enable_reg |= RADEON_CRTC2_VBLANK_MASK; RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg); dev_priv->irq_enabled = 1; } /* drm_dma.h hooks /* drm_dma.h hooks */ */ void radeon_driver_irq_preinstall(drm_device_t * dev) void radeon_driver_irq_preinstall(drm_device_t * dev) Loading @@ -216,7 +269,8 @@ void radeon_driver_irq_preinstall(drm_device_t * dev) /* Clear bits if they're already high */ /* Clear bits if they're already high */ radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK | radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK | RADEON_CRTC_VBLANK_STAT)); RADEON_CRTC_VBLANK_STAT | RADEON_CRTC2_VBLANK_STAT)); } } void radeon_driver_irq_postinstall(drm_device_t * dev) void radeon_driver_irq_postinstall(drm_device_t * dev) Loading @@ -227,9 +281,7 @@ void radeon_driver_irq_postinstall(drm_device_t * dev) atomic_set(&dev_priv->swi_emitted, 0); atomic_set(&dev_priv->swi_emitted, 0); DRM_INIT_WAITQUEUE(&dev_priv->swi_queue); DRM_INIT_WAITQUEUE(&dev_priv->swi_queue); /* Turn on SW and VBL ints */ radeon_enable_interrupt(dev); RADEON_WRITE(RADEON_GEN_INT_CNTL, RADEON_CRTC_VBLANK_MASK | RADEON_SW_INT_ENABLE); } } void radeon_driver_irq_uninstall(drm_device_t * dev) void radeon_driver_irq_uninstall(drm_device_t * dev) Loading @@ -239,6 +291,38 @@ void radeon_driver_irq_uninstall(drm_device_t * dev) if (!dev_priv) if (!dev_priv) return; return; dev_priv->irq_enabled = 0; /* Disable *all* interrupts */ /* Disable *all* interrupts */ RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); } } int radeon_vblank_crtc_get(drm_device_t *dev) { drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; u32 flag; u32 value; flag = RADEON_READ(RADEON_GEN_INT_CNTL); value = 0; if (flag & RADEON_CRTC_VBLANK_MASK) value |= DRM_RADEON_VBLANK_CRTC1; if (flag & RADEON_CRTC2_VBLANK_MASK) value |= DRM_RADEON_VBLANK_CRTC2; return value; } int radeon_vblank_crtc_set(drm_device_t *dev, int64_t value) { drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; if (value & ~(DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) { DRM_ERROR("called with invalid crtc 0x%x\n", (unsigned int)value); return DRM_ERR(EINVAL); } dev_priv->vblank_crtc = (unsigned int)value; radeon_enable_interrupt(dev); return 0; } Loading
drivers/char/drm/radeon_cp.c +4 −0 Original line number Original line Diff line number Diff line Loading @@ -1420,6 +1420,10 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) return DRM_ERR(EINVAL); return DRM_ERR(EINVAL); } } /* Enable vblank on CRTC1 for older X servers */ dev_priv->vblank_crtc = DRM_RADEON_VBLANK_CRTC1; switch(init->func) { switch(init->func) { case RADEON_INIT_R200_CP: case RADEON_INIT_R200_CP: dev_priv->microcode_version = UCODE_R200; dev_priv->microcode_version = UCODE_R200; Loading
drivers/char/drm/radeon_drm.h +5 −1 Original line number Original line Diff line number Diff line Loading @@ -655,6 +655,7 @@ typedef struct drm_radeon_indirect { #define RADEON_PARAM_GART_TEX_HANDLE 10 #define RADEON_PARAM_GART_TEX_HANDLE 10 #define RADEON_PARAM_SCRATCH_OFFSET 11 #define RADEON_PARAM_SCRATCH_OFFSET 11 #define RADEON_PARAM_CARD_TYPE 12 #define RADEON_PARAM_CARD_TYPE 12 #define RADEON_PARAM_VBLANK_CRTC 13 /* VBLANK CRTC */ typedef struct drm_radeon_getparam { typedef struct drm_radeon_getparam { int param; int param; Loading Loading @@ -708,7 +709,7 @@ typedef struct drm_radeon_setparam { #define RADEON_SETPARAM_PCIGART_LOCATION 3 /* PCI Gart Location */ #define RADEON_SETPARAM_PCIGART_LOCATION 3 /* PCI Gart Location */ #define RADEON_SETPARAM_NEW_MEMMAP 4 /* Use new memory map */ #define RADEON_SETPARAM_NEW_MEMMAP 4 /* Use new memory map */ #define RADEON_SETPARAM_PCIGART_TABLE_SIZE 5 /* PCI GART Table Size */ #define RADEON_SETPARAM_PCIGART_TABLE_SIZE 5 /* PCI GART Table Size */ #define RADEON_SETPARAM_VBLANK_CRTC 6 /* VBLANK CRTC */ /* 1.14: Clients can allocate/free a surface /* 1.14: Clients can allocate/free a surface */ */ typedef struct drm_radeon_surface_alloc { typedef struct drm_radeon_surface_alloc { Loading @@ -721,4 +722,7 @@ typedef struct drm_radeon_surface_free { unsigned int address; unsigned int address; } drm_radeon_surface_free_t; } drm_radeon_surface_free_t; #define DRM_RADEON_VBLANK_CRTC1 1 #define DRM_RADEON_VBLANK_CRTC2 2 #endif #endif
drivers/char/drm/radeon_drv.c +2 −1 Original line number Original line Diff line number Diff line Loading @@ -60,7 +60,7 @@ static struct drm_driver driver = { .driver_features = .driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED | DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL, DRIVER_IRQ_VBL | DRIVER_IRQ_VBL2, .dev_priv_size = sizeof(drm_radeon_buf_priv_t), .dev_priv_size = sizeof(drm_radeon_buf_priv_t), .load = radeon_driver_load, .load = radeon_driver_load, .firstopen = radeon_driver_firstopen, .firstopen = radeon_driver_firstopen, Loading @@ -70,6 +70,7 @@ static struct drm_driver driver = { .lastclose = radeon_driver_lastclose, .lastclose = radeon_driver_lastclose, .unload = radeon_driver_unload, .unload = radeon_driver_unload, .vblank_wait = radeon_driver_vblank_wait, .vblank_wait = radeon_driver_vblank_wait, .vblank_wait2 = radeon_driver_vblank_wait2, .dri_library_name = dri_library_name, .dri_library_name = dri_library_name, .irq_preinstall = radeon_driver_irq_preinstall, .irq_preinstall = radeon_driver_irq_preinstall, .irq_postinstall = radeon_driver_irq_postinstall, .irq_postinstall = radeon_driver_irq_postinstall, Loading
drivers/char/drm/radeon_drv.h +12 −1 Original line number Original line Diff line number Diff line Loading @@ -97,9 +97,10 @@ * new packet type) * new packet type) * 1.26- Add support for variable size PCI(E) gart aperture * 1.26- Add support for variable size PCI(E) gart aperture * 1.27- Add support for IGP GART * 1.27- Add support for IGP GART * 1.28- Add support for VBL on CRTC2 */ */ #define DRIVER_MAJOR 1 #define DRIVER_MAJOR 1 #define DRIVER_MINOR 27 #define DRIVER_MINOR 28 #define DRIVER_PATCHLEVEL 0 #define DRIVER_PATCHLEVEL 0 /* /* Loading Loading @@ -277,6 +278,9 @@ typedef struct drm_radeon_private { /* SW interrupt */ /* SW interrupt */ wait_queue_head_t swi_queue; wait_queue_head_t swi_queue; atomic_t swi_emitted; atomic_t swi_emitted; int vblank_crtc; uint32_t irq_enable_reg; int irq_enabled; struct radeon_surface surfaces[RADEON_MAX_SURFACES]; struct radeon_surface surfaces[RADEON_MAX_SURFACES]; struct radeon_virt_surface virt_surfaces[2 * RADEON_MAX_SURFACES]; struct radeon_virt_surface virt_surfaces[2 * RADEON_MAX_SURFACES]; Loading Loading @@ -356,10 +360,14 @@ extern int radeon_irq_wait(DRM_IOCTL_ARGS); extern void radeon_do_release(drm_device_t * dev); extern void radeon_do_release(drm_device_t * dev); extern int radeon_driver_vblank_wait(drm_device_t * dev, extern int radeon_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence); unsigned int *sequence); extern int radeon_driver_vblank_wait2(drm_device_t * dev, unsigned int *sequence); extern irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS); extern irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS); extern void radeon_driver_irq_preinstall(drm_device_t * dev); extern void radeon_driver_irq_preinstall(drm_device_t * dev); extern void radeon_driver_irq_postinstall(drm_device_t * dev); extern void radeon_driver_irq_postinstall(drm_device_t * dev); extern void radeon_driver_irq_uninstall(drm_device_t * dev); extern void radeon_driver_irq_uninstall(drm_device_t * dev); extern int radeon_vblank_crtc_get(drm_device_t *dev); extern int radeon_vblank_crtc_set(drm_device_t *dev, int64_t value); extern int radeon_driver_load(struct drm_device *dev, unsigned long flags); extern int radeon_driver_load(struct drm_device *dev, unsigned long flags); extern int radeon_driver_unload(struct drm_device *dev); extern int radeon_driver_unload(struct drm_device *dev); Loading Loading @@ -496,12 +504,15 @@ extern int r300_do_cp_cmdbuf(drm_device_t * dev, DRMFILE filp, #define RADEON_GEN_INT_CNTL 0x0040 #define RADEON_GEN_INT_CNTL 0x0040 # define RADEON_CRTC_VBLANK_MASK (1 << 0) # define RADEON_CRTC_VBLANK_MASK (1 << 0) # define RADEON_CRTC2_VBLANK_MASK (1 << 9) # define RADEON_GUI_IDLE_INT_ENABLE (1 << 19) # define RADEON_GUI_IDLE_INT_ENABLE (1 << 19) # define RADEON_SW_INT_ENABLE (1 << 25) # define RADEON_SW_INT_ENABLE (1 << 25) #define RADEON_GEN_INT_STATUS 0x0044 #define RADEON_GEN_INT_STATUS 0x0044 # define RADEON_CRTC_VBLANK_STAT (1 << 0) # define RADEON_CRTC_VBLANK_STAT (1 << 0) # define RADEON_CRTC_VBLANK_STAT_ACK (1 << 0) # define RADEON_CRTC_VBLANK_STAT_ACK (1 << 0) # define RADEON_CRTC2_VBLANK_STAT (1 << 9) # define RADEON_CRTC2_VBLANK_STAT_ACK (1 << 9) # define RADEON_GUI_IDLE_INT_TEST_ACK (1 << 19) # define RADEON_GUI_IDLE_INT_TEST_ACK (1 << 19) # define RADEON_SW_INT_TEST (1 << 25) # define RADEON_SW_INT_TEST (1 << 25) # define RADEON_SW_INT_TEST_ACK (1 << 25) # define RADEON_SW_INT_TEST_ACK (1 << 25) Loading
drivers/char/drm/radeon_irq.c +95 −11 Original line number Original line Diff line number Diff line Loading @@ -73,18 +73,35 @@ irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS) * outside the DRM * outside the DRM */ */ stat = radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK | stat = radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK | RADEON_CRTC_VBLANK_STAT)); RADEON_CRTC_VBLANK_STAT | RADEON_CRTC2_VBLANK_STAT)); if (!stat) if (!stat) return IRQ_NONE; return IRQ_NONE; stat &= dev_priv->irq_enable_reg; /* SW interrupt */ /* SW interrupt */ if (stat & RADEON_SW_INT_TEST) { if (stat & RADEON_SW_INT_TEST) { DRM_WAKEUP(&dev_priv->swi_queue); DRM_WAKEUP(&dev_priv->swi_queue); } } /* VBLANK interrupt */ /* VBLANK interrupt */ if (stat & RADEON_CRTC_VBLANK_STAT) { if (stat & (RADEON_CRTC_VBLANK_STAT|RADEON_CRTC2_VBLANK_STAT)) { int vblank_crtc = dev_priv->vblank_crtc; if ((vblank_crtc & (DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) == (DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) { if (stat & RADEON_CRTC_VBLANK_STAT) atomic_inc(&dev->vbl_received); if (stat & RADEON_CRTC2_VBLANK_STAT) atomic_inc(&dev->vbl_received2); } else if (((stat & RADEON_CRTC_VBLANK_STAT) && (vblank_crtc & DRM_RADEON_VBLANK_CRTC1)) || ((stat & RADEON_CRTC2_VBLANK_STAT) && (vblank_crtc & DRM_RADEON_VBLANK_CRTC2))) atomic_inc(&dev->vbl_received); atomic_inc(&dev->vbl_received); DRM_WAKEUP(&dev->vbl_queue); DRM_WAKEUP(&dev->vbl_queue); drm_vbl_send_signals(dev); drm_vbl_send_signals(dev); } } Loading Loading @@ -127,19 +144,30 @@ static int radeon_wait_irq(drm_device_t * dev, int swi_nr) return ret; return ret; } } int radeon_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence) int radeon_driver_vblank_do_wait(drm_device_t * dev, unsigned int *sequence, int crtc) { { drm_radeon_private_t *dev_priv = drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; (drm_radeon_private_t *) dev->dev_private; unsigned int cur_vblank; unsigned int cur_vblank; int ret = 0; int ret = 0; int ack = 0; atomic_t *counter; if (!dev_priv) { if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __FUNCTION__); DRM_ERROR("%s called with no initialization\n", __FUNCTION__); return DRM_ERR(EINVAL); return DRM_ERR(EINVAL); } } radeon_acknowledge_irqs(dev_priv, RADEON_CRTC_VBLANK_STAT); if (crtc == DRM_RADEON_VBLANK_CRTC1) { counter = &dev->vbl_received; ack |= RADEON_CRTC_VBLANK_STAT; } else if (crtc == DRM_RADEON_VBLANK_CRTC2) { counter = &dev->vbl_received2; ack |= RADEON_CRTC2_VBLANK_STAT; } else return DRM_ERR(EINVAL); radeon_acknowledge_irqs(dev_priv, ack); dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; Loading @@ -148,7 +176,7 @@ int radeon_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence) * using vertical blanks... * using vertical blanks... */ */ DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, (((cur_vblank = atomic_read(&dev->vbl_received)) (((cur_vblank = atomic_read(counter)) - *sequence) <= (1 << 23))); - *sequence) <= (1 << 23))); *sequence = cur_vblank; *sequence = cur_vblank; Loading @@ -156,6 +184,16 @@ int radeon_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence) return ret; return ret; } } int radeon_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence) { return radeon_driver_vblank_do_wait(dev, sequence, DRM_RADEON_VBLANK_CRTC1); } int radeon_driver_vblank_wait2(drm_device_t *dev, unsigned int *sequence) { return radeon_driver_vblank_do_wait(dev, sequence, DRM_RADEON_VBLANK_CRTC2); } /* Needs the lock as it touches the ring. /* Needs the lock as it touches the ring. */ */ int radeon_irq_emit(DRM_IOCTL_ARGS) int radeon_irq_emit(DRM_IOCTL_ARGS) Loading Loading @@ -204,6 +242,21 @@ int radeon_irq_wait(DRM_IOCTL_ARGS) return radeon_wait_irq(dev, irqwait.irq_seq); return radeon_wait_irq(dev, irqwait.irq_seq); } } static void radeon_enable_interrupt(drm_device_t *dev) { drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; dev_priv->irq_enable_reg = RADEON_SW_INT_ENABLE; if (dev_priv->vblank_crtc & DRM_RADEON_VBLANK_CRTC1) dev_priv->irq_enable_reg |= RADEON_CRTC_VBLANK_MASK; if (dev_priv->vblank_crtc & DRM_RADEON_VBLANK_CRTC2) dev_priv->irq_enable_reg |= RADEON_CRTC2_VBLANK_MASK; RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg); dev_priv->irq_enabled = 1; } /* drm_dma.h hooks /* drm_dma.h hooks */ */ void radeon_driver_irq_preinstall(drm_device_t * dev) void radeon_driver_irq_preinstall(drm_device_t * dev) Loading @@ -216,7 +269,8 @@ void radeon_driver_irq_preinstall(drm_device_t * dev) /* Clear bits if they're already high */ /* Clear bits if they're already high */ radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK | radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK | RADEON_CRTC_VBLANK_STAT)); RADEON_CRTC_VBLANK_STAT | RADEON_CRTC2_VBLANK_STAT)); } } void radeon_driver_irq_postinstall(drm_device_t * dev) void radeon_driver_irq_postinstall(drm_device_t * dev) Loading @@ -227,9 +281,7 @@ void radeon_driver_irq_postinstall(drm_device_t * dev) atomic_set(&dev_priv->swi_emitted, 0); atomic_set(&dev_priv->swi_emitted, 0); DRM_INIT_WAITQUEUE(&dev_priv->swi_queue); DRM_INIT_WAITQUEUE(&dev_priv->swi_queue); /* Turn on SW and VBL ints */ radeon_enable_interrupt(dev); RADEON_WRITE(RADEON_GEN_INT_CNTL, RADEON_CRTC_VBLANK_MASK | RADEON_SW_INT_ENABLE); } } void radeon_driver_irq_uninstall(drm_device_t * dev) void radeon_driver_irq_uninstall(drm_device_t * dev) Loading @@ -239,6 +291,38 @@ void radeon_driver_irq_uninstall(drm_device_t * dev) if (!dev_priv) if (!dev_priv) return; return; dev_priv->irq_enabled = 0; /* Disable *all* interrupts */ /* Disable *all* interrupts */ RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); } } int radeon_vblank_crtc_get(drm_device_t *dev) { drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; u32 flag; u32 value; flag = RADEON_READ(RADEON_GEN_INT_CNTL); value = 0; if (flag & RADEON_CRTC_VBLANK_MASK) value |= DRM_RADEON_VBLANK_CRTC1; if (flag & RADEON_CRTC2_VBLANK_MASK) value |= DRM_RADEON_VBLANK_CRTC2; return value; } int radeon_vblank_crtc_set(drm_device_t *dev, int64_t value) { drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; if (value & ~(DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) { DRM_ERROR("called with invalid crtc 0x%x\n", (unsigned int)value); return DRM_ERR(EINVAL); } dev_priv->vblank_crtc = (unsigned int)value; radeon_enable_interrupt(dev); return 0; }