1139749Simp/* radeon_irq.c -- IRQ handling for radeon -*- linux-c -*- */ 2139749Simp/*- 3112015Sanholt * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. 4145132Sanholt * 5112015Sanholt * The Weather Channel (TM) funded Tungsten Graphics to develop the 6112015Sanholt * initial release of the Radeon 8500 driver under the XFree86 license. 7112015Sanholt * This notice must be preserved. 8112015Sanholt * 9112015Sanholt * Permission is hereby granted, free of charge, to any person obtaining a 10112015Sanholt * copy of this software and associated documentation files (the "Software"), 11112015Sanholt * to deal in the Software without restriction, including without limitation 12112015Sanholt * the rights to use, copy, modify, merge, publish, distribute, sublicense, 13112015Sanholt * and/or sell copies of the Software, and to permit persons to whom the 14112015Sanholt * Software is furnished to do so, subject to the following conditions: 15112015Sanholt * 16112015Sanholt * The above copyright notice and this permission notice (including the next 17112015Sanholt * paragraph) shall be included in all copies or substantial portions of the 18112015Sanholt * Software. 19112015Sanholt * 20112015Sanholt * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21112015Sanholt * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22112015Sanholt * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 23112015Sanholt * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 24112015Sanholt * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 25112015Sanholt * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26112015Sanholt * DEALINGS IN THE SOFTWARE. 27112015Sanholt * 28112015Sanholt * Authors: 29112015Sanholt * Keith Whitwell <keith@tungstengraphics.com> 30145132Sanholt * Michel D���zer <michel@daenzer.net> 31112015Sanholt */ 32112015Sanholt 33152909Sanholt#include <sys/cdefs.h> 34152909Sanholt__FBSDID("$FreeBSD$"); 35152909Sanholt 36112015Sanholt#include "dev/drm/drmP.h" 37112015Sanholt#include "dev/drm/drm.h" 38112015Sanholt#include "dev/drm/radeon_drm.h" 39112015Sanholt#include "dev/drm/radeon_drv.h" 40112015Sanholt 41182080Srnolandvoid radeon_irq_set_state(struct drm_device *dev, u32 mask, int state) 42152909Sanholt{ 43182080Srnoland drm_radeon_private_t *dev_priv = dev->dev_private; 44182080Srnoland 45182080Srnoland if (state) 46182080Srnoland dev_priv->irq_enable_reg |= mask; 47182080Srnoland else 48182080Srnoland dev_priv->irq_enable_reg &= ~mask; 49182080Srnoland 50186465Srnoland if (dev->irq_enabled) 51186465Srnoland RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg); 52182080Srnoland} 53182080Srnoland 54182080Srnolandstatic void r500_vbl_irq_set_state(struct drm_device *dev, u32 mask, int state) 55182080Srnoland{ 56182080Srnoland drm_radeon_private_t *dev_priv = dev->dev_private; 57182080Srnoland 58182080Srnoland if (state) 59182080Srnoland dev_priv->r500_disp_irq_reg |= mask; 60182080Srnoland else 61182080Srnoland dev_priv->r500_disp_irq_reg &= ~mask; 62182080Srnoland 63186465Srnoland if (dev->irq_enabled) 64186465Srnoland RADEON_WRITE(R500_DxMODE_INT_MASK, dev_priv->r500_disp_irq_reg); 65182080Srnoland} 66182080Srnoland 67182080Srnolandint radeon_enable_vblank(struct drm_device *dev, int crtc) 68182080Srnoland{ 69182080Srnoland drm_radeon_private_t *dev_priv = dev->dev_private; 70182080Srnoland 71189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) { 72182080Srnoland switch (crtc) { 73182080Srnoland case 0: 74182080Srnoland r500_vbl_irq_set_state(dev, R500_D1MODE_INT_MASK, 1); 75182080Srnoland break; 76182080Srnoland case 1: 77182080Srnoland r500_vbl_irq_set_state(dev, R500_D2MODE_INT_MASK, 1); 78182080Srnoland break; 79182080Srnoland default: 80182080Srnoland DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", 81182080Srnoland crtc); 82182080Srnoland return EINVAL; 83182080Srnoland } 84182080Srnoland } else { 85182080Srnoland switch (crtc) { 86182080Srnoland case 0: 87182080Srnoland radeon_irq_set_state(dev, RADEON_CRTC_VBLANK_MASK, 1); 88182080Srnoland break; 89182080Srnoland case 1: 90182080Srnoland radeon_irq_set_state(dev, RADEON_CRTC2_VBLANK_MASK, 1); 91182080Srnoland break; 92182080Srnoland default: 93182080Srnoland DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", 94182080Srnoland crtc); 95182080Srnoland return EINVAL; 96182080Srnoland } 97182080Srnoland } 98182080Srnoland 99182080Srnoland return 0; 100182080Srnoland} 101182080Srnoland 102182080Srnolandvoid radeon_disable_vblank(struct drm_device *dev, int crtc) 103182080Srnoland{ 104182080Srnoland drm_radeon_private_t *dev_priv = dev->dev_private; 105182080Srnoland 106189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) { 107182080Srnoland switch (crtc) { 108182080Srnoland case 0: 109182080Srnoland r500_vbl_irq_set_state(dev, R500_D1MODE_INT_MASK, 0); 110182080Srnoland break; 111182080Srnoland case 1: 112182080Srnoland r500_vbl_irq_set_state(dev, R500_D2MODE_INT_MASK, 0); 113182080Srnoland break; 114182080Srnoland default: 115182080Srnoland DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", 116182080Srnoland crtc); 117182080Srnoland break; 118182080Srnoland } 119182080Srnoland } else { 120182080Srnoland switch (crtc) { 121182080Srnoland case 0: 122182080Srnoland radeon_irq_set_state(dev, RADEON_CRTC_VBLANK_MASK, 0); 123182080Srnoland break; 124182080Srnoland case 1: 125182080Srnoland radeon_irq_set_state(dev, RADEON_CRTC2_VBLANK_MASK, 0); 126182080Srnoland break; 127182080Srnoland default: 128182080Srnoland DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", 129182080Srnoland crtc); 130182080Srnoland break; 131182080Srnoland } 132182080Srnoland } 133182080Srnoland} 134182080Srnoland 135182080Srnolandstatic __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t * dev_priv, u32 *r500_disp_int) 136182080Srnoland{ 137182080Srnoland u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS); 138182080Srnoland u32 irq_mask = RADEON_SW_INT_TEST; 139182080Srnoland 140182080Srnoland *r500_disp_int = 0; 141189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) { 142182080Srnoland /* vbl interrupts in a different place */ 143182080Srnoland 144182080Srnoland if (irqs & R500_DISPLAY_INT_STATUS) { 145182080Srnoland /* if a display interrupt */ 146182080Srnoland u32 disp_irq; 147182080Srnoland 148182080Srnoland disp_irq = RADEON_READ(R500_DISP_INTERRUPT_STATUS); 149182080Srnoland 150182080Srnoland *r500_disp_int = disp_irq; 151182080Srnoland if (disp_irq & R500_D1_VBLANK_INTERRUPT) { 152182080Srnoland RADEON_WRITE(R500_D1MODE_VBLANK_STATUS, R500_VBLANK_ACK); 153182080Srnoland } 154182080Srnoland if (disp_irq & R500_D2_VBLANK_INTERRUPT) { 155182080Srnoland RADEON_WRITE(R500_D2MODE_VBLANK_STATUS, R500_VBLANK_ACK); 156182080Srnoland } 157182080Srnoland } 158182080Srnoland irq_mask |= R500_DISPLAY_INT_STATUS; 159182080Srnoland } else 160182080Srnoland irq_mask |= RADEON_CRTC_VBLANK_STAT | RADEON_CRTC2_VBLANK_STAT; 161182080Srnoland 162182080Srnoland irqs &= irq_mask; 163182080Srnoland 164152909Sanholt if (irqs) 165152909Sanholt RADEON_WRITE(RADEON_GEN_INT_STATUS, irqs); 166182080Srnoland 167152909Sanholt return irqs; 168152909Sanholt} 169152909Sanholt 170112015Sanholt/* Interrupts - Used for device synchronization and flushing in the 171112015Sanholt * following circumstances: 172112015Sanholt * 173112015Sanholt * - Exclusive FB access with hw idle: 174112015Sanholt * - Wait for GUI Idle (?) interrupt, then do normal flush. 175112015Sanholt * 176112015Sanholt * - Frame throttling, NV_fence: 177112015Sanholt * - Drop marker irq's into command stream ahead of time. 178112015Sanholt * - Wait on irq's with lock *not held* 179112015Sanholt * - Check each for termination condition 180112015Sanholt * 181112015Sanholt * - Internally in cp_getbuffer, etc: 182112015Sanholt * - as above, but wait with lock held??? 183112015Sanholt * 184112015Sanholt * NOTE: These functions are misleadingly named -- the irq's aren't 185112015Sanholt * tied to dma at all, this is just a hangover from dri prehistory. 186112015Sanholt */ 187112015Sanholt 188145132Sanholtirqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS) 189112015Sanholt{ 190182080Srnoland struct drm_device *dev = (struct drm_device *) arg; 191145132Sanholt drm_radeon_private_t *dev_priv = 192145132Sanholt (drm_radeon_private_t *) dev->dev_private; 193145132Sanholt u32 stat; 194182080Srnoland u32 r500_disp_int; 195189051Srnoland u32 tmp; 196112015Sanholt 197197603Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) 198197603Srnoland return IRQ_NONE; 199197603Srnoland 200112015Sanholt /* Only consider the bits we're interested in - others could be used 201112015Sanholt * outside the DRM 202112015Sanholt */ 203182080Srnoland stat = radeon_acknowledge_irqs(dev_priv, &r500_disp_int); 204112015Sanholt if (!stat) 205119098Sanholt return IRQ_NONE; 206112015Sanholt 207182080Srnoland stat &= dev_priv->irq_enable_reg; 208182080Srnoland 209112015Sanholt /* SW interrupt */ 210182080Srnoland if (stat & RADEON_SW_INT_TEST) 211145132Sanholt DRM_WAKEUP(&dev_priv->swi_queue); 212112015Sanholt 213112015Sanholt /* VBLANK interrupt */ 214189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) { 215182080Srnoland if (r500_disp_int & R500_D1_VBLANK_INTERRUPT) 216182080Srnoland drm_handle_vblank(dev, 0); 217182080Srnoland if (r500_disp_int & R500_D2_VBLANK_INTERRUPT) 218182080Srnoland drm_handle_vblank(dev, 1); 219182080Srnoland } else { 220182080Srnoland if (stat & RADEON_CRTC_VBLANK_STAT) 221182080Srnoland drm_handle_vblank(dev, 0); 222182080Srnoland if (stat & RADEON_CRTC2_VBLANK_STAT) 223182080Srnoland drm_handle_vblank(dev, 1); 224112015Sanholt } 225189051Srnoland if (dev->msi_enabled) { 226189051Srnoland switch(dev_priv->flags & RADEON_FAMILY_MASK) { 227189051Srnoland case CHIP_RS400: 228189051Srnoland case CHIP_RS480: 229189051Srnoland tmp = RADEON_READ(RADEON_AIC_CNTL) & 230189051Srnoland ~RS400_MSI_REARM; 231189051Srnoland RADEON_WRITE(RADEON_AIC_CNTL, tmp); 232189051Srnoland RADEON_WRITE(RADEON_AIC_CNTL, 233189051Srnoland tmp | RS400_MSI_REARM); 234189051Srnoland break; 235189899Srnoland case CHIP_RS600: 236189051Srnoland case CHIP_RS690: 237189051Srnoland case CHIP_RS740: 238189051Srnoland tmp = RADEON_READ(RADEON_BUS_CNTL) & 239189051Srnoland ~RS600_MSI_REARM; 240189051Srnoland RADEON_WRITE(RADEON_BUS_CNTL, tmp); 241189051Srnoland RADEON_WRITE(RADEON_BUS_CNTL, tmp | 242189051Srnoland RS600_MSI_REARM); 243189051Srnoland break; 244189051Srnoland default: 245189051Srnoland tmp = RADEON_READ(RADEON_MSI_REARM_EN) & 246189051Srnoland ~RV370_MSI_REARM_EN; 247189051Srnoland RADEON_WRITE(RADEON_MSI_REARM_EN, tmp); 248189051Srnoland RADEON_WRITE(RADEON_MSI_REARM_EN, 249189051Srnoland tmp | RV370_MSI_REARM_EN); 250189051Srnoland break; 251189051Srnoland } 252189051Srnoland } 253119098Sanholt return IRQ_HANDLED; 254112015Sanholt} 255112015Sanholt 256182080Srnolandstatic int radeon_emit_irq(struct drm_device * dev) 257112015Sanholt{ 258112015Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 259112015Sanholt unsigned int ret; 260112015Sanholt RING_LOCALS; 261112015Sanholt 262112015Sanholt atomic_inc(&dev_priv->swi_emitted); 263112015Sanholt ret = atomic_read(&dev_priv->swi_emitted); 264112015Sanholt 265145132Sanholt BEGIN_RING(4); 266145132Sanholt OUT_RING_REG(RADEON_LAST_SWI_REG, ret); 267145132Sanholt OUT_RING_REG(RADEON_GEN_INT_STATUS, RADEON_SW_INT_FIRE); 268145132Sanholt ADVANCE_RING(); 269145132Sanholt COMMIT_RING(); 270112015Sanholt 271112015Sanholt return ret; 272112015Sanholt} 273112015Sanholt 274182080Srnolandstatic int radeon_wait_irq(struct drm_device * dev, int swi_nr) 275112015Sanholt{ 276145132Sanholt drm_radeon_private_t *dev_priv = 277145132Sanholt (drm_radeon_private_t *) dev->dev_private; 278112015Sanholt int ret = 0; 279112015Sanholt 280145132Sanholt if (RADEON_READ(RADEON_LAST_SWI_REG) >= swi_nr) 281145132Sanholt return 0; 282112015Sanholt 283112015Sanholt dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; 284112015Sanholt 285145132Sanholt DRM_WAIT_ON(ret, dev_priv->swi_queue, 3 * DRM_HZ, 286145132Sanholt RADEON_READ(RADEON_LAST_SWI_REG) >= swi_nr); 287112015Sanholt 288190023Srnoland if (ret == -ERESTART) 289190023Srnoland DRM_DEBUG("restarting syscall"); 290190023Srnoland 291112015Sanholt return ret; 292112015Sanholt} 293112015Sanholt 294182080Srnolandu32 radeon_get_vblank_counter(struct drm_device *dev, int crtc) 295112015Sanholt{ 296182080Srnoland drm_radeon_private_t *dev_priv = dev->dev_private; 297112015Sanholt 298145132Sanholt if (!dev_priv) { 299182080Srnoland DRM_ERROR("called with no initialization\n"); 300182080Srnoland return -EINVAL; 301112015Sanholt } 302112015Sanholt 303182080Srnoland if (crtc < 0 || crtc > 1) { 304182080Srnoland DRM_ERROR("Invalid crtc %d\n", crtc); 305182080Srnoland return -EINVAL; 306182080Srnoland } 307112015Sanholt 308189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) { 309182080Srnoland if (crtc == 0) 310182080Srnoland return RADEON_READ(R500_D1CRTC_FRAME_COUNT); 311182080Srnoland else 312182080Srnoland return RADEON_READ(R500_D2CRTC_FRAME_COUNT); 313182080Srnoland } else { 314182080Srnoland if (crtc == 0) 315182080Srnoland return RADEON_READ(RADEON_CRTC_CRNT_FRAME); 316182080Srnoland else 317182080Srnoland return RADEON_READ(RADEON_CRTC2_CRNT_FRAME); 318182080Srnoland } 319112015Sanholt} 320112015Sanholt 321112015Sanholt/* Needs the lock as it touches the ring. 322112015Sanholt */ 323182080Srnolandint radeon_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_priv) 324112015Sanholt{ 325112015Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 326182080Srnoland drm_radeon_irq_emit_t *emit = data; 327112015Sanholt int result; 328112015Sanholt 329197603Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) 330197603Srnoland return -EINVAL; 331197603Srnoland 332182080Srnoland LOCK_TEST_WITH_RETURN(dev, file_priv); 333112015Sanholt 334145132Sanholt if (!dev_priv) { 335182080Srnoland DRM_ERROR("called with no initialization\n"); 336182080Srnoland return -EINVAL; 337112015Sanholt } 338112015Sanholt 339145132Sanholt result = radeon_emit_irq(dev); 340112015Sanholt 341182080Srnoland if (DRM_COPY_TO_USER(emit->irq_seq, &result, sizeof(int))) { 342145132Sanholt DRM_ERROR("copy_to_user\n"); 343182080Srnoland return -EFAULT; 344112015Sanholt } 345112015Sanholt 346112015Sanholt return 0; 347112015Sanholt} 348112015Sanholt 349112015Sanholt/* Doesn't need the hardware lock. 350112015Sanholt */ 351182080Srnolandint radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_priv) 352112015Sanholt{ 353112015Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 354182080Srnoland drm_radeon_irq_wait_t *irqwait = data; 355112015Sanholt 356145132Sanholt if (!dev_priv) { 357182080Srnoland DRM_ERROR("called with no initialization\n"); 358182080Srnoland return -EINVAL; 359112015Sanholt } 360112015Sanholt 361182080Srnoland return radeon_wait_irq(dev, irqwait->irq_seq); 362112015Sanholt} 363112015Sanholt 364112015Sanholt/* drm_dma.h hooks 365112015Sanholt*/ 366182080Srnolandvoid radeon_driver_irq_preinstall(struct drm_device * dev) 367145132Sanholt{ 368112015Sanholt drm_radeon_private_t *dev_priv = 369145132Sanholt (drm_radeon_private_t *) dev->dev_private; 370182080Srnoland u32 dummy; 371112015Sanholt 372197603Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) 373197603Srnoland return; 374197603Srnoland 375145132Sanholt /* Disable *all* interrupts */ 376189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) 377182080Srnoland RADEON_WRITE(R500_DxMODE_INT_MASK, 0); 378145132Sanholt RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); 379112015Sanholt 380112015Sanholt /* Clear bits if they're already high */ 381182080Srnoland radeon_acknowledge_irqs(dev_priv, &dummy); 382112015Sanholt} 383112015Sanholt 384182080Srnolandint radeon_driver_irq_postinstall(struct drm_device * dev) 385145132Sanholt{ 386112015Sanholt drm_radeon_private_t *dev_priv = 387145132Sanholt (drm_radeon_private_t *) dev->dev_private; 388112015Sanholt 389145132Sanholt atomic_set(&dev_priv->swi_emitted, 0); 390145132Sanholt DRM_INIT_WAITQUEUE(&dev_priv->swi_queue); 391112015Sanholt 392197603Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) 393197603Srnoland return 0; 394197603Srnoland 395182080Srnoland radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1); 396182080Srnoland 397182080Srnoland return 0; 398112015Sanholt} 399112015Sanholt 400182080Srnolandvoid radeon_driver_irq_uninstall(struct drm_device * dev) 401145132Sanholt{ 402112015Sanholt drm_radeon_private_t *dev_priv = 403145132Sanholt (drm_radeon_private_t *) dev->dev_private; 404119098Sanholt if (!dev_priv) 405119098Sanholt return; 406119098Sanholt 407182080Srnoland dev_priv->irq_enabled = 0; 408182080Srnoland 409197603Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) 410197603Srnoland return; 411197603Srnoland 412189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) 413182080Srnoland RADEON_WRITE(R500_DxMODE_INT_MASK, 0); 414119098Sanholt /* Disable *all* interrupts */ 415145132Sanholt RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); 416112015Sanholt} 417182080Srnoland 418182080Srnoland 419182080Srnolandint radeon_vblank_crtc_get(struct drm_device *dev) 420182080Srnoland{ 421182080Srnoland drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; 422182080Srnoland 423182080Srnoland return dev_priv->vblank_crtc; 424182080Srnoland} 425182080Srnoland 426182080Srnolandint radeon_vblank_crtc_set(struct drm_device *dev, int64_t value) 427182080Srnoland{ 428182080Srnoland drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; 429182080Srnoland if (value & ~(DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) { 430182080Srnoland DRM_ERROR("called with invalid crtc 0x%x\n", (unsigned int)value); 431182080Srnoland return -EINVAL; 432182080Srnoland } 433182080Srnoland dev_priv->vblank_crtc = (unsigned int)value; 434182080Srnoland return 0; 435182080Srnoland} 436