radeon_irq.c revision 0f7bfed6285b1bd6a65b05cc5f6ab4687ca999e6
0f7bfed6285b1bd6a65b05cc5f6ab4687ca999e6miao chen - Sun Microsystems - Beijing China * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
e57b9183811d515e3bbcd1a104516f0102fde114cg * Use is subject to license terms.
e57b9183811d515e3bbcd1a104516f0102fde114cg/* radeon_irq.c -- IRQ handling for radeon -*- linux-c -*- */
e57b9183811d515e3bbcd1a104516f0102fde114cg * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
e57b9183811d515e3bbcd1a104516f0102fde114cg * The Weather Channel (TM) funded Tungsten Graphics to develop the
e57b9183811d515e3bbcd1a104516f0102fde114cg * initial release of the Radeon 8500 driver under the XFree86 license.
e57b9183811d515e3bbcd1a104516f0102fde114cg * This notice must be preserved.
e57b9183811d515e3bbcd1a104516f0102fde114cg * Permission is hereby granted, free of charge, to any person obtaining a
e57b9183811d515e3bbcd1a104516f0102fde114cg * copy of this software and associated documentation files (the "Software"),
e57b9183811d515e3bbcd1a104516f0102fde114cg * to deal in the Software without restriction, including without limitation
e57b9183811d515e3bbcd1a104516f0102fde114cg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
e57b9183811d515e3bbcd1a104516f0102fde114cg * and/or sell copies of the Software, and to permit persons to whom the
e57b9183811d515e3bbcd1a104516f0102fde114cg * Software is furnished to do so, subject to the following conditions:
e57b9183811d515e3bbcd1a104516f0102fde114cg * The above copyright notice and this permission notice (including the next
e57b9183811d515e3bbcd1a104516f0102fde114cg * paragraph) shall be included in all copies or substantial portions of the
e57b9183811d515e3bbcd1a104516f0102fde114cg * Software.
e57b9183811d515e3bbcd1a104516f0102fde114cg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
e57b9183811d515e3bbcd1a104516f0102fde114cg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
e57b9183811d515e3bbcd1a104516f0102fde114cg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
e57b9183811d515e3bbcd1a104516f0102fde114cg * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
e57b9183811d515e3bbcd1a104516f0102fde114cg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
e57b9183811d515e3bbcd1a104516f0102fde114cg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
e57b9183811d515e3bbcd1a104516f0102fde114cg * DEALINGS IN THE SOFTWARE.
e57b9183811d515e3bbcd1a104516f0102fde114cg * Authors:
e57b9183811d515e3bbcd1a104516f0102fde114cg * Keith Whitwell <keith@tungstengraphics.com>
e57b9183811d515e3bbcd1a104516f0102fde114cg * Michel D�zer <michel@daenzer.net>
e57b9183811d515e3bbcd1a104516f0102fde114cgstatic inline u32
e57b9183811d515e3bbcd1a104516f0102fde114cgradeon_acknowledge_irqs(drm_radeon_private_t *dev_priv, u32 mask)
e57b9183811d515e3bbcd1a104516f0102fde114cg uint32_t irqs = RADEON_READ(RADEON_GEN_INT_STATUS) & mask;
e57b9183811d515e3bbcd1a104516f0102fde114cg * Interrupts - Used for device synchronization and flushing in the
e57b9183811d515e3bbcd1a104516f0102fde114cg * following circumstances:
e57b9183811d515e3bbcd1a104516f0102fde114cg * - Exclusive FB access with hw idle:
e57b9183811d515e3bbcd1a104516f0102fde114cg * - Wait for GUI Idle (?) interrupt, then do normal flush.
e57b9183811d515e3bbcd1a104516f0102fde114cg * - Frame throttling, NV_fence:
e57b9183811d515e3bbcd1a104516f0102fde114cg * - Drop marker irq's into command stream ahead of time.
e57b9183811d515e3bbcd1a104516f0102fde114cg * - Wait on irq's with lock *not held*
e57b9183811d515e3bbcd1a104516f0102fde114cg * - Check each for termination condition
e57b9183811d515e3bbcd1a104516f0102fde114cg * - Internally in cp_getbuffer, etc:
e57b9183811d515e3bbcd1a104516f0102fde114cg * - as above, but wait with lock held???
e57b9183811d515e3bbcd1a104516f0102fde114cg * NOTE: These functions are misleadingly named -- the irq's aren't
e57b9183811d515e3bbcd1a104516f0102fde114cg * tied to dma at all, this is just a hangover from dri prehistory.
e57b9183811d515e3bbcd1a104516f0102fde114cg * Only consider the bits we're interested in - others could be used
e57b9183811d515e3bbcd1a104516f0102fde114cg * outside the DRM
e57b9183811d515e3bbcd1a104516f0102fde114cg stat = radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK |
e57b9183811d515e3bbcd1a104516f0102fde114cg /* SW interrupt */
e57b9183811d515e3bbcd1a104516f0102fde114cg /* VBLANK interrupt */
e57b9183811d515e3bbcd1a104516f0102fde114cg if (stat & (RADEON_CRTC_VBLANK_STAT | RADEON_CRTC2_VBLANK_STAT)) {
e57b9183811d515e3bbcd1a104516f0102fde114cg unsigned int ret;
e57b9183811d515e3bbcd1a104516f0102fde114cg return (0);
e57b9183811d515e3bbcd1a104516f0102fde114cgstatic int radeon_driver_vblank_do_wait(struct drm_device *dev,
e57b9183811d515e3bbcd1a104516f0102fde114cg unsigned int cur_vblank;
e57b9183811d515e3bbcd1a104516f0102fde114cg DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
e57b9183811d515e3bbcd1a104516f0102fde114cg * I don't know why reset Intr Status Register here,
e57b9183811d515e3bbcd1a104516f0102fde114cg * it might miss intr. So, I remove the code which
e57b9183811d515e3bbcd1a104516f0102fde114cg * exists in open source, and changes as follows:
e57b9183811d515e3bbcd1a104516f0102fde114cg * Assume that the user has missed the current sequence number
e57b9183811d515e3bbcd1a104516f0102fde114cg * by about a day rather than she wants to wait for years
e57b9183811d515e3bbcd1a104516f0102fde114cg * using vertical blanks...
e57b9183811d515e3bbcd1a104516f0102fde114cg (((cur_vblank = atomic_read(counter)) - *sequence) <= (1 << 23)));
e57b9183811d515e3bbcd1a104516f0102fde114cgradeon_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence)
e57b9183811d515e3bbcd1a104516f0102fde114cgradeon_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence)
e57b9183811d515e3bbcd1a104516f0102fde114cg * Needs the lock as it touches the ring.
e57b9183811d515e3bbcd1a104516f0102fde114cg/*ARGSUSED*/
e57b9183811d515e3bbcd1a104516f0102fde114cg DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
e57b9183811d515e3bbcd1a104516f0102fde114cg if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
e57b9183811d515e3bbcd1a104516f0102fde114cg sizeof (emit32));
e57b9183811d515e3bbcd1a104516f0102fde114cg DRM_COPYFROM_WITH_RETURN(&emit, (void *) data, sizeof (emit));
e57b9183811d515e3bbcd1a104516f0102fde114cg if (DRM_COPY_TO_USER(emit.irq_seq, &result, sizeof (int))) {
e57b9183811d515e3bbcd1a104516f0102fde114cg return (0);
e57b9183811d515e3bbcd1a104516f0102fde114cg * Doesn't need the hardware lock.
e57b9183811d515e3bbcd1a104516f0102fde114cg/*ARGSUSED*/
e57b9183811d515e3bbcd1a104516f0102fde114cg DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
e57b9183811d515e3bbcd1a104516f0102fde114cg DRM_COPYFROM_WITH_RETURN(&irqwait, (void *) data, sizeof (irqwait));
e57b9183811d515e3bbcd1a104516f0102fde114cgstatic void radeon_enable_interrupt(struct drm_device *dev)
e57b9183811d515e3bbcd1a104516f0102fde114cg RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg);
0f7bfed6285b1bd6a65b05cc5f6ab4687ca999e6miao chen - Sun Microsystems - Beijing China if (!dev_priv->mmio)
0f7bfed6285b1bd6a65b05cc5f6ab4687ca999e6miao chen - Sun Microsystems - Beijing China return (EINVAL);
e57b9183811d515e3bbcd1a104516f0102fde114cg /* Disable *all* interrupts */
e57b9183811d515e3bbcd1a104516f0102fde114cg /* Clear bits if they're already high */
e57b9183811d515e3bbcd1a104516f0102fde114cg DRM_INIT_WAITQUEUE(&dev_priv->swi_queue, DRM_INTR_PRI(dev));
e57b9183811d515e3bbcd1a104516f0102fde114cg /* Disable *all* interrupts */
e57b9183811d515e3bbcd1a104516f0102fde114cg if (value & ~(DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) {
e57b9183811d515e3bbcd1a104516f0102fde114cg (unsigned int)value);
e57b9183811d515e3bbcd1a104516f0102fde114cg return (0);