1ae115bc7Smrj /* BEGIN CSTYLED */
2ae115bc7Smrj
3ae115bc7Smrj /* i915_irq.c -- IRQ support for the I915 -*- linux-c -*-
4ae115bc7Smrj */
5e92e3a86Szw161486 /*
6ae115bc7Smrj * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
70035d21cSmiao chen - Sun Microsystems - Beijing China * Copyright (c) 2009, Intel Corporation.
8ae115bc7Smrj * All Rights Reserved.
9ae115bc7Smrj *
10ae115bc7Smrj * Permission is hereby granted, free of charge, to any person obtaining a
11ae115bc7Smrj * copy of this software and associated documentation files (the
12ae115bc7Smrj * "Software"), to deal in the Software without restriction, including
13ae115bc7Smrj * without limitation the rights to use, copy, modify, merge, publish,
14ae115bc7Smrj * distribute, sub license, and/or sell copies of the Software, and to
15ae115bc7Smrj * permit persons to whom the Software is furnished to do so, subject to
16ae115bc7Smrj * the following conditions:
17ae115bc7Smrj *
18ae115bc7Smrj * The above copyright notice and this permission notice (including the
19ae115bc7Smrj * next paragraph) shall be included in all copies or substantial portions
20ae115bc7Smrj * of the Software.
21ae115bc7Smrj *
22ae115bc7Smrj * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23ae115bc7Smrj * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24ae115bc7Smrj * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
25ae115bc7Smrj * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
26ae115bc7Smrj * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
27ae115bc7Smrj * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28ae115bc7Smrj * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29ae115bc7Smrj *
30e92e3a86Szw161486 */
31e92e3a86Szw161486
32e92e3a86Szw161486 /*
33d0231070Smiao chen - Sun Microsystems - Beijing China * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
34e92e3a86Szw161486 * Use is subject to license terms.
35e92e3a86Szw161486 */
36ae115bc7Smrj
37ae115bc7Smrj #include "drmP.h"
38ae115bc7Smrj #include "drm.h"
39ae115bc7Smrj #include "i915_drm.h"
40ae115bc7Smrj #include "i915_drv.h"
41ae115bc7Smrj
42e92e3a86Szw161486
43ae115bc7Smrj #define MAX_NOPID ((u32)~0)
44e92e3a86Szw161486
450035d21cSmiao chen - Sun Microsystems - Beijing China /**
460035d21cSmiao chen - Sun Microsystems - Beijing China * Interrupts that are always left unmasked.
470035d21cSmiao chen - Sun Microsystems - Beijing China *
480035d21cSmiao chen - Sun Microsystems - Beijing China * Since pipe events are edge-triggered from the PIPESTAT register to IIR,
490035d21cSmiao chen - Sun Microsystems - Beijing China * we leave them always unmasked in IMR and then control enabling them through
500035d21cSmiao chen - Sun Microsystems - Beijing China * PIPESTAT alone.
51d0231070Smiao chen - Sun Microsystems - Beijing China */
520035d21cSmiao chen - Sun Microsystems - Beijing China
530035d21cSmiao chen - Sun Microsystems - Beijing China #define I915_INTERRUPT_ENABLE_FIX (I915_ASLE_INTERRUPT | \
54d0231070Smiao chen - Sun Microsystems - Beijing China I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | \
550035d21cSmiao chen - Sun Microsystems - Beijing China I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | \
560035d21cSmiao chen - Sun Microsystems - Beijing China I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT)
570035d21cSmiao chen - Sun Microsystems - Beijing China
580035d21cSmiao chen - Sun Microsystems - Beijing China /** Interrupts that we mask and unmask at runtime. */
590035d21cSmiao chen - Sun Microsystems - Beijing China #define I915_INTERRUPT_ENABLE_VAR (I915_USER_INTERRUPT)
600035d21cSmiao chen - Sun Microsystems - Beijing China
610035d21cSmiao chen - Sun Microsystems - Beijing China /** These are all of the interrupts used by the driver */
620035d21cSmiao chen - Sun Microsystems - Beijing China #define I915_INTERRUPT_ENABLE_MASK (I915_INTERRUPT_ENABLE_FIX | \
630035d21cSmiao chen - Sun Microsystems - Beijing China I915_INTERRUPT_ENABLE_VAR)
64d0231070Smiao chen - Sun Microsystems - Beijing China
65*2e6e901dSmiao chen - Sun Microsystems - Beijing China void
igdng_enable_irq(drm_i915_private_t * dev_priv,u32 mask,int gfx_irq)66*2e6e901dSmiao chen - Sun Microsystems - Beijing China igdng_enable_irq(drm_i915_private_t *dev_priv, u32 mask, int gfx_irq)
67*2e6e901dSmiao chen - Sun Microsystems - Beijing China {
68*2e6e901dSmiao chen - Sun Microsystems - Beijing China if (gfx_irq && ((dev_priv->gt_irq_mask_reg & mask) != 0)) {
69*2e6e901dSmiao chen - Sun Microsystems - Beijing China dev_priv->gt_irq_mask_reg &= ~mask;
70*2e6e901dSmiao chen - Sun Microsystems - Beijing China I915_WRITE(GTIMR, dev_priv->gt_irq_mask_reg);
71*2e6e901dSmiao chen - Sun Microsystems - Beijing China (void) I915_READ(GTIMR);
72*2e6e901dSmiao chen - Sun Microsystems - Beijing China } else if ((dev_priv->irq_mask_reg & mask) != 0) {
73*2e6e901dSmiao chen - Sun Microsystems - Beijing China dev_priv->irq_mask_reg &= ~mask;
74*2e6e901dSmiao chen - Sun Microsystems - Beijing China I915_WRITE(DEIMR, dev_priv->irq_mask_reg);
75*2e6e901dSmiao chen - Sun Microsystems - Beijing China (void) I915_READ(DEIMR);
76*2e6e901dSmiao chen - Sun Microsystems - Beijing China
77*2e6e901dSmiao chen - Sun Microsystems - Beijing China }
78*2e6e901dSmiao chen - Sun Microsystems - Beijing China }
79*2e6e901dSmiao chen - Sun Microsystems - Beijing China
80*2e6e901dSmiao chen - Sun Microsystems - Beijing China static inline void
igdng_disable_irq(drm_i915_private_t * dev_priv,u32 mask,int gfx_irq)81*2e6e901dSmiao chen - Sun Microsystems - Beijing China igdng_disable_irq(drm_i915_private_t *dev_priv, u32 mask, int gfx_irq)
82*2e6e901dSmiao chen - Sun Microsystems - Beijing China {
83*2e6e901dSmiao chen - Sun Microsystems - Beijing China if (gfx_irq && ((dev_priv->gt_irq_mask_reg & mask) != mask)) {
84*2e6e901dSmiao chen - Sun Microsystems - Beijing China dev_priv->gt_irq_mask_reg |= mask;
85*2e6e901dSmiao chen - Sun Microsystems - Beijing China I915_WRITE(GTIMR, dev_priv->gt_irq_mask_reg);
86*2e6e901dSmiao chen - Sun Microsystems - Beijing China (void) I915_READ(GTIMR);
87*2e6e901dSmiao chen - Sun Microsystems - Beijing China } else if ((dev_priv->irq_mask_reg & mask) != mask) {
88*2e6e901dSmiao chen - Sun Microsystems - Beijing China dev_priv->irq_mask_reg |= mask;
89*2e6e901dSmiao chen - Sun Microsystems - Beijing China I915_WRITE(DEIMR, dev_priv->irq_mask_reg);
90*2e6e901dSmiao chen - Sun Microsystems - Beijing China (void) I915_READ(DEIMR);
91*2e6e901dSmiao chen - Sun Microsystems - Beijing China }
92*2e6e901dSmiao chen - Sun Microsystems - Beijing China }
93*2e6e901dSmiao chen - Sun Microsystems - Beijing China
94*2e6e901dSmiao chen - Sun Microsystems - Beijing China /* For display hotplug interrupt */
95*2e6e901dSmiao chen - Sun Microsystems - Beijing China void
igdng_enable_display_irq(drm_i915_private_t * dev_priv,u32 mask)96*2e6e901dSmiao chen - Sun Microsystems - Beijing China igdng_enable_display_irq(drm_i915_private_t *dev_priv, u32 mask)
97*2e6e901dSmiao chen - Sun Microsystems - Beijing China {
98*2e6e901dSmiao chen - Sun Microsystems - Beijing China if ((dev_priv->irq_mask_reg & mask) != 0) {
99*2e6e901dSmiao chen - Sun Microsystems - Beijing China dev_priv->irq_mask_reg &= ~mask;
100*2e6e901dSmiao chen - Sun Microsystems - Beijing China I915_WRITE(DEIMR, dev_priv->irq_mask_reg);
101*2e6e901dSmiao chen - Sun Microsystems - Beijing China (void) I915_READ(DEIMR);
102*2e6e901dSmiao chen - Sun Microsystems - Beijing China }
103*2e6e901dSmiao chen - Sun Microsystems - Beijing China }
104*2e6e901dSmiao chen - Sun Microsystems - Beijing China
105*2e6e901dSmiao chen - Sun Microsystems - Beijing China #if 0
106*2e6e901dSmiao chen - Sun Microsystems - Beijing China static inline void
107*2e6e901dSmiao chen - Sun Microsystems - Beijing China igdng_disable_display_irq(drm_i915_private_t *dev_priv, u32 mask)
108*2e6e901dSmiao chen - Sun Microsystems - Beijing China {
109*2e6e901dSmiao chen - Sun Microsystems - Beijing China if ((dev_priv->irq_mask_reg & mask) != mask) {
110*2e6e901dSmiao chen - Sun Microsystems - Beijing China dev_priv->irq_mask_reg |= mask;
111*2e6e901dSmiao chen - Sun Microsystems - Beijing China I915_WRITE(DEIMR, dev_priv->irq_mask_reg);
112*2e6e901dSmiao chen - Sun Microsystems - Beijing China (void) I915_READ(DEIMR);
113*2e6e901dSmiao chen - Sun Microsystems - Beijing China }
114*2e6e901dSmiao chen - Sun Microsystems - Beijing China }
115*2e6e901dSmiao chen - Sun Microsystems - Beijing China #endif
116*2e6e901dSmiao chen - Sun Microsystems - Beijing China
117d0231070Smiao chen - Sun Microsystems - Beijing China static inline void
i915_enable_irq(drm_i915_private_t * dev_priv,uint32_t mask)118d0231070Smiao chen - Sun Microsystems - Beijing China i915_enable_irq(drm_i915_private_t *dev_priv, uint32_t mask)
119d0231070Smiao chen - Sun Microsystems - Beijing China {
120d0231070Smiao chen - Sun Microsystems - Beijing China if ((dev_priv->irq_mask_reg & mask) != 0) {
121d0231070Smiao chen - Sun Microsystems - Beijing China dev_priv->irq_mask_reg &= ~mask;
122d0231070Smiao chen - Sun Microsystems - Beijing China I915_WRITE(IMR, dev_priv->irq_mask_reg);
123d0231070Smiao chen - Sun Microsystems - Beijing China (void) I915_READ(IMR);
124d0231070Smiao chen - Sun Microsystems - Beijing China }
125d0231070Smiao chen - Sun Microsystems - Beijing China }
126d0231070Smiao chen - Sun Microsystems - Beijing China
127d0231070Smiao chen - Sun Microsystems - Beijing China static inline void
i915_disable_irq(drm_i915_private_t * dev_priv,uint32_t mask)128d0231070Smiao chen - Sun Microsystems - Beijing China i915_disable_irq(drm_i915_private_t *dev_priv, uint32_t mask)
129d0231070Smiao chen - Sun Microsystems - Beijing China {
130d0231070Smiao chen - Sun Microsystems - Beijing China if ((dev_priv->irq_mask_reg & mask) != mask) {
131d0231070Smiao chen - Sun Microsystems - Beijing China dev_priv->irq_mask_reg |= mask;
132d0231070Smiao chen - Sun Microsystems - Beijing China I915_WRITE(IMR, dev_priv->irq_mask_reg);
133d0231070Smiao chen - Sun Microsystems - Beijing China (void) I915_READ(IMR);
134d0231070Smiao chen - Sun Microsystems - Beijing China }
135d0231070Smiao chen - Sun Microsystems - Beijing China }
1360035d21cSmiao chen - Sun Microsystems - Beijing China
1370035d21cSmiao chen - Sun Microsystems - Beijing China static inline uint32_t
i915_pipestat(int pipe)1380035d21cSmiao chen - Sun Microsystems - Beijing China i915_pipestat(int pipe)
139d0231070Smiao chen - Sun Microsystems - Beijing China {
1400035d21cSmiao chen - Sun Microsystems - Beijing China if (pipe == 0)
1410035d21cSmiao chen - Sun Microsystems - Beijing China return PIPEASTAT;
1420035d21cSmiao chen - Sun Microsystems - Beijing China if (pipe == 1)
1430035d21cSmiao chen - Sun Microsystems - Beijing China return PIPEBSTAT;
1440035d21cSmiao chen - Sun Microsystems - Beijing China return 0;
145d0231070Smiao chen - Sun Microsystems - Beijing China }
146d0231070Smiao chen - Sun Microsystems - Beijing China
1470035d21cSmiao chen - Sun Microsystems - Beijing China void
i915_enable_pipestat(drm_i915_private_t * dev_priv,int pipe,uint32_t mask)1480035d21cSmiao chen - Sun Microsystems - Beijing China i915_enable_pipestat(drm_i915_private_t *dev_priv, int pipe, uint32_t mask)
149d0231070Smiao chen - Sun Microsystems - Beijing China {
1500035d21cSmiao chen - Sun Microsystems - Beijing China if ((dev_priv->pipestat[pipe] & mask) != mask) {
1510035d21cSmiao chen - Sun Microsystems - Beijing China u32 reg = i915_pipestat(pipe);
1520035d21cSmiao chen - Sun Microsystems - Beijing China
1530035d21cSmiao chen - Sun Microsystems - Beijing China dev_priv->pipestat[pipe] |= mask;
1540035d21cSmiao chen - Sun Microsystems - Beijing China /* Enable the interrupt, clear any pending status */
1550035d21cSmiao chen - Sun Microsystems - Beijing China I915_WRITE(reg, dev_priv->pipestat[pipe] | (mask >> 16));
1560035d21cSmiao chen - Sun Microsystems - Beijing China (void) I915_READ(reg);
1570035d21cSmiao chen - Sun Microsystems - Beijing China }
1580035d21cSmiao chen - Sun Microsystems - Beijing China }
1590035d21cSmiao chen - Sun Microsystems - Beijing China
1600035d21cSmiao chen - Sun Microsystems - Beijing China void
i915_disable_pipestat(drm_i915_private_t * dev_priv,int pipe,u32 mask)1610035d21cSmiao chen - Sun Microsystems - Beijing China i915_disable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask)
1620035d21cSmiao chen - Sun Microsystems - Beijing China {
1630035d21cSmiao chen - Sun Microsystems - Beijing China if ((dev_priv->pipestat[pipe] & mask) != 0) {
1640035d21cSmiao chen - Sun Microsystems - Beijing China u32 reg = i915_pipestat(pipe);
1650035d21cSmiao chen - Sun Microsystems - Beijing China
1660035d21cSmiao chen - Sun Microsystems - Beijing China dev_priv->pipestat[pipe] &= ~mask;
1670035d21cSmiao chen - Sun Microsystems - Beijing China I915_WRITE(reg, dev_priv->pipestat[pipe]);
1680035d21cSmiao chen - Sun Microsystems - Beijing China (void) I915_READ(reg);
1690035d21cSmiao chen - Sun Microsystems - Beijing China }
170d0231070Smiao chen - Sun Microsystems - Beijing China }
171d0231070Smiao chen - Sun Microsystems - Beijing China
172d0231070Smiao chen - Sun Microsystems - Beijing China /**
173d0231070Smiao chen - Sun Microsystems - Beijing China * i915_pipe_enabled - check if a pipe is enabled
174d0231070Smiao chen - Sun Microsystems - Beijing China * @dev: DRM device
175d0231070Smiao chen - Sun Microsystems - Beijing China * @pipe: pipe to check
176d0231070Smiao chen - Sun Microsystems - Beijing China *
177d0231070Smiao chen - Sun Microsystems - Beijing China * Reading certain registers when the pipe is disabled can hang the chip.
178d0231070Smiao chen - Sun Microsystems - Beijing China * Use this routine to make sure the PLL is running and the pipe is active
179d0231070Smiao chen - Sun Microsystems - Beijing China * before reading such registers if unsure.
180d0231070Smiao chen - Sun Microsystems - Beijing China */
181d0231070Smiao chen - Sun Microsystems - Beijing China static int
i915_pipe_enabled(struct drm_device * dev,int pipe)182d0231070Smiao chen - Sun Microsystems - Beijing China i915_pipe_enabled(struct drm_device *dev, int pipe)
183d0231070Smiao chen - Sun Microsystems - Beijing China {
184d0231070Smiao chen - Sun Microsystems - Beijing China drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
185d0231070Smiao chen - Sun Microsystems - Beijing China unsigned long pipeconf = pipe ? PIPEBCONF : PIPEACONF;
186d0231070Smiao chen - Sun Microsystems - Beijing China
187d0231070Smiao chen - Sun Microsystems - Beijing China if (I915_READ(pipeconf) & PIPEACONF_ENABLE)
188d0231070Smiao chen - Sun Microsystems - Beijing China return 1;
189d0231070Smiao chen - Sun Microsystems - Beijing China
190d0231070Smiao chen - Sun Microsystems - Beijing China return 0;
191d0231070Smiao chen - Sun Microsystems - Beijing China }
192d0231070Smiao chen - Sun Microsystems - Beijing China
i915_get_vblank_counter(struct drm_device * dev,int pipe)1930035d21cSmiao chen - Sun Microsystems - Beijing China u32 i915_get_vblank_counter(struct drm_device *dev, int pipe)
194d0231070Smiao chen - Sun Microsystems - Beijing China {
195d0231070Smiao chen - Sun Microsystems - Beijing China drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
196d0231070Smiao chen - Sun Microsystems - Beijing China unsigned long high_frame;
197d0231070Smiao chen - Sun Microsystems - Beijing China unsigned long low_frame;
198d0231070Smiao chen - Sun Microsystems - Beijing China u32 high1, high2, low, count;
199d0231070Smiao chen - Sun Microsystems - Beijing China
200d0231070Smiao chen - Sun Microsystems - Beijing China high_frame = pipe ? PIPEBFRAMEHIGH : PIPEAFRAMEHIGH;
201d0231070Smiao chen - Sun Microsystems - Beijing China low_frame = pipe ? PIPEBFRAMEPIXEL : PIPEAFRAMEPIXEL;
202d0231070Smiao chen - Sun Microsystems - Beijing China
203d0231070Smiao chen - Sun Microsystems - Beijing China if (!i915_pipe_enabled(dev, pipe)) {
2040035d21cSmiao chen - Sun Microsystems - Beijing China DRM_ERROR("trying to get vblank count for disabled pipe %d\n", pipe);
205d0231070Smiao chen - Sun Microsystems - Beijing China return 0;
206d0231070Smiao chen - Sun Microsystems - Beijing China }
207d0231070Smiao chen - Sun Microsystems - Beijing China
208d0231070Smiao chen - Sun Microsystems - Beijing China /*
209d0231070Smiao chen - Sun Microsystems - Beijing China * High & low register fields aren't synchronized, so make sure
210d0231070Smiao chen - Sun Microsystems - Beijing China * we get a low value that's stable across two reads of the high
211d0231070Smiao chen - Sun Microsystems - Beijing China * register.
212d0231070Smiao chen - Sun Microsystems - Beijing China */
213d0231070Smiao chen - Sun Microsystems - Beijing China do {
214d0231070Smiao chen - Sun Microsystems - Beijing China high1 = ((I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >>
215d0231070Smiao chen - Sun Microsystems - Beijing China PIPE_FRAME_HIGH_SHIFT);
216d0231070Smiao chen - Sun Microsystems - Beijing China low = ((I915_READ(low_frame) & PIPE_FRAME_LOW_MASK) >>
217d0231070Smiao chen - Sun Microsystems - Beijing China PIPE_FRAME_LOW_SHIFT);
218d0231070Smiao chen - Sun Microsystems - Beijing China high2 = ((I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >>
219d0231070Smiao chen - Sun Microsystems - Beijing China PIPE_FRAME_HIGH_SHIFT);
220d0231070Smiao chen - Sun Microsystems - Beijing China } while (high1 != high2);
221d0231070Smiao chen - Sun Microsystems - Beijing China
222d0231070Smiao chen - Sun Microsystems - Beijing China count = (high1 << 8) | low;
223d0231070Smiao chen - Sun Microsystems - Beijing China
224d0231070Smiao chen - Sun Microsystems - Beijing China return count;
225d0231070Smiao chen - Sun Microsystems - Beijing China }
226d0231070Smiao chen - Sun Microsystems - Beijing China
2270035d21cSmiao chen - Sun Microsystems - Beijing China /**
2280035d21cSmiao chen - Sun Microsystems - Beijing China * i915_capture_error_state - capture an error record for later analysis
2290035d21cSmiao chen - Sun Microsystems - Beijing China * @dev: drm device
2300035d21cSmiao chen - Sun Microsystems - Beijing China *
2310035d21cSmiao chen - Sun Microsystems - Beijing China * Should be called when an error is detected (either a hang or an error
2320035d21cSmiao chen - Sun Microsystems - Beijing China * interrupt) to capture error state from the time of the error. Fills
2330035d21cSmiao chen - Sun Microsystems - Beijing China * out a structure which becomes available in debugfs for user level tools
2340035d21cSmiao chen - Sun Microsystems - Beijing China * to pick up.
2350035d21cSmiao chen - Sun Microsystems - Beijing China */
i915_capture_error_state(struct drm_device * dev)2360035d21cSmiao chen - Sun Microsystems - Beijing China static void i915_capture_error_state(struct drm_device *dev)
2370035d21cSmiao chen - Sun Microsystems - Beijing China {
2380035d21cSmiao chen - Sun Microsystems - Beijing China struct drm_i915_private *dev_priv = dev->dev_private;
2390035d21cSmiao chen - Sun Microsystems - Beijing China struct drm_i915_error_state *error;
2400035d21cSmiao chen - Sun Microsystems - Beijing China
2410035d21cSmiao chen - Sun Microsystems - Beijing China spin_lock_irqsave(&dev_priv->error_lock, flags);
2420035d21cSmiao chen - Sun Microsystems - Beijing China #if 0
2430035d21cSmiao chen - Sun Microsystems - Beijing China if (dev_priv->first_error)
2440035d21cSmiao chen - Sun Microsystems - Beijing China goto out;
2450035d21cSmiao chen - Sun Microsystems - Beijing China #endif
2460035d21cSmiao chen - Sun Microsystems - Beijing China error = drm_alloc(sizeof(*error), DRM_MEM_DRIVER);
2470035d21cSmiao chen - Sun Microsystems - Beijing China if (!error) {
2480035d21cSmiao chen - Sun Microsystems - Beijing China DRM_DEBUG("out ot memory, not capturing error state\n");
2490035d21cSmiao chen - Sun Microsystems - Beijing China goto out;
2500035d21cSmiao chen - Sun Microsystems - Beijing China }
2510035d21cSmiao chen - Sun Microsystems - Beijing China
2520035d21cSmiao chen - Sun Microsystems - Beijing China error->eir = I915_READ(EIR);
2530035d21cSmiao chen - Sun Microsystems - Beijing China error->pgtbl_er = I915_READ(PGTBL_ER);
2540035d21cSmiao chen - Sun Microsystems - Beijing China error->pipeastat = I915_READ(PIPEASTAT);
2550035d21cSmiao chen - Sun Microsystems - Beijing China error->pipebstat = I915_READ(PIPEBSTAT);
2560035d21cSmiao chen - Sun Microsystems - Beijing China error->instpm = I915_READ(INSTPM);
2570035d21cSmiao chen - Sun Microsystems - Beijing China if (!IS_I965G(dev)) {
2580035d21cSmiao chen - Sun Microsystems - Beijing China error->ipeir = I915_READ(IPEIR);
2590035d21cSmiao chen - Sun Microsystems - Beijing China error->ipehr = I915_READ(IPEHR);
2600035d21cSmiao chen - Sun Microsystems - Beijing China error->instdone = I915_READ(INSTDONE);
2610035d21cSmiao chen - Sun Microsystems - Beijing China error->acthd = I915_READ(ACTHD);
2620035d21cSmiao chen - Sun Microsystems - Beijing China } else {
2630035d21cSmiao chen - Sun Microsystems - Beijing China error->ipeir = I915_READ(IPEIR_I965);
2640035d21cSmiao chen - Sun Microsystems - Beijing China error->ipehr = I915_READ(IPEHR_I965);
2650035d21cSmiao chen - Sun Microsystems - Beijing China error->instdone = I915_READ(INSTDONE_I965);
2660035d21cSmiao chen - Sun Microsystems - Beijing China error->instps = I915_READ(INSTPS);
2670035d21cSmiao chen - Sun Microsystems - Beijing China error->instdone1 = I915_READ(INSTDONE1);
2680035d21cSmiao chen - Sun Microsystems - Beijing China error->acthd = I915_READ(ACTHD_I965);
2690035d21cSmiao chen - Sun Microsystems - Beijing China }
2700035d21cSmiao chen - Sun Microsystems - Beijing China
2710035d21cSmiao chen - Sun Microsystems - Beijing China (void) uniqtime(&error->time);
2720035d21cSmiao chen - Sun Microsystems - Beijing China
2730035d21cSmiao chen - Sun Microsystems - Beijing China dev_priv->first_error = error;
2740035d21cSmiao chen - Sun Microsystems - Beijing China
2750035d21cSmiao chen - Sun Microsystems - Beijing China DRM_DEBUG("Time: %ld s %ld us\n", error->time.tv_sec,
2760035d21cSmiao chen - Sun Microsystems - Beijing China error->time.tv_usec);
2770035d21cSmiao chen - Sun Microsystems - Beijing China DRM_DEBUG("EIR: 0x%08x\n", error->eir);
2780035d21cSmiao chen - Sun Microsystems - Beijing China DRM_DEBUG(" PGTBL_ER: 0x%08x\n", error->pgtbl_er);
2790035d21cSmiao chen - Sun Microsystems - Beijing China DRM_DEBUG(" INSTPM: 0x%08x\n", error->instpm);
2800035d21cSmiao chen - Sun Microsystems - Beijing China DRM_DEBUG(" IPEIR: 0x%08x\n", error->ipeir);
2810035d21cSmiao chen - Sun Microsystems - Beijing China DRM_DEBUG(" IPEHR: 0x%08x\n", error->ipehr);
2820035d21cSmiao chen - Sun Microsystems - Beijing China DRM_DEBUG(" INSTDONE: 0x%08x\n", error->instdone);
2830035d21cSmiao chen - Sun Microsystems - Beijing China DRM_DEBUG(" ACTHD: 0x%08x\n", error->acthd);
2840035d21cSmiao chen - Sun Microsystems - Beijing China DRM_DEBUG(" DMA_FADD_P: 0x%08x\n", I915_READ(0x2078));
2850035d21cSmiao chen - Sun Microsystems - Beijing China if (IS_I965G(dev)) {
2860035d21cSmiao chen - Sun Microsystems - Beijing China DRM_DEBUG(" INSTPS: 0x%08x\n", error->instps);
2870035d21cSmiao chen - Sun Microsystems - Beijing China DRM_DEBUG(" INSTDONE1: 0x%08x\n", error->instdone1);
2880035d21cSmiao chen - Sun Microsystems - Beijing China }
2890035d21cSmiao chen - Sun Microsystems - Beijing China drm_free(error, sizeof(*error), DRM_MEM_DRIVER);
2900035d21cSmiao chen - Sun Microsystems - Beijing China out:
2910035d21cSmiao chen - Sun Microsystems - Beijing China spin_unlock_irqrestore(&dev_priv->error_lock, flags);
2920035d21cSmiao chen - Sun Microsystems - Beijing China }
2930035d21cSmiao chen - Sun Microsystems - Beijing China
2940035d21cSmiao chen - Sun Microsystems - Beijing China /**
2950035d21cSmiao chen - Sun Microsystems - Beijing China * i915_handle_error - handle an error interrupt
2960035d21cSmiao chen - Sun Microsystems - Beijing China * @dev: drm device
2970035d21cSmiao chen - Sun Microsystems - Beijing China *
2980035d21cSmiao chen - Sun Microsystems - Beijing China * Do some basic checking of regsiter state at error interrupt time and
2990035d21cSmiao chen - Sun Microsystems - Beijing China * dump it to the syslog. Also call i915_capture_error_state() to make
3000035d21cSmiao chen - Sun Microsystems - Beijing China * sure we get a record and make it available in debugfs. Fire a uevent
3010035d21cSmiao chen - Sun Microsystems - Beijing China * so userspace knows something bad happened (should trigger collection
3020035d21cSmiao chen - Sun Microsystems - Beijing China * of a ring dump etc.).
3030035d21cSmiao chen - Sun Microsystems - Beijing China */
i915_handle_error(struct drm_device * dev)3040035d21cSmiao chen - Sun Microsystems - Beijing China void i915_handle_error(struct drm_device *dev)
3050035d21cSmiao chen - Sun Microsystems - Beijing China {
3060035d21cSmiao chen - Sun Microsystems - Beijing China struct drm_i915_private *dev_priv = dev->dev_private;
3070035d21cSmiao chen - Sun Microsystems - Beijing China u32 eir = I915_READ(EIR);
3080035d21cSmiao chen - Sun Microsystems - Beijing China u32 pipea_stats = I915_READ(PIPEASTAT);
3090035d21cSmiao chen - Sun Microsystems - Beijing China u32 pipeb_stats = I915_READ(PIPEBSTAT);
3100035d21cSmiao chen - Sun Microsystems - Beijing China
3110035d21cSmiao chen - Sun Microsystems - Beijing China i915_capture_error_state(dev);
3120035d21cSmiao chen - Sun Microsystems - Beijing China
3130035d21cSmiao chen - Sun Microsystems - Beijing China DRM_DEBUG("render error detected, EIR: 0x%08x\n",
3140035d21cSmiao chen - Sun Microsystems - Beijing China eir);
3150035d21cSmiao chen - Sun Microsystems - Beijing China
3160035d21cSmiao chen - Sun Microsystems - Beijing China if (IS_G4X(dev)) {
3170035d21cSmiao chen - Sun Microsystems - Beijing China if (eir & (GM45_ERROR_MEM_PRIV | GM45_ERROR_CP_PRIV)) {
3180035d21cSmiao chen - Sun Microsystems - Beijing China u32 ipeir = I915_READ(IPEIR_I965);
3190035d21cSmiao chen - Sun Microsystems - Beijing China
3200035d21cSmiao chen - Sun Microsystems - Beijing China DRM_DEBUG(" IPEIR: 0x%08x\n",
3210035d21cSmiao chen - Sun Microsystems - Beijing China I915_READ(IPEIR_I965));
3220035d21cSmiao chen - Sun Microsystems - Beijing China DRM_DEBUG(" IPEHR: 0x%08x\n",
3230035d21cSmiao chen - Sun Microsystems - Beijing China I915_READ(IPEHR_I965));
3240035d21cSmiao chen - Sun Microsystems - Beijing China DRM_DEBUG(" INSTDONE: 0x%08x\n",
3250035d21cSmiao chen - Sun Microsystems - Beijing China I915_READ(INSTDONE_I965));
3260035d21cSmiao chen - Sun Microsystems - Beijing China DRM_DEBUG(" INSTPS: 0x%08x\n",
3270035d21cSmiao chen - Sun Microsystems - Beijing China I915_READ(INSTPS));
3280035d21cSmiao chen - Sun Microsystems - Beijing China DRM_DEBUG(" INSTDONE1: 0x%08x\n",
3290035d21cSmiao chen - Sun Microsystems - Beijing China I915_READ(INSTDONE1));
3300035d21cSmiao chen - Sun Microsystems - Beijing China DRM_DEBUG(" ACTHD: 0x%08x\n",
3310035d21cSmiao chen - Sun Microsystems - Beijing China I915_READ(ACTHD_I965));
3320035d21cSmiao chen - Sun Microsystems - Beijing China I915_WRITE(IPEIR_I965, ipeir);
3330035d21cSmiao chen - Sun Microsystems - Beijing China (void)I915_READ(IPEIR_I965);
3340035d21cSmiao chen - Sun Microsystems - Beijing China }
3350035d21cSmiao chen - Sun Microsystems - Beijing China if (eir & GM45_ERROR_PAGE_TABLE) {
3360035d21cSmiao chen - Sun Microsystems - Beijing China u32 pgtbl_err = I915_READ(PGTBL_ER);
3370035d21cSmiao chen - Sun Microsystems - Beijing China DRM_DEBUG("page table error\n");
3380035d21cSmiao chen - Sun Microsystems - Beijing China DRM_DEBUG(" PGTBL_ER: 0x%08x\n",
3390035d21cSmiao chen - Sun Microsystems - Beijing China pgtbl_err);
3400035d21cSmiao chen - Sun Microsystems - Beijing China I915_WRITE(PGTBL_ER, pgtbl_err);
3410035d21cSmiao chen - Sun Microsystems - Beijing China (void)I915_READ(PGTBL_ER);
3420035d21cSmiao chen - Sun Microsystems - Beijing China }
3430035d21cSmiao chen - Sun Microsystems - Beijing China }
3440035d21cSmiao chen - Sun Microsystems - Beijing China
3450035d21cSmiao chen - Sun Microsystems - Beijing China if (IS_I9XX(dev)) {
3460035d21cSmiao chen - Sun Microsystems - Beijing China if (eir & I915_ERROR_PAGE_TABLE) {
3470035d21cSmiao chen - Sun Microsystems - Beijing China u32 pgtbl_err = I915_READ(PGTBL_ER);
3480035d21cSmiao chen - Sun Microsystems - Beijing China DRM_DEBUG("page table error\n");
3490035d21cSmiao chen - Sun Microsystems - Beijing China DRM_DEBUG("PGTBL_ER: 0x%08x\n",
3500035d21cSmiao chen - Sun Microsystems - Beijing China pgtbl_err);
3510035d21cSmiao chen - Sun Microsystems - Beijing China I915_WRITE(PGTBL_ER, pgtbl_err);
3520035d21cSmiao chen - Sun Microsystems - Beijing China (void)I915_READ(PGTBL_ER);
3530035d21cSmiao chen - Sun Microsystems - Beijing China }
3540035d21cSmiao chen - Sun Microsystems - Beijing China }
3550035d21cSmiao chen - Sun Microsystems - Beijing China
3560035d21cSmiao chen - Sun Microsystems - Beijing China if (eir & I915_ERROR_MEMORY_REFRESH) {
3570035d21cSmiao chen - Sun Microsystems - Beijing China DRM_DEBUG("memory refresh error\n");
3580035d21cSmiao chen - Sun Microsystems - Beijing China DRM_DEBUG("PIPEASTAT: 0x%08x\n",
3590035d21cSmiao chen - Sun Microsystems - Beijing China pipea_stats);
3600035d21cSmiao chen - Sun Microsystems - Beijing China DRM_DEBUG("PIPEBSTAT: 0x%08x\n",
3610035d21cSmiao chen - Sun Microsystems - Beijing China pipeb_stats);
3620035d21cSmiao chen - Sun Microsystems - Beijing China /* pipestat has already been acked */
3630035d21cSmiao chen - Sun Microsystems - Beijing China }
3640035d21cSmiao chen - Sun Microsystems - Beijing China if (eir & I915_ERROR_INSTRUCTION) {
3650035d21cSmiao chen - Sun Microsystems - Beijing China DRM_DEBUG("instruction error\n");
3660035d21cSmiao chen - Sun Microsystems - Beijing China DRM_DEBUG(" INSTPM: 0x%08x\n",
3670035d21cSmiao chen - Sun Microsystems - Beijing China I915_READ(INSTPM));
3680035d21cSmiao chen - Sun Microsystems - Beijing China if (!IS_I965G(dev)) {
3690035d21cSmiao chen - Sun Microsystems - Beijing China u32 ipeir = I915_READ(IPEIR);
3700035d21cSmiao chen - Sun Microsystems - Beijing China
3710035d21cSmiao chen - Sun Microsystems - Beijing China DRM_DEBUG(" IPEIR: 0x%08x\n",
3720035d21cSmiao chen - Sun Microsystems - Beijing China I915_READ(IPEIR));
3730035d21cSmiao chen - Sun Microsystems - Beijing China DRM_DEBUG(" IPEHR: 0x%08x\n",
3740035d21cSmiao chen - Sun Microsystems - Beijing China I915_READ(IPEHR));
3750035d21cSmiao chen - Sun Microsystems - Beijing China DRM_DEBUG(" INSTDONE: 0x%08x\n",
3760035d21cSmiao chen - Sun Microsystems - Beijing China I915_READ(INSTDONE));
3770035d21cSmiao chen - Sun Microsystems - Beijing China DRM_DEBUG(" ACTHD: 0x%08x\n",
3780035d21cSmiao chen - Sun Microsystems - Beijing China I915_READ(ACTHD));
3790035d21cSmiao chen - Sun Microsystems - Beijing China I915_WRITE(IPEIR, ipeir);
3800035d21cSmiao chen - Sun Microsystems - Beijing China (void)I915_READ(IPEIR);
3810035d21cSmiao chen - Sun Microsystems - Beijing China } else {
3820035d21cSmiao chen - Sun Microsystems - Beijing China u32 ipeir = I915_READ(IPEIR_I965);
3830035d21cSmiao chen - Sun Microsystems - Beijing China
3840035d21cSmiao chen - Sun Microsystems - Beijing China DRM_DEBUG(" IPEIR: 0x%08x\n",
3850035d21cSmiao chen - Sun Microsystems - Beijing China I915_READ(IPEIR_I965));
3860035d21cSmiao chen - Sun Microsystems - Beijing China DRM_DEBUG(" IPEHR: 0x%08x\n",
3870035d21cSmiao chen - Sun Microsystems - Beijing China I915_READ(IPEHR_I965));
3880035d21cSmiao chen - Sun Microsystems - Beijing China DRM_DEBUG(" INSTDONE: 0x%08x\n",
3890035d21cSmiao chen - Sun Microsystems - Beijing China I915_READ(INSTDONE_I965));
3900035d21cSmiao chen - Sun Microsystems - Beijing China DRM_DEBUG(" INSTPS: 0x%08x\n",
3910035d21cSmiao chen - Sun Microsystems - Beijing China I915_READ(INSTPS));
3920035d21cSmiao chen - Sun Microsystems - Beijing China DRM_DEBUG(" INSTDONE1: 0x%08x\n",
3930035d21cSmiao chen - Sun Microsystems - Beijing China I915_READ(INSTDONE1));
3940035d21cSmiao chen - Sun Microsystems - Beijing China DRM_DEBUG(" ACTHD: 0x%08x\n",
3950035d21cSmiao chen - Sun Microsystems - Beijing China I915_READ(ACTHD_I965));
3960035d21cSmiao chen - Sun Microsystems - Beijing China I915_WRITE(IPEIR_I965, ipeir);
3970035d21cSmiao chen - Sun Microsystems - Beijing China (void)I915_READ(IPEIR_I965);
3980035d21cSmiao chen - Sun Microsystems - Beijing China }
3990035d21cSmiao chen - Sun Microsystems - Beijing China }
4000035d21cSmiao chen - Sun Microsystems - Beijing China
4010035d21cSmiao chen - Sun Microsystems - Beijing China I915_WRITE(EIR, eir);
4020035d21cSmiao chen - Sun Microsystems - Beijing China (void)I915_READ(EIR);
4030035d21cSmiao chen - Sun Microsystems - Beijing China eir = I915_READ(EIR);
4040035d21cSmiao chen - Sun Microsystems - Beijing China if (eir) {
4050035d21cSmiao chen - Sun Microsystems - Beijing China /*
4060035d21cSmiao chen - Sun Microsystems - Beijing China * some errors might have become stuck,
4070035d21cSmiao chen - Sun Microsystems - Beijing China * mask them.
4080035d21cSmiao chen - Sun Microsystems - Beijing China */
4090035d21cSmiao chen - Sun Microsystems - Beijing China DRM_DEBUG("EIR stuck: 0x%08x, masking\n", eir);
4100035d21cSmiao chen - Sun Microsystems - Beijing China I915_WRITE(EMR, I915_READ(EMR) | eir);
4110035d21cSmiao chen - Sun Microsystems - Beijing China I915_WRITE(IIR, I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT);
4120035d21cSmiao chen - Sun Microsystems - Beijing China }
4130035d21cSmiao chen - Sun Microsystems - Beijing China
4140035d21cSmiao chen - Sun Microsystems - Beijing China }
4150035d21cSmiao chen - Sun Microsystems - Beijing China
gm45_get_vblank_counter(struct drm_device * dev,int pipe)4160035d21cSmiao chen - Sun Microsystems - Beijing China u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe)
4170035d21cSmiao chen - Sun Microsystems - Beijing China {
4180035d21cSmiao chen - Sun Microsystems - Beijing China drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
4190035d21cSmiao chen - Sun Microsystems - Beijing China int reg = pipe ? PIPEB_FRMCOUNT_GM45 : PIPEA_FRMCOUNT_GM45;
4200035d21cSmiao chen - Sun Microsystems - Beijing China
4210035d21cSmiao chen - Sun Microsystems - Beijing China if (!i915_pipe_enabled(dev, pipe)) {
4220035d21cSmiao chen - Sun Microsystems - Beijing China DRM_ERROR("trying to get vblank count for disabled pipe %d\n", pipe);
4230035d21cSmiao chen - Sun Microsystems - Beijing China return 0;
4240035d21cSmiao chen - Sun Microsystems - Beijing China }
4250035d21cSmiao chen - Sun Microsystems - Beijing China
4260035d21cSmiao chen - Sun Microsystems - Beijing China return I915_READ(reg);
4270035d21cSmiao chen - Sun Microsystems - Beijing China }
4280035d21cSmiao chen - Sun Microsystems - Beijing China
igdng_irq_handler(struct drm_device * dev)429*2e6e901dSmiao chen - Sun Microsystems - Beijing China irqreturn_t igdng_irq_handler(struct drm_device *dev)
430*2e6e901dSmiao chen - Sun Microsystems - Beijing China {
431*2e6e901dSmiao chen - Sun Microsystems - Beijing China drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
432*2e6e901dSmiao chen - Sun Microsystems - Beijing China int ret = IRQ_NONE;
433*2e6e901dSmiao chen - Sun Microsystems - Beijing China u32 de_iir, gt_iir, de_ier;
434*2e6e901dSmiao chen - Sun Microsystems - Beijing China u32 new_de_iir, new_gt_iir;
435*2e6e901dSmiao chen - Sun Microsystems - Beijing China int vblank = 0;
436*2e6e901dSmiao chen - Sun Microsystems - Beijing China
437*2e6e901dSmiao chen - Sun Microsystems - Beijing China /* disable master interrupt before clearing iir */
438*2e6e901dSmiao chen - Sun Microsystems - Beijing China de_ier = I915_READ(DEIER);
439*2e6e901dSmiao chen - Sun Microsystems - Beijing China I915_WRITE(DEIER, de_ier & ~DE_MASTER_IRQ_CONTROL);
440*2e6e901dSmiao chen - Sun Microsystems - Beijing China (void)I915_READ(DEIER);
441*2e6e901dSmiao chen - Sun Microsystems - Beijing China
442*2e6e901dSmiao chen - Sun Microsystems - Beijing China de_iir = I915_READ(DEIIR);
443*2e6e901dSmiao chen - Sun Microsystems - Beijing China gt_iir = I915_READ(GTIIR);
444*2e6e901dSmiao chen - Sun Microsystems - Beijing China
445*2e6e901dSmiao chen - Sun Microsystems - Beijing China for (;;) {
446*2e6e901dSmiao chen - Sun Microsystems - Beijing China if (de_iir == 0 && gt_iir == 0)
447*2e6e901dSmiao chen - Sun Microsystems - Beijing China break;
448*2e6e901dSmiao chen - Sun Microsystems - Beijing China
449*2e6e901dSmiao chen - Sun Microsystems - Beijing China ret = IRQ_HANDLED;
450*2e6e901dSmiao chen - Sun Microsystems - Beijing China
451*2e6e901dSmiao chen - Sun Microsystems - Beijing China I915_WRITE(DEIIR, de_iir);
452*2e6e901dSmiao chen - Sun Microsystems - Beijing China new_de_iir = I915_READ(DEIIR);
453*2e6e901dSmiao chen - Sun Microsystems - Beijing China I915_WRITE(GTIIR, gt_iir);
454*2e6e901dSmiao chen - Sun Microsystems - Beijing China new_gt_iir = I915_READ(GTIIR);
455*2e6e901dSmiao chen - Sun Microsystems - Beijing China
456*2e6e901dSmiao chen - Sun Microsystems - Beijing China if (dev_priv->sarea_priv) {
457*2e6e901dSmiao chen - Sun Microsystems - Beijing China dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
458*2e6e901dSmiao chen - Sun Microsystems - Beijing China
459*2e6e901dSmiao chen - Sun Microsystems - Beijing China }
460*2e6e901dSmiao chen - Sun Microsystems - Beijing China
461*2e6e901dSmiao chen - Sun Microsystems - Beijing China if (gt_iir & GT_USER_INTERRUPT) {
462*2e6e901dSmiao chen - Sun Microsystems - Beijing China dev_priv->mm.irq_gem_seqno = i915_get_gem_seqno(dev);
463*2e6e901dSmiao chen - Sun Microsystems - Beijing China DRM_WAKEUP(&dev_priv->irq_queue);
464*2e6e901dSmiao chen - Sun Microsystems - Beijing China }
465*2e6e901dSmiao chen - Sun Microsystems - Beijing China if (de_iir & DE_PIPEA_VBLANK) {
466*2e6e901dSmiao chen - Sun Microsystems - Beijing China vblank++;
467*2e6e901dSmiao chen - Sun Microsystems - Beijing China drm_handle_vblank(dev, 0);
468*2e6e901dSmiao chen - Sun Microsystems - Beijing China }
469*2e6e901dSmiao chen - Sun Microsystems - Beijing China
470*2e6e901dSmiao chen - Sun Microsystems - Beijing China if (de_iir & DE_PIPEB_VBLANK) {
471*2e6e901dSmiao chen - Sun Microsystems - Beijing China vblank++;
472*2e6e901dSmiao chen - Sun Microsystems - Beijing China drm_handle_vblank(dev, 1);
473*2e6e901dSmiao chen - Sun Microsystems - Beijing China }
474*2e6e901dSmiao chen - Sun Microsystems - Beijing China
475*2e6e901dSmiao chen - Sun Microsystems - Beijing China de_iir = new_de_iir;
476*2e6e901dSmiao chen - Sun Microsystems - Beijing China gt_iir = new_gt_iir;
477*2e6e901dSmiao chen - Sun Microsystems - Beijing China }
478*2e6e901dSmiao chen - Sun Microsystems - Beijing China
479*2e6e901dSmiao chen - Sun Microsystems - Beijing China I915_WRITE(DEIER, de_ier);
480*2e6e901dSmiao chen - Sun Microsystems - Beijing China (void)I915_READ(DEIER);
481*2e6e901dSmiao chen - Sun Microsystems - Beijing China
482*2e6e901dSmiao chen - Sun Microsystems - Beijing China return ret;
483*2e6e901dSmiao chen - Sun Microsystems - Beijing China }
484*2e6e901dSmiao chen - Sun Microsystems - Beijing China
i915_driver_irq_handler(DRM_IRQ_ARGS)485ae115bc7Smrj irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
486ae115bc7Smrj {
4870bdffa0fShh224818 drm_device_t *dev = (drm_device_t *) (void *) arg;
488ae115bc7Smrj drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
489d0231070Smiao chen - Sun Microsystems - Beijing China u32 iir;
490d0231070Smiao chen - Sun Microsystems - Beijing China u32 pipea_stats = 0, pipeb_stats = 0;
491d0231070Smiao chen - Sun Microsystems - Beijing China int vblank = 0;
492e92e3a86Szw161486
493*2e6e901dSmiao chen - Sun Microsystems - Beijing China if (IS_IGDNG(dev))
494*2e6e901dSmiao chen - Sun Microsystems - Beijing China return igdng_irq_handler(dev);
495*2e6e901dSmiao chen - Sun Microsystems - Beijing China
4960035d21cSmiao chen - Sun Microsystems - Beijing China iir = I915_READ(IIR);
497ae115bc7Smrj
498d0231070Smiao chen - Sun Microsystems - Beijing China if (iir == 0) {
499e92e3a86Szw161486 return IRQ_NONE;
500d0231070Smiao chen - Sun Microsystems - Beijing China }
5010035d21cSmiao chen - Sun Microsystems - Beijing China start:
5020035d21cSmiao chen - Sun Microsystems - Beijing China
5030035d21cSmiao chen - Sun Microsystems - Beijing China if (dev_priv->sarea_priv) {
5040035d21cSmiao chen - Sun Microsystems - Beijing China if (dev_priv->hw_status_page)
5050035d21cSmiao chen - Sun Microsystems - Beijing China dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
5060035d21cSmiao chen - Sun Microsystems - Beijing China }
5070035d21cSmiao chen - Sun Microsystems - Beijing China
5080035d21cSmiao chen - Sun Microsystems - Beijing China I915_WRITE(IIR, iir);
5090035d21cSmiao chen - Sun Microsystems - Beijing China
5100035d21cSmiao chen - Sun Microsystems - Beijing China (void) I915_READ(IIR); /* Flush posted writes */
5110035d21cSmiao chen - Sun Microsystems - Beijing China
5120035d21cSmiao chen - Sun Microsystems - Beijing China
5130035d21cSmiao chen - Sun Microsystems - Beijing China if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT)
5140035d21cSmiao chen - Sun Microsystems - Beijing China i915_handle_error(dev);
5150035d21cSmiao chen - Sun Microsystems - Beijing China
5160035d21cSmiao chen - Sun Microsystems - Beijing China if (iir & I915_USER_INTERRUPT) {
5170035d21cSmiao chen - Sun Microsystems - Beijing China dev_priv->mm.irq_gem_seqno = i915_get_gem_seqno(dev);
5180035d21cSmiao chen - Sun Microsystems - Beijing China DRM_WAKEUP(&dev_priv->irq_queue);
5190035d21cSmiao chen - Sun Microsystems - Beijing China }
520ae115bc7Smrj
521d0231070Smiao chen - Sun Microsystems - Beijing China if (iir & I915_DISPLAY_PIPE_A_EVENT_INTERRUPT) {
522d0231070Smiao chen - Sun Microsystems - Beijing China pipea_stats = I915_READ(PIPEASTAT);
523e92e3a86Szw161486
524d0231070Smiao chen - Sun Microsystems - Beijing China /* The vblank interrupt gets enabled even if we didn't ask for
525d0231070Smiao chen - Sun Microsystems - Beijing China it, so make sure it's shut down again */
526d0231070Smiao chen - Sun Microsystems - Beijing China if (!(dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A))
527d0231070Smiao chen - Sun Microsystems - Beijing China pipea_stats &= ~(PIPE_START_VBLANK_INTERRUPT_ENABLE |
528d0231070Smiao chen - Sun Microsystems - Beijing China PIPE_VBLANK_INTERRUPT_ENABLE);
529d0231070Smiao chen - Sun Microsystems - Beijing China else if (pipea_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS|
530d0231070Smiao chen - Sun Microsystems - Beijing China PIPE_VBLANK_INTERRUPT_STATUS))
531d0231070Smiao chen - Sun Microsystems - Beijing China {
532d0231070Smiao chen - Sun Microsystems - Beijing China vblank++;
5330035d21cSmiao chen - Sun Microsystems - Beijing China drm_handle_vblank(dev, 0);
534d0231070Smiao chen - Sun Microsystems - Beijing China }
535d0231070Smiao chen - Sun Microsystems - Beijing China
536d0231070Smiao chen - Sun Microsystems - Beijing China I915_WRITE(PIPEASTAT, pipea_stats);
537d0231070Smiao chen - Sun Microsystems - Beijing China }
538d0231070Smiao chen - Sun Microsystems - Beijing China if (iir & I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) {
539d0231070Smiao chen - Sun Microsystems - Beijing China pipeb_stats = I915_READ(PIPEBSTAT);
540d0231070Smiao chen - Sun Microsystems - Beijing China
541d0231070Smiao chen - Sun Microsystems - Beijing China /* The vblank interrupt gets enabled even if we didn't ask for
542d0231070Smiao chen - Sun Microsystems - Beijing China it, so make sure it's shut down again */
543d0231070Smiao chen - Sun Microsystems - Beijing China if (!(dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B))
544d0231070Smiao chen - Sun Microsystems - Beijing China pipeb_stats &= ~(PIPE_START_VBLANK_INTERRUPT_ENABLE |
545d0231070Smiao chen - Sun Microsystems - Beijing China PIPE_VBLANK_INTERRUPT_ENABLE);
546d0231070Smiao chen - Sun Microsystems - Beijing China else if (pipeb_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS|
547d0231070Smiao chen - Sun Microsystems - Beijing China PIPE_VBLANK_INTERRUPT_STATUS))
548d0231070Smiao chen - Sun Microsystems - Beijing China {
549d0231070Smiao chen - Sun Microsystems - Beijing China vblank++;
5500035d21cSmiao chen - Sun Microsystems - Beijing China drm_handle_vblank(dev, 1);
551d0231070Smiao chen - Sun Microsystems - Beijing China }
552d0231070Smiao chen - Sun Microsystems - Beijing China
553d0231070Smiao chen - Sun Microsystems - Beijing China I915_WRITE(PIPEBSTAT, pipeb_stats);
554d0231070Smiao chen - Sun Microsystems - Beijing China }
555ae115bc7Smrj return IRQ_HANDLED;
556d0231070Smiao chen - Sun Microsystems - Beijing China
557ae115bc7Smrj }
558ae115bc7Smrj
i915_emit_irq(drm_device_t * dev)559e92e3a86Szw161486 int i915_emit_irq(drm_device_t * dev)
560ae115bc7Smrj {
561e92e3a86Szw161486
562ae115bc7Smrj drm_i915_private_t *dev_priv = dev->dev_private;
563ae115bc7Smrj RING_LOCALS;
564ae115bc7Smrj
565ae115bc7Smrj i915_kernel_lost_context(dev);
566ae115bc7Smrj
5670035d21cSmiao chen - Sun Microsystems - Beijing China dev_priv->counter++;
5680035d21cSmiao chen - Sun Microsystems - Beijing China if (dev_priv->counter > 0x7FFFFFFFUL)
5690035d21cSmiao chen - Sun Microsystems - Beijing China dev_priv->counter = 1;
5700035d21cSmiao chen - Sun Microsystems - Beijing China if (dev_priv->sarea_priv)
5710035d21cSmiao chen - Sun Microsystems - Beijing China dev_priv->sarea_priv->last_enqueue = dev_priv->counter;
572ae115bc7Smrj
5730035d21cSmiao chen - Sun Microsystems - Beijing China #if defined(__i386)
5740035d21cSmiao chen - Sun Microsystems - Beijing China if (IS_GM45(dev)) {
5750035d21cSmiao chen - Sun Microsystems - Beijing China BEGIN_LP_RING(3);
5760035d21cSmiao chen - Sun Microsystems - Beijing China OUT_RING(MI_STORE_DWORD_INDEX);
5770035d21cSmiao chen - Sun Microsystems - Beijing China OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
5780035d21cSmiao chen - Sun Microsystems - Beijing China OUT_RING(dev_priv->counter);
5790035d21cSmiao chen - Sun Microsystems - Beijing China ADVANCE_LP_RING();
5800035d21cSmiao chen - Sun Microsystems - Beijing China
5810035d21cSmiao chen - Sun Microsystems - Beijing China (void) READ_BREADCRUMB(dev_priv);
582d0231070Smiao chen - Sun Microsystems - Beijing China BEGIN_LP_RING(2);
583e92e3a86Szw161486 OUT_RING(0);
584d0231070Smiao chen - Sun Microsystems - Beijing China OUT_RING(MI_USER_INTERRUPT);
585ae115bc7Smrj ADVANCE_LP_RING();
5860035d21cSmiao chen - Sun Microsystems - Beijing China } else {
5870035d21cSmiao chen - Sun Microsystems - Beijing China #endif /* __i386 */
5880035d21cSmiao chen - Sun Microsystems - Beijing China BEGIN_LP_RING(4);
5890035d21cSmiao chen - Sun Microsystems - Beijing China OUT_RING(MI_STORE_DWORD_INDEX);
5900035d21cSmiao chen - Sun Microsystems - Beijing China OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
5910035d21cSmiao chen - Sun Microsystems - Beijing China OUT_RING(dev_priv->counter);
5920035d21cSmiao chen - Sun Microsystems - Beijing China OUT_RING(MI_USER_INTERRUPT);
5930035d21cSmiao chen - Sun Microsystems - Beijing China ADVANCE_LP_RING();
5940035d21cSmiao chen - Sun Microsystems - Beijing China #if defined(__i386)
5950035d21cSmiao chen - Sun Microsystems - Beijing China }
5960035d21cSmiao chen - Sun Microsystems - Beijing China #endif /* __i386 */
5970035d21cSmiao chen - Sun Microsystems - Beijing China
5980035d21cSmiao chen - Sun Microsystems - Beijing China #if defined(__i386)
599*2e6e901dSmiao chen - Sun Microsystems - Beijing China if (IS_I965GM(dev) || IS_IGDNG(dev) || IS_GM45(dev))
6000035d21cSmiao chen - Sun Microsystems - Beijing China #else
601*2e6e901dSmiao chen - Sun Microsystems - Beijing China if (IS_I965GM(dev) || IS_IGDNG(dev))
6020035d21cSmiao chen - Sun Microsystems - Beijing China #endif /* __i386 */
6030035d21cSmiao chen - Sun Microsystems - Beijing China {
6040035d21cSmiao chen - Sun Microsystems - Beijing China (void) READ_BREADCRUMB(dev_priv);
6050035d21cSmiao chen - Sun Microsystems - Beijing China BEGIN_LP_RING(2);
6060035d21cSmiao chen - Sun Microsystems - Beijing China OUT_RING(0);
6070035d21cSmiao chen - Sun Microsystems - Beijing China OUT_RING(0);
6080035d21cSmiao chen - Sun Microsystems - Beijing China ADVANCE_LP_RING();
6090035d21cSmiao chen - Sun Microsystems - Beijing China (void) READ_BREADCRUMB(dev_priv);
6100035d21cSmiao chen - Sun Microsystems - Beijing China }
611ae115bc7Smrj
612e92e3a86Szw161486 return dev_priv->counter;
613ae115bc7Smrj }
614ae115bc7Smrj
i915_user_irq_on(struct drm_device * dev)6150035d21cSmiao chen - Sun Microsystems - Beijing China void i915_user_irq_on(struct drm_device *dev)
616e92e3a86Szw161486 {
6170035d21cSmiao chen - Sun Microsystems - Beijing China drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
618e92e3a86Szw161486 spin_lock(&dev_priv->user_irq_lock);
6190035d21cSmiao chen - Sun Microsystems - Beijing China if (dev->irq_enabled && (++dev_priv->user_irq_refcount == 1)){
620*2e6e901dSmiao chen - Sun Microsystems - Beijing China if (IS_IGDNG(dev))
621*2e6e901dSmiao chen - Sun Microsystems - Beijing China igdng_enable_irq(dev_priv, GT_USER_INTERRUPT, 1);
622*2e6e901dSmiao chen - Sun Microsystems - Beijing China else
623d0231070Smiao chen - Sun Microsystems - Beijing China i915_enable_irq(dev_priv, I915_USER_INTERRUPT);
624e92e3a86Szw161486 }
625e92e3a86Szw161486 spin_unlock(&dev_priv->user_irq_lock);
626e92e3a86Szw161486
627e92e3a86Szw161486 }
628e92e3a86Szw161486
i915_user_irq_off(struct drm_device * dev)6290035d21cSmiao chen - Sun Microsystems - Beijing China void i915_user_irq_off(struct drm_device *dev)
630e92e3a86Szw161486 {
6310035d21cSmiao chen - Sun Microsystems - Beijing China drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
632e92e3a86Szw161486 spin_lock(&dev_priv->user_irq_lock);
6330035d21cSmiao chen - Sun Microsystems - Beijing China if (dev->irq_enabled && (--dev_priv->user_irq_refcount == 0)) {
634*2e6e901dSmiao chen - Sun Microsystems - Beijing China if (IS_IGDNG(dev))
635*2e6e901dSmiao chen - Sun Microsystems - Beijing China igdng_disable_irq(dev_priv, GT_USER_INTERRUPT, 1);
636*2e6e901dSmiao chen - Sun Microsystems - Beijing China else
637d0231070Smiao chen - Sun Microsystems - Beijing China i915_disable_irq(dev_priv, I915_USER_INTERRUPT);
638e92e3a86Szw161486 }
639e92e3a86Szw161486 spin_unlock(&dev_priv->user_irq_lock);
640e92e3a86Szw161486 }
641e92e3a86Szw161486
642e92e3a86Szw161486
i915_wait_irq(drm_device_t * dev,int irq_nr)643ae115bc7Smrj static int i915_wait_irq(drm_device_t * dev, int irq_nr)
644ae115bc7Smrj {
645ae115bc7Smrj drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
646ae115bc7Smrj int ret = 0;
647*2e6e901dSmiao chen - Sun Microsystems - Beijing China int wait_time = 0;
648ae115bc7Smrj
649d0231070Smiao chen - Sun Microsystems - Beijing China if (!dev_priv) {
650d0231070Smiao chen - Sun Microsystems - Beijing China DRM_ERROR("called with no initialization\n");
651d0231070Smiao chen - Sun Microsystems - Beijing China return -EINVAL;
652d0231070Smiao chen - Sun Microsystems - Beijing China }
653d0231070Smiao chen - Sun Microsystems - Beijing China
654*2e6e901dSmiao chen - Sun Microsystems - Beijing China waitmore:
655*2e6e901dSmiao chen - Sun Microsystems - Beijing China wait_time++;
656d0231070Smiao chen - Sun Microsystems - Beijing China if (READ_BREADCRUMB(dev_priv) >= irq_nr) {
6570035d21cSmiao chen - Sun Microsystems - Beijing China if (dev_priv->sarea_priv) {
658d0231070Smiao chen - Sun Microsystems - Beijing China dev_priv->sarea_priv->last_dispatch =
659d0231070Smiao chen - Sun Microsystems - Beijing China READ_BREADCRUMB(dev_priv);
6600035d21cSmiao chen - Sun Microsystems - Beijing China }
661ae115bc7Smrj return 0;
662d0231070Smiao chen - Sun Microsystems - Beijing China }
663d0231070Smiao chen - Sun Microsystems - Beijing China DRM_DEBUG("i915_wait_irq: irq_nr=%d breadcrumb=%d\n", irq_nr, READ_BREADCRUMB(dev_priv));
6640035d21cSmiao chen - Sun Microsystems - Beijing China i915_user_irq_on(dev);
665d0538f66Scg149915 DRM_WAIT_ON(ret, &dev_priv->irq_queue, 3 * DRM_HZ,
666ae115bc7Smrj READ_BREADCRUMB(dev_priv) >= irq_nr);
6670035d21cSmiao chen - Sun Microsystems - Beijing China i915_user_irq_off(dev);
668ae115bc7Smrj
6690035d21cSmiao chen - Sun Microsystems - Beijing China if (ret == EBUSY) {
670*2e6e901dSmiao chen - Sun Microsystems - Beijing China if (wait_time > 5) {
671d0231070Smiao chen - Sun Microsystems - Beijing China DRM_DEBUG("%d: EBUSY -- rec: %d emitted: %d\n",
672d0231070Smiao chen - Sun Microsystems - Beijing China ret,
673ae115bc7Smrj READ_BREADCRUMB(dev_priv), (int)dev_priv->counter);
674*2e6e901dSmiao chen - Sun Microsystems - Beijing China return ret;
675*2e6e901dSmiao chen - Sun Microsystems - Beijing China }
676*2e6e901dSmiao chen - Sun Microsystems - Beijing China goto waitmore;
677ae115bc7Smrj }
678ae115bc7Smrj
679d0231070Smiao chen - Sun Microsystems - Beijing China if (dev_priv->sarea_priv)
680ae115bc7Smrj dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
681e92e3a86Szw161486
682*2e6e901dSmiao chen - Sun Microsystems - Beijing China if (ret == EINTR) {
683*2e6e901dSmiao chen - Sun Microsystems - Beijing China if (wait_time > 5) {
684*2e6e901dSmiao chen - Sun Microsystems - Beijing China DRM_DEBUG("EINTR wait %d now %d", dev_priv->counter, READ_BREADCRUMB(dev_priv));
685*2e6e901dSmiao chen - Sun Microsystems - Beijing China return ret;
686*2e6e901dSmiao chen - Sun Microsystems - Beijing China }
687*2e6e901dSmiao chen - Sun Microsystems - Beijing China goto waitmore;
688*2e6e901dSmiao chen - Sun Microsystems - Beijing China }
689*2e6e901dSmiao chen - Sun Microsystems - Beijing China
690e92e3a86Szw161486 return ret;
691e92e3a86Szw161486 }
692e92e3a86Szw161486
693e92e3a86Szw161486
694ae115bc7Smrj /* Needs the lock as it touches the ring.
695ae115bc7Smrj */
696ae115bc7Smrj /*ARGSUSED*/
i915_irq_emit(DRM_IOCTL_ARGS)697ae115bc7Smrj int i915_irq_emit(DRM_IOCTL_ARGS)
698ae115bc7Smrj {
699ae115bc7Smrj DRM_DEVICE;
700ae115bc7Smrj drm_i915_private_t *dev_priv = dev->dev_private;
701ae115bc7Smrj drm_i915_irq_emit_t emit;
702ae115bc7Smrj int result;
703ae115bc7Smrj
704d0538f66Scg149915 LOCK_TEST_WITH_RETURN(dev, fpriv);
705ae115bc7Smrj
706ae115bc7Smrj if (!dev_priv) {
707ae115bc7Smrj DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
708d0538f66Scg149915 return (EINVAL);
709ae115bc7Smrj }
710ae115bc7Smrj
7110035d21cSmiao chen - Sun Microsystems - Beijing China
712ae115bc7Smrj if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
713ae115bc7Smrj drm_i915_irq_emit32_t irq_emit32;
714ae115bc7Smrj
715d0538f66Scg149915 DRM_COPYFROM_WITH_RETURN(&irq_emit32,
716ae115bc7Smrj (drm_i915_irq_emit32_t __user *) data,
717ae115bc7Smrj sizeof (drm_i915_irq_emit32_t));
718ae115bc7Smrj emit.irq_seq = (int __user *)(uintptr_t)irq_emit32.irq_seq;
719ae115bc7Smrj } else
720d0538f66Scg149915 DRM_COPYFROM_WITH_RETURN(&emit,
721d0538f66Scg149915 (drm_i915_irq_emit_t __user *) data, sizeof(emit));
722ae115bc7Smrj
7230035d21cSmiao chen - Sun Microsystems - Beijing China spin_lock(&dev->struct_mutex);
724ae115bc7Smrj result = i915_emit_irq(dev);
7250035d21cSmiao chen - Sun Microsystems - Beijing China spin_unlock(&dev->struct_mutex);
726ae115bc7Smrj
727ae115bc7Smrj if (DRM_COPY_TO_USER(emit.irq_seq, &result, sizeof(int))) {
728ae115bc7Smrj DRM_ERROR("copy_to_user\n");
729d0538f66Scg149915 return (EFAULT);
730ae115bc7Smrj }
731ae115bc7Smrj
732ae115bc7Smrj return 0;
733ae115bc7Smrj }
734ae115bc7Smrj
735ae115bc7Smrj /* Doesn't need the hardware lock.
736ae115bc7Smrj */
737ae115bc7Smrj /*ARGSUSED*/
i915_irq_wait(DRM_IOCTL_ARGS)738ae115bc7Smrj int i915_irq_wait(DRM_IOCTL_ARGS)
739ae115bc7Smrj {
740ae115bc7Smrj DRM_DEVICE;
741ae115bc7Smrj drm_i915_private_t *dev_priv = dev->dev_private;
742ae115bc7Smrj drm_i915_irq_wait_t irqwait;
743ae115bc7Smrj
744ae115bc7Smrj if (!dev_priv) {
745ae115bc7Smrj DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
746d0538f66Scg149915 return (EINVAL);
747ae115bc7Smrj }
748ae115bc7Smrj
749d0538f66Scg149915 DRM_COPYFROM_WITH_RETURN(&irqwait,
750d0538f66Scg149915 (drm_i915_irq_wait_t __user *) data, sizeof(irqwait));
751ae115bc7Smrj
752ae115bc7Smrj return i915_wait_irq(dev, irqwait.irq_seq);
753ae115bc7Smrj }
754ae115bc7Smrj
igdng_enable_vblank(struct drm_device * dev,int pipe)755*2e6e901dSmiao chen - Sun Microsystems - Beijing China static void igdng_enable_vblank(struct drm_device *dev, int pipe)
756*2e6e901dSmiao chen - Sun Microsystems - Beijing China {
757*2e6e901dSmiao chen - Sun Microsystems - Beijing China drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
758*2e6e901dSmiao chen - Sun Microsystems - Beijing China u32 vblank;
759*2e6e901dSmiao chen - Sun Microsystems - Beijing China
760*2e6e901dSmiao chen - Sun Microsystems - Beijing China if (pipe == 0)
761*2e6e901dSmiao chen - Sun Microsystems - Beijing China vblank = DE_PIPEA_VBLANK;
762*2e6e901dSmiao chen - Sun Microsystems - Beijing China else
763*2e6e901dSmiao chen - Sun Microsystems - Beijing China vblank = DE_PIPEB_VBLANK;
764*2e6e901dSmiao chen - Sun Microsystems - Beijing China
765*2e6e901dSmiao chen - Sun Microsystems - Beijing China if ((dev_priv->de_irq_enable_reg & vblank) == 0) {
766*2e6e901dSmiao chen - Sun Microsystems - Beijing China igdng_enable_irq(dev_priv, vblank, 0);
767*2e6e901dSmiao chen - Sun Microsystems - Beijing China dev_priv->de_irq_enable_reg |= vblank;
768*2e6e901dSmiao chen - Sun Microsystems - Beijing China I915_WRITE(DEIER, dev_priv->de_irq_enable_reg);
769*2e6e901dSmiao chen - Sun Microsystems - Beijing China (void) I915_READ(DEIER);
770*2e6e901dSmiao chen - Sun Microsystems - Beijing China }
771*2e6e901dSmiao chen - Sun Microsystems - Beijing China }
772*2e6e901dSmiao chen - Sun Microsystems - Beijing China
igdng_disable_vblank(struct drm_device * dev,int pipe)773*2e6e901dSmiao chen - Sun Microsystems - Beijing China static void igdng_disable_vblank(struct drm_device *dev, int pipe)
774*2e6e901dSmiao chen - Sun Microsystems - Beijing China {
775*2e6e901dSmiao chen - Sun Microsystems - Beijing China drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
776*2e6e901dSmiao chen - Sun Microsystems - Beijing China u32 vblank;
777*2e6e901dSmiao chen - Sun Microsystems - Beijing China
778*2e6e901dSmiao chen - Sun Microsystems - Beijing China if (pipe == 0)
779*2e6e901dSmiao chen - Sun Microsystems - Beijing China vblank = DE_PIPEA_VBLANK;
780*2e6e901dSmiao chen - Sun Microsystems - Beijing China else
781*2e6e901dSmiao chen - Sun Microsystems - Beijing China vblank = DE_PIPEB_VBLANK;
782*2e6e901dSmiao chen - Sun Microsystems - Beijing China
783*2e6e901dSmiao chen - Sun Microsystems - Beijing China if ((dev_priv->de_irq_enable_reg & vblank) != 0) {
784*2e6e901dSmiao chen - Sun Microsystems - Beijing China igdng_disable_irq(dev_priv, vblank, 0);
785*2e6e901dSmiao chen - Sun Microsystems - Beijing China dev_priv->de_irq_enable_reg &= ~vblank;
786*2e6e901dSmiao chen - Sun Microsystems - Beijing China I915_WRITE(DEIER, dev_priv->de_irq_enable_reg);
787*2e6e901dSmiao chen - Sun Microsystems - Beijing China (void) I915_READ(DEIER);
788*2e6e901dSmiao chen - Sun Microsystems - Beijing China }
789*2e6e901dSmiao chen - Sun Microsystems - Beijing China }
790*2e6e901dSmiao chen - Sun Microsystems - Beijing China
i915_enable_vblank(struct drm_device * dev,int pipe)7910035d21cSmiao chen - Sun Microsystems - Beijing China int i915_enable_vblank(struct drm_device *dev, int pipe)
792d0231070Smiao chen - Sun Microsystems - Beijing China {
793d0231070Smiao chen - Sun Microsystems - Beijing China drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
7940035d21cSmiao chen - Sun Microsystems - Beijing China int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
7950035d21cSmiao chen - Sun Microsystems - Beijing China u32 pipeconf;
796d0231070Smiao chen - Sun Microsystems - Beijing China
7970035d21cSmiao chen - Sun Microsystems - Beijing China pipeconf = I915_READ(pipeconf_reg);
7980035d21cSmiao chen - Sun Microsystems - Beijing China if (!(pipeconf & PIPEACONF_ENABLE))
7990035d21cSmiao chen - Sun Microsystems - Beijing China return -EINVAL;
800d0231070Smiao chen - Sun Microsystems - Beijing China
8010035d21cSmiao chen - Sun Microsystems - Beijing China spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
802*2e6e901dSmiao chen - Sun Microsystems - Beijing China if (IS_IGDNG(dev))
803*2e6e901dSmiao chen - Sun Microsystems - Beijing China igdng_enable_vblank(dev, pipe);
804*2e6e901dSmiao chen - Sun Microsystems - Beijing China else if (IS_I965G(dev))
8050035d21cSmiao chen - Sun Microsystems - Beijing China i915_enable_pipestat(dev_priv, pipe,
8060035d21cSmiao chen - Sun Microsystems - Beijing China PIPE_START_VBLANK_INTERRUPT_ENABLE);
807d0231070Smiao chen - Sun Microsystems - Beijing China else
8080035d21cSmiao chen - Sun Microsystems - Beijing China i915_enable_pipestat(dev_priv, pipe,
8090035d21cSmiao chen - Sun Microsystems - Beijing China PIPE_VBLANK_INTERRUPT_ENABLE);
8100035d21cSmiao chen - Sun Microsystems - Beijing China spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags);
811d0231070Smiao chen - Sun Microsystems - Beijing China
812d0231070Smiao chen - Sun Microsystems - Beijing China return 0;
813d0231070Smiao chen - Sun Microsystems - Beijing China }
814d0231070Smiao chen - Sun Microsystems - Beijing China
i915_disable_vblank(struct drm_device * dev,int pipe)8150035d21cSmiao chen - Sun Microsystems - Beijing China void i915_disable_vblank(struct drm_device *dev, int pipe)
816e92e3a86Szw161486 {
817e92e3a86Szw161486 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
818e92e3a86Szw161486
8190035d21cSmiao chen - Sun Microsystems - Beijing China spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
820*2e6e901dSmiao chen - Sun Microsystems - Beijing China if (IS_IGDNG(dev))
821*2e6e901dSmiao chen - Sun Microsystems - Beijing China igdng_disable_vblank(dev, pipe);
822*2e6e901dSmiao chen - Sun Microsystems - Beijing China else
8230035d21cSmiao chen - Sun Microsystems - Beijing China i915_disable_pipestat(dev_priv, pipe,
8240035d21cSmiao chen - Sun Microsystems - Beijing China PIPE_VBLANK_INTERRUPT_ENABLE |
8250035d21cSmiao chen - Sun Microsystems - Beijing China PIPE_START_VBLANK_INTERRUPT_ENABLE);
8260035d21cSmiao chen - Sun Microsystems - Beijing China spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags);
827e92e3a86Szw161486 }
828e92e3a86Szw161486
829d0231070Smiao chen - Sun Microsystems - Beijing China /* Set the vblank monitor pipe
830d0231070Smiao chen - Sun Microsystems - Beijing China */
831d0231070Smiao chen - Sun Microsystems - Beijing China /*ARGSUSED*/
i915_vblank_pipe_set(DRM_IOCTL_ARGS)832d0231070Smiao chen - Sun Microsystems - Beijing China int i915_vblank_pipe_set(DRM_IOCTL_ARGS)
833d0231070Smiao chen - Sun Microsystems - Beijing China {
834d0231070Smiao chen - Sun Microsystems - Beijing China DRM_DEVICE;
835d0231070Smiao chen - Sun Microsystems - Beijing China drm_i915_private_t *dev_priv = dev->dev_private;
836d0231070Smiao chen - Sun Microsystems - Beijing China
837d0231070Smiao chen - Sun Microsystems - Beijing China if (!dev_priv) {
838d0231070Smiao chen - Sun Microsystems - Beijing China DRM_ERROR("called with no initialization\n");
839d0231070Smiao chen - Sun Microsystems - Beijing China return (-EINVAL);
840d0231070Smiao chen - Sun Microsystems - Beijing China }
841d0231070Smiao chen - Sun Microsystems - Beijing China
842d0231070Smiao chen - Sun Microsystems - Beijing China return (0);
843d0231070Smiao chen - Sun Microsystems - Beijing China }
844d0231070Smiao chen - Sun Microsystems - Beijing China
845d0231070Smiao chen - Sun Microsystems - Beijing China /*ARGSUSED*/
i915_vblank_pipe_get(DRM_IOCTL_ARGS)846d0231070Smiao chen - Sun Microsystems - Beijing China int i915_vblank_pipe_get(DRM_IOCTL_ARGS)
847d0231070Smiao chen - Sun Microsystems - Beijing China {
848d0231070Smiao chen - Sun Microsystems - Beijing China DRM_DEVICE;
849d0231070Smiao chen - Sun Microsystems - Beijing China drm_i915_private_t *dev_priv = dev->dev_private;
850d0231070Smiao chen - Sun Microsystems - Beijing China drm_i915_vblank_pipe_t pipe;
851d0231070Smiao chen - Sun Microsystems - Beijing China
852d0231070Smiao chen - Sun Microsystems - Beijing China if (!dev_priv) {
853d0231070Smiao chen - Sun Microsystems - Beijing China DRM_ERROR("called with no initialization\n");
854d0231070Smiao chen - Sun Microsystems - Beijing China return -EINVAL;
855d0231070Smiao chen - Sun Microsystems - Beijing China }
856d0231070Smiao chen - Sun Microsystems - Beijing China
857d0231070Smiao chen - Sun Microsystems - Beijing China DRM_COPYFROM_WITH_RETURN(&pipe, (drm_i915_vblank_pipe_t __user *)data, sizeof (pipe));
858d0231070Smiao chen - Sun Microsystems - Beijing China
859d0231070Smiao chen - Sun Microsystems - Beijing China pipe.pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B;
860d0231070Smiao chen - Sun Microsystems - Beijing China
861d0231070Smiao chen - Sun Microsystems - Beijing China return 0;
862d0231070Smiao chen - Sun Microsystems - Beijing China }
863d0231070Smiao chen - Sun Microsystems - Beijing China
864d0231070Smiao chen - Sun Microsystems - Beijing China /**
865d0231070Smiao chen - Sun Microsystems - Beijing China * Schedule buffer swap at given vertical blank.
866d0231070Smiao chen - Sun Microsystems - Beijing China */
867d0231070Smiao chen - Sun Microsystems - Beijing China /*ARGSUSED*/
i915_vblank_swap(DRM_IOCTL_ARGS)868d0231070Smiao chen - Sun Microsystems - Beijing China int i915_vblank_swap(DRM_IOCTL_ARGS)
869d0231070Smiao chen - Sun Microsystems - Beijing China {
8700035d21cSmiao chen - Sun Microsystems - Beijing China /* The delayed swap mechanism was fundamentally racy, and has been
8710035d21cSmiao chen - Sun Microsystems - Beijing China * removed. The model was that the client requested a delayed flip/swap
8720035d21cSmiao chen - Sun Microsystems - Beijing China * from the kernel, then waited for vblank before continuing to perform
8730035d21cSmiao chen - Sun Microsystems - Beijing China * rendering. The problem was that the kernel might wake the client
8740035d21cSmiao chen - Sun Microsystems - Beijing China * up before it dispatched the vblank swap (since the lock has to be
8750035d21cSmiao chen - Sun Microsystems - Beijing China * held while touching the ringbuffer), in which case the client would
8760035d21cSmiao chen - Sun Microsystems - Beijing China * clear and start the next frame before the swap occurred, and
8770035d21cSmiao chen - Sun Microsystems - Beijing China * flicker would occur in addition to likely missing the vblank.
8780035d21cSmiao chen - Sun Microsystems - Beijing China *
8790035d21cSmiao chen - Sun Microsystems - Beijing China * In the absence of this ioctl, userland falls back to a correct path
8800035d21cSmiao chen - Sun Microsystems - Beijing China * of waiting for a vblank, then dispatching the swap on its own.
8810035d21cSmiao chen - Sun Microsystems - Beijing China * Context switching to userland and back is plenty fast enough for
8820035d21cSmiao chen - Sun Microsystems - Beijing China * meeting the requirements of vblank swapping.
883d0231070Smiao chen - Sun Microsystems - Beijing China */
884d0231070Smiao chen - Sun Microsystems - Beijing China return -EINVAL;
885d0231070Smiao chen - Sun Microsystems - Beijing China
886d0231070Smiao chen - Sun Microsystems - Beijing China }
887d0231070Smiao chen - Sun Microsystems - Beijing China
888ae115bc7Smrj /* drm_dma.h hooks
889ae115bc7Smrj */
890*2e6e901dSmiao chen - Sun Microsystems - Beijing China
igdng_irq_preinstall(struct drm_device * dev)891*2e6e901dSmiao chen - Sun Microsystems - Beijing China static void igdng_irq_preinstall(struct drm_device *dev)
892*2e6e901dSmiao chen - Sun Microsystems - Beijing China {
893*2e6e901dSmiao chen - Sun Microsystems - Beijing China drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
894*2e6e901dSmiao chen - Sun Microsystems - Beijing China
895*2e6e901dSmiao chen - Sun Microsystems - Beijing China I915_WRITE(HWSTAM, 0xeffe);
896*2e6e901dSmiao chen - Sun Microsystems - Beijing China
897*2e6e901dSmiao chen - Sun Microsystems - Beijing China /* XXX hotplug from PCH */
898*2e6e901dSmiao chen - Sun Microsystems - Beijing China
899*2e6e901dSmiao chen - Sun Microsystems - Beijing China I915_WRITE(DEIMR, 0xffffffff);
900*2e6e901dSmiao chen - Sun Microsystems - Beijing China I915_WRITE(DEIER, 0x0);
901*2e6e901dSmiao chen - Sun Microsystems - Beijing China (void) I915_READ(DEIER);
902*2e6e901dSmiao chen - Sun Microsystems - Beijing China
903*2e6e901dSmiao chen - Sun Microsystems - Beijing China /* and GT */
904*2e6e901dSmiao chen - Sun Microsystems - Beijing China I915_WRITE(GTIMR, 0xffffffff);
905*2e6e901dSmiao chen - Sun Microsystems - Beijing China I915_WRITE(GTIER, 0x0);
906*2e6e901dSmiao chen - Sun Microsystems - Beijing China (void) I915_READ(GTIER);
907*2e6e901dSmiao chen - Sun Microsystems - Beijing China }
908*2e6e901dSmiao chen - Sun Microsystems - Beijing China
igdng_irq_postinstall(struct drm_device * dev)909*2e6e901dSmiao chen - Sun Microsystems - Beijing China static int igdng_irq_postinstall(struct drm_device *dev)
910*2e6e901dSmiao chen - Sun Microsystems - Beijing China {
911*2e6e901dSmiao chen - Sun Microsystems - Beijing China drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
912*2e6e901dSmiao chen - Sun Microsystems - Beijing China /* enable kind of interrupts always enabled */
913*2e6e901dSmiao chen - Sun Microsystems - Beijing China u32 display_mask = DE_MASTER_IRQ_CONTROL /*| DE_PCH_EVENT */;
914*2e6e901dSmiao chen - Sun Microsystems - Beijing China u32 render_mask = GT_USER_INTERRUPT;
915*2e6e901dSmiao chen - Sun Microsystems - Beijing China
916*2e6e901dSmiao chen - Sun Microsystems - Beijing China dev_priv->irq_mask_reg = ~display_mask;
917*2e6e901dSmiao chen - Sun Microsystems - Beijing China dev_priv->de_irq_enable_reg = display_mask;
918*2e6e901dSmiao chen - Sun Microsystems - Beijing China
919*2e6e901dSmiao chen - Sun Microsystems - Beijing China /* should always can generate irq */
920*2e6e901dSmiao chen - Sun Microsystems - Beijing China I915_WRITE(DEIIR, I915_READ(DEIIR));
921*2e6e901dSmiao chen - Sun Microsystems - Beijing China (void) I915_READ(DEIIR);
922*2e6e901dSmiao chen - Sun Microsystems - Beijing China I915_WRITE(DEIMR, dev_priv->irq_mask_reg);
923*2e6e901dSmiao chen - Sun Microsystems - Beijing China I915_WRITE(DEIER, dev_priv->de_irq_enable_reg);
924*2e6e901dSmiao chen - Sun Microsystems - Beijing China (void) I915_READ(DEIER);
925*2e6e901dSmiao chen - Sun Microsystems - Beijing China
926*2e6e901dSmiao chen - Sun Microsystems - Beijing China /* user interrupt should be enabled, but masked initial */
927*2e6e901dSmiao chen - Sun Microsystems - Beijing China dev_priv->gt_irq_mask_reg = 0xffffffff;
928*2e6e901dSmiao chen - Sun Microsystems - Beijing China dev_priv->gt_irq_enable_reg = render_mask;
929*2e6e901dSmiao chen - Sun Microsystems - Beijing China
930*2e6e901dSmiao chen - Sun Microsystems - Beijing China I915_WRITE(GTIIR, I915_READ(GTIIR));
931*2e6e901dSmiao chen - Sun Microsystems - Beijing China (void) I915_READ(GTIIR);
932*2e6e901dSmiao chen - Sun Microsystems - Beijing China I915_WRITE(GTIMR, dev_priv->gt_irq_mask_reg);
933*2e6e901dSmiao chen - Sun Microsystems - Beijing China I915_WRITE(GTIER, dev_priv->gt_irq_enable_reg);
934*2e6e901dSmiao chen - Sun Microsystems - Beijing China (void) I915_READ(GTIER);
935*2e6e901dSmiao chen - Sun Microsystems - Beijing China
936*2e6e901dSmiao chen - Sun Microsystems - Beijing China return 0;
937*2e6e901dSmiao chen - Sun Microsystems - Beijing China }
938*2e6e901dSmiao chen - Sun Microsystems - Beijing China
igdng_irq_uninstall(struct drm_device * dev)939*2e6e901dSmiao chen - Sun Microsystems - Beijing China static void igdng_irq_uninstall(struct drm_device *dev)
940*2e6e901dSmiao chen - Sun Microsystems - Beijing China {
941*2e6e901dSmiao chen - Sun Microsystems - Beijing China drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
942*2e6e901dSmiao chen - Sun Microsystems - Beijing China I915_WRITE(HWSTAM, 0xffffffff);
943*2e6e901dSmiao chen - Sun Microsystems - Beijing China
944*2e6e901dSmiao chen - Sun Microsystems - Beijing China I915_WRITE(DEIMR, 0xffffffff);
945*2e6e901dSmiao chen - Sun Microsystems - Beijing China I915_WRITE(DEIER, 0x0);
946*2e6e901dSmiao chen - Sun Microsystems - Beijing China I915_WRITE(DEIIR, I915_READ(DEIIR));
947*2e6e901dSmiao chen - Sun Microsystems - Beijing China
948*2e6e901dSmiao chen - Sun Microsystems - Beijing China I915_WRITE(GTIMR, 0xffffffff);
949*2e6e901dSmiao chen - Sun Microsystems - Beijing China I915_WRITE(GTIER, 0x0);
950*2e6e901dSmiao chen - Sun Microsystems - Beijing China I915_WRITE(GTIIR, I915_READ(GTIIR));
951*2e6e901dSmiao chen - Sun Microsystems - Beijing China }
952*2e6e901dSmiao chen - Sun Microsystems - Beijing China
i915_driver_irq_preinstall(drm_device_t * dev)9530f7bfed6Smiao chen - Sun Microsystems - Beijing China int i915_driver_irq_preinstall(drm_device_t * dev)
954ae115bc7Smrj {
955ae115bc7Smrj drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
956ae115bc7Smrj
9570f7bfed6Smiao chen - Sun Microsystems - Beijing China if (!dev_priv->mmio_map)
9580f7bfed6Smiao chen - Sun Microsystems - Beijing China return -EINVAL;
9590f7bfed6Smiao chen - Sun Microsystems - Beijing China
960*2e6e901dSmiao chen - Sun Microsystems - Beijing China if (IS_IGDNG(dev)) {
961*2e6e901dSmiao chen - Sun Microsystems - Beijing China igdng_irq_preinstall(dev);
962*2e6e901dSmiao chen - Sun Microsystems - Beijing China return 0;
963*2e6e901dSmiao chen - Sun Microsystems - Beijing China }
964*2e6e901dSmiao chen - Sun Microsystems - Beijing China
9650035d21cSmiao chen - Sun Microsystems - Beijing China I915_WRITE16(HWSTAM, 0xeffe);
9660035d21cSmiao chen - Sun Microsystems - Beijing China I915_WRITE(PIPEASTAT, 0);
9670035d21cSmiao chen - Sun Microsystems - Beijing China I915_WRITE(PIPEBSTAT, 0);
968d0231070Smiao chen - Sun Microsystems - Beijing China I915_WRITE(IMR, 0xffffffff);
9690035d21cSmiao chen - Sun Microsystems - Beijing China I915_WRITE16(IER, 0x0);
9700035d21cSmiao chen - Sun Microsystems - Beijing China (void) I915_READ(IER);
9710f7bfed6Smiao chen - Sun Microsystems - Beijing China
9720f7bfed6Smiao chen - Sun Microsystems - Beijing China return 0;
973ae115bc7Smrj }
974ae115bc7Smrj
i915_driver_irq_postinstall(drm_device_t * dev)975ae115bc7Smrj void i915_driver_irq_postinstall(drm_device_t * dev)
976ae115bc7Smrj {
9770035d21cSmiao chen - Sun Microsystems - Beijing China int error_mask;
978ae115bc7Smrj drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
979ae115bc7Smrj
980d0231070Smiao chen - Sun Microsystems - Beijing China dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B;
981d0538f66Scg149915
982*2e6e901dSmiao chen - Sun Microsystems - Beijing China if (IS_IGDNG(dev)) {
983*2e6e901dSmiao chen - Sun Microsystems - Beijing China (void) igdng_irq_postinstall(dev);
984*2e6e901dSmiao chen - Sun Microsystems - Beijing China DRM_INIT_WAITQUEUE(&dev_priv->irq_queue, DRM_INTR_PRI(dev));
985*2e6e901dSmiao chen - Sun Microsystems - Beijing China return;
986*2e6e901dSmiao chen - Sun Microsystems - Beijing China }
987*2e6e901dSmiao chen - Sun Microsystems - Beijing China
9880035d21cSmiao chen - Sun Microsystems - Beijing China /* Unmask the interrupts that we always want on. */
9890035d21cSmiao chen - Sun Microsystems - Beijing China dev_priv->irq_mask_reg = ~I915_INTERRUPT_ENABLE_FIX;
9900035d21cSmiao chen - Sun Microsystems - Beijing China
9910035d21cSmiao chen - Sun Microsystems - Beijing China dev_priv->pipestat[0] = 0;
9920035d21cSmiao chen - Sun Microsystems - Beijing China dev_priv->pipestat[1] = 0;
9930035d21cSmiao chen - Sun Microsystems - Beijing China
9940035d21cSmiao chen - Sun Microsystems - Beijing China /*
9950035d21cSmiao chen - Sun Microsystems - Beijing China * Enable some error detection, note the instruction error mask
9960035d21cSmiao chen - Sun Microsystems - Beijing China * bit is reserved, so we leave it masked.
9970035d21cSmiao chen - Sun Microsystems - Beijing China */
9980035d21cSmiao chen - Sun Microsystems - Beijing China if (IS_G4X(dev)) {
9990035d21cSmiao chen - Sun Microsystems - Beijing China error_mask = ~(GM45_ERROR_PAGE_TABLE |
10000035d21cSmiao chen - Sun Microsystems - Beijing China GM45_ERROR_MEM_PRIV |
10010035d21cSmiao chen - Sun Microsystems - Beijing China GM45_ERROR_CP_PRIV |
10020035d21cSmiao chen - Sun Microsystems - Beijing China I915_ERROR_MEMORY_REFRESH);
10030035d21cSmiao chen - Sun Microsystems - Beijing China } else {
10040035d21cSmiao chen - Sun Microsystems - Beijing China error_mask = ~(I915_ERROR_PAGE_TABLE |
10050035d21cSmiao chen - Sun Microsystems - Beijing China I915_ERROR_MEMORY_REFRESH);
10060035d21cSmiao chen - Sun Microsystems - Beijing China }
10070035d21cSmiao chen - Sun Microsystems - Beijing China I915_WRITE(EMR, error_mask);
10080035d21cSmiao chen - Sun Microsystems - Beijing China
10090035d21cSmiao chen - Sun Microsystems - Beijing China /* Disable pipe interrupt enables, clear pending pipe status */
10100035d21cSmiao chen - Sun Microsystems - Beijing China I915_WRITE(PIPEASTAT, I915_READ(PIPEASTAT) & 0x8000ffff);
10110035d21cSmiao chen - Sun Microsystems - Beijing China I915_WRITE(PIPEBSTAT, I915_READ(PIPEBSTAT) & 0x8000ffff);
1012*2e6e901dSmiao chen - Sun Microsystems - Beijing China (void) I915_READ(PIPEASTAT);
1013*2e6e901dSmiao chen - Sun Microsystems - Beijing China (void) I915_READ(PIPEBSTAT);
10140035d21cSmiao chen - Sun Microsystems - Beijing China /* Clear pending interrupt status */
10150035d21cSmiao chen - Sun Microsystems - Beijing China I915_WRITE(IIR, I915_READ(IIR));
10160035d21cSmiao chen - Sun Microsystems - Beijing China
1017*2e6e901dSmiao chen - Sun Microsystems - Beijing China (void) I915_READ(IIR);
10180035d21cSmiao chen - Sun Microsystems - Beijing China I915_WRITE(IMR, dev_priv->irq_mask_reg);
10190035d21cSmiao chen - Sun Microsystems - Beijing China I915_WRITE(IER, I915_INTERRUPT_ENABLE_MASK);
10200035d21cSmiao chen - Sun Microsystems - Beijing China (void) I915_READ(IER);
1021d0538f66Scg149915
1022d0231070Smiao chen - Sun Microsystems - Beijing China DRM_INIT_WAITQUEUE(&dev_priv->irq_queue, DRM_INTR_PRI(dev));
1023e92e3a86Szw161486
1024d0231070Smiao chen - Sun Microsystems - Beijing China return;
1025ae115bc7Smrj }
1026ae115bc7Smrj
i915_driver_irq_uninstall(drm_device_t * dev)1027ae115bc7Smrj void i915_driver_irq_uninstall(drm_device_t * dev)
1028ae115bc7Smrj {
1029ae115bc7Smrj drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
10300035d21cSmiao chen - Sun Microsystems - Beijing China if ((!dev_priv) || (dev->irq_enabled == 0))
1031ae115bc7Smrj return;
1032ae115bc7Smrj
1033d0231070Smiao chen - Sun Microsystems - Beijing China dev_priv->vblank_pipe = 0;
1034e92e3a86Szw161486
1035*2e6e901dSmiao chen - Sun Microsystems - Beijing China if (IS_IGDNG(dev)) {
1036*2e6e901dSmiao chen - Sun Microsystems - Beijing China igdng_irq_uninstall(dev);
1037*2e6e901dSmiao chen - Sun Microsystems - Beijing China DRM_FINI_WAITQUEUE(&dev_priv->irq_queue);
1038*2e6e901dSmiao chen - Sun Microsystems - Beijing China return;
1039*2e6e901dSmiao chen - Sun Microsystems - Beijing China }
1040*2e6e901dSmiao chen - Sun Microsystems - Beijing China
1041d0231070Smiao chen - Sun Microsystems - Beijing China I915_WRITE(HWSTAM, 0xffffffff);
10420035d21cSmiao chen - Sun Microsystems - Beijing China I915_WRITE(PIPEASTAT, 0);
10430035d21cSmiao chen - Sun Microsystems - Beijing China I915_WRITE(PIPEBSTAT, 0);
1044d0231070Smiao chen - Sun Microsystems - Beijing China I915_WRITE(IMR, 0xffffffff);
1045d0231070Smiao chen - Sun Microsystems - Beijing China I915_WRITE(IER, 0x0);
1046d0538f66Scg149915
10470035d21cSmiao chen - Sun Microsystems - Beijing China I915_WRITE(PIPEASTAT, I915_READ(PIPEASTAT) & 0x8000ffff);
10480035d21cSmiao chen - Sun Microsystems - Beijing China I915_WRITE(PIPEBSTAT, I915_READ(PIPEBSTAT) & 0x8000ffff);
10490035d21cSmiao chen - Sun Microsystems - Beijing China I915_WRITE(IIR, I915_READ(IIR));
1050d0538f66Scg149915
10510035d21cSmiao chen - Sun Microsystems - Beijing China DRM_FINI_WAITQUEUE(&dev_priv->irq_queue);
1052ae115bc7Smrj }
1053