2 * Copyright (C) 2006 Ben Skeggs.
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sublicense, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial
16 * portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
22 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 * Ben Skeggs <darktama@iinet.net.au>
35 #include "nouveau_drm.h"
36 #include "nouveau_drv.h"
37 #include "nouveau_reg.h"
39 void nouveau_irq_preinstall(struct drm_device *dev)
41 struct drm_nouveau_private *dev_priv = dev->dev_private;
43 DRM_DEBUG("IRQ: preinst\n");
46 DRM_ERROR("AIII, no dev_priv\n");
49 if (!dev_priv->mmio) {
50 DRM_ERROR("AIII, no dev_priv->mmio\n");
54 /* Disable/Clear PFIFO interrupts */
55 NV_WRITE(NV03_PFIFO_INTR_EN_0, 0);
56 NV_WRITE(NV03_PFIFO_INTR_0, 0xFFFFFFFF);
57 /* Disable/Clear PGRAPH interrupts */
58 if (dev_priv->card_type<NV_40)
59 NV_WRITE(NV03_PGRAPH_INTR_EN, 0);
61 NV_WRITE(NV40_PGRAPH_INTR_EN, 0);
62 NV_WRITE(NV03_PGRAPH_INTR, 0xFFFFFFFF);
64 /* Disable/Clear CRTC0/1 interrupts */
65 NV_WRITE(NV_CRTC0_INTEN, 0);
66 NV_WRITE(NV_CRTC0_INTSTAT, NV_CRTC_INTR_VBLANK);
67 NV_WRITE(NV_CRTC1_INTEN, 0);
68 NV_WRITE(NV_CRTC1_INTSTAT, NV_CRTC_INTR_VBLANK);
71 NV_WRITE(NV03_PMC_INTR_EN_0, 0);
74 void nouveau_irq_postinstall(struct drm_device *dev)
76 struct drm_nouveau_private *dev_priv = dev->dev_private;
79 DRM_ERROR("AIII, no dev_priv\n");
82 if (!dev_priv->mmio) {
83 DRM_ERROR("AIII, no dev_priv->mmio\n");
87 DRM_DEBUG("IRQ: postinst\n");
89 /* Enable PFIFO error reporting */
90 NV_WRITE(NV03_PFIFO_INTR_EN_0, 0xFFFFFFFF);
91 NV_WRITE(NV03_PFIFO_INTR_0, 0xFFFFFFFF);
93 /* Enable PGRAPH interrupts */
94 if (dev_priv->card_type<NV_40)
95 NV_WRITE(NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);
97 NV_WRITE(NV40_PGRAPH_INTR_EN, 0xFFFFFFFF);
98 NV_WRITE(NV03_PGRAPH_INTR, 0xFFFFFFFF);
101 /* Enable CRTC0/1 interrupts */
102 NV_WRITE(NV_CRTC0_INTEN, NV_CRTC_INTR_VBLANK);
103 NV_WRITE(NV_CRTC1_INTEN, NV_CRTC_INTR_VBLANK);
107 NV_WRITE(NV03_PMC_INTR_EN_0, NV_PMC_INTR_EN_0_MASTER_ENABLE);
110 void nouveau_irq_uninstall(struct drm_device *dev)
112 struct drm_nouveau_private *dev_priv = dev->dev_private;
115 DRM_ERROR("AIII, no dev_priv\n");
118 if (!dev_priv->mmio) {
119 DRM_ERROR("AIII, no dev_priv->mmio\n");
123 DRM_DEBUG("IRQ: uninst\n");
125 /* Disable PFIFO interrupts */
126 NV_WRITE(NV03_PFIFO_INTR_EN_0, 0);
127 /* Disable PGRAPH interrupts */
128 if (dev_priv->card_type<NV_40)
129 NV_WRITE(NV03_PGRAPH_INTR_EN, 0);
131 NV_WRITE(NV40_PGRAPH_INTR_EN, 0);
133 /* Disable CRTC0/1 interrupts */
134 NV_WRITE(NV_CRTC0_INTEN, 0);
135 NV_WRITE(NV_CRTC1_INTEN, 0);
138 NV_WRITE(NV03_PMC_INTR_EN_0, 0);
141 static void nouveau_fifo_irq_handler(struct drm_device *dev)
143 uint32_t status, chmode, chstat, channel;
144 struct drm_nouveau_private *dev_priv = dev->dev_private;
146 status = NV_READ(NV03_PFIFO_INTR_0);
149 chmode = NV_READ(NV04_PFIFO_MODE);
150 chstat = NV_READ(NV04_PFIFO_DMA);
151 channel=NV_READ(NV03_PFIFO_CACHE1_PUSH1)&(nouveau_fifo_number(dev)-1);
153 DRM_DEBUG("NV: PFIFO interrupt! Channel=%d, INTSTAT=0x%08x/MODE=0x%08x/PEND=0x%08x\n", channel, status, chmode, chstat);
155 if (status & NV_PFIFO_INTR_CACHE_ERROR) {
156 uint32_t c1get, c1method, c1data;
158 DRM_ERROR("NV: PFIFO error interrupt\n");
160 c1get = NV_READ(NV03_PFIFO_CACHE1_GET) >> 2;
161 if (dev_priv->card_type < NV_40) {
162 /* Untested, so it may not work.. */
163 c1method = NV_READ(NV04_PFIFO_CACHE1_METHOD(c1get));
164 c1data = NV_READ(NV04_PFIFO_CACHE1_DATA(c1get));
166 c1method = NV_READ(NV40_PFIFO_CACHE1_METHOD(c1get));
167 c1data = NV_READ(NV40_PFIFO_CACHE1_DATA(c1get));
170 DRM_ERROR("NV: Channel %d/%d - Method 0x%04x, Data 0x%08x\n",
171 channel, (c1method >> 13) & 7,
172 c1method & 0x1ffc, c1data
175 status &= ~NV_PFIFO_INTR_CACHE_ERROR;
176 NV_WRITE(NV03_PFIFO_INTR_0, NV_PFIFO_INTR_CACHE_ERROR);
179 if (status & NV_PFIFO_INTR_DMA_PUSHER) {
180 DRM_INFO("NV: PFIFO DMA pusher interrupt\n");
182 status &= ~NV_PFIFO_INTR_DMA_PUSHER;
183 NV_WRITE(NV03_PFIFO_INTR_0, NV_PFIFO_INTR_DMA_PUSHER);
185 NV_WRITE(NV04_PFIFO_CACHE1_DMA_STATE, 0x00000000);
186 if (NV_READ(NV04_PFIFO_CACHE1_DMA_PUT)!=NV_READ(NV04_PFIFO_CACHE1_DMA_GET))
188 uint32_t getval=NV_READ(NV04_PFIFO_CACHE1_DMA_GET)+4;
189 NV_WRITE(NV04_PFIFO_CACHE1_DMA_GET,getval);
194 DRM_INFO("NV: unknown PFIFO interrupt. status=0x%08x\n", status);
196 NV_WRITE(NV03_PFIFO_INTR_0, status);
199 NV_WRITE(NV03_PMC_INTR_0, NV_PMC_INTR_0_PFIFO_PENDING);
203 static void nouveau_nv04_context_switch(struct drm_device *dev)
205 struct drm_nouveau_private *dev_priv = dev->dev_private;
208 NV_WRITE(NV04_PGRAPH_FIFO,0x0);
209 channel=NV_READ(NV03_PFIFO_CACHE1_PUSH1)&(nouveau_fifo_number(dev)-1);
210 //DRM_INFO("raw PFIFO_CACH1_PHS1 reg is %x\n",NV_READ(NV03_PFIFO_CACHE1_PUSH1));
211 //DRM_INFO("currently on channel %d\n",channel);
212 for (i=0;i<nouveau_fifo_number(dev);i++)
213 if ((dev_priv->fifos[i].used)&&(i!=channel)) {
214 uint32_t put,get,pending;
215 //put=NV_READ(dev_priv->ramfc_offset+i*32);
216 //get=NV_READ(dev_priv->ramfc_offset+4+i*32);
217 put=NV_READ(NV03_FIFO_REGS_DMAPUT(i));
218 get=NV_READ(NV03_FIFO_REGS_DMAGET(i));
219 pending=NV_READ(NV04_PFIFO_DMA);
220 //DRM_INFO("Channel %d (put/get %x/%x)\n",i,put,get);
221 /* mark all pending channels as such */
222 if ((put!=get)&!(pending&(1<<i)))
225 NV_WRITE(NV04_PFIFO_DMA,pending);
229 nouveau_wait_for_idle(dev);
232 /* 2-channel commute */
233 // NV_WRITE(NV03_PFIFO_CACHE1_PUSH1,channel|0x100);
238 // dev_priv->cur_fifo=channel;
239 NV_WRITE(NV04_PFIFO_NEXT_CHANNEL,channel|0x100);
241 //NV_WRITE(NV03_PFIFO_CACHE1_PUSH1,max|0x100);
242 //NV_WRITE(0x2050,max|0x100);
244 NV_WRITE(NV04_PGRAPH_FIFO,0x1);
250 struct nouveau_bitfield_names
256 static struct nouveau_bitfield_names nouveau_nstatus_names[] =
258 { NV03_PGRAPH_NSTATUS_STATE_IN_USE, "STATE_IN_USE" },
259 { NV03_PGRAPH_NSTATUS_INVALID_STATE, "INVALID_STATE" },
260 { NV03_PGRAPH_NSTATUS_BAD_ARGUMENT, "BAD_ARGUMENT" },
261 { NV03_PGRAPH_NSTATUS_PROTECTION_FAULT, "PROTECTION_FAULT" }
264 static struct nouveau_bitfield_names nouveau_nsource_names[] =
266 { NV03_PGRAPH_NSOURCE_NOTIFICATION, "NOTIFICATION" },
267 { NV03_PGRAPH_NSOURCE_DATA_ERROR, "DATA_ERROR" },
268 { NV03_PGRAPH_NSOURCE_PROTECTION_ERROR, "PROTECTION_ERROR" },
269 { NV03_PGRAPH_NSOURCE_RANGE_EXCEPTION, "RANGE_EXCEPTION" },
270 { NV03_PGRAPH_NSOURCE_LIMIT_COLOR, "LIMIT_COLOR" },
271 { NV03_PGRAPH_NSOURCE_LIMIT_ZETA, "LIMIT_ZETA" },
272 { NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD, "ILLEGAL_MTHD" },
273 { NV03_PGRAPH_NSOURCE_DMA_R_PROTECTION, "DMA_R_PROTECTION" },
274 { NV03_PGRAPH_NSOURCE_DMA_W_PROTECTION, "DMA_W_PROTECTION" },
275 { NV03_PGRAPH_NSOURCE_FORMAT_EXCEPTION, "FORMAT_EXCEPTION" },
276 { NV03_PGRAPH_NSOURCE_PATCH_EXCEPTION, "PATCH_EXCEPTION" },
277 { NV03_PGRAPH_NSOURCE_STATE_INVALID, "STATE_INVALID" },
278 { NV03_PGRAPH_NSOURCE_DOUBLE_NOTIFY, "DOUBLE_NOTIFY" },
279 { NV03_PGRAPH_NSOURCE_NOTIFY_IN_USE, "NOTIFY_IN_USE" },
280 { NV03_PGRAPH_NSOURCE_METHOD_CNT, "METHOD_CNT" },
281 { NV03_PGRAPH_NSOURCE_BFR_NOTIFICATION, "BFR_NOTIFICATION" },
282 { NV03_PGRAPH_NSOURCE_DMA_VTX_PROTECTION, "DMA_VTX_PROTECTION" },
283 { NV03_PGRAPH_NSOURCE_DMA_WIDTH_A, "DMA_WIDTH_A" },
284 { NV03_PGRAPH_NSOURCE_DMA_WIDTH_B, "DMA_WIDTH_B" },
288 nouveau_print_bitfield_names(uint32_t value,
289 const struct nouveau_bitfield_names *namelist,
290 const int namelist_len)
293 for(i=0; i<namelist_len; ++i) {
294 uint32_t mask = namelist[i].mask;
296 printk(" %s", namelist[i].name);
301 printk(" (unknown bits 0x%08x)", value);
305 nouveau_graph_dump_trap_info(struct drm_device *dev)
307 struct drm_nouveau_private *dev_priv = dev->dev_private;
309 uint32_t channel, class;
310 uint32_t method, subc, data;
311 uint32_t nsource, nstatus;
313 address = NV_READ(0x400704);
314 channel = (address >> 20) & 0x1F;
315 subc = (address >> 16) & 0x7;
316 method = address & 0x1FFC;
317 data = NV_READ(0x400708);
318 nsource = NV_READ(NV03_PGRAPH_NSOURCE);
319 nstatus = NV_READ(NV03_PGRAPH_NSTATUS);
320 if (dev_priv->card_type < NV_50) {
321 class = NV_READ(0x400160 + subc*4) & 0xFFFF;
323 class = NV_READ(0x400814);
326 DRM_ERROR("nSource:");
327 nouveau_print_bitfield_names(nsource, nouveau_nsource_names,
328 ARRAY_SIZE(nouveau_nsource_names));
329 printk(", nStatus:");
330 nouveau_print_bitfield_names(nstatus, nouveau_nstatus_names,
331 ARRAY_SIZE(nouveau_nstatus_names));
334 DRM_ERROR("NV: Channel %d/%d (class 0x%04x) - "
335 "Method 0x%04x, Data 0x%08x\n",
336 channel, subc, class, method, data
340 static void nouveau_pgraph_irq_handler(struct drm_device *dev)
343 struct drm_nouveau_private *dev_priv = dev->dev_private;
345 status = NV_READ(NV03_PGRAPH_INTR);
349 if (status & NV_PGRAPH_INTR_NOTIFY) {
350 uint32_t nsource, nstatus, instance, notify;
351 DRM_DEBUG("NV: PGRAPH notify interrupt\n");
353 nstatus = NV_READ(NV03_PGRAPH_NSTATUS);
354 nsource = NV_READ(NV03_PGRAPH_NSOURCE);
355 DRM_DEBUG("nsource:0x%08x\tnstatus:0x%08x\n", nsource, nstatus);
357 /* if this wasn't NOTIFICATION_PENDING, dump extra trap info */
358 if (nsource & ~(1<<0)) {
359 nouveau_graph_dump_trap_info(dev);
361 instance = NV_READ(0x00400158);
362 notify = NV_READ(0x00400150) >> 16;
363 DRM_DEBUG("instance:0x%08x\tnotify:0x%08x\n",
367 status &= ~NV_PGRAPH_INTR_NOTIFY;
368 NV_WRITE(NV03_PGRAPH_INTR, NV_PGRAPH_INTR_NOTIFY);
371 if (status & NV_PGRAPH_INTR_BUFFER_NOTIFY) {
372 uint32_t nsource, nstatus, instance, notify;
373 DRM_DEBUG("NV: PGRAPH buffer notify interrupt\n");
375 nstatus = NV_READ(NV03_PGRAPH_NSTATUS);
376 nsource = NV_READ(NV03_PGRAPH_NSOURCE);
377 DRM_DEBUG("nsource:0x%08x\tnstatus:0x%08x\n", nsource, nstatus);
379 instance = NV_READ(0x00400158);
380 notify = NV_READ(0x00400150) >> 16;
381 DRM_DEBUG("instance:0x%08x\tnotify:0x%08x\n", instance, notify);
383 status &= ~NV_PGRAPH_INTR_BUFFER_NOTIFY;
384 NV_WRITE(NV03_PGRAPH_INTR, NV_PGRAPH_INTR_BUFFER_NOTIFY);
387 if (status & NV_PGRAPH_INTR_MISSING_HW) {
388 DRM_ERROR("NV: PGRAPH missing hw interrupt\n");
390 status &= ~NV_PGRAPH_INTR_MISSING_HW;
391 NV_WRITE(NV03_PGRAPH_INTR, NV_PGRAPH_INTR_MISSING_HW);
394 if (status & NV_PGRAPH_INTR_ERROR) {
395 uint32_t nsource, nstatus, instance;
397 DRM_ERROR("NV: PGRAPH error interrupt\n");
399 nstatus = NV_READ(NV03_PGRAPH_NSTATUS);
400 nsource = NV_READ(NV03_PGRAPH_NSOURCE);
401 DRM_ERROR("nsource:0x%08x\tnstatus:0x%08x\n", nsource, nstatus);
403 instance = NV_READ(0x00400158);
404 DRM_ERROR("instance:0x%08x\n", instance);
406 nouveau_graph_dump_trap_info(dev);
408 status &= ~NV_PGRAPH_INTR_ERROR;
409 NV_WRITE(NV03_PGRAPH_INTR, NV_PGRAPH_INTR_ERROR);
412 if (status & NV_PGRAPH_INTR_CONTEXT_SWITCH) {
413 uint32_t channel=NV_READ(NV03_PFIFO_CACHE1_PUSH1)&(nouveau_fifo_number(dev)-1);
414 DRM_INFO("NV: PGRAPH context switch interrupt channel %x\n",channel);
415 switch(dev_priv->card_type)
419 nouveau_nv04_context_switch(dev);
424 nouveau_nv10_context_switch(dev);
428 nouveau_nv20_context_switch(dev);
431 DRM_INFO("NV: Context switch not implemented\n");
435 status &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH;
436 NV_WRITE(NV03_PGRAPH_INTR, NV_PGRAPH_INTR_CONTEXT_SWITCH);
440 DRM_INFO("NV: Unknown PGRAPH interrupt! STAT=0x%08x\n", status);
441 NV_WRITE(NV03_PGRAPH_INTR, status);
444 NV_WRITE(NV03_PMC_INTR_0, NV_PMC_INTR_0_PGRAPH_PENDING);
447 static void nouveau_crtc_irq_handler(struct drm_device *dev, int crtc)
449 struct drm_nouveau_private *dev_priv = dev->dev_private;
451 NV_WRITE(NV_CRTC0_INTSTAT, NV_CRTC_INTR_VBLANK);
455 NV_WRITE(NV_CRTC1_INTSTAT, NV_CRTC_INTR_VBLANK);
459 irqreturn_t nouveau_irq_handler(DRM_IRQ_ARGS)
461 struct drm_device *dev = (struct drm_device*)arg;
462 struct drm_nouveau_private *dev_priv = dev->dev_private;
465 status = NV_READ(NV03_PMC_INTR_0);
469 DRM_DEBUG("PMC INTSTAT: 0x%08x\n", status);
471 if (status & NV_PMC_INTR_0_PFIFO_PENDING) {
472 nouveau_fifo_irq_handler(dev);
473 status &= ~NV_PMC_INTR_0_PFIFO_PENDING;
475 if (status & NV_PMC_INTR_0_PGRAPH_PENDING) {
476 nouveau_pgraph_irq_handler(dev);
477 status &= ~NV_PMC_INTR_0_PGRAPH_PENDING;
479 if (status & NV_PMC_INTR_0_CRTCn_PENDING) {
480 nouveau_crtc_irq_handler(dev, (status>>24)&3);
481 status &= ~NV_PMC_INTR_0_CRTCn_PENDING;
485 DRM_ERROR("Unhandled PMC INTR status bits 0x%08x\n", status);