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"
38 #include "nouveau_swmthd.h"
41 nouveau_irq_preinstall(struct drm_device
*dev
)
43 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
46 NV_WRITE(NV03_PMC_INTR_EN_0
, 0);
50 nouveau_irq_postinstall(struct drm_device
*dev
)
52 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
55 NV_WRITE(NV03_PMC_INTR_EN_0
, NV_PMC_INTR_EN_0_MASTER_ENABLE
);
61 nouveau_irq_uninstall(struct drm_device
*dev
)
63 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
66 NV_WRITE(NV03_PMC_INTR_EN_0
, 0);
70 nouveau_fifo_irq_handler(struct drm_device
*dev
)
72 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
73 struct nouveau_engine
*engine
= &dev_priv
->Engine
;
74 uint32_t status
, reassign
;
76 reassign
= NV_READ(NV03_PFIFO_CACHES
) & 1;
77 while ((status
= NV_READ(NV03_PFIFO_INTR_0
))) {
80 NV_WRITE(NV03_PFIFO_CACHES
, 0);
82 chid
= engine
->fifo
.channel_id(dev
);
83 get
= NV_READ(NV03_PFIFO_CACHE1_GET
);
85 if (status
& NV_PFIFO_INTR_CACHE_ERROR
) {
90 if (dev_priv
->card_type
< NV_40
) {
91 mthd
= NV_READ(NV04_PFIFO_CACHE1_METHOD(ptr
));
92 data
= NV_READ(NV04_PFIFO_CACHE1_DATA(ptr
));
94 mthd
= NV_READ(NV40_PFIFO_CACHE1_METHOD(ptr
));
95 data
= NV_READ(NV40_PFIFO_CACHE1_DATA(ptr
));
98 DRM_INFO("PFIFO_CACHE_ERROR - "
99 "Ch %d/%d Mthd 0x%04x Data 0x%08x\n",
100 chid
, (mthd
>> 13) & 7, mthd
& 0x1ffc, data
);
102 NV_WRITE(NV03_PFIFO_CACHE1_GET
, get
+ 4);
103 NV_WRITE(NV04_PFIFO_CACHE1_PULL0
, 1);
105 status
&= ~NV_PFIFO_INTR_CACHE_ERROR
;
106 NV_WRITE(NV03_PFIFO_INTR_0
, NV_PFIFO_INTR_CACHE_ERROR
);
109 if (status
& NV_PFIFO_INTR_DMA_PUSHER
) {
110 DRM_INFO("PFIFO_DMA_PUSHER - Ch %d\n", chid
);
112 status
&= ~NV_PFIFO_INTR_DMA_PUSHER
;
113 NV_WRITE(NV03_PFIFO_INTR_0
, NV_PFIFO_INTR_DMA_PUSHER
);
115 NV_WRITE(NV04_PFIFO_CACHE1_DMA_STATE
, 0x00000000);
116 if (NV_READ(NV04_PFIFO_CACHE1_DMA_PUT
) != get
)
117 NV_WRITE(NV04_PFIFO_CACHE1_DMA_GET
, get
+ 4);
121 DRM_INFO("Unhandled PFIFO_INTR - 0x%08x\n", status
);
122 NV_WRITE(NV03_PFIFO_INTR_0
, status
);
123 NV_WRITE(NV03_PMC_INTR_EN_0
, 0);
126 NV_WRITE(NV03_PFIFO_CACHES
, reassign
);
129 NV_WRITE(NV03_PMC_INTR_0
, NV_PMC_INTR_0_PFIFO_PENDING
);
132 struct nouveau_bitfield_names
{
137 static struct nouveau_bitfield_names nouveau_nstatus_names
[] =
139 { NV04_PGRAPH_NSTATUS_STATE_IN_USE
, "STATE_IN_USE" },
140 { NV04_PGRAPH_NSTATUS_INVALID_STATE
, "INVALID_STATE" },
141 { NV04_PGRAPH_NSTATUS_BAD_ARGUMENT
, "BAD_ARGUMENT" },
142 { NV04_PGRAPH_NSTATUS_PROTECTION_FAULT
, "PROTECTION_FAULT" }
145 static struct nouveau_bitfield_names nouveau_nstatus_names_nv10
[] =
147 { NV10_PGRAPH_NSTATUS_STATE_IN_USE
, "STATE_IN_USE" },
148 { NV10_PGRAPH_NSTATUS_INVALID_STATE
, "INVALID_STATE" },
149 { NV10_PGRAPH_NSTATUS_BAD_ARGUMENT
, "BAD_ARGUMENT" },
150 { NV10_PGRAPH_NSTATUS_PROTECTION_FAULT
, "PROTECTION_FAULT" }
153 static struct nouveau_bitfield_names nouveau_nsource_names
[] =
155 { NV03_PGRAPH_NSOURCE_NOTIFICATION
, "NOTIFICATION" },
156 { NV03_PGRAPH_NSOURCE_DATA_ERROR
, "DATA_ERROR" },
157 { NV03_PGRAPH_NSOURCE_PROTECTION_ERROR
, "PROTECTION_ERROR" },
158 { NV03_PGRAPH_NSOURCE_RANGE_EXCEPTION
, "RANGE_EXCEPTION" },
159 { NV03_PGRAPH_NSOURCE_LIMIT_COLOR
, "LIMIT_COLOR" },
160 { NV03_PGRAPH_NSOURCE_LIMIT_ZETA
, "LIMIT_ZETA" },
161 { NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD
, "ILLEGAL_MTHD" },
162 { NV03_PGRAPH_NSOURCE_DMA_R_PROTECTION
, "DMA_R_PROTECTION" },
163 { NV03_PGRAPH_NSOURCE_DMA_W_PROTECTION
, "DMA_W_PROTECTION" },
164 { NV03_PGRAPH_NSOURCE_FORMAT_EXCEPTION
, "FORMAT_EXCEPTION" },
165 { NV03_PGRAPH_NSOURCE_PATCH_EXCEPTION
, "PATCH_EXCEPTION" },
166 { NV03_PGRAPH_NSOURCE_STATE_INVALID
, "STATE_INVALID" },
167 { NV03_PGRAPH_NSOURCE_DOUBLE_NOTIFY
, "DOUBLE_NOTIFY" },
168 { NV03_PGRAPH_NSOURCE_NOTIFY_IN_USE
, "NOTIFY_IN_USE" },
169 { NV03_PGRAPH_NSOURCE_METHOD_CNT
, "METHOD_CNT" },
170 { NV03_PGRAPH_NSOURCE_BFR_NOTIFICATION
, "BFR_NOTIFICATION" },
171 { NV03_PGRAPH_NSOURCE_DMA_VTX_PROTECTION
, "DMA_VTX_PROTECTION" },
172 { NV03_PGRAPH_NSOURCE_DMA_WIDTH_A
, "DMA_WIDTH_A" },
173 { NV03_PGRAPH_NSOURCE_DMA_WIDTH_B
, "DMA_WIDTH_B" },
177 nouveau_print_bitfield_names(uint32_t value
,
178 const struct nouveau_bitfield_names
*namelist
,
179 const int namelist_len
)
182 for(i
=0; i
<namelist_len
; ++i
) {
183 uint32_t mask
= namelist
[i
].mask
;
185 printk(" %s", namelist
[i
].name
);
190 printk(" (unknown bits 0x%08x)", value
);
194 nouveau_graph_chid_from_grctx(struct drm_device
*dev
)
196 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
200 if (dev_priv
->card_type
< NV_40
)
201 return dev_priv
->Engine
.fifo
.channels
;
203 if (dev_priv
->card_type
< NV_50
)
204 inst
= (NV_READ(0x40032c) & 0xfffff) << 4;
206 inst
= NV_READ(0x40032c) & 0xfffff;
208 for (i
= 0; i
< dev_priv
->Engine
.fifo
.channels
; i
++) {
209 struct nouveau_channel
*chan
= dev_priv
->fifos
[i
];
211 if (!chan
|| !chan
->ramin_grctx
)
214 if (dev_priv
->card_type
< NV_50
) {
215 if (inst
== chan
->ramin_grctx
->instance
)
218 if (inst
== INSTANCE_RD(chan
->ramin_grctx
->gpuobj
, 0))
227 nouveau_graph_trapped_channel(struct drm_device
*dev
, int *channel_ret
)
229 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
230 struct nouveau_engine
*engine
= &dev_priv
->Engine
;
233 if (dev_priv
->card_type
< NV_10
)
234 channel
= (NV_READ(NV04_PGRAPH_TRAPPED_ADDR
) >> 24) & 0xf;
236 if (dev_priv
->card_type
< NV_40
)
237 channel
= (NV_READ(NV04_PGRAPH_TRAPPED_ADDR
) >> 20) & 0x1f;
239 channel
= nouveau_graph_chid_from_grctx(dev
);
241 if (channel
>= engine
->fifo
.channels
|| !dev_priv
->fifos
[channel
]) {
242 DRM_ERROR("AIII, invalid/inactive channel id %d\n", channel
);
246 *channel_ret
= channel
;
250 struct nouveau_pgraph_trap
{
253 int subc
, mthd
, size
;
254 uint32_t data
, data2
;
255 uint32_t nsource
, nstatus
;
259 nouveau_graph_trap_info(struct drm_device
*dev
,
260 struct nouveau_pgraph_trap
*trap
)
262 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
265 trap
->nsource
= trap
->nstatus
= 0;
266 if (dev_priv
->card_type
< NV_50
) {
267 trap
->nsource
= NV_READ(NV03_PGRAPH_NSOURCE
);
268 trap
->nstatus
= NV_READ(NV03_PGRAPH_NSTATUS
);
271 if (nouveau_graph_trapped_channel(dev
, &trap
->channel
))
273 address
= NV_READ(NV04_PGRAPH_TRAPPED_ADDR
);
275 trap
->mthd
= address
& 0x1FFC;
276 trap
->data
= NV_READ(NV04_PGRAPH_TRAPPED_DATA
);
277 if (dev_priv
->card_type
< NV_10
) {
278 trap
->subc
= (address
>> 13) & 0x7;
280 trap
->subc
= (address
>> 16) & 0x7;
281 trap
->data2
= NV_READ(NV10_PGRAPH_TRAPPED_DATA_HIGH
);
284 if (dev_priv
->card_type
< NV_10
) {
285 trap
->class = NV_READ(0x400180 + trap
->subc
*4) & 0xFF;
286 } else if (dev_priv
->card_type
< NV_40
) {
287 trap
->class = NV_READ(0x400160 + trap
->subc
*4) & 0xFFF;
288 } else if (dev_priv
->card_type
< NV_50
) {
289 trap
->class = NV_READ(0x400160 + trap
->subc
*4) & 0xFFFF;
291 trap
->class = NV_READ(0x400814);
296 nouveau_graph_dump_trap_info(struct drm_device
*dev
, const char *id
,
297 struct nouveau_pgraph_trap
*trap
)
299 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
300 uint32_t nsource
= trap
->nsource
, nstatus
= trap
->nstatus
;
302 DRM_INFO("%s - nSource:", id
);
303 nouveau_print_bitfield_names(nsource
, nouveau_nsource_names
,
304 ARRAY_SIZE(nouveau_nsource_names
));
305 printk(", nStatus:");
306 if (dev_priv
->card_type
< NV_10
)
307 nouveau_print_bitfield_names(nstatus
, nouveau_nstatus_names
,
308 ARRAY_SIZE(nouveau_nstatus_names
));
310 nouveau_print_bitfield_names(nstatus
, nouveau_nstatus_names_nv10
,
311 ARRAY_SIZE(nouveau_nstatus_names_nv10
));
314 DRM_INFO("%s - Ch %d/%d Class 0x%04x Mthd 0x%04x Data 0x%08x:0x%08x\n",
315 id
, trap
->channel
, trap
->subc
, trap
->class, trap
->mthd
,
316 trap
->data2
, trap
->data
);
320 nouveau_pgraph_intr_notify(struct drm_device
*dev
, uint32_t nsource
)
322 struct nouveau_pgraph_trap trap
;
325 nouveau_graph_trap_info(dev
, &trap
);
327 if (nsource
& NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD
) {
328 /* NV4 (nvidia TNT 1) reports software methods with
329 * PGRAPH NOTIFY ILLEGAL_MTHD
331 DRM_DEBUG("Got NV04 software method method %x for class %#x\n",
332 trap
.mthd
, trap
.class);
334 if (nouveau_sw_method_execute(dev
, trap
.class, trap
.mthd
)) {
335 DRM_ERROR("Unable to execute NV04 software method %x "
336 "for object class %x. Please report.\n",
337 trap
.mthd
, trap
.class);
345 nouveau_graph_dump_trap_info(dev
, "PGRAPH_NOTIFY", &trap
);
349 nouveau_pgraph_intr_error(struct drm_device
*dev
, uint32_t nsource
)
351 struct nouveau_pgraph_trap trap
;
354 nouveau_graph_trap_info(dev
, &trap
);
355 trap
.nsource
= nsource
;
357 if (nsource
& NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD
) {
358 if (trap
.channel
>= 0 && trap
.mthd
== 0x0150) {
359 nouveau_fence_handler(dev
, trap
.channel
);
361 if (nouveau_sw_method_execute(dev
, trap
.class, trap
.mthd
)) {
369 nouveau_graph_dump_trap_info(dev
, "PGRAPH_ERROR", &trap
);
373 nouveau_pgraph_intr_context_switch(struct drm_device
*dev
)
375 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
376 struct nouveau_engine
*engine
= &dev_priv
->Engine
;
379 chid
= engine
->fifo
.channel_id(dev
);
380 DRM_DEBUG("PGRAPH context switch interrupt channel %x\n", chid
);
382 switch(dev_priv
->card_type
) {
385 nouveau_nv04_context_switch(dev
);
390 nouveau_nv10_context_switch(dev
);
393 DRM_ERROR("Context switch not implemented\n");
399 nouveau_pgraph_irq_handler(struct drm_device
*dev
)
401 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
404 while ((status
= NV_READ(NV03_PGRAPH_INTR
))) {
405 uint32_t nsource
= NV_READ(NV03_PGRAPH_NSOURCE
);
407 if (status
& NV_PGRAPH_INTR_NOTIFY
) {
408 nouveau_pgraph_intr_notify(dev
, nsource
);
410 status
&= ~NV_PGRAPH_INTR_NOTIFY
;
411 NV_WRITE(NV03_PGRAPH_INTR
, NV_PGRAPH_INTR_NOTIFY
);
414 if (status
& NV_PGRAPH_INTR_ERROR
) {
415 nouveau_pgraph_intr_error(dev
, nsource
);
417 status
&= ~NV_PGRAPH_INTR_ERROR
;
418 NV_WRITE(NV03_PGRAPH_INTR
, NV_PGRAPH_INTR_ERROR
);
421 if (status
& NV_PGRAPH_INTR_CONTEXT_SWITCH
) {
422 nouveau_pgraph_intr_context_switch(dev
);
424 status
&= ~NV_PGRAPH_INTR_CONTEXT_SWITCH
;
425 NV_WRITE(NV03_PGRAPH_INTR
,
426 NV_PGRAPH_INTR_CONTEXT_SWITCH
);
430 DRM_INFO("Unhandled PGRAPH_INTR - 0x%08x\n", status
);
431 NV_WRITE(NV03_PGRAPH_INTR
, status
);
434 if ((NV_READ(NV04_PGRAPH_FIFO
) & (1 << 0)) == 0)
435 NV_WRITE(NV04_PGRAPH_FIFO
, 1);
438 NV_WRITE(NV03_PMC_INTR_0
, NV_PMC_INTR_0_PGRAPH_PENDING
);
442 nv50_pgraph_irq_handler(struct drm_device
*dev
)
444 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
445 uint32_t status
, nsource
;
447 status
= NV_READ(NV03_PGRAPH_INTR
);
448 nsource
= NV_READ(NV03_PGRAPH_NSOURCE
);
450 if (status
& 0x00000020) {
451 nouveau_pgraph_intr_error(dev
,
452 NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD
);
454 status
&= ~0x00000020;
455 NV_WRITE(NV03_PGRAPH_INTR
, 0x00000020);
458 if (status
& 0x00100000) {
459 nouveau_pgraph_intr_error(dev
,
460 NV03_PGRAPH_NSOURCE_DATA_ERROR
);
462 status
&= ~0x00100000;
463 NV_WRITE(NV03_PGRAPH_INTR
, 0x00100000);
466 if (status
& 0x00200000) {
469 nouveau_pgraph_intr_error(dev
, nsource
|
470 NV03_PGRAPH_NSOURCE_PROTECTION_ERROR
);
472 DRM_ERROR("magic set 1:\n");
473 for (r
= 0x408900; r
<= 0x408910; r
+= 4)
474 DRM_ERROR("\t0x%08x: 0x%08x\n", r
, NV_READ(r
));
475 NV_WRITE(0x408900, NV_READ(0x408904) | 0xc0000000);
476 for (r
= 0x408e08; r
<= 0x408e24; r
+= 4)
477 DRM_ERROR("\t0x%08x: 0x%08x\n", r
, NV_READ(r
));
478 NV_WRITE(0x408e08, NV_READ(0x408e08) | 0xc0000000);
480 DRM_ERROR("magic set 2:\n");
481 for (r
= 0x409900; r
<= 0x409910; r
+= 4)
482 DRM_ERROR("\t0x%08x: 0x%08x\n", r
, NV_READ(r
));
483 NV_WRITE(0x409900, NV_READ(0x409904) | 0xc0000000);
484 for (r
= 0x409e08; r
<= 0x409e24; r
+= 4)
485 DRM_ERROR("\t0x%08x: 0x%08x\n", r
, NV_READ(r
));
486 NV_WRITE(0x409e08, NV_READ(0x409e08) | 0xc0000000);
488 status
&= ~0x00200000;
489 NV_WRITE(NV03_PGRAPH_NSOURCE
, nsource
);
490 NV_WRITE(NV03_PGRAPH_INTR
, 0x00200000);
494 DRM_INFO("Unhandled PGRAPH_INTR - 0x%08x\n", status
);
495 NV_WRITE(NV03_PGRAPH_INTR
, status
);
499 const int isb
= (1 << 16) | (1 << 0);
501 if ((NV_READ(0x400500) & isb
) != isb
)
502 NV_WRITE(0x400500, NV_READ(0x400500) | isb
);
505 NV_WRITE(NV03_PMC_INTR_0
, NV_PMC_INTR_0_PGRAPH_PENDING
);
509 nouveau_crtc_irq_handler(struct drm_device
*dev
, int crtc
)
511 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
514 NV_WRITE(NV_CRTC0_INTSTAT
, NV_CRTC_INTR_VBLANK
);
518 NV_WRITE(NV_CRTC1_INTSTAT
, NV_CRTC_INTR_VBLANK
);
523 nouveau_nv50_display_irq_handler(struct drm_device
*dev
)
525 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
526 uint32_t val
= NV_READ(NV50_DISPLAY_SUPERVISOR
);
528 DRM_INFO("NV50_DISPLAY_INTR - 0x%08X\n", val
);
530 NV_WRITE(NV50_DISPLAY_SUPERVISOR
, val
);
534 nouveau_nv50_i2c_irq_handler(struct drm_device
*dev
)
536 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
538 DRM_INFO("NV50_I2C_INTR - 0x%08X\n", NV_READ(NV50_I2C_CONTROLLER
));
540 /* This seems to be the way to acknowledge an interrupt. */
541 NV_WRITE(NV50_I2C_CONTROLLER
, 0x7FFF7FFF);
545 nouveau_irq_handler(DRM_IRQ_ARGS
)
547 struct drm_device
*dev
= (struct drm_device
*)arg
;
548 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
551 status
= NV_READ(NV03_PMC_INTR_0
);
555 if (status
& NV_PMC_INTR_0_PFIFO_PENDING
) {
556 nouveau_fifo_irq_handler(dev
);
557 status
&= ~NV_PMC_INTR_0_PFIFO_PENDING
;
560 if (status
& NV_PMC_INTR_0_PGRAPH_PENDING
) {
561 if (dev_priv
->card_type
>= NV_50
)
562 nv50_pgraph_irq_handler(dev
);
564 nouveau_pgraph_irq_handler(dev
);
566 status
&= ~NV_PMC_INTR_0_PGRAPH_PENDING
;
569 if (status
& NV_PMC_INTR_0_CRTCn_PENDING
) {
570 nouveau_crtc_irq_handler(dev
, (status
>>24)&3);
571 status
&= ~NV_PMC_INTR_0_CRTCn_PENDING
;
574 if (status
& NV_PMC_INTR_0_NV50_DISPLAY_PENDING
) {
575 nouveau_nv50_display_irq_handler(dev
);
576 status
&= ~NV_PMC_INTR_0_NV50_DISPLAY_PENDING
;
579 if (status
& NV_PMC_INTR_0_NV50_I2C_PENDING
) {
580 nouveau_nv50_i2c_irq_handler(dev
);
581 status
&= ~NV_PMC_INTR_0_NV50_I2C_PENDING
;
585 DRM_ERROR("Unhandled PMC INTR status bits 0x%08x\n", status
);