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[] = {
31 NV04_PGRAPH_CTX_SWITCH1,
32 NV04_PGRAPH_CTX_SWITCH2,
33 NV04_PGRAPH_CTX_SWITCH3,
34 NV04_PGRAPH_CTX_SWITCH4,
35 NV04_PGRAPH_CTX_CACHE1,
36 NV04_PGRAPH_CTX_CACHE2,
37 NV04_PGRAPH_CTX_CACHE3,
38 NV04_PGRAPH_CTX_CACHE4,
68 NV04_PGRAPH_DMA_START_0,
69 NV04_PGRAPH_DMA_START_1,
70 NV04_PGRAPH_DMA_LENGTH,
72 NV04_PGRAPH_DMA_PITCH,
98 NV04_PGRAPH_BSWIZZLE2,
99 NV04_PGRAPH_BSWIZZLE5,
102 NV04_PGRAPH_PATT_COLOR0,
103 NV04_PGRAPH_PATT_COLOR1,
104 NV04_PGRAPH_PATT_COLORRAM+0x00,
105 NV04_PGRAPH_PATT_COLORRAM+0x01,
106 NV04_PGRAPH_PATT_COLORRAM+0x02,
107 NV04_PGRAPH_PATT_COLORRAM+0x03,
108 NV04_PGRAPH_PATT_COLORRAM+0x04,
109 NV04_PGRAPH_PATT_COLORRAM+0x05,
110 NV04_PGRAPH_PATT_COLORRAM+0x06,
111 NV04_PGRAPH_PATT_COLORRAM+0x07,
112 NV04_PGRAPH_PATT_COLORRAM+0x08,
113 NV04_PGRAPH_PATT_COLORRAM+0x09,
114 NV04_PGRAPH_PATT_COLORRAM+0x0A,
115 NV04_PGRAPH_PATT_COLORRAM+0x0B,
116 NV04_PGRAPH_PATT_COLORRAM+0x0C,
117 NV04_PGRAPH_PATT_COLORRAM+0x0D,
118 NV04_PGRAPH_PATT_COLORRAM+0x0E,
119 NV04_PGRAPH_PATT_COLORRAM+0x0F,
120 NV04_PGRAPH_PATT_COLORRAM+0x10,
121 NV04_PGRAPH_PATT_COLORRAM+0x11,
122 NV04_PGRAPH_PATT_COLORRAM+0x12,
123 NV04_PGRAPH_PATT_COLORRAM+0x13,
124 NV04_PGRAPH_PATT_COLORRAM+0x14,
125 NV04_PGRAPH_PATT_COLORRAM+0x15,
126 NV04_PGRAPH_PATT_COLORRAM+0x16,
127 NV04_PGRAPH_PATT_COLORRAM+0x17,
128 NV04_PGRAPH_PATT_COLORRAM+0x18,
129 NV04_PGRAPH_PATT_COLORRAM+0x19,
130 NV04_PGRAPH_PATT_COLORRAM+0x1A,
131 NV04_PGRAPH_PATT_COLORRAM+0x1B,
132 NV04_PGRAPH_PATT_COLORRAM+0x1C,
133 NV04_PGRAPH_PATT_COLORRAM+0x1D,
134 NV04_PGRAPH_PATT_COLORRAM+0x1E,
135 NV04_PGRAPH_PATT_COLORRAM+0x1F,
136 NV04_PGRAPH_PATT_COLORRAM+0x20,
137 NV04_PGRAPH_PATT_COLORRAM+0x21,
138 NV04_PGRAPH_PATT_COLORRAM+0x22,
139 NV04_PGRAPH_PATT_COLORRAM+0x23,
140 NV04_PGRAPH_PATT_COLORRAM+0x24,
141 NV04_PGRAPH_PATT_COLORRAM+0x25,
142 NV04_PGRAPH_PATT_COLORRAM+0x26,
143 NV04_PGRAPH_PATT_COLORRAM+0x27,
144 NV04_PGRAPH_PATT_COLORRAM+0x28,
145 NV04_PGRAPH_PATT_COLORRAM+0x29,
146 NV04_PGRAPH_PATT_COLORRAM+0x2A,
147 NV04_PGRAPH_PATT_COLORRAM+0x2B,
148 NV04_PGRAPH_PATT_COLORRAM+0x2C,
149 NV04_PGRAPH_PATT_COLORRAM+0x2D,
150 NV04_PGRAPH_PATT_COLORRAM+0x2E,
151 NV04_PGRAPH_PATT_COLORRAM+0x2F,
152 NV04_PGRAPH_PATT_COLORRAM+0x30,
153 NV04_PGRAPH_PATT_COLORRAM+0x31,
154 NV04_PGRAPH_PATT_COLORRAM+0x32,
155 NV04_PGRAPH_PATT_COLORRAM+0x33,
156 NV04_PGRAPH_PATT_COLORRAM+0x34,
157 NV04_PGRAPH_PATT_COLORRAM+0x35,
158 NV04_PGRAPH_PATT_COLORRAM+0x36,
159 NV04_PGRAPH_PATT_COLORRAM+0x37,
160 NV04_PGRAPH_PATT_COLORRAM+0x38,
161 NV04_PGRAPH_PATT_COLORRAM+0x39,
162 NV04_PGRAPH_PATT_COLORRAM+0x3A,
163 NV04_PGRAPH_PATT_COLORRAM+0x3B,
164 NV04_PGRAPH_PATT_COLORRAM+0x3C,
165 NV04_PGRAPH_PATT_COLORRAM+0x3D,
166 NV04_PGRAPH_PATT_COLORRAM+0x3E,
167 NV04_PGRAPH_PATT_COLORRAM+0x3F,
170 NV04_PGRAPH_PATTERN_SHAPE,
174 NV04_PGRAPH_BETA_AND,
175 NV04_PGRAPH_BETA_PREMULT,
176 NV04_PGRAPH_CONTROL0,
177 NV04_PGRAPH_CONTROL1,
178 NV04_PGRAPH_CONTROL2,
180 NV04_PGRAPH_STORED_FMT,
181 NV04_PGRAPH_SOURCE_COLOR,
333 NV04_PGRAPH_PASSTHRU_0,
334 NV04_PGRAPH_PASSTHRU_1,
335 NV04_PGRAPH_PASSTHRU_2,
336 NV04_PGRAPH_DVD_COLORFMT,
337 NV04_PGRAPH_SCALED_FORMAT,
338 NV04_PGRAPH_MISC24_0,
339 NV04_PGRAPH_MISC24_1,
340 NV04_PGRAPH_MISC24_2,
350 int nv04[ARRAY_SIZE(nv04_graph_ctx_regs)];
353 struct nouveau_channel *
354 nv04_graph_channel(struct drm_device *dev)
356 struct drm_nouveau_private *dev_priv = dev->dev_private;
357 int chid = dev_priv->engine.fifo.channels;
359 if (nv_rd32(dev, NV04_PGRAPH_CTX_CONTROL) & 0x00010000)
360 chid = nv_rd32(dev, NV04_PGRAPH_CTX_USER) >> 24;
362 if (chid >= dev_priv->engine.fifo.channels)
365 return dev_priv->fifos[chid];
369 nv04_graph_context_switch(struct drm_device *dev)
371 struct drm_nouveau_private *dev_priv = dev->dev_private;
372 struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
373 struct nouveau_channel *chan = NULL;
376 pgraph->fifo_access(dev, false);
377 nouveau_wait_for_idle(dev);
379 /* If previous context is valid, we need to save it */
380 pgraph->unload_context(dev);
382 /* Load context for next channel */
383 chid = dev_priv->engine.fifo.channel_id(dev);
384 chan = dev_priv->fifos[chid];
386 nv04_graph_load_context(chan);
388 pgraph->fifo_access(dev, true);
391 int nv04_graph_create_context(struct nouveau_channel *chan)
393 struct graph_state *pgraph_ctx;
394 NV_DEBUG(chan->dev, "nv04_graph_context_create %d\n", chan->id);
396 chan->pgraph_ctx = pgraph_ctx = kzalloc(sizeof(*pgraph_ctx),
398 if (pgraph_ctx == NULL)
401 /* dev_priv->fifos[channel].pgraph_ctx_user = channel << 24; */
402 pgraph_ctx->nv04[0] = 0x0001ffff;
403 /* is it really needed ??? */
405 dev_priv->fifos[channel].pgraph_ctx[1] =
406 nv_rd32(dev, NV_PGRAPH_DEBUG_4);
407 dev_priv->fifos[channel].pgraph_ctx[2] =
408 nv_rd32(dev, 0x004006b0);
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);
432 nv_wr32(dev, NV04_PGRAPH_CTX_USER, chan->id << 24);
433 tmp = nv_rd32(dev, NV04_PGRAPH_FFINTFC_ST2);
434 nv_wr32(dev, NV04_PGRAPH_FFINTFC_ST2, tmp & 0x000fffff);
439 nv04_graph_unload_context(struct drm_device *dev)
441 struct drm_nouveau_private *dev_priv = dev->dev_private;
442 struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
443 struct nouveau_channel *chan = NULL;
444 struct graph_state *ctx;
448 chan = pgraph->channel(dev);
451 ctx = chan->pgraph_ctx;
453 for (i = 0; i < ARRAY_SIZE(nv04_graph_ctx_regs); i++)
454 ctx->nv04[i] = nv_rd32(dev, nv04_graph_ctx_regs[i]);
456 nv_wr32(dev, NV04_PGRAPH_CTX_CONTROL, 0x10000000);
457 tmp = nv_rd32(dev, NV04_PGRAPH_CTX_USER) & 0x00ffffff;
458 tmp |= (dev_priv->engine.fifo.channels - 1) << 24;
459 nv_wr32(dev, NV04_PGRAPH_CTX_USER, tmp);
463 int nv04_graph_init(struct drm_device *dev)
465 struct drm_nouveau_private *dev_priv = dev->dev_private;
468 nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) &
469 ~NV_PMC_ENABLE_PGRAPH);
470 nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) |
471 NV_PMC_ENABLE_PGRAPH);
473 /* Enable PGRAPH interrupts */
474 nv_wr32(dev, NV03_PGRAPH_INTR, 0xFFFFFFFF);
475 nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);
477 nv_wr32(dev, NV04_PGRAPH_VALID1, 0);
478 nv_wr32(dev, NV04_PGRAPH_VALID2, 0);
479 /*nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x000001FF);
480 nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x001FFFFF);*/
481 nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x1231c000);
482 /*1231C000 blob, 001 haiku*/
483 //*V_WRITE(NV04_PGRAPH_DEBUG_1, 0xf2d91100);*/
484 nv_wr32(dev, NV04_PGRAPH_DEBUG_1, 0x72111100);
485 /*0x72111100 blob , 01 haiku*/
486 /*nv_wr32(dev, NV04_PGRAPH_DEBUG_2, 0x11d5f870);*/
487 nv_wr32(dev, NV04_PGRAPH_DEBUG_2, 0x11d5f071);
490 /*nv_wr32(dev, NV04_PGRAPH_DEBUG_3, 0xfad4ff31);*/
491 nv_wr32(dev, NV04_PGRAPH_DEBUG_3, 0xf0d4ff31);
492 /*haiku and blob 10d4*/
494 nv_wr32(dev, NV04_PGRAPH_STATE , 0xFFFFFFFF);
495 nv_wr32(dev, NV04_PGRAPH_CTX_CONTROL , 0x10000100);
496 tmp = nv_rd32(dev, NV04_PGRAPH_CTX_USER) & 0x00ffffff;
497 tmp |= dev_priv->engine.fifo.channels << 24;
498 nv_wr32(dev, NV04_PGRAPH_CTX_USER, tmp);
500 /* These don't belong here, they're part of a per-channel context */
501 nv_wr32(dev, NV04_PGRAPH_PATTERN_SHAPE, 0x00000000);
502 nv_wr32(dev, NV04_PGRAPH_BETA_AND , 0xFFFFFFFF);
507 void nv04_graph_takedown(struct drm_device *dev)
512 nv04_graph_fifo_access(struct drm_device *dev, bool enabled)
515 nv_wr32(dev, NV04_PGRAPH_FIFO,
516 nv_rd32(dev, NV04_PGRAPH_FIFO) | 1);
518 nv_wr32(dev, NV04_PGRAPH_FIFO,
519 nv_rd32(dev, NV04_PGRAPH_FIFO) & ~1);
523 nv04_graph_mthd_set_ref(struct nouveau_channel *chan, int grclass,
524 int mthd, uint32_t data)
526 chan->fence.last_sequence_irq = data;
527 nouveau_fence_handler(chan->dev, chan->id);
532 nv04_graph_mthd_set_operation(struct nouveau_channel *chan, int grclass,
533 int mthd, uint32_t data)
535 struct drm_device *dev = chan->dev;
536 uint32_t instance = nv_rd32(dev, NV04_PGRAPH_CTX_SWITCH4) & 0xffff;
537 int subc = (nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR) >> 13) & 0x7;
540 tmp = nv_ri32(dev, instance);
542 tmp |= ((data & 7) << 15);
544 nv_wi32(dev, instance, tmp);
545 nv_wr32(dev, NV04_PGRAPH_CTX_SWITCH1, tmp);
546 nv_wr32(dev, NV04_PGRAPH_CTX_CACHE1 + (subc<<2), tmp);
550 static struct nouveau_pgraph_object_method nv04_graph_mthds_m2mf[] = {
551 { 0x0150, nv04_graph_mthd_set_ref },
555 static struct nouveau_pgraph_object_method nv04_graph_mthds_set_operation[] = {
556 { 0x02fc, nv04_graph_mthd_set_operation },
560 struct nouveau_pgraph_object_class nv04_graph_grclass[] = {
561 { 0x0039, false, nv04_graph_mthds_m2mf },
562 { 0x004a, false, nv04_graph_mthds_set_operation }, /* gdirect */
563 { 0x005f, false, nv04_graph_mthds_set_operation }, /* imageblit */
564 { 0x0061, false, nv04_graph_mthds_set_operation }, /* ifc */
565 { 0x0077, false, nv04_graph_mthds_set_operation }, /* sifm */
566 { 0x0030, false, NULL }, /* null */
567 { 0x0042, false, NULL }, /* surf2d */
568 { 0x0043, false, NULL }, /* rop */
569 { 0x0012, false, NULL }, /* beta1 */
570 { 0x0072, false, NULL }, /* beta4 */
571 { 0x0019, false, NULL }, /* cliprect */
572 { 0x0044, false, NULL }, /* pattern */
573 { 0x0052, false, NULL }, /* swzsurf */
574 { 0x0053, false, NULL }, /* surf3d */
575 { 0x0054, false, NULL }, /* tex_tri */
576 { 0x0055, false, NULL }, /* multitex_tri */