2 * Copyright 2007 Matthieu CASTET <castet.matthieu@free.fr>
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"
31 static void nv10_praph_pipe(drm_device_t *dev) {
32 drm_nouveau_private_t *dev_priv = dev->dev_private;
35 nouveau_wait_for_idle(dev);
36 /* XXX check haiku comments */
37 NV_WRITE(NV10_PGRAPH_XFMODE0, 0x10000000);
38 NV_WRITE(NV10_PGRAPH_XFMODE1, 0x00000000);
39 NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, 0x000064c0);
40 for (i = 0; i < 4; i++)
41 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x3f800000);
42 for (i = 0; i < 4; i++)
43 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
45 NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, 0x00006ab0);
47 for (i = 0; i < 3; i++)
48 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x3f800000);
50 NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, 0x00006a80);
51 for (i = 0; i < 3; i++)
52 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
54 NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, 0x00000040);
55 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000008);
57 NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, 0x00000200);
58 for (i = 0; i < 48; i++)
59 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
61 nouveau_wait_for_idle(dev);
63 NV_WRITE(NV10_PGRAPH_XFMODE0, 0x00000000);
64 NV_WRITE(NV10_PGRAPH_XFMODE1, 0x00000000);
65 NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, 0x00006400);
66 for (i = 0; i < 211; i++)
67 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
69 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x3f800000);
70 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x40000000);
71 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x40000000);
72 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x40000000);
73 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x40000000);
74 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
75 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
76 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x3f800000);
77 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
78 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x3f000000);
79 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x3f000000);
80 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
81 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
82 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
83 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
84 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x3f800000);
85 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
86 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
87 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
88 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
89 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
90 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x3f800000);
91 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x3f800000);
92 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x3f800000);
93 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x3f800000);
95 NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, 0x00006800);
96 for (i = 0; i < 162; i++)
97 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
98 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x3f800000);
99 for (i = 0; i < 25; i++)
100 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
102 NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, 0x00006c00);
103 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
104 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
105 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
106 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
107 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0xbf800000);
108 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
109 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
110 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
111 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
112 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
113 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
114 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
115 NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, 0x00007000);
116 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
117 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
118 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
119 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
120 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
121 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
122 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
123 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
124 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
125 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
126 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
127 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
128 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x7149f2ca);
129 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
130 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
131 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
132 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x7149f2ca);
133 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
134 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
135 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
136 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x7149f2ca);
137 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
138 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
139 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
140 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x7149f2ca);
141 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
142 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
143 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
144 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x7149f2ca);
145 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
146 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
147 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
148 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x7149f2ca);
149 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
150 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
151 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
152 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x7149f2ca);
153 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
154 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
155 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
156 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x7149f2ca);
157 for (i = 0; i < 35; i++)
158 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
161 NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, 0x00007400);
162 for (i = 0; i < 48; i++)
163 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
165 NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, 0x00007800);
166 for (i = 0; i < 48; i++)
167 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
169 NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, 0x00004400);
170 for (i = 0; i < 32; i++)
171 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
173 NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, 0x00000000);
174 for (i = 0; i < 16; i++)
175 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
177 NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, 0x00000040);
178 for (i = 0; i < 4; i++)
179 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000);
181 nouveau_wait_for_idle(dev);
184 /* TODO replace address with name
186 static int nv10_graph_ctx_regs [] = {
187 NV03_PGRAPH_XY_LOGIC_MISC0,
189 //NV10_PGRAPH_CTX_SWITCH1, make ctx switch crash
190 NV10_PGRAPH_CTX_SWITCH2,
191 NV10_PGRAPH_CTX_SWITCH3,
192 NV10_PGRAPH_CTX_SWITCH4,
193 NV10_PGRAPH_CTX_SWITCH5,
194 NV10_PGRAPH_CTX_CACHE1, /* 8 values from 0x400160 to 0x40017c */
195 NV10_PGRAPH_CTX_CACHE2, /* 8 values from 0x400180 to 0x40019c */
196 NV10_PGRAPH_CTX_CACHE3, /* 8 values from 0x4001a0 to 0x4001bc */
197 NV10_PGRAPH_CTX_CACHE4, /* 8 values from 0x4001c0 to 0x4001dc */
198 NV10_PGRAPH_CTX_CACHE5, /* 8 values from 0x4001e0 to 0x4001fc */
234 NV10_PGRAPH_CTX_USER,
235 NV04_PGRAPH_DMA_START_0,
236 NV04_PGRAPH_DMA_START_1,
237 NV04_PGRAPH_DMA_LENGTH,
238 NV04_PGRAPH_DMA_MISC,
239 NV10_PGRAPH_DMA_PITCH,
240 NV04_PGRAPH_BOFFSET0,
243 NV04_PGRAPH_BOFFSET1,
246 NV04_PGRAPH_BOFFSET2,
249 NV04_PGRAPH_BOFFSET3,
252 NV04_PGRAPH_BOFFSET4,
255 NV04_PGRAPH_BOFFSET5,
265 NV04_PGRAPH_BSWIZZLE2,
266 NV04_PGRAPH_BSWIZZLE5,
269 NV04_PGRAPH_PATT_COLOR0,
270 NV04_PGRAPH_PATT_COLOR1,
271 NV04_PGRAPH_PATT_COLORRAM, /* 64 values from 0x400900 to 0x4009fc */
335 NV04_PGRAPH_PATTERN, /* 2 values from 0x400808 to 0x40080c */
337 NV04_PGRAPH_PATTERN_SHAPE,
338 NV03_PGRAPH_MONO_COLOR0,
341 NV04_PGRAPH_BETA_AND,
342 NV04_PGRAPH_BETA_PREMULT,
358 NV10_PGRAPH_WINDOWCLIP_HORIZONTAL, /* 8 values from 0x400f00 to 0x400f1c */
359 NV10_PGRAPH_WINDOWCLIP_VERTICAL, /* 8 values from 0x400f20 to 0x400f3c */
376 NV10_PGRAPH_GLOBALSTATE0,
377 NV10_PGRAPH_GLOBALSTATE1,
378 NV04_PGRAPH_STORED_FMT,
379 NV04_PGRAPH_SOURCE_COLOR,
380 NV03_PGRAPH_ABS_X_RAM, /* 32 values from 0x400400 to 0x40047c */
381 NV03_PGRAPH_ABS_Y_RAM, /* 32 values from 0x400480 to 0x4004fc */
444 NV03_PGRAPH_ABS_UCLIP_XMIN,
445 NV03_PGRAPH_ABS_UCLIP_XMAX,
446 NV03_PGRAPH_ABS_UCLIP_YMIN,
447 NV03_PGRAPH_ABS_UCLIP_YMAX,
452 NV03_PGRAPH_ABS_UCLIPA_XMIN,
453 NV03_PGRAPH_ABS_UCLIPA_XMAX,
454 NV03_PGRAPH_ABS_UCLIPA_YMIN,
455 NV03_PGRAPH_ABS_UCLIPA_YMAX,
456 NV03_PGRAPH_ABS_ICLIP_XMAX,
457 NV03_PGRAPH_ABS_ICLIP_YMAX,
458 NV03_PGRAPH_XY_LOGIC_MISC1,
459 NV03_PGRAPH_XY_LOGIC_MISC2,
460 NV03_PGRAPH_XY_LOGIC_MISC3,
493 NV04_PGRAPH_PASSTHRU_0,
494 NV04_PGRAPH_PASSTHRU_1,
495 NV04_PGRAPH_PASSTHRU_2,
496 NV10_PGRAPH_DIMX_TEXTURE,
497 NV10_PGRAPH_WDIMX_TEXTURE,
498 NV10_PGRAPH_DVD_COLORFMT,
499 NV10_PGRAPH_SCALED_FORMAT,
500 NV04_PGRAPH_MISC24_0,
501 NV04_PGRAPH_MISC24_1,
502 NV04_PGRAPH_MISC24_2,
509 static int nv17_graph_ctx_regs [] = {
530 void nouveau_nv10_context_switch(drm_device_t *dev)
532 drm_nouveau_private_t *dev_priv = dev->dev_private;
533 int channel, channel_old, i, j;
535 channel=NV_READ(NV03_PFIFO_CACHE1_PUSH1)&(nouveau_fifo_number(dev)-1);
536 channel_old = (NV_READ(NV10_PGRAPH_CTX_USER) >> 24) & (nouveau_fifo_number(dev)-1);
538 DRM_INFO("NV: PGRAPH context switch interrupt channel %x -> %x\n",channel_old, channel);
540 NV_WRITE(NV04_PGRAPH_FIFO,0x0);
542 NV_WRITE(NV_PFIFO_CACH1_PUL0, 0x00000000);
543 NV_WRITE(NV_PFIFO_CACH1_PUL1, 0x00000000);
544 NV_WRITE(NV_PFIFO_CACHES, 0x00000000);
547 // save PGRAPH context
548 for (i = 0; i < sizeof(nv10_graph_ctx_regs)/sizeof(nv10_graph_ctx_regs[0]); i++)
549 dev_priv->fifos[channel_old].pgraph_ctx[i] = NV_READ(nv10_graph_ctx_regs[i]);
550 if (dev_priv->chipset>=0x17) {
551 for (j = 0; j < sizeof(nv17_graph_ctx_regs)/sizeof(nv17_graph_ctx_regs[0]); i++,j++)
552 dev_priv->fifos[channel_old].pgraph_ctx[i] = NV_READ(nv17_graph_ctx_regs[j]);
555 nouveau_wait_for_idle(dev);
557 NV_WRITE(NV03_PGRAPH_CTX_CONTROL, 0x10000000);
558 NV_WRITE(NV10_PGRAPH_CTX_USER, (NV_READ(NV10_PGRAPH_CTX_USER) & 0xffffff) | (0x1f << 24));
560 nouveau_wait_for_idle(dev);
561 // restore PGRAPH context
562 //XXX not working yet
564 for (i = 0; i < sizeof(nv10_graph_ctx_regs)/sizeof(nv10_graph_ctx_regs[0]); i++)
565 NV_WRITE(nv10_graph_ctx_regs[i], dev_priv->fifos[channel].pgraph_ctx[i]);
566 if (dev_priv->chipset>=0x17) {
567 for (j = 0; j < sizeof(nv17_graph_ctx_regs)/sizeof(nv17_graph_ctx_regs[0]); i++,j++)
568 NV_WRITE(nv17_graph_ctx_regs[j], dev_priv->fifos[channel].pgraph_ctx[i]);
570 nouveau_wait_for_idle(dev);
573 NV_WRITE(NV03_PGRAPH_CTX_CONTROL, 0x10010100);
574 NV_WRITE(NV10_PGRAPH_CTX_USER, channel << 24);
575 NV_WRITE(NV10_PGRAPH_FFINTFC_ST2, NV_READ(NV10_PGRAPH_FFINTFC_ST2)&0xCFFFFFFF);
578 NV_WRITE(NV_PFIFO_CACH1_PUL0, 0x00000001);
579 NV_WRITE(NV_PFIFO_CACH1_PUL1, 0x00000001);
580 NV_WRITE(NV_PFIFO_CACHES, 0x00000001);
582 NV_WRITE(NV04_PGRAPH_FIFO,0x1);
585 int nv10_graph_context_create(drm_device_t *dev, int channel) {
586 drm_nouveau_private_t *dev_priv = dev->dev_private;
587 DRM_DEBUG("nv10_graph_context_create %d\n", channel);
589 memset(dev_priv->fifos[channel].pgraph_ctx, 0, sizeof(dev_priv->fifos[channel].pgraph_ctx));
591 //dev_priv->fifos[channel].pgraph_ctx_user = channel << 24;
592 dev_priv->fifos[channel].pgraph_ctx[0] = 0x0001ffff;
593 /* is it really needed ??? */
594 if (dev_priv->chipset>=0x17) {
595 dev_priv->fifos[channel].pgraph_ctx[sizeof(nv10_graph_ctx_regs) + 0] = NV_READ(NV10_PGRAPH_DEBUG_4);
596 dev_priv->fifos[channel].pgraph_ctx[sizeof(nv10_graph_ctx_regs) + 1] = NV_READ(0x004006b0);
600 //XXX should be saved/restored for each fifo
601 //we supposed here we have X fifo and only one 3D fifo.
602 nv10_praph_pipe(dev);
607 int nv10_graph_init(drm_device_t *dev) {