Linux 2.6.33-rc6
[cris-mirror.git] / drivers / gpu / drm / nouveau / nv04_graph.c
blobe260986ea65af09281dc72dea034f1e975490b40
1 /*
2 * Copyright 2007 Stephane Marchesin
3 * All Rights Reserved.
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
14 * Software.
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.
25 #include "drmP.h"
26 #include "drm.h"
27 #include "nouveau_drm.h"
28 #include "nouveau_drv.h"
30 static uint32_t nv04_graph_ctx_regs[] = {
31 0x0040053c,
32 0x00400544,
33 0x00400540,
34 0x00400548,
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,
43 0x00400184,
44 0x004001a4,
45 0x004001c4,
46 0x004001e4,
47 0x00400188,
48 0x004001a8,
49 0x004001c8,
50 0x004001e8,
51 0x0040018c,
52 0x004001ac,
53 0x004001cc,
54 0x004001ec,
55 0x00400190,
56 0x004001b0,
57 0x004001d0,
58 0x004001f0,
59 0x00400194,
60 0x004001b4,
61 0x004001d4,
62 0x004001f4,
63 0x00400198,
64 0x004001b8,
65 0x004001d8,
66 0x004001f8,
67 0x0040019c,
68 0x004001bc,
69 0x004001dc,
70 0x004001fc,
71 0x00400174,
72 NV04_PGRAPH_DMA_START_0,
73 NV04_PGRAPH_DMA_START_1,
74 NV04_PGRAPH_DMA_LENGTH,
75 NV04_PGRAPH_DMA_MISC,
76 NV04_PGRAPH_DMA_PITCH,
77 NV04_PGRAPH_BOFFSET0,
78 NV04_PGRAPH_BBASE0,
79 NV04_PGRAPH_BLIMIT0,
80 NV04_PGRAPH_BOFFSET1,
81 NV04_PGRAPH_BBASE1,
82 NV04_PGRAPH_BLIMIT1,
83 NV04_PGRAPH_BOFFSET2,
84 NV04_PGRAPH_BBASE2,
85 NV04_PGRAPH_BLIMIT2,
86 NV04_PGRAPH_BOFFSET3,
87 NV04_PGRAPH_BBASE3,
88 NV04_PGRAPH_BLIMIT3,
89 NV04_PGRAPH_BOFFSET4,
90 NV04_PGRAPH_BBASE4,
91 NV04_PGRAPH_BLIMIT4,
92 NV04_PGRAPH_BOFFSET5,
93 NV04_PGRAPH_BBASE5,
94 NV04_PGRAPH_BLIMIT5,
95 NV04_PGRAPH_BPITCH0,
96 NV04_PGRAPH_BPITCH1,
97 NV04_PGRAPH_BPITCH2,
98 NV04_PGRAPH_BPITCH3,
99 NV04_PGRAPH_BPITCH4,
100 NV04_PGRAPH_SURFACE,
101 NV04_PGRAPH_STATE,
102 NV04_PGRAPH_BSWIZZLE2,
103 NV04_PGRAPH_BSWIZZLE5,
104 NV04_PGRAPH_BPIXEL,
105 NV04_PGRAPH_NOTIFY,
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,
172 NV04_PGRAPH_PATTERN,
173 0x0040080c,
174 NV04_PGRAPH_PATTERN_SHAPE,
175 0x00400600,
176 NV04_PGRAPH_ROP3,
177 NV04_PGRAPH_CHROMA,
178 NV04_PGRAPH_BETA_AND,
179 NV04_PGRAPH_BETA_PREMULT,
180 NV04_PGRAPH_CONTROL0,
181 NV04_PGRAPH_CONTROL1,
182 NV04_PGRAPH_CONTROL2,
183 NV04_PGRAPH_BLEND,
184 NV04_PGRAPH_STORED_FMT,
185 NV04_PGRAPH_SOURCE_COLOR,
186 0x00400560,
187 0x00400568,
188 0x00400564,
189 0x0040056c,
190 0x00400400,
191 0x00400480,
192 0x00400404,
193 0x00400484,
194 0x00400408,
195 0x00400488,
196 0x0040040c,
197 0x0040048c,
198 0x00400410,
199 0x00400490,
200 0x00400414,
201 0x00400494,
202 0x00400418,
203 0x00400498,
204 0x0040041c,
205 0x0040049c,
206 0x00400420,
207 0x004004a0,
208 0x00400424,
209 0x004004a4,
210 0x00400428,
211 0x004004a8,
212 0x0040042c,
213 0x004004ac,
214 0x00400430,
215 0x004004b0,
216 0x00400434,
217 0x004004b4,
218 0x00400438,
219 0x004004b8,
220 0x0040043c,
221 0x004004bc,
222 0x00400440,
223 0x004004c0,
224 0x00400444,
225 0x004004c4,
226 0x00400448,
227 0x004004c8,
228 0x0040044c,
229 0x004004cc,
230 0x00400450,
231 0x004004d0,
232 0x00400454,
233 0x004004d4,
234 0x00400458,
235 0x004004d8,
236 0x0040045c,
237 0x004004dc,
238 0x00400460,
239 0x004004e0,
240 0x00400464,
241 0x004004e4,
242 0x00400468,
243 0x004004e8,
244 0x0040046c,
245 0x004004ec,
246 0x00400470,
247 0x004004f0,
248 0x00400474,
249 0x004004f4,
250 0x00400478,
251 0x004004f8,
252 0x0040047c,
253 0x004004fc,
254 0x00400534,
255 0x00400538,
256 0x00400514,
257 0x00400518,
258 0x0040051c,
259 0x00400520,
260 0x00400524,
261 0x00400528,
262 0x0040052c,
263 0x00400530,
264 0x00400d00,
265 0x00400d40,
266 0x00400d80,
267 0x00400d04,
268 0x00400d44,
269 0x00400d84,
270 0x00400d08,
271 0x00400d48,
272 0x00400d88,
273 0x00400d0c,
274 0x00400d4c,
275 0x00400d8c,
276 0x00400d10,
277 0x00400d50,
278 0x00400d90,
279 0x00400d14,
280 0x00400d54,
281 0x00400d94,
282 0x00400d18,
283 0x00400d58,
284 0x00400d98,
285 0x00400d1c,
286 0x00400d5c,
287 0x00400d9c,
288 0x00400d20,
289 0x00400d60,
290 0x00400da0,
291 0x00400d24,
292 0x00400d64,
293 0x00400da4,
294 0x00400d28,
295 0x00400d68,
296 0x00400da8,
297 0x00400d2c,
298 0x00400d6c,
299 0x00400dac,
300 0x00400d30,
301 0x00400d70,
302 0x00400db0,
303 0x00400d34,
304 0x00400d74,
305 0x00400db4,
306 0x00400d38,
307 0x00400d78,
308 0x00400db8,
309 0x00400d3c,
310 0x00400d7c,
311 0x00400dbc,
312 0x00400590,
313 0x00400594,
314 0x00400598,
315 0x0040059c,
316 0x004005a8,
317 0x004005ac,
318 0x004005b0,
319 0x004005b4,
320 0x004005c0,
321 0x004005c4,
322 0x004005c8,
323 0x004005cc,
324 0x004005d0,
325 0x004005d4,
326 0x004005d8,
327 0x004005dc,
328 0x004005e0,
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,
337 0x00400500,
338 0x00400504,
339 NV04_PGRAPH_VALID1,
340 NV04_PGRAPH_VALID2,
341 NV04_PGRAPH_DEBUG_3
344 struct graph_state {
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)
358 return NULL;
360 return dev_priv->fifos[chid];
363 void
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;
369 int chid;
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];
380 if (chan)
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)
388 int i;
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];
395 return NULL;
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),
404 GFP_KERNEL);
405 if (pgraph_ctx == NULL)
406 return -ENOMEM;
408 *ctx_reg(pgraph_ctx, NV04_PGRAPH_DEBUG_3) = 0xfad4ff31;
410 return 0;
413 void nv04_graph_destroy_context(struct nouveau_channel *chan)
415 struct graph_state *pgraph_ctx = chan->pgraph_ctx;
417 kfree(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;
425 uint32_t tmp;
426 int i;
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);
439 return 0;
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;
449 uint32_t tmp;
450 int i;
452 chan = pgraph->channel(dev);
453 if (!chan)
454 return 0;
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);
464 return 0;
467 int nv04_graph_init(struct drm_device *dev)
469 struct drm_nouveau_private *dev_priv = dev->dev_private;
470 uint32_t tmp;
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);
492 /*haiku same*/
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);
508 return 0;
511 void nv04_graph_takedown(struct drm_device *dev)
515 void
516 nv04_graph_fifo_access(struct drm_device *dev, bool enabled)
518 if (enabled)
519 nv_wr32(dev, NV04_PGRAPH_FIFO,
520 nv_rd32(dev, NV04_PGRAPH_FIFO) | 1);
521 else
522 nv_wr32(dev, NV04_PGRAPH_FIFO,
523 nv_rd32(dev, NV04_PGRAPH_FIFO) & ~1);
526 static int
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);
532 return 0;
535 static int
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;
542 uint32_t tmp;
544 tmp = nv_ri32(dev, instance);
545 tmp &= ~0x00038000;
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);
551 return 0;
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 },