2 * Copyright 2007 Stephane Marchesin
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
27 #include "nouveau_drm.h"
28 #include "nouveau_drv.h"
30 static uint32_t nv04_graph_ctx_regs
[] = {
35 NV04_PGRAPH_CTX_SWITCH1
,
36 NV04_PGRAPH_CTX_SWITCH2
,
37 NV04_PGRAPH_CTX_SWITCH3
,
38 NV04_PGRAPH_CTX_SWITCH4
,
39 NV04_PGRAPH_CTX_CACHE1
,
40 NV04_PGRAPH_CTX_CACHE2
,
41 NV04_PGRAPH_CTX_CACHE3
,
42 NV04_PGRAPH_CTX_CACHE4
,
72 NV04_PGRAPH_DMA_START_0
,
73 NV04_PGRAPH_DMA_START_1
,
74 NV04_PGRAPH_DMA_LENGTH
,
76 NV04_PGRAPH_DMA_PITCH
,
102 NV04_PGRAPH_BSWIZZLE2
,
103 NV04_PGRAPH_BSWIZZLE5
,
106 NV04_PGRAPH_PATT_COLOR0
,
107 NV04_PGRAPH_PATT_COLOR1
,
108 NV04_PGRAPH_PATT_COLORRAM
+0x00,
109 NV04_PGRAPH_PATT_COLORRAM
+0x04,
110 NV04_PGRAPH_PATT_COLORRAM
+0x08,
111 NV04_PGRAPH_PATT_COLORRAM
+0x0c,
112 NV04_PGRAPH_PATT_COLORRAM
+0x10,
113 NV04_PGRAPH_PATT_COLORRAM
+0x14,
114 NV04_PGRAPH_PATT_COLORRAM
+0x18,
115 NV04_PGRAPH_PATT_COLORRAM
+0x1c,
116 NV04_PGRAPH_PATT_COLORRAM
+0x20,
117 NV04_PGRAPH_PATT_COLORRAM
+0x24,
118 NV04_PGRAPH_PATT_COLORRAM
+0x28,
119 NV04_PGRAPH_PATT_COLORRAM
+0x2c,
120 NV04_PGRAPH_PATT_COLORRAM
+0x30,
121 NV04_PGRAPH_PATT_COLORRAM
+0x34,
122 NV04_PGRAPH_PATT_COLORRAM
+0x38,
123 NV04_PGRAPH_PATT_COLORRAM
+0x3c,
124 NV04_PGRAPH_PATT_COLORRAM
+0x40,
125 NV04_PGRAPH_PATT_COLORRAM
+0x44,
126 NV04_PGRAPH_PATT_COLORRAM
+0x48,
127 NV04_PGRAPH_PATT_COLORRAM
+0x4c,
128 NV04_PGRAPH_PATT_COLORRAM
+0x50,
129 NV04_PGRAPH_PATT_COLORRAM
+0x54,
130 NV04_PGRAPH_PATT_COLORRAM
+0x58,
131 NV04_PGRAPH_PATT_COLORRAM
+0x5c,
132 NV04_PGRAPH_PATT_COLORRAM
+0x60,
133 NV04_PGRAPH_PATT_COLORRAM
+0x64,
134 NV04_PGRAPH_PATT_COLORRAM
+0x68,
135 NV04_PGRAPH_PATT_COLORRAM
+0x6c,
136 NV04_PGRAPH_PATT_COLORRAM
+0x70,
137 NV04_PGRAPH_PATT_COLORRAM
+0x74,
138 NV04_PGRAPH_PATT_COLORRAM
+0x78,
139 NV04_PGRAPH_PATT_COLORRAM
+0x7c,
140 NV04_PGRAPH_PATT_COLORRAM
+0x80,
141 NV04_PGRAPH_PATT_COLORRAM
+0x84,
142 NV04_PGRAPH_PATT_COLORRAM
+0x88,
143 NV04_PGRAPH_PATT_COLORRAM
+0x8c,
144 NV04_PGRAPH_PATT_COLORRAM
+0x90,
145 NV04_PGRAPH_PATT_COLORRAM
+0x94,
146 NV04_PGRAPH_PATT_COLORRAM
+0x98,
147 NV04_PGRAPH_PATT_COLORRAM
+0x9c,
148 NV04_PGRAPH_PATT_COLORRAM
+0xa0,
149 NV04_PGRAPH_PATT_COLORRAM
+0xa4,
150 NV04_PGRAPH_PATT_COLORRAM
+0xa8,
151 NV04_PGRAPH_PATT_COLORRAM
+0xac,
152 NV04_PGRAPH_PATT_COLORRAM
+0xb0,
153 NV04_PGRAPH_PATT_COLORRAM
+0xb4,
154 NV04_PGRAPH_PATT_COLORRAM
+0xb8,
155 NV04_PGRAPH_PATT_COLORRAM
+0xbc,
156 NV04_PGRAPH_PATT_COLORRAM
+0xc0,
157 NV04_PGRAPH_PATT_COLORRAM
+0xc4,
158 NV04_PGRAPH_PATT_COLORRAM
+0xc8,
159 NV04_PGRAPH_PATT_COLORRAM
+0xcc,
160 NV04_PGRAPH_PATT_COLORRAM
+0xd0,
161 NV04_PGRAPH_PATT_COLORRAM
+0xd4,
162 NV04_PGRAPH_PATT_COLORRAM
+0xd8,
163 NV04_PGRAPH_PATT_COLORRAM
+0xdc,
164 NV04_PGRAPH_PATT_COLORRAM
+0xe0,
165 NV04_PGRAPH_PATT_COLORRAM
+0xe4,
166 NV04_PGRAPH_PATT_COLORRAM
+0xe8,
167 NV04_PGRAPH_PATT_COLORRAM
+0xec,
168 NV04_PGRAPH_PATT_COLORRAM
+0xf0,
169 NV04_PGRAPH_PATT_COLORRAM
+0xf4,
170 NV04_PGRAPH_PATT_COLORRAM
+0xf8,
171 NV04_PGRAPH_PATT_COLORRAM
+0xfc,
174 NV04_PGRAPH_PATTERN_SHAPE
,
178 NV04_PGRAPH_BETA_AND
,
179 NV04_PGRAPH_BETA_PREMULT
,
180 NV04_PGRAPH_CONTROL0
,
181 NV04_PGRAPH_CONTROL1
,
182 NV04_PGRAPH_CONTROL2
,
184 NV04_PGRAPH_STORED_FMT
,
185 NV04_PGRAPH_SOURCE_COLOR
,
329 NV04_PGRAPH_PASSTHRU_0
,
330 NV04_PGRAPH_PASSTHRU_1
,
331 NV04_PGRAPH_PASSTHRU_2
,
332 NV04_PGRAPH_DVD_COLORFMT
,
333 NV04_PGRAPH_SCALED_FORMAT
,
334 NV04_PGRAPH_MISC24_0
,
335 NV04_PGRAPH_MISC24_1
,
336 NV04_PGRAPH_MISC24_2
,
345 int nv04
[ARRAY_SIZE(nv04_graph_ctx_regs
)];
348 struct nouveau_channel
*
349 nv04_graph_channel(struct drm_device
*dev
)
351 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
352 int chid
= dev_priv
->engine
.fifo
.channels
;
354 if (nv_rd32(dev
, NV04_PGRAPH_CTX_CONTROL
) & 0x00010000)
355 chid
= nv_rd32(dev
, NV04_PGRAPH_CTX_USER
) >> 24;
357 if (chid
>= dev_priv
->engine
.fifo
.channels
)
360 return dev_priv
->fifos
[chid
];
364 nv04_graph_context_switch(struct drm_device
*dev
)
366 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
367 struct nouveau_pgraph_engine
*pgraph
= &dev_priv
->engine
.graph
;
368 struct nouveau_channel
*chan
= NULL
;
371 pgraph
->fifo_access(dev
, false);
372 nouveau_wait_for_idle(dev
);
374 /* If previous context is valid, we need to save it */
375 pgraph
->unload_context(dev
);
377 /* Load context for next channel */
378 chid
= dev_priv
->engine
.fifo
.channel_id(dev
);
379 chan
= dev_priv
->fifos
[chid
];
381 nv04_graph_load_context(chan
);
383 pgraph
->fifo_access(dev
, true);
386 static uint32_t *ctx_reg(struct graph_state
*ctx
, uint32_t reg
)
390 for (i
= 0; i
< ARRAY_SIZE(nv04_graph_ctx_regs
); i
++) {
391 if (nv04_graph_ctx_regs
[i
] == reg
)
392 return &ctx
->nv04
[i
];
398 int nv04_graph_create_context(struct nouveau_channel
*chan
)
400 struct graph_state
*pgraph_ctx
;
401 NV_DEBUG(chan
->dev
, "nv04_graph_context_create %d\n", chan
->id
);
403 chan
->pgraph_ctx
= pgraph_ctx
= kzalloc(sizeof(*pgraph_ctx
),
405 if (pgraph_ctx
== NULL
)
408 *ctx_reg(pgraph_ctx
, NV04_PGRAPH_DEBUG_3
) = 0xfad4ff31;
413 void nv04_graph_destroy_context(struct nouveau_channel
*chan
)
415 struct graph_state
*pgraph_ctx
= chan
->pgraph_ctx
;
418 chan
->pgraph_ctx
= NULL
;
421 int nv04_graph_load_context(struct nouveau_channel
*chan
)
423 struct drm_device
*dev
= chan
->dev
;
424 struct graph_state
*pgraph_ctx
= chan
->pgraph_ctx
;
428 for (i
= 0; i
< ARRAY_SIZE(nv04_graph_ctx_regs
); i
++)
429 nv_wr32(dev
, nv04_graph_ctx_regs
[i
], pgraph_ctx
->nv04
[i
]);
431 nv_wr32(dev
, NV04_PGRAPH_CTX_CONTROL
, 0x10010100);
433 tmp
= nv_rd32(dev
, NV04_PGRAPH_CTX_USER
) & 0x00ffffff;
434 nv_wr32(dev
, NV04_PGRAPH_CTX_USER
, tmp
| chan
->id
<< 24);
436 tmp
= nv_rd32(dev
, NV04_PGRAPH_FFINTFC_ST2
);
437 nv_wr32(dev
, NV04_PGRAPH_FFINTFC_ST2
, tmp
& 0x000fffff);
443 nv04_graph_unload_context(struct drm_device
*dev
)
445 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
446 struct nouveau_pgraph_engine
*pgraph
= &dev_priv
->engine
.graph
;
447 struct nouveau_channel
*chan
= NULL
;
448 struct graph_state
*ctx
;
452 chan
= pgraph
->channel(dev
);
455 ctx
= chan
->pgraph_ctx
;
457 for (i
= 0; i
< ARRAY_SIZE(nv04_graph_ctx_regs
); i
++)
458 ctx
->nv04
[i
] = nv_rd32(dev
, nv04_graph_ctx_regs
[i
]);
460 nv_wr32(dev
, NV04_PGRAPH_CTX_CONTROL
, 0x10000000);
461 tmp
= nv_rd32(dev
, NV04_PGRAPH_CTX_USER
) & 0x00ffffff;
462 tmp
|= (dev_priv
->engine
.fifo
.channels
- 1) << 24;
463 nv_wr32(dev
, NV04_PGRAPH_CTX_USER
, tmp
);
467 int nv04_graph_init(struct drm_device
*dev
)
469 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
472 nv_wr32(dev
, NV03_PMC_ENABLE
, nv_rd32(dev
, NV03_PMC_ENABLE
) &
473 ~NV_PMC_ENABLE_PGRAPH
);
474 nv_wr32(dev
, NV03_PMC_ENABLE
, nv_rd32(dev
, NV03_PMC_ENABLE
) |
475 NV_PMC_ENABLE_PGRAPH
);
477 /* Enable PGRAPH interrupts */
478 nv_wr32(dev
, NV03_PGRAPH_INTR
, 0xFFFFFFFF);
479 nv_wr32(dev
, NV03_PGRAPH_INTR_EN
, 0xFFFFFFFF);
481 nv_wr32(dev
, NV04_PGRAPH_VALID1
, 0);
482 nv_wr32(dev
, NV04_PGRAPH_VALID2
, 0);
483 /*nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x000001FF);
484 nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x001FFFFF);*/
485 nv_wr32(dev
, NV04_PGRAPH_DEBUG_0
, 0x1231c000);
486 /*1231C000 blob, 001 haiku*/
487 //*V_WRITE(NV04_PGRAPH_DEBUG_1, 0xf2d91100);*/
488 nv_wr32(dev
, NV04_PGRAPH_DEBUG_1
, 0x72111100);
489 /*0x72111100 blob , 01 haiku*/
490 /*nv_wr32(dev, NV04_PGRAPH_DEBUG_2, 0x11d5f870);*/
491 nv_wr32(dev
, NV04_PGRAPH_DEBUG_2
, 0x11d5f071);
494 /*nv_wr32(dev, NV04_PGRAPH_DEBUG_3, 0xfad4ff31);*/
495 nv_wr32(dev
, NV04_PGRAPH_DEBUG_3
, 0xf0d4ff31);
496 /*haiku and blob 10d4*/
498 nv_wr32(dev
, NV04_PGRAPH_STATE
, 0xFFFFFFFF);
499 nv_wr32(dev
, NV04_PGRAPH_CTX_CONTROL
, 0x10000100);
500 tmp
= nv_rd32(dev
, NV04_PGRAPH_CTX_USER
) & 0x00ffffff;
501 tmp
|= (dev_priv
->engine
.fifo
.channels
- 1) << 24;
502 nv_wr32(dev
, NV04_PGRAPH_CTX_USER
, tmp
);
504 /* These don't belong here, they're part of a per-channel context */
505 nv_wr32(dev
, NV04_PGRAPH_PATTERN_SHAPE
, 0x00000000);
506 nv_wr32(dev
, NV04_PGRAPH_BETA_AND
, 0xFFFFFFFF);
511 void nv04_graph_takedown(struct drm_device
*dev
)
516 nv04_graph_fifo_access(struct drm_device
*dev
, bool enabled
)
519 nv_wr32(dev
, NV04_PGRAPH_FIFO
,
520 nv_rd32(dev
, NV04_PGRAPH_FIFO
) | 1);
522 nv_wr32(dev
, NV04_PGRAPH_FIFO
,
523 nv_rd32(dev
, NV04_PGRAPH_FIFO
) & ~1);
527 nv04_graph_mthd_set_ref(struct nouveau_channel
*chan
, int grclass
,
528 int mthd
, uint32_t data
)
530 chan
->fence
.last_sequence_irq
= data
;
531 nouveau_fence_handler(chan
->dev
, chan
->id
);
536 nv04_graph_mthd_set_operation(struct nouveau_channel
*chan
, int grclass
,
537 int mthd
, uint32_t data
)
539 struct drm_device
*dev
= chan
->dev
;
540 uint32_t instance
= (nv_rd32(dev
, NV04_PGRAPH_CTX_SWITCH4
) & 0xffff) << 4;
541 int subc
= (nv_rd32(dev
, NV04_PGRAPH_TRAPPED_ADDR
) >> 13) & 0x7;
544 tmp
= nv_ri32(dev
, instance
);
546 tmp
|= ((data
& 7) << 15);
548 nv_wi32(dev
, instance
, tmp
);
549 nv_wr32(dev
, NV04_PGRAPH_CTX_SWITCH1
, tmp
);
550 nv_wr32(dev
, NV04_PGRAPH_CTX_CACHE1
+ (subc
<<2), tmp
);
554 static struct nouveau_pgraph_object_method nv04_graph_mthds_sw
[] = {
555 { 0x0150, nv04_graph_mthd_set_ref
},
559 static struct nouveau_pgraph_object_method nv04_graph_mthds_set_operation
[] = {
560 { 0x02fc, nv04_graph_mthd_set_operation
},
564 struct nouveau_pgraph_object_class nv04_graph_grclass
[] = {
565 { 0x0039, false, NULL
},
566 { 0x004a, false, nv04_graph_mthds_set_operation
}, /* gdirect */
567 { 0x005f, false, nv04_graph_mthds_set_operation
}, /* imageblit */
568 { 0x0061, false, nv04_graph_mthds_set_operation
}, /* ifc */
569 { 0x0077, false, nv04_graph_mthds_set_operation
}, /* sifm */
570 { 0x0030, false, NULL
}, /* null */
571 { 0x0042, false, NULL
}, /* surf2d */
572 { 0x0043, false, NULL
}, /* rop */
573 { 0x0012, false, NULL
}, /* beta1 */
574 { 0x0072, false, NULL
}, /* beta4 */
575 { 0x0019, false, NULL
}, /* cliprect */
576 { 0x0044, false, NULL
}, /* pattern */
577 { 0x0052, false, NULL
}, /* swzsurf */
578 { 0x0053, false, NULL
}, /* surf3d */
579 { 0x0054, false, NULL
}, /* tex_tri */
580 { 0x0055, false, NULL
}, /* multitex_tri */
581 { 0x506e, true, nv04_graph_mthds_sw
},