• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6.36/drivers/gpu/drm/radeon/
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 "drmP.h"
34#include "drm.h"
35#include "radeon_drm.h"
36#include "radeon_drv.h"
37
38void radeon_irq_set_state(struct drm_device *dev, u32 mask, int state)
39{
40	drm_radeon_private_t *dev_priv = dev->dev_private;
41
42	if (state)
43		dev_priv->irq_enable_reg |= mask;
44	else
45		dev_priv->irq_enable_reg &= ~mask;
46
47	if (dev->irq_enabled)
48		RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg);
49}
50
51static void r500_vbl_irq_set_state(struct drm_device *dev, u32 mask, int state)
52{
53	drm_radeon_private_t *dev_priv = dev->dev_private;
54
55	if (state)
56		dev_priv->r500_disp_irq_reg |= mask;
57	else
58		dev_priv->r500_disp_irq_reg &= ~mask;
59
60	if (dev->irq_enabled)
61		RADEON_WRITE(R500_DxMODE_INT_MASK, dev_priv->r500_disp_irq_reg);
62}
63
64int radeon_enable_vblank(struct drm_device *dev, int crtc)
65{
66	drm_radeon_private_t *dev_priv = dev->dev_private;
67
68	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) {
69		switch (crtc) {
70		case 0:
71			r500_vbl_irq_set_state(dev, R500_D1MODE_INT_MASK, 1);
72			break;
73		case 1:
74			r500_vbl_irq_set_state(dev, R500_D2MODE_INT_MASK, 1);
75			break;
76		default:
77			DRM_ERROR("tried to enable vblank on non-existent crtc %d\n",
78				  crtc);
79			return EINVAL;
80		}
81	} else {
82		switch (crtc) {
83		case 0:
84			radeon_irq_set_state(dev, RADEON_CRTC_VBLANK_MASK, 1);
85			break;
86		case 1:
87			radeon_irq_set_state(dev, RADEON_CRTC2_VBLANK_MASK, 1);
88			break;
89		default:
90			DRM_ERROR("tried to enable vblank on non-existent crtc %d\n",
91				  crtc);
92			return EINVAL;
93		}
94	}
95
96	return 0;
97}
98
99void radeon_disable_vblank(struct drm_device *dev, int crtc)
100{
101	drm_radeon_private_t *dev_priv = dev->dev_private;
102
103	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) {
104		switch (crtc) {
105		case 0:
106			r500_vbl_irq_set_state(dev, R500_D1MODE_INT_MASK, 0);
107			break;
108		case 1:
109			r500_vbl_irq_set_state(dev, R500_D2MODE_INT_MASK, 0);
110			break;
111		default:
112			DRM_ERROR("tried to enable vblank on non-existent crtc %d\n",
113				  crtc);
114			break;
115		}
116	} else {
117		switch (crtc) {
118		case 0:
119			radeon_irq_set_state(dev, RADEON_CRTC_VBLANK_MASK, 0);
120			break;
121		case 1:
122			radeon_irq_set_state(dev, RADEON_CRTC2_VBLANK_MASK, 0);
123			break;
124		default:
125			DRM_ERROR("tried to enable vblank on non-existent crtc %d\n",
126				  crtc);
127			break;
128		}
129	}
130}
131
132static inline u32 radeon_acknowledge_irqs(drm_radeon_private_t *dev_priv, u32 *r500_disp_int)
133{
134	u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS);
135	u32 irq_mask = RADEON_SW_INT_TEST;
136
137	*r500_disp_int = 0;
138	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) {
139		/* vbl interrupts in a different place */
140
141		if (irqs & R500_DISPLAY_INT_STATUS) {
142			/* if a display interrupt */
143			u32 disp_irq;
144
145			disp_irq = RADEON_READ(R500_DISP_INTERRUPT_STATUS);
146
147			*r500_disp_int = disp_irq;
148			if (disp_irq & R500_D1_VBLANK_INTERRUPT)
149				RADEON_WRITE(R500_D1MODE_VBLANK_STATUS, R500_VBLANK_ACK);
150			if (disp_irq & R500_D2_VBLANK_INTERRUPT)
151				RADEON_WRITE(R500_D2MODE_VBLANK_STATUS, R500_VBLANK_ACK);
152		}
153		irq_mask |= R500_DISPLAY_INT_STATUS;
154	} else
155		irq_mask |= RADEON_CRTC_VBLANK_STAT | RADEON_CRTC2_VBLANK_STAT;
156
157	irqs &=	irq_mask;
158
159	if (irqs)
160		RADEON_WRITE(RADEON_GEN_INT_STATUS, irqs);
161
162	return irqs;
163}
164
165/* Interrupts - Used for device synchronization and flushing in the
166 * following circumstances:
167 *
168 * - Exclusive FB access with hw idle:
169 *    - Wait for GUI Idle (?) interrupt, then do normal flush.
170 *
171 * - Frame throttling, NV_fence:
172 *    - Drop marker irq's into command stream ahead of time.
173 *    - Wait on irq's with lock *not held*
174 *    - Check each for termination condition
175 *
176 * - Internally in cp_getbuffer, etc:
177 *    - as above, but wait with lock held???
178 *
179 * NOTE: These functions are misleadingly named -- the irq's aren't
180 * tied to dma at all, this is just a hangover from dri prehistory.
181 */
182
183irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS)
184{
185	struct drm_device *dev = (struct drm_device *) arg;
186	drm_radeon_private_t *dev_priv =
187	    (drm_radeon_private_t *) dev->dev_private;
188	u32 stat;
189	u32 r500_disp_int;
190
191	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
192		return IRQ_NONE;
193
194	/* Only consider the bits we're interested in - others could be used
195	 * outside the DRM
196	 */
197	stat = radeon_acknowledge_irqs(dev_priv, &r500_disp_int);
198	if (!stat)
199		return IRQ_NONE;
200
201	stat &= dev_priv->irq_enable_reg;
202
203	/* SW interrupt */
204	if (stat & RADEON_SW_INT_TEST)
205		DRM_WAKEUP(&dev_priv->swi_queue);
206
207	/* VBLANK interrupt */
208	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) {
209		if (r500_disp_int & R500_D1_VBLANK_INTERRUPT)
210			drm_handle_vblank(dev, 0);
211		if (r500_disp_int & R500_D2_VBLANK_INTERRUPT)
212			drm_handle_vblank(dev, 1);
213	} else {
214		if (stat & RADEON_CRTC_VBLANK_STAT)
215			drm_handle_vblank(dev, 0);
216		if (stat & RADEON_CRTC2_VBLANK_STAT)
217			drm_handle_vblank(dev, 1);
218	}
219	return IRQ_HANDLED;
220}
221
222static int radeon_emit_irq(struct drm_device * dev)
223{
224	drm_radeon_private_t *dev_priv = dev->dev_private;
225	unsigned int ret;
226	RING_LOCALS;
227
228	atomic_inc(&dev_priv->swi_emitted);
229	ret = atomic_read(&dev_priv->swi_emitted);
230
231	BEGIN_RING(4);
232	OUT_RING_REG(RADEON_LAST_SWI_REG, ret);
233	OUT_RING_REG(RADEON_GEN_INT_STATUS, RADEON_SW_INT_FIRE);
234	ADVANCE_RING();
235	COMMIT_RING();
236
237	return ret;
238}
239
240static int radeon_wait_irq(struct drm_device * dev, int swi_nr)
241{
242	drm_radeon_private_t *dev_priv =
243	    (drm_radeon_private_t *) dev->dev_private;
244	int ret = 0;
245
246	if (RADEON_READ(RADEON_LAST_SWI_REG) >= swi_nr)
247		return 0;
248
249	dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
250
251	DRM_WAIT_ON(ret, dev_priv->swi_queue, 3 * DRM_HZ,
252		    RADEON_READ(RADEON_LAST_SWI_REG) >= swi_nr);
253
254	return ret;
255}
256
257u32 radeon_get_vblank_counter(struct drm_device *dev, int crtc)
258{
259	drm_radeon_private_t *dev_priv = dev->dev_private;
260
261	if (!dev_priv) {
262		DRM_ERROR("called with no initialization\n");
263		return -EINVAL;
264	}
265
266	if (crtc < 0 || crtc > 1) {
267		DRM_ERROR("Invalid crtc %d\n", crtc);
268		return -EINVAL;
269	}
270
271	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) {
272		if (crtc == 0)
273			return RADEON_READ(R500_D1CRTC_FRAME_COUNT);
274		else
275			return RADEON_READ(R500_D2CRTC_FRAME_COUNT);
276	} else {
277		if (crtc == 0)
278			return RADEON_READ(RADEON_CRTC_CRNT_FRAME);
279		else
280			return RADEON_READ(RADEON_CRTC2_CRNT_FRAME);
281	}
282}
283
284/* Needs the lock as it touches the ring.
285 */
286int radeon_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_priv)
287{
288	drm_radeon_private_t *dev_priv = dev->dev_private;
289	drm_radeon_irq_emit_t *emit = data;
290	int result;
291
292	if (!dev_priv) {
293		DRM_ERROR("called with no initialization\n");
294		return -EINVAL;
295	}
296
297	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
298		return -EINVAL;
299
300	LOCK_TEST_WITH_RETURN(dev, file_priv);
301
302	result = radeon_emit_irq(dev);
303
304	if (DRM_COPY_TO_USER(emit->irq_seq, &result, sizeof(int))) {
305		DRM_ERROR("copy_to_user\n");
306		return -EFAULT;
307	}
308
309	return 0;
310}
311
312/* Doesn't need the hardware lock.
313 */
314int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_priv)
315{
316	drm_radeon_private_t *dev_priv = dev->dev_private;
317	drm_radeon_irq_wait_t *irqwait = data;
318
319	if (!dev_priv) {
320		DRM_ERROR("called with no initialization\n");
321		return -EINVAL;
322	}
323
324	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
325		return -EINVAL;
326
327	return radeon_wait_irq(dev, irqwait->irq_seq);
328}
329
330/* drm_dma.h hooks
331*/
332void radeon_driver_irq_preinstall(struct drm_device * dev)
333{
334	drm_radeon_private_t *dev_priv =
335	    (drm_radeon_private_t *) dev->dev_private;
336	u32 dummy;
337
338	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
339		return;
340
341	/* Disable *all* interrupts */
342	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600)
343		RADEON_WRITE(R500_DxMODE_INT_MASK, 0);
344	RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
345
346	/* Clear bits if they're already high */
347	radeon_acknowledge_irqs(dev_priv, &dummy);
348}
349
350int radeon_driver_irq_postinstall(struct drm_device *dev)
351{
352	drm_radeon_private_t *dev_priv =
353	    (drm_radeon_private_t *) dev->dev_private;
354
355	atomic_set(&dev_priv->swi_emitted, 0);
356	DRM_INIT_WAITQUEUE(&dev_priv->swi_queue);
357
358	dev->max_vblank_count = 0x001fffff;
359
360	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
361		return 0;
362
363	radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1);
364
365	return 0;
366}
367
368void radeon_driver_irq_uninstall(struct drm_device * dev)
369{
370	drm_radeon_private_t *dev_priv =
371	    (drm_radeon_private_t *) dev->dev_private;
372	if (!dev_priv)
373		return;
374
375	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
376		return;
377
378	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600)
379		RADEON_WRITE(R500_DxMODE_INT_MASK, 0);
380	/* Disable *all* interrupts */
381	RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
382}
383
384
385int radeon_vblank_crtc_get(struct drm_device *dev)
386{
387	drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private;
388
389	return dev_priv->vblank_crtc;
390}
391
392int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value)
393{
394	drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private;
395	if (value & ~(DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) {
396		DRM_ERROR("called with invalid crtc 0x%x\n", (unsigned int)value);
397		return -EINVAL;
398	}
399	dev_priv->vblank_crtc = (unsigned int)value;
400	return 0;
401}
402