diff options
| author | Dave Airlie <airlied@linux.ie> | 2007-07-10 22:16:01 -0400 |
|---|---|---|
| committer | Dave Airlie <airlied@linux.ie> | 2007-07-10 22:16:01 -0400 |
| commit | ddbee33328dcfb892cd91f2d57a1822f4d6f70d9 (patch) | |
| tree | 6db71299d2cf09f22201a44487d925e222facb33 | |
| parent | 7c158acef8f0e51c3a5f71133aaf402628370a64 (diff) | |
radeon: add support for vblank on crtc2
This adds support for CRTC2 vblank on radeon similiar to the i915.
Signed-off-by: Dave Airlie <airlied@linux.ie>
| -rw-r--r-- | drivers/char/drm/radeon_cp.c | 4 | ||||
| -rw-r--r-- | drivers/char/drm/radeon_drm.h | 6 | ||||
| -rw-r--r-- | drivers/char/drm/radeon_drv.c | 3 | ||||
| -rw-r--r-- | drivers/char/drm/radeon_drv.h | 13 | ||||
| -rw-r--r-- | drivers/char/drm/radeon_irq.c | 106 | ||||
| -rw-r--r-- | drivers/char/drm/radeon_state.c | 6 |
6 files changed, 124 insertions, 14 deletions
diff --git a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c index aac5db3a0eb..7dd98005522 100644 --- a/drivers/char/drm/radeon_cp.c +++ b/drivers/char/drm/radeon_cp.c | |||
| @@ -1420,6 +1420,10 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) | |||
| 1420 | return DRM_ERR(EINVAL); | 1420 | return DRM_ERR(EINVAL); |
| 1421 | } | 1421 | } |
| 1422 | 1422 | ||
| 1423 | /* Enable vblank on CRTC1 for older X servers | ||
| 1424 | */ | ||
| 1425 | dev_priv->vblank_crtc = DRM_RADEON_VBLANK_CRTC1; | ||
| 1426 | |||
| 1423 | switch(init->func) { | 1427 | switch(init->func) { |
| 1424 | case RADEON_INIT_R200_CP: | 1428 | case RADEON_INIT_R200_CP: |
| 1425 | dev_priv->microcode_version = UCODE_R200; | 1429 | dev_priv->microcode_version = UCODE_R200; |
diff --git a/drivers/char/drm/radeon_drm.h b/drivers/char/drm/radeon_drm.h index 66c4b6fed04..04de7a15df9 100644 --- a/drivers/char/drm/radeon_drm.h +++ b/drivers/char/drm/radeon_drm.h | |||
| @@ -655,6 +655,7 @@ typedef struct drm_radeon_indirect { | |||
| 655 | #define RADEON_PARAM_GART_TEX_HANDLE 10 | 655 | #define RADEON_PARAM_GART_TEX_HANDLE 10 |
| 656 | #define RADEON_PARAM_SCRATCH_OFFSET 11 | 656 | #define RADEON_PARAM_SCRATCH_OFFSET 11 |
| 657 | #define RADEON_PARAM_CARD_TYPE 12 | 657 | #define RADEON_PARAM_CARD_TYPE 12 |
| 658 | #define RADEON_PARAM_VBLANK_CRTC 13 /* VBLANK CRTC */ | ||
| 658 | 659 | ||
| 659 | typedef struct drm_radeon_getparam { | 660 | typedef struct drm_radeon_getparam { |
| 660 | int param; | 661 | int param; |
| @@ -708,7 +709,7 @@ typedef struct drm_radeon_setparam { | |||
| 708 | #define RADEON_SETPARAM_PCIGART_LOCATION 3 /* PCI Gart Location */ | 709 | #define RADEON_SETPARAM_PCIGART_LOCATION 3 /* PCI Gart Location */ |
| 709 | #define RADEON_SETPARAM_NEW_MEMMAP 4 /* Use new memory map */ | 710 | #define RADEON_SETPARAM_NEW_MEMMAP 4 /* Use new memory map */ |
| 710 | #define RADEON_SETPARAM_PCIGART_TABLE_SIZE 5 /* PCI GART Table Size */ | 711 | #define RADEON_SETPARAM_PCIGART_TABLE_SIZE 5 /* PCI GART Table Size */ |
| 711 | 712 | #define RADEON_SETPARAM_VBLANK_CRTC 6 /* VBLANK CRTC */ | |
| 712 | /* 1.14: Clients can allocate/free a surface | 713 | /* 1.14: Clients can allocate/free a surface |
| 713 | */ | 714 | */ |
| 714 | typedef struct drm_radeon_surface_alloc { | 715 | typedef struct drm_radeon_surface_alloc { |
| @@ -721,4 +722,7 @@ typedef struct drm_radeon_surface_free { | |||
| 721 | unsigned int address; | 722 | unsigned int address; |
| 722 | } drm_radeon_surface_free_t; | 723 | } drm_radeon_surface_free_t; |
| 723 | 724 | ||
| 725 | #define DRM_RADEON_VBLANK_CRTC1 1 | ||
| 726 | #define DRM_RADEON_VBLANK_CRTC2 2 | ||
| 727 | |||
| 724 | #endif | 728 | #endif |
diff --git a/drivers/char/drm/radeon_drv.c b/drivers/char/drm/radeon_drv.c index 2eb652ec674..349ac3d3b84 100644 --- a/drivers/char/drm/radeon_drv.c +++ b/drivers/char/drm/radeon_drv.c | |||
| @@ -60,7 +60,7 @@ static struct drm_driver driver = { | |||
| 60 | .driver_features = | 60 | .driver_features = |
| 61 | DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | | 61 | DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | |
| 62 | DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED | | 62 | DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED | |
| 63 | DRIVER_IRQ_VBL, | 63 | DRIVER_IRQ_VBL | DRIVER_IRQ_VBL2, |
| 64 | .dev_priv_size = sizeof(drm_radeon_buf_priv_t), | 64 | .dev_priv_size = sizeof(drm_radeon_buf_priv_t), |
| 65 | .load = radeon_driver_load, | 65 | .load = radeon_driver_load, |
| 66 | .firstopen = radeon_driver_firstopen, | 66 | .firstopen = radeon_driver_firstopen, |
| @@ -70,6 +70,7 @@ static struct drm_driver driver = { | |||
| 70 | .lastclose = radeon_driver_lastclose, | 70 | .lastclose = radeon_driver_lastclose, |
| 71 | .unload = radeon_driver_unload, | 71 | .unload = radeon_driver_unload, |
| 72 | .vblank_wait = radeon_driver_vblank_wait, | 72 | .vblank_wait = radeon_driver_vblank_wait, |
| 73 | .vblank_wait2 = radeon_driver_vblank_wait2, | ||
| 73 | .dri_library_name = dri_library_name, | 74 | .dri_library_name = dri_library_name, |
| 74 | .irq_preinstall = radeon_driver_irq_preinstall, | 75 | .irq_preinstall = radeon_driver_irq_preinstall, |
| 75 | .irq_postinstall = radeon_driver_irq_postinstall, | 76 | .irq_postinstall = radeon_driver_irq_postinstall, |
diff --git a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h index 54f49ef4bef..4422ae3a68b 100644 --- a/drivers/char/drm/radeon_drv.h +++ b/drivers/char/drm/radeon_drv.h | |||
| @@ -97,9 +97,10 @@ | |||
| 97 | * new packet type) | 97 | * new packet type) |
| 98 | * 1.26- Add support for variable size PCI(E) gart aperture | 98 | * 1.26- Add support for variable size PCI(E) gart aperture |
| 99 | * 1.27- Add support for IGP GART | 99 | * 1.27- Add support for IGP GART |
| 100 | * 1.28- Add support for VBL on CRTC2 | ||
| 100 | */ | 101 | */ |
| 101 | #define DRIVER_MAJOR 1 | 102 | #define DRIVER_MAJOR 1 |
| 102 | #define DRIVER_MINOR 27 | 103 | #define DRIVER_MINOR 28 |
| 103 | #define DRIVER_PATCHLEVEL 0 | 104 | #define DRIVER_PATCHLEVEL 0 |
| 104 | 105 | ||
| 105 | /* | 106 | /* |
| @@ -277,6 +278,9 @@ typedef struct drm_radeon_private { | |||
| 277 | /* SW interrupt */ | 278 | /* SW interrupt */ |
| 278 | wait_queue_head_t swi_queue; | 279 | wait_queue_head_t swi_queue; |
| 279 | atomic_t swi_emitted; | 280 | atomic_t swi_emitted; |
| 281 | int vblank_crtc; | ||
| 282 | uint32_t irq_enable_reg; | ||
| 283 | int irq_enabled; | ||
| 280 | 284 | ||
| 281 | struct radeon_surface surfaces[RADEON_MAX_SURFACES]; | 285 | struct radeon_surface surfaces[RADEON_MAX_SURFACES]; |
| 282 | struct radeon_virt_surface virt_surfaces[2 * RADEON_MAX_SURFACES]; | 286 | struct radeon_virt_surface virt_surfaces[2 * RADEON_MAX_SURFACES]; |
| @@ -356,10 +360,14 @@ extern int radeon_irq_wait(DRM_IOCTL_ARGS); | |||
| 356 | extern void radeon_do_release(drm_device_t * dev); | 360 | extern void radeon_do_release(drm_device_t * dev); |
| 357 | extern int radeon_driver_vblank_wait(drm_device_t * dev, | 361 | extern int radeon_driver_vblank_wait(drm_device_t * dev, |
| 358 | unsigned int *sequence); | 362 | unsigned int *sequence); |
| 363 | extern int radeon_driver_vblank_wait2(drm_device_t * dev, | ||
| 364 | unsigned int *sequence); | ||
| 359 | extern irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS); | 365 | extern irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS); |
| 360 | extern void radeon_driver_irq_preinstall(drm_device_t * dev); | 366 | extern void radeon_driver_irq_preinstall(drm_device_t * dev); |
| 361 | extern void radeon_driver_irq_postinstall(drm_device_t * dev); | 367 | extern void radeon_driver_irq_postinstall(drm_device_t * dev); |
| 362 | extern void radeon_driver_irq_uninstall(drm_device_t * dev); | 368 | extern void radeon_driver_irq_uninstall(drm_device_t * dev); |
| 369 | extern int radeon_vblank_crtc_get(drm_device_t *dev); | ||
| 370 | extern int radeon_vblank_crtc_set(drm_device_t *dev, int64_t value); | ||
| 363 | 371 | ||
| 364 | extern int radeon_driver_load(struct drm_device *dev, unsigned long flags); | 372 | extern int radeon_driver_load(struct drm_device *dev, unsigned long flags); |
| 365 | extern int radeon_driver_unload(struct drm_device *dev); | 373 | extern int radeon_driver_unload(struct drm_device *dev); |
| @@ -496,12 +504,15 @@ extern int r300_do_cp_cmdbuf(drm_device_t * dev, DRMFILE filp, | |||
| 496 | 504 | ||
| 497 | #define RADEON_GEN_INT_CNTL 0x0040 | 505 | #define RADEON_GEN_INT_CNTL 0x0040 |
| 498 | # define RADEON_CRTC_VBLANK_MASK (1 << 0) | 506 | # define RADEON_CRTC_VBLANK_MASK (1 << 0) |
| 507 | # define RADEON_CRTC2_VBLANK_MASK (1 << 9) | ||
| 499 | # define RADEON_GUI_IDLE_INT_ENABLE (1 << 19) | 508 | # define RADEON_GUI_IDLE_INT_ENABLE (1 << 19) |
| 500 | # define RADEON_SW_INT_ENABLE (1 << 25) | 509 | # define RADEON_SW_INT_ENABLE (1 << 25) |
| 501 | 510 | ||
| 502 | #define RADEON_GEN_INT_STATUS 0x0044 | 511 | #define RADEON_GEN_INT_STATUS 0x0044 |
| 503 | # define RADEON_CRTC_VBLANK_STAT (1 << 0) | 512 | # define RADEON_CRTC_VBLANK_STAT (1 << 0) |
| 504 | # define RADEON_CRTC_VBLANK_STAT_ACK (1 << 0) | 513 | # define RADEON_CRTC_VBLANK_STAT_ACK (1 << 0) |
| 514 | # define RADEON_CRTC2_VBLANK_STAT (1 << 9) | ||
| 515 | # define RADEON_CRTC2_VBLANK_STAT_ACK (1 << 9) | ||
| 505 | # define RADEON_GUI_IDLE_INT_TEST_ACK (1 << 19) | 516 | # define RADEON_GUI_IDLE_INT_TEST_ACK (1 << 19) |
| 506 | # define RADEON_SW_INT_TEST (1 << 25) | 517 | # define RADEON_SW_INT_TEST (1 << 25) |
| 507 | # define RADEON_SW_INT_TEST_ACK (1 << 25) | 518 | # define RADEON_SW_INT_TEST_ACK (1 << 25) |
diff --git a/drivers/char/drm/radeon_irq.c b/drivers/char/drm/radeon_irq.c index 3ff0baa2fbf..a4be86e3812 100644 --- a/drivers/char/drm/radeon_irq.c +++ b/drivers/char/drm/radeon_irq.c | |||
| @@ -73,18 +73,35 @@ irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS) | |||
| 73 | * outside the DRM | 73 | * outside the DRM |
| 74 | */ | 74 | */ |
| 75 | stat = radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK | | 75 | stat = radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK | |
| 76 | RADEON_CRTC_VBLANK_STAT)); | 76 | RADEON_CRTC_VBLANK_STAT | |
| 77 | RADEON_CRTC2_VBLANK_STAT)); | ||
| 77 | if (!stat) | 78 | if (!stat) |
| 78 | return IRQ_NONE; | 79 | return IRQ_NONE; |
| 79 | 80 | ||
| 81 | stat &= dev_priv->irq_enable_reg; | ||
| 82 | |||
| 80 | /* SW interrupt */ | 83 | /* SW interrupt */ |
| 81 | if (stat & RADEON_SW_INT_TEST) { | 84 | if (stat & RADEON_SW_INT_TEST) { |
| 82 | DRM_WAKEUP(&dev_priv->swi_queue); | 85 | DRM_WAKEUP(&dev_priv->swi_queue); |
| 83 | } | 86 | } |
| 84 | 87 | ||
| 85 | /* VBLANK interrupt */ | 88 | /* VBLANK interrupt */ |
| 86 | if (stat & RADEON_CRTC_VBLANK_STAT) { | 89 | if (stat & (RADEON_CRTC_VBLANK_STAT|RADEON_CRTC2_VBLANK_STAT)) { |
| 87 | atomic_inc(&dev->vbl_received); | 90 | int vblank_crtc = dev_priv->vblank_crtc; |
| 91 | |||
| 92 | if ((vblank_crtc & | ||
| 93 | (DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) == | ||
| 94 | (DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) { | ||
| 95 | if (stat & RADEON_CRTC_VBLANK_STAT) | ||
| 96 | atomic_inc(&dev->vbl_received); | ||
| 97 | if (stat & RADEON_CRTC2_VBLANK_STAT) | ||
| 98 | atomic_inc(&dev->vbl_received2); | ||
| 99 | } else if (((stat & RADEON_CRTC_VBLANK_STAT) && | ||
| 100 | (vblank_crtc & DRM_RADEON_VBLANK_CRTC1)) || | ||
| 101 | ((stat & RADEON_CRTC2_VBLANK_STAT) && | ||
| 102 | (vblank_crtc & DRM_RADEON_VBLANK_CRTC2))) | ||
| 103 | atomic_inc(&dev->vbl_received); | ||
| 104 | |||
| 88 | DRM_WAKEUP(&dev->vbl_queue); | 105 | DRM_WAKEUP(&dev->vbl_queue); |
| 89 | drm_vbl_send_signals(dev); | 106 | drm_vbl_send_signals(dev); |
| 90 | } | 107 | } |
| @@ -127,19 +144,30 @@ static int radeon_wait_irq(drm_device_t * dev, int swi_nr) | |||
| 127 | return ret; | 144 | return ret; |
| 128 | } | 145 | } |
| 129 | 146 | ||
| 130 | int radeon_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence) | 147 | int radeon_driver_vblank_do_wait(drm_device_t * dev, unsigned int *sequence, |
| 148 | int crtc) | ||
| 131 | { | 149 | { |
| 132 | drm_radeon_private_t *dev_priv = | 150 | drm_radeon_private_t *dev_priv = |
| 133 | (drm_radeon_private_t *) dev->dev_private; | 151 | (drm_radeon_private_t *) dev->dev_private; |
| 134 | unsigned int cur_vblank; | 152 | unsigned int cur_vblank; |
| 135 | int ret = 0; | 153 | int ret = 0; |
| 136 | 154 | int ack = 0; | |
| 155 | atomic_t *counter; | ||
| 137 | if (!dev_priv) { | 156 | if (!dev_priv) { |
| 138 | DRM_ERROR("%s called with no initialization\n", __FUNCTION__); | 157 | DRM_ERROR("%s called with no initialization\n", __FUNCTION__); |
| 139 | return DRM_ERR(EINVAL); | 158 | return DRM_ERR(EINVAL); |
| 140 | } | 159 | } |
| 141 | 160 | ||
| 142 | radeon_acknowledge_irqs(dev_priv, RADEON_CRTC_VBLANK_STAT); | 161 | if (crtc == DRM_RADEON_VBLANK_CRTC1) { |
| 162 | counter = &dev->vbl_received; | ||
| 163 | ack |= RADEON_CRTC_VBLANK_STAT; | ||
| 164 | } else if (crtc == DRM_RADEON_VBLANK_CRTC2) { | ||
| 165 | counter = &dev->vbl_received2; | ||
| 166 | ack |= RADEON_CRTC2_VBLANK_STAT; | ||
| 167 | } else | ||
| 168 | return DRM_ERR(EINVAL); | ||
| 169 | |||
| 170 | radeon_acknowledge_irqs(dev_priv, ack); | ||
| 143 | 171 | ||
| 144 | dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; | 172 | dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; |
| 145 | 173 | ||
| @@ -148,7 +176,7 @@ int radeon_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence) | |||
| 148 | * using vertical blanks... | 176 | * using vertical blanks... |
| 149 | */ | 177 | */ |
| 150 | DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, | 178 | DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, |
| 151 | (((cur_vblank = atomic_read(&dev->vbl_received)) | 179 | (((cur_vblank = atomic_read(counter)) |
| 152 | - *sequence) <= (1 << 23))); | 180 | - *sequence) <= (1 << 23))); |
| 153 | 181 | ||
| 154 | *sequence = cur_vblank; | 182 | *sequence = cur_vblank; |
| @@ -156,6 +184,16 @@ int radeon_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence) | |||
| 156 | return ret; | 184 | return ret; |
| 157 | } | 185 | } |
| 158 | 186 | ||
| 187 | int radeon_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence) | ||
| 188 | { | ||
| 189 | return radeon_driver_vblank_do_wait(dev, sequence, DRM_RADEON_VBLANK_CRTC1); | ||
| 190 | } | ||
| 191 | |||
| 192 | int radeon_driver_vblank_wait2(drm_device_t *dev, unsigned int *sequence) | ||
| 193 | { | ||
| 194 | return radeon_driver_vblank_do_wait(dev, sequence, DRM_RADEON_VBLANK_CRTC2); | ||
| 195 | } | ||
| 196 | |||
| 159 | /* Needs the lock as it touches the ring. | 197 | /* Needs the lock as it touches the ring. |
| 160 | */ | 198 | */ |
| 161 | int radeon_irq_emit(DRM_IOCTL_ARGS) | 199 | int radeon_irq_emit(DRM_IOCTL_ARGS) |
| @@ -204,6 +242,21 @@ int radeon_irq_wait(DRM_IOCTL_ARGS) | |||
| 204 | return radeon_wait_irq(dev, irqwait.irq_seq); | 242 | return radeon_wait_irq(dev, irqwait.irq_seq); |
| 205 | } | 243 | } |
| 206 | 244 | ||
| 245 | static void radeon_enable_interrupt(drm_device_t *dev) | ||
| 246 | { | ||
| 247 | drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; | ||
| 248 | |||
| 249 | dev_priv->irq_enable_reg = RADEON_SW_INT_ENABLE; | ||
| 250 | if (dev_priv->vblank_crtc & DRM_RADEON_VBLANK_CRTC1) | ||
| 251 | dev_priv->irq_enable_reg |= RADEON_CRTC_VBLANK_MASK; | ||
| 252 | |||
| 253 | if (dev_priv->vblank_crtc & DRM_RADEON_VBLANK_CRTC2) | ||
| 254 | dev_priv->irq_enable_reg |= RADEON_CRTC2_VBLANK_MASK; | ||
| 255 | |||
| 256 | RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg); | ||
| 257 | dev_priv->irq_enabled = 1; | ||
| 258 | } | ||
| 259 | |||
| 207 | /* drm_dma.h hooks | 260 | /* drm_dma.h hooks |
| 208 | */ | 261 | */ |
| 209 | void radeon_driver_irq_preinstall(drm_device_t * dev) | 262 | void radeon_driver_irq_preinstall(drm_device_t * dev) |
| @@ -216,7 +269,8 @@ void radeon_driver_irq_preinstall(drm_device_t * dev) | |||
| 216 | 269 | ||
| 217 | /* Clear bits if they're already high */ | 270 | /* Clear bits if they're already high */ |
| 218 | radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK | | 271 | radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK | |
| 219 | RADEON_CRTC_VBLANK_STAT)); | 272 | RADEON_CRTC_VBLANK_STAT | |
| 273 | RADEON_CRTC2_VBLANK_STAT)); | ||
| 220 | } | 274 | } |
| 221 | 275 | ||
| 222 | void radeon_driver_irq_postinstall(drm_device_t * dev) | 276 | void radeon_driver_irq_postinstall(drm_device_t * dev) |
| @@ -227,9 +281,7 @@ void radeon_driver_irq_postinstall(drm_device_t * dev) | |||
| 227 | atomic_set(&dev_priv->swi_emitted, 0); | 281 | atomic_set(&dev_priv->swi_emitted, 0); |
| 228 | DRM_INIT_WAITQUEUE(&dev_priv->swi_queue); | 282 | DRM_INIT_WAITQUEUE(&dev_priv->swi_queue); |
| 229 | 283 | ||
| 230 | /* Turn on SW and VBL ints */ | 284 | radeon_enable_interrupt(dev); |
| 231 | RADEON_WRITE(RADEON_GEN_INT_CNTL, | ||
| 232 | RADEON_CRTC_VBLANK_MASK | RADEON_SW_INT_ENABLE); | ||
| 233 | } | 285 | } |
| 234 | 286 | ||
| 235 | void radeon_driver_irq_uninstall(drm_device_t * dev) | 287 | void radeon_driver_irq_uninstall(drm_device_t * dev) |
| @@ -239,6 +291,38 @@ void radeon_driver_irq_uninstall(drm_device_t * dev) | |||
| 239 | if (!dev_priv) | 291 | if (!dev_priv) |
| 240 | return; | 292 | return; |
| 241 | 293 | ||
| 294 | dev_priv->irq_enabled = 0; | ||
| 295 | |||
| 242 | /* Disable *all* interrupts */ | 296 | /* Disable *all* interrupts */ |
| 243 | RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); | 297 | RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); |
| 244 | } | 298 | } |
| 299 | |||
| 300 | |||
| 301 | int radeon_vblank_crtc_get(drm_device_t *dev) | ||
| 302 | { | ||
| 303 | drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; | ||
| 304 | u32 flag; | ||
| 305 | u32 value; | ||
| 306 | |||
| 307 | flag = RADEON_READ(RADEON_GEN_INT_CNTL); | ||
| 308 | value = 0; | ||
| 309 | |||
| 310 | if (flag & RADEON_CRTC_VBLANK_MASK) | ||
| 311 | value |= DRM_RADEON_VBLANK_CRTC1; | ||
| 312 | |||
| 313 | if (flag & RADEON_CRTC2_VBLANK_MASK) | ||
| 314 | value |= DRM_RADEON_VBLANK_CRTC2; | ||
| 315 | return value; | ||
| 316 | } | ||
| 317 | |||
| 318 | int radeon_vblank_crtc_set(drm_device_t *dev, int64_t value) | ||
| 319 | { | ||
| 320 | drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; | ||
| 321 | if (value & ~(DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) { | ||
| 322 | DRM_ERROR("called with invalid crtc 0x%x\n", (unsigned int)value); | ||
| 323 | return DRM_ERR(EINVAL); | ||
| 324 | } | ||
| 325 | dev_priv->vblank_crtc = (unsigned int)value; | ||
| 326 | radeon_enable_interrupt(dev); | ||
| 327 | return 0; | ||
| 328 | } | ||
diff --git a/drivers/char/drm/radeon_state.c b/drivers/char/drm/radeon_state.c index 98c5f1d3a8e..5b89e471bc7 100644 --- a/drivers/char/drm/radeon_state.c +++ b/drivers/char/drm/radeon_state.c | |||
| @@ -3085,6 +3085,9 @@ static int radeon_cp_getparam(DRM_IOCTL_ARGS) | |||
| 3085 | else | 3085 | else |
| 3086 | value = RADEON_CARD_PCI; | 3086 | value = RADEON_CARD_PCI; |
| 3087 | break; | 3087 | break; |
| 3088 | case RADEON_PARAM_VBLANK_CRTC: | ||
| 3089 | value = radeon_vblank_crtc_get(dev); | ||
| 3090 | break; | ||
| 3088 | default: | 3091 | default: |
| 3089 | DRM_DEBUG("Invalid parameter %d\n", param.param); | 3092 | DRM_DEBUG("Invalid parameter %d\n", param.param); |
| 3090 | return DRM_ERR(EINVAL); | 3093 | return DRM_ERR(EINVAL); |
| @@ -3141,6 +3144,9 @@ static int radeon_cp_setparam(DRM_IOCTL_ARGS) | |||
| 3141 | if (dev_priv->gart_info.table_size < RADEON_PCIGART_TABLE_SIZE) | 3144 | if (dev_priv->gart_info.table_size < RADEON_PCIGART_TABLE_SIZE) |
| 3142 | dev_priv->gart_info.table_size = RADEON_PCIGART_TABLE_SIZE; | 3145 | dev_priv->gart_info.table_size = RADEON_PCIGART_TABLE_SIZE; |
| 3143 | break; | 3146 | break; |
| 3147 | case RADEON_SETPARAM_VBLANK_CRTC: | ||
| 3148 | return radeon_vblank_crtc_set(dev, sp.value); | ||
| 3149 | break; | ||
| 3144 | default: | 3150 | default: |
| 3145 | DRM_DEBUG("Invalid parameter %d\n", sp.param); | 3151 | DRM_DEBUG("Invalid parameter %d\n", sp.param); |
| 3146 | return DRM_ERR(EINVAL); | 3152 | return DRM_ERR(EINVAL); |
