1/* radeon_irq.c -- IRQ handling for radeon -*- linux-c -*- */ 2/* 3 * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. 4 * 5 * The Weather Channel (TM) funded Tungsten Graphics to develop the 6 * initial release of the Radeon 8500 driver under the XFree86 license. 7 * This notice must be preserved. 8 * 9 * Permission is hereby granted, free of charge, to any person obtaining a 10 * copy of this software and associated documentation files (the "Software"), 11 * to deal in the Software without restriction, including without limitation 12 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 13 * and/or sell copies of the Software, and to permit persons to whom the 14 * Software is furnished to do so, subject to the following conditions: 15 * 16 * The above copyright notice and this permission notice (including the next 17 * paragraph) shall be included in all copies or substantial portions of the 18 * Software. 19 * 20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 23 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 24 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 * DEALINGS IN THE SOFTWARE. 27 * 28 * Authors: 29 * Keith Whitwell <keith@tungstengraphics.com> 30 * Michel D���zer <michel@daenzer.net> 31 */ 32 33#include <sys/cdefs.h> 34__FBSDID("$FreeBSD: stable/11/sys/dev/drm2/radeon/radeon_irq.c 342691 2019-01-02 16:28:56Z markj $"); 35 36#include <dev/drm2/drmP.h> 37#include <dev/drm2/radeon/radeon_drm.h> 38#include "radeon_drv.h" 39 40void radeon_irq_set_state(struct drm_device *dev, u32 mask, int state) 41{ 42 drm_radeon_private_t *dev_priv = dev->dev_private; 43 44 if (state) 45 dev_priv->irq_enable_reg |= mask; 46 else 47 dev_priv->irq_enable_reg &= ~mask; 48 49 if (dev->irq_enabled) 50 RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg); 51} 52 53static void r500_vbl_irq_set_state(struct drm_device *dev, u32 mask, int state) 54{ 55 drm_radeon_private_t *dev_priv = dev->dev_private; 56 57 if (state) 58 dev_priv->r500_disp_irq_reg |= mask; 59 else 60 dev_priv->r500_disp_irq_reg &= ~mask; 61 62 if (dev->irq_enabled) 63 RADEON_WRITE(R500_DxMODE_INT_MASK, dev_priv->r500_disp_irq_reg); 64} 65 66int radeon_enable_vblank(struct drm_device *dev, int crtc) 67{ 68 drm_radeon_private_t *dev_priv = dev->dev_private; 69 70 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) { 71 switch (crtc) { 72 case 0: 73 r500_vbl_irq_set_state(dev, R500_D1MODE_INT_MASK, 1); 74 break; 75 case 1: 76 r500_vbl_irq_set_state(dev, R500_D2MODE_INT_MASK, 1); 77 break; 78 default: 79 DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", 80 crtc); 81 return -EINVAL; 82 } 83 } else { 84 switch (crtc) { 85 case 0: 86 radeon_irq_set_state(dev, RADEON_CRTC_VBLANK_MASK, 1); 87 break; 88 case 1: 89 radeon_irq_set_state(dev, RADEON_CRTC2_VBLANK_MASK, 1); 90 break; 91 default: 92 DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", 93 crtc); 94 return -EINVAL; 95 } 96 } 97 98 return 0; 99} 100 101void radeon_disable_vblank(struct drm_device *dev, int crtc) 102{ 103 drm_radeon_private_t *dev_priv = dev->dev_private; 104 105 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) { 106 switch (crtc) { 107 case 0: 108 r500_vbl_irq_set_state(dev, R500_D1MODE_INT_MASK, 0); 109 break; 110 case 1: 111 r500_vbl_irq_set_state(dev, R500_D2MODE_INT_MASK, 0); 112 break; 113 default: 114 DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", 115 crtc); 116 break; 117 } 118 } else { 119 switch (crtc) { 120 case 0: 121 radeon_irq_set_state(dev, RADEON_CRTC_VBLANK_MASK, 0); 122 break; 123 case 1: 124 radeon_irq_set_state(dev, RADEON_CRTC2_VBLANK_MASK, 0); 125 break; 126 default: 127 DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", 128 crtc); 129 break; 130 } 131 } 132} 133 134static u32 radeon_acknowledge_irqs(drm_radeon_private_t *dev_priv, u32 *r500_disp_int) 135{ 136 u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS); 137 u32 irq_mask = RADEON_SW_INT_TEST; 138 139 *r500_disp_int = 0; 140 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) { 141 /* vbl interrupts in a different place */ 142 143 if (irqs & R500_DISPLAY_INT_STATUS) { 144 /* if a display interrupt */ 145 u32 disp_irq; 146 147 disp_irq = RADEON_READ(R500_DISP_INTERRUPT_STATUS); 148 149 *r500_disp_int = disp_irq; 150 if (disp_irq & R500_D1_VBLANK_INTERRUPT) 151 RADEON_WRITE(R500_D1MODE_VBLANK_STATUS, R500_VBLANK_ACK); 152 if (disp_irq & R500_D2_VBLANK_INTERRUPT) 153 RADEON_WRITE(R500_D2MODE_VBLANK_STATUS, R500_VBLANK_ACK); 154 } 155 irq_mask |= R500_DISPLAY_INT_STATUS; 156 } else 157 irq_mask |= RADEON_CRTC_VBLANK_STAT | RADEON_CRTC2_VBLANK_STAT; 158 159 irqs &= irq_mask; 160 161 if (irqs) 162 RADEON_WRITE(RADEON_GEN_INT_STATUS, irqs); 163 164 return irqs; 165} 166 167/* Interrupts - Used for device synchronization and flushing in the 168 * following circumstances: 169 * 170 * - Exclusive FB access with hw idle: 171 * - Wait for GUI Idle (?) interrupt, then do normal flush. 172 * 173 * - Frame throttling, NV_fence: 174 * - Drop marker irq's into command stream ahead of time. 175 * - Wait on irq's with lock *not held* 176 * - Check each for termination condition 177 * 178 * - Internally in cp_getbuffer, etc: 179 * - as above, but wait with lock held??? 180 * 181 * NOTE: These functions are misleadingly named -- the irq's aren't 182 * tied to dma at all, this is just a hangover from dri prehistory. 183 */ 184 185irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS) 186{ 187 struct drm_device *dev = (struct drm_device *) arg; 188 drm_radeon_private_t *dev_priv = 189 (drm_radeon_private_t *) dev->dev_private; 190 u32 stat; 191 u32 r500_disp_int; 192 193 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) 194 return IRQ_NONE; 195 196 /* Only consider the bits we're interested in - others could be used 197 * outside the DRM 198 */ 199 stat = radeon_acknowledge_irqs(dev_priv, &r500_disp_int); 200 if (!stat) 201 return IRQ_NONE; 202 203 stat &= dev_priv->irq_enable_reg; 204 205 /* SW interrupt */ 206 if (stat & RADEON_SW_INT_TEST) 207 DRM_WAKEUP(&dev_priv->swi_queue); 208 209 /* VBLANK interrupt */ 210 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) { 211 if (r500_disp_int & R500_D1_VBLANK_INTERRUPT) 212 drm_handle_vblank(dev, 0); 213 if (r500_disp_int & R500_D2_VBLANK_INTERRUPT) 214 drm_handle_vblank(dev, 1); 215 } else { 216 if (stat & RADEON_CRTC_VBLANK_STAT) 217 drm_handle_vblank(dev, 0); 218 if (stat & RADEON_CRTC2_VBLANK_STAT) 219 drm_handle_vblank(dev, 1); 220 } 221 return IRQ_HANDLED; 222} 223 224u32 radeon_get_vblank_counter(struct drm_device *dev, int crtc) 225{ 226 drm_radeon_private_t *dev_priv = dev->dev_private; 227 228 if (!dev_priv) { 229 DRM_ERROR("called with no initialization\n"); 230 return -EINVAL; 231 } 232 233 if (crtc < 0 || crtc > 1) { 234 DRM_ERROR("Invalid crtc %d\n", crtc); 235 return -EINVAL; 236 } 237 238 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) { 239 if (crtc == 0) 240 return RADEON_READ(R500_D1CRTC_FRAME_COUNT); 241 else 242 return RADEON_READ(R500_D2CRTC_FRAME_COUNT); 243 } else { 244 if (crtc == 0) 245 return RADEON_READ(RADEON_CRTC_CRNT_FRAME); 246 else 247 return RADEON_READ(RADEON_CRTC2_CRNT_FRAME); 248 } 249} 250 251/* drm_dma.h hooks 252*/ 253void radeon_driver_irq_preinstall(struct drm_device * dev) 254{ 255 drm_radeon_private_t *dev_priv = 256 (drm_radeon_private_t *) dev->dev_private; 257 u32 dummy; 258 259 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) 260 return; 261 262 /* Disable *all* interrupts */ 263 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) 264 RADEON_WRITE(R500_DxMODE_INT_MASK, 0); 265 RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); 266 267 /* Clear bits if they're already high */ 268 radeon_acknowledge_irqs(dev_priv, &dummy); 269} 270 271int radeon_driver_irq_postinstall(struct drm_device *dev) 272{ 273 drm_radeon_private_t *dev_priv = 274 (drm_radeon_private_t *) dev->dev_private; 275 276 atomic_set(&dev_priv->swi_emitted, 0); 277 DRM_INIT_WAITQUEUE(&dev_priv->swi_queue); 278 279 dev->max_vblank_count = 0x001fffff; 280 281 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) 282 return 0; 283 284 radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1); 285 286 return 0; 287} 288 289void radeon_driver_irq_uninstall(struct drm_device * dev) 290{ 291 drm_radeon_private_t *dev_priv = 292 (drm_radeon_private_t *) dev->dev_private; 293 if (!dev_priv) 294 return; 295 296 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) 297 return; 298 299 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) 300 RADEON_WRITE(R500_DxMODE_INT_MASK, 0); 301 /* Disable *all* interrupts */ 302 RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); 303} 304 305 306int radeon_vblank_crtc_get(struct drm_device *dev) 307{ 308 drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; 309 310 return dev_priv->vblank_crtc; 311} 312 313int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value) 314{ 315 drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; 316 if (value & ~(DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) { 317 DRM_ERROR("called with invalid crtc 0x%x\n", (unsigned int)value); 318 return -EINVAL; 319 } 320 dev_priv->vblank_crtc = (unsigned int)value; 321 return 0; 322} 323