blob: 0bc616d35eb6ac11649e1c4b5d22dc2185974b17 [file] [log] [blame]
Ben Skeggs6ee73862009-12-11 19:24:15 +10001/*
2 * Copyright 2007 Stephane Marchesin
3 * All Rights Reserved.
4 *
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:
11 *
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.
15 *
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.
23 */
24
25#include "drmP.h"
26#include "drm.h"
27#include "nouveau_drm.h"
28#include "nouveau_drv.h"
Francisco Jerez332b2422010-10-20 23:35:40 +020029#include "nouveau_hw.h"
Ben Skeggs274fec92010-11-03 13:16:18 +100030#include "nouveau_util.h"
Ben Skeggs6ee73862009-12-11 19:24:15 +100031
Ben Skeggs274fec92010-11-03 13:16:18 +100032static int nv04_graph_register(struct drm_device *dev);
33static void nv04_graph_isr(struct drm_device *dev);
Ben Skeggsb8c157d2010-10-20 10:39:35 +100034
Ben Skeggs6ee73862009-12-11 19:24:15 +100035static uint32_t nv04_graph_ctx_regs[] = {
Francisco Jerezea911a12009-12-26 14:39:46 +010036 0x0040053c,
37 0x00400544,
38 0x00400540,
39 0x00400548,
Ben Skeggs6ee73862009-12-11 19:24:15 +100040 NV04_PGRAPH_CTX_SWITCH1,
41 NV04_PGRAPH_CTX_SWITCH2,
42 NV04_PGRAPH_CTX_SWITCH3,
43 NV04_PGRAPH_CTX_SWITCH4,
44 NV04_PGRAPH_CTX_CACHE1,
45 NV04_PGRAPH_CTX_CACHE2,
46 NV04_PGRAPH_CTX_CACHE3,
47 NV04_PGRAPH_CTX_CACHE4,
48 0x00400184,
49 0x004001a4,
50 0x004001c4,
51 0x004001e4,
52 0x00400188,
53 0x004001a8,
54 0x004001c8,
55 0x004001e8,
56 0x0040018c,
57 0x004001ac,
58 0x004001cc,
59 0x004001ec,
60 0x00400190,
61 0x004001b0,
62 0x004001d0,
63 0x004001f0,
64 0x00400194,
65 0x004001b4,
66 0x004001d4,
67 0x004001f4,
68 0x00400198,
69 0x004001b8,
70 0x004001d8,
71 0x004001f8,
72 0x0040019c,
73 0x004001bc,
74 0x004001dc,
75 0x004001fc,
76 0x00400174,
77 NV04_PGRAPH_DMA_START_0,
78 NV04_PGRAPH_DMA_START_1,
79 NV04_PGRAPH_DMA_LENGTH,
80 NV04_PGRAPH_DMA_MISC,
81 NV04_PGRAPH_DMA_PITCH,
82 NV04_PGRAPH_BOFFSET0,
83 NV04_PGRAPH_BBASE0,
84 NV04_PGRAPH_BLIMIT0,
85 NV04_PGRAPH_BOFFSET1,
86 NV04_PGRAPH_BBASE1,
87 NV04_PGRAPH_BLIMIT1,
88 NV04_PGRAPH_BOFFSET2,
89 NV04_PGRAPH_BBASE2,
90 NV04_PGRAPH_BLIMIT2,
91 NV04_PGRAPH_BOFFSET3,
92 NV04_PGRAPH_BBASE3,
93 NV04_PGRAPH_BLIMIT3,
94 NV04_PGRAPH_BOFFSET4,
95 NV04_PGRAPH_BBASE4,
96 NV04_PGRAPH_BLIMIT4,
97 NV04_PGRAPH_BOFFSET5,
98 NV04_PGRAPH_BBASE5,
99 NV04_PGRAPH_BLIMIT5,
100 NV04_PGRAPH_BPITCH0,
101 NV04_PGRAPH_BPITCH1,
102 NV04_PGRAPH_BPITCH2,
103 NV04_PGRAPH_BPITCH3,
104 NV04_PGRAPH_BPITCH4,
105 NV04_PGRAPH_SURFACE,
106 NV04_PGRAPH_STATE,
107 NV04_PGRAPH_BSWIZZLE2,
108 NV04_PGRAPH_BSWIZZLE5,
109 NV04_PGRAPH_BPIXEL,
110 NV04_PGRAPH_NOTIFY,
111 NV04_PGRAPH_PATT_COLOR0,
112 NV04_PGRAPH_PATT_COLOR1,
113 NV04_PGRAPH_PATT_COLORRAM+0x00,
Ben Skeggs6ee73862009-12-11 19:24:15 +1000114 NV04_PGRAPH_PATT_COLORRAM+0x04,
Ben Skeggs6ee73862009-12-11 19:24:15 +1000115 NV04_PGRAPH_PATT_COLORRAM+0x08,
Francisco Jerezea911a12009-12-26 14:39:46 +0100116 NV04_PGRAPH_PATT_COLORRAM+0x0c,
Ben Skeggs6ee73862009-12-11 19:24:15 +1000117 NV04_PGRAPH_PATT_COLORRAM+0x10,
Ben Skeggs6ee73862009-12-11 19:24:15 +1000118 NV04_PGRAPH_PATT_COLORRAM+0x14,
Ben Skeggs6ee73862009-12-11 19:24:15 +1000119 NV04_PGRAPH_PATT_COLORRAM+0x18,
Francisco Jerezea911a12009-12-26 14:39:46 +0100120 NV04_PGRAPH_PATT_COLORRAM+0x1c,
Ben Skeggs6ee73862009-12-11 19:24:15 +1000121 NV04_PGRAPH_PATT_COLORRAM+0x20,
Ben Skeggs6ee73862009-12-11 19:24:15 +1000122 NV04_PGRAPH_PATT_COLORRAM+0x24,
Ben Skeggs6ee73862009-12-11 19:24:15 +1000123 NV04_PGRAPH_PATT_COLORRAM+0x28,
Francisco Jerezea911a12009-12-26 14:39:46 +0100124 NV04_PGRAPH_PATT_COLORRAM+0x2c,
Ben Skeggs6ee73862009-12-11 19:24:15 +1000125 NV04_PGRAPH_PATT_COLORRAM+0x30,
Ben Skeggs6ee73862009-12-11 19:24:15 +1000126 NV04_PGRAPH_PATT_COLORRAM+0x34,
Ben Skeggs6ee73862009-12-11 19:24:15 +1000127 NV04_PGRAPH_PATT_COLORRAM+0x38,
Francisco Jerezea911a12009-12-26 14:39:46 +0100128 NV04_PGRAPH_PATT_COLORRAM+0x3c,
129 NV04_PGRAPH_PATT_COLORRAM+0x40,
130 NV04_PGRAPH_PATT_COLORRAM+0x44,
131 NV04_PGRAPH_PATT_COLORRAM+0x48,
132 NV04_PGRAPH_PATT_COLORRAM+0x4c,
133 NV04_PGRAPH_PATT_COLORRAM+0x50,
134 NV04_PGRAPH_PATT_COLORRAM+0x54,
135 NV04_PGRAPH_PATT_COLORRAM+0x58,
136 NV04_PGRAPH_PATT_COLORRAM+0x5c,
137 NV04_PGRAPH_PATT_COLORRAM+0x60,
138 NV04_PGRAPH_PATT_COLORRAM+0x64,
139 NV04_PGRAPH_PATT_COLORRAM+0x68,
140 NV04_PGRAPH_PATT_COLORRAM+0x6c,
141 NV04_PGRAPH_PATT_COLORRAM+0x70,
142 NV04_PGRAPH_PATT_COLORRAM+0x74,
143 NV04_PGRAPH_PATT_COLORRAM+0x78,
144 NV04_PGRAPH_PATT_COLORRAM+0x7c,
145 NV04_PGRAPH_PATT_COLORRAM+0x80,
146 NV04_PGRAPH_PATT_COLORRAM+0x84,
147 NV04_PGRAPH_PATT_COLORRAM+0x88,
148 NV04_PGRAPH_PATT_COLORRAM+0x8c,
149 NV04_PGRAPH_PATT_COLORRAM+0x90,
150 NV04_PGRAPH_PATT_COLORRAM+0x94,
151 NV04_PGRAPH_PATT_COLORRAM+0x98,
152 NV04_PGRAPH_PATT_COLORRAM+0x9c,
153 NV04_PGRAPH_PATT_COLORRAM+0xa0,
154 NV04_PGRAPH_PATT_COLORRAM+0xa4,
155 NV04_PGRAPH_PATT_COLORRAM+0xa8,
156 NV04_PGRAPH_PATT_COLORRAM+0xac,
157 NV04_PGRAPH_PATT_COLORRAM+0xb0,
158 NV04_PGRAPH_PATT_COLORRAM+0xb4,
159 NV04_PGRAPH_PATT_COLORRAM+0xb8,
160 NV04_PGRAPH_PATT_COLORRAM+0xbc,
161 NV04_PGRAPH_PATT_COLORRAM+0xc0,
162 NV04_PGRAPH_PATT_COLORRAM+0xc4,
163 NV04_PGRAPH_PATT_COLORRAM+0xc8,
164 NV04_PGRAPH_PATT_COLORRAM+0xcc,
165 NV04_PGRAPH_PATT_COLORRAM+0xd0,
166 NV04_PGRAPH_PATT_COLORRAM+0xd4,
167 NV04_PGRAPH_PATT_COLORRAM+0xd8,
168 NV04_PGRAPH_PATT_COLORRAM+0xdc,
169 NV04_PGRAPH_PATT_COLORRAM+0xe0,
170 NV04_PGRAPH_PATT_COLORRAM+0xe4,
171 NV04_PGRAPH_PATT_COLORRAM+0xe8,
172 NV04_PGRAPH_PATT_COLORRAM+0xec,
173 NV04_PGRAPH_PATT_COLORRAM+0xf0,
174 NV04_PGRAPH_PATT_COLORRAM+0xf4,
175 NV04_PGRAPH_PATT_COLORRAM+0xf8,
176 NV04_PGRAPH_PATT_COLORRAM+0xfc,
Ben Skeggs6ee73862009-12-11 19:24:15 +1000177 NV04_PGRAPH_PATTERN,
178 0x0040080c,
179 NV04_PGRAPH_PATTERN_SHAPE,
180 0x00400600,
181 NV04_PGRAPH_ROP3,
182 NV04_PGRAPH_CHROMA,
183 NV04_PGRAPH_BETA_AND,
184 NV04_PGRAPH_BETA_PREMULT,
185 NV04_PGRAPH_CONTROL0,
186 NV04_PGRAPH_CONTROL1,
187 NV04_PGRAPH_CONTROL2,
188 NV04_PGRAPH_BLEND,
189 NV04_PGRAPH_STORED_FMT,
190 NV04_PGRAPH_SOURCE_COLOR,
191 0x00400560,
192 0x00400568,
193 0x00400564,
194 0x0040056c,
195 0x00400400,
196 0x00400480,
197 0x00400404,
198 0x00400484,
199 0x00400408,
200 0x00400488,
201 0x0040040c,
202 0x0040048c,
203 0x00400410,
204 0x00400490,
205 0x00400414,
206 0x00400494,
207 0x00400418,
208 0x00400498,
209 0x0040041c,
210 0x0040049c,
211 0x00400420,
212 0x004004a0,
213 0x00400424,
214 0x004004a4,
215 0x00400428,
216 0x004004a8,
217 0x0040042c,
218 0x004004ac,
219 0x00400430,
220 0x004004b0,
221 0x00400434,
222 0x004004b4,
223 0x00400438,
224 0x004004b8,
225 0x0040043c,
226 0x004004bc,
227 0x00400440,
228 0x004004c0,
229 0x00400444,
230 0x004004c4,
231 0x00400448,
232 0x004004c8,
233 0x0040044c,
234 0x004004cc,
235 0x00400450,
236 0x004004d0,
237 0x00400454,
238 0x004004d4,
239 0x00400458,
240 0x004004d8,
241 0x0040045c,
242 0x004004dc,
243 0x00400460,
244 0x004004e0,
245 0x00400464,
246 0x004004e4,
247 0x00400468,
248 0x004004e8,
249 0x0040046c,
250 0x004004ec,
251 0x00400470,
252 0x004004f0,
253 0x00400474,
254 0x004004f4,
255 0x00400478,
256 0x004004f8,
257 0x0040047c,
258 0x004004fc,
Ben Skeggs6ee73862009-12-11 19:24:15 +1000259 0x00400534,
260 0x00400538,
261 0x00400514,
262 0x00400518,
263 0x0040051c,
264 0x00400520,
265 0x00400524,
266 0x00400528,
267 0x0040052c,
268 0x00400530,
269 0x00400d00,
270 0x00400d40,
271 0x00400d80,
272 0x00400d04,
273 0x00400d44,
274 0x00400d84,
275 0x00400d08,
276 0x00400d48,
277 0x00400d88,
278 0x00400d0c,
279 0x00400d4c,
280 0x00400d8c,
281 0x00400d10,
282 0x00400d50,
283 0x00400d90,
284 0x00400d14,
285 0x00400d54,
286 0x00400d94,
287 0x00400d18,
288 0x00400d58,
289 0x00400d98,
290 0x00400d1c,
291 0x00400d5c,
292 0x00400d9c,
293 0x00400d20,
294 0x00400d60,
295 0x00400da0,
296 0x00400d24,
297 0x00400d64,
298 0x00400da4,
299 0x00400d28,
300 0x00400d68,
301 0x00400da8,
302 0x00400d2c,
303 0x00400d6c,
304 0x00400dac,
305 0x00400d30,
306 0x00400d70,
307 0x00400db0,
308 0x00400d34,
309 0x00400d74,
310 0x00400db4,
311 0x00400d38,
312 0x00400d78,
313 0x00400db8,
314 0x00400d3c,
315 0x00400d7c,
316 0x00400dbc,
317 0x00400590,
318 0x00400594,
319 0x00400598,
320 0x0040059c,
321 0x004005a8,
322 0x004005ac,
323 0x004005b0,
324 0x004005b4,
325 0x004005c0,
326 0x004005c4,
327 0x004005c8,
328 0x004005cc,
329 0x004005d0,
330 0x004005d4,
331 0x004005d8,
332 0x004005dc,
333 0x004005e0,
334 NV04_PGRAPH_PASSTHRU_0,
335 NV04_PGRAPH_PASSTHRU_1,
336 NV04_PGRAPH_PASSTHRU_2,
337 NV04_PGRAPH_DVD_COLORFMT,
338 NV04_PGRAPH_SCALED_FORMAT,
339 NV04_PGRAPH_MISC24_0,
340 NV04_PGRAPH_MISC24_1,
341 NV04_PGRAPH_MISC24_2,
342 0x00400500,
343 0x00400504,
344 NV04_PGRAPH_VALID1,
Francisco Jerezea911a12009-12-26 14:39:46 +0100345 NV04_PGRAPH_VALID2,
346 NV04_PGRAPH_DEBUG_3
Ben Skeggs6ee73862009-12-11 19:24:15 +1000347};
348
349struct graph_state {
Francisco Jerez6e86e042010-07-03 18:36:39 +0200350 uint32_t nv04[ARRAY_SIZE(nv04_graph_ctx_regs)];
Ben Skeggs6ee73862009-12-11 19:24:15 +1000351};
352
353struct nouveau_channel *
354nv04_graph_channel(struct drm_device *dev)
355{
356 struct drm_nouveau_private *dev_priv = dev->dev_private;
357 int chid = dev_priv->engine.fifo.channels;
358
359 if (nv_rd32(dev, NV04_PGRAPH_CTX_CONTROL) & 0x00010000)
360 chid = nv_rd32(dev, NV04_PGRAPH_CTX_USER) >> 24;
361
362 if (chid >= dev_priv->engine.fifo.channels)
363 return NULL;
364
Ben Skeggscff5c132010-10-06 16:16:59 +1000365 return dev_priv->channels.ptr[chid];
Ben Skeggs6ee73862009-12-11 19:24:15 +1000366}
367
Ben Skeggs274fec92010-11-03 13:16:18 +1000368static void
Ben Skeggs6ee73862009-12-11 19:24:15 +1000369nv04_graph_context_switch(struct drm_device *dev)
370{
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;
374 int chid;
375
376 pgraph->fifo_access(dev, false);
377 nouveau_wait_for_idle(dev);
378
379 /* If previous context is valid, we need to save it */
380 pgraph->unload_context(dev);
381
382 /* Load context for next channel */
383 chid = dev_priv->engine.fifo.channel_id(dev);
Ben Skeggscff5c132010-10-06 16:16:59 +1000384 chan = dev_priv->channels.ptr[chid];
Ben Skeggs6ee73862009-12-11 19:24:15 +1000385 if (chan)
386 nv04_graph_load_context(chan);
387
388 pgraph->fifo_access(dev, true);
389}
390
Francisco Jerezea911a12009-12-26 14:39:46 +0100391static uint32_t *ctx_reg(struct graph_state *ctx, uint32_t reg)
392{
393 int i;
394
395 for (i = 0; i < ARRAY_SIZE(nv04_graph_ctx_regs); i++) {
396 if (nv04_graph_ctx_regs[i] == reg)
397 return &ctx->nv04[i];
398 }
399
400 return NULL;
401}
402
Ben Skeggs6ee73862009-12-11 19:24:15 +1000403int nv04_graph_create_context(struct nouveau_channel *chan)
404{
405 struct graph_state *pgraph_ctx;
406 NV_DEBUG(chan->dev, "nv04_graph_context_create %d\n", chan->id);
407
408 chan->pgraph_ctx = pgraph_ctx = kzalloc(sizeof(*pgraph_ctx),
409 GFP_KERNEL);
410 if (pgraph_ctx == NULL)
411 return -ENOMEM;
412
Francisco Jerezea911a12009-12-26 14:39:46 +0100413 *ctx_reg(pgraph_ctx, NV04_PGRAPH_DEBUG_3) = 0xfad4ff31;
414
Ben Skeggs6ee73862009-12-11 19:24:15 +1000415 return 0;
416}
417
418void nv04_graph_destroy_context(struct nouveau_channel *chan)
419{
Francisco Jerez3945e472010-10-18 03:53:39 +0200420 struct drm_device *dev = chan->dev;
421 struct drm_nouveau_private *dev_priv = dev->dev_private;
422 struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
Ben Skeggs6ee73862009-12-11 19:24:15 +1000423 struct graph_state *pgraph_ctx = chan->pgraph_ctx;
Francisco Jerez3945e472010-10-18 03:53:39 +0200424 unsigned long flags;
Ben Skeggs6ee73862009-12-11 19:24:15 +1000425
Francisco Jerez3945e472010-10-18 03:53:39 +0200426 spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
427 pgraph->fifo_access(dev, false);
428
429 /* Unload the context if it's the currently active one */
430 if (pgraph->channel(dev) == chan)
431 pgraph->unload_context(dev);
432
433 /* Free the context resources */
Ben Skeggs6ee73862009-12-11 19:24:15 +1000434 kfree(pgraph_ctx);
435 chan->pgraph_ctx = NULL;
Francisco Jerez3945e472010-10-18 03:53:39 +0200436
437 pgraph->fifo_access(dev, true);
438 spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
Ben Skeggs6ee73862009-12-11 19:24:15 +1000439}
440
441int nv04_graph_load_context(struct nouveau_channel *chan)
442{
443 struct drm_device *dev = chan->dev;
444 struct graph_state *pgraph_ctx = chan->pgraph_ctx;
445 uint32_t tmp;
446 int i;
447
448 for (i = 0; i < ARRAY_SIZE(nv04_graph_ctx_regs); i++)
449 nv_wr32(dev, nv04_graph_ctx_regs[i], pgraph_ctx->nv04[i]);
450
451 nv_wr32(dev, NV04_PGRAPH_CTX_CONTROL, 0x10010100);
Francisco Jerezea911a12009-12-26 14:39:46 +0100452
453 tmp = nv_rd32(dev, NV04_PGRAPH_CTX_USER) & 0x00ffffff;
454 nv_wr32(dev, NV04_PGRAPH_CTX_USER, tmp | chan->id << 24);
455
Ben Skeggs6ee73862009-12-11 19:24:15 +1000456 tmp = nv_rd32(dev, NV04_PGRAPH_FFINTFC_ST2);
457 nv_wr32(dev, NV04_PGRAPH_FFINTFC_ST2, tmp & 0x000fffff);
Francisco Jerezea911a12009-12-26 14:39:46 +0100458
Ben Skeggs6ee73862009-12-11 19:24:15 +1000459 return 0;
460}
461
462int
463nv04_graph_unload_context(struct drm_device *dev)
464{
465 struct drm_nouveau_private *dev_priv = dev->dev_private;
466 struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
467 struct nouveau_channel *chan = NULL;
468 struct graph_state *ctx;
469 uint32_t tmp;
470 int i;
471
472 chan = pgraph->channel(dev);
473 if (!chan)
474 return 0;
475 ctx = chan->pgraph_ctx;
476
477 for (i = 0; i < ARRAY_SIZE(nv04_graph_ctx_regs); i++)
478 ctx->nv04[i] = nv_rd32(dev, nv04_graph_ctx_regs[i]);
479
480 nv_wr32(dev, NV04_PGRAPH_CTX_CONTROL, 0x10000000);
481 tmp = nv_rd32(dev, NV04_PGRAPH_CTX_USER) & 0x00ffffff;
482 tmp |= (dev_priv->engine.fifo.channels - 1) << 24;
483 nv_wr32(dev, NV04_PGRAPH_CTX_USER, tmp);
484 return 0;
485}
486
487int nv04_graph_init(struct drm_device *dev)
488{
489 struct drm_nouveau_private *dev_priv = dev->dev_private;
490 uint32_t tmp;
Ben Skeggsb8c157d2010-10-20 10:39:35 +1000491 int ret;
Ben Skeggs6ee73862009-12-11 19:24:15 +1000492
493 nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) &
494 ~NV_PMC_ENABLE_PGRAPH);
495 nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) |
496 NV_PMC_ENABLE_PGRAPH);
497
Ben Skeggsb8c157d2010-10-20 10:39:35 +1000498 ret = nv04_graph_register(dev);
499 if (ret)
500 return ret;
501
Ben Skeggs6ee73862009-12-11 19:24:15 +1000502 /* Enable PGRAPH interrupts */
Ben Skeggs274fec92010-11-03 13:16:18 +1000503 nouveau_irq_register(dev, 12, nv04_graph_isr);
Ben Skeggs6ee73862009-12-11 19:24:15 +1000504 nv_wr32(dev, NV03_PGRAPH_INTR, 0xFFFFFFFF);
505 nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);
506
507 nv_wr32(dev, NV04_PGRAPH_VALID1, 0);
508 nv_wr32(dev, NV04_PGRAPH_VALID2, 0);
509 /*nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x000001FF);
510 nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x001FFFFF);*/
511 nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x1231c000);
512 /*1231C000 blob, 001 haiku*/
513 //*V_WRITE(NV04_PGRAPH_DEBUG_1, 0xf2d91100);*/
514 nv_wr32(dev, NV04_PGRAPH_DEBUG_1, 0x72111100);
515 /*0x72111100 blob , 01 haiku*/
516 /*nv_wr32(dev, NV04_PGRAPH_DEBUG_2, 0x11d5f870);*/
517 nv_wr32(dev, NV04_PGRAPH_DEBUG_2, 0x11d5f071);
518 /*haiku same*/
519
520 /*nv_wr32(dev, NV04_PGRAPH_DEBUG_3, 0xfad4ff31);*/
521 nv_wr32(dev, NV04_PGRAPH_DEBUG_3, 0xf0d4ff31);
522 /*haiku and blob 10d4*/
523
524 nv_wr32(dev, NV04_PGRAPH_STATE , 0xFFFFFFFF);
525 nv_wr32(dev, NV04_PGRAPH_CTX_CONTROL , 0x10000100);
526 tmp = nv_rd32(dev, NV04_PGRAPH_CTX_USER) & 0x00ffffff;
Francisco Jerezea911a12009-12-26 14:39:46 +0100527 tmp |= (dev_priv->engine.fifo.channels - 1) << 24;
Ben Skeggs6ee73862009-12-11 19:24:15 +1000528 nv_wr32(dev, NV04_PGRAPH_CTX_USER, tmp);
529
530 /* These don't belong here, they're part of a per-channel context */
531 nv_wr32(dev, NV04_PGRAPH_PATTERN_SHAPE, 0x00000000);
532 nv_wr32(dev, NV04_PGRAPH_BETA_AND , 0xFFFFFFFF);
533
534 return 0;
535}
536
537void nv04_graph_takedown(struct drm_device *dev)
538{
Ben Skeggs274fec92010-11-03 13:16:18 +1000539 nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0x00000000);
540 nouveau_irq_unregister(dev, 12);
Ben Skeggs6ee73862009-12-11 19:24:15 +1000541}
542
543void
544nv04_graph_fifo_access(struct drm_device *dev, bool enabled)
545{
546 if (enabled)
547 nv_wr32(dev, NV04_PGRAPH_FIFO,
548 nv_rd32(dev, NV04_PGRAPH_FIFO) | 1);
549 else
550 nv_wr32(dev, NV04_PGRAPH_FIFO,
551 nv_rd32(dev, NV04_PGRAPH_FIFO) & ~1);
552}
553
554static int
Ben Skeggsb8c157d2010-10-20 10:39:35 +1000555nv04_graph_mthd_set_ref(struct nouveau_channel *chan,
556 u32 class, u32 mthd, u32 data)
Ben Skeggs6ee73862009-12-11 19:24:15 +1000557{
Ben Skeggs047d1d32010-05-31 12:00:43 +1000558 atomic_set(&chan->fence.last_sequence_irq, data);
Ben Skeggs6ee73862009-12-11 19:24:15 +1000559 return 0;
560}
561
Francisco Jerez332b2422010-10-20 23:35:40 +0200562int
563nv04_graph_mthd_page_flip(struct nouveau_channel *chan,
564 u32 class, u32 mthd, u32 data)
565{
566 struct drm_device *dev = chan->dev;
567 struct nouveau_page_flip_state s;
568
569 if (!nouveau_finish_page_flip(chan, &s))
570 nv_set_crtc_base(dev, s.crtc,
571 s.offset + s.y * s.pitch + s.x * s.bpp / 8);
572
573 return 0;
574}
575
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000576/*
577 * Software methods, why they are needed, and how they all work:
578 *
579 * NV04 and NV05 keep most of the state in PGRAPH context itself, but some
580 * 2d engine settings are kept inside the grobjs themselves. The grobjs are
581 * 3 words long on both. grobj format on NV04 is:
582 *
583 * word 0:
584 * - bits 0-7: class
585 * - bit 12: color key active
586 * - bit 13: clip rect active
587 * - bit 14: if set, destination surface is swizzled and taken from buffer 5
588 * [set by NV04_SWIZZLED_SURFACE], otherwise it's linear and taken
589 * from buffer 0 [set by NV04_CONTEXT_SURFACES_2D or
590 * NV03_CONTEXT_SURFACE_DST].
591 * - bits 15-17: 2d operation [aka patch config]
592 * - bit 24: patch valid [enables rendering using this object]
593 * - bit 25: surf3d valid [for tex_tri and multitex_tri only]
594 * word 1:
595 * - bits 0-1: mono format
596 * - bits 8-13: color format
597 * - bits 16-31: DMA_NOTIFY instance
598 * word 2:
599 * - bits 0-15: DMA_A instance
600 * - bits 16-31: DMA_B instance
601 *
602 * On NV05 it's:
603 *
604 * word 0:
605 * - bits 0-7: class
606 * - bit 12: color key active
607 * - bit 13: clip rect active
608 * - bit 14: if set, destination surface is swizzled and taken from buffer 5
609 * [set by NV04_SWIZZLED_SURFACE], otherwise it's linear and taken
610 * from buffer 0 [set by NV04_CONTEXT_SURFACES_2D or
611 * NV03_CONTEXT_SURFACE_DST].
612 * - bits 15-17: 2d operation [aka patch config]
613 * - bits 20-22: dither mode
614 * - bit 24: patch valid [enables rendering using this object]
615 * - bit 25: surface_dst/surface_color/surf2d/surf3d valid
616 * - bit 26: surface_src/surface_zeta valid
617 * - bit 27: pattern valid
618 * - bit 28: rop valid
619 * - bit 29: beta1 valid
620 * - bit 30: beta4 valid
621 * word 1:
622 * - bits 0-1: mono format
623 * - bits 8-13: color format
624 * - bits 16-31: DMA_NOTIFY instance
625 * word 2:
626 * - bits 0-15: DMA_A instance
627 * - bits 16-31: DMA_B instance
628 *
629 * NV05 will set/unset the relevant valid bits when you poke the relevant
630 * object-binding methods with object of the proper type, or with the NULL
631 * type. It'll only allow rendering using the grobj if all needed objects
632 * are bound. The needed set of objects depends on selected operation: for
633 * example rop object is needed by ROP_AND, but not by SRCCOPY_AND.
634 *
635 * NV04 doesn't have these methods implemented at all, and doesn't have the
636 * relevant bits in grobj. Instead, it'll allow rendering whenever bit 24
637 * is set. So we have to emulate them in software, internally keeping the
638 * same bits as NV05 does. Since grobjs are aligned to 16 bytes on nv04,
639 * but the last word isn't actually used for anything, we abuse it for this
640 * purpose.
641 *
642 * Actually, NV05 can optionally check bit 24 too, but we disable this since
643 * there's no use for it.
644 *
645 * For unknown reasons, NV04 implements surf3d binding in hardware as an
646 * exception. Also for unknown reasons, NV04 doesn't implement the clipping
647 * methods on the surf3d object, so we have to emulate them too.
648 */
649
650static void
Ben Skeggsb8c157d2010-10-20 10:39:35 +1000651nv04_graph_set_ctx1(struct nouveau_channel *chan, u32 mask, u32 value)
Ben Skeggs6ee73862009-12-11 19:24:15 +1000652{
653 struct drm_device *dev = chan->dev;
Ben Skeggsb8c157d2010-10-20 10:39:35 +1000654 u32 instance = (nv_rd32(dev, NV04_PGRAPH_CTX_SWITCH4) & 0xffff) << 4;
Ben Skeggs6ee73862009-12-11 19:24:15 +1000655 int subc = (nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR) >> 13) & 0x7;
Ben Skeggsb8c157d2010-10-20 10:39:35 +1000656 u32 tmp;
Ben Skeggs6ee73862009-12-11 19:24:15 +1000657
658 tmp = nv_ri32(dev, instance);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000659 tmp &= ~mask;
660 tmp |= value;
Ben Skeggs6ee73862009-12-11 19:24:15 +1000661
662 nv_wi32(dev, instance, tmp);
663 nv_wr32(dev, NV04_PGRAPH_CTX_SWITCH1, tmp);
Marcin Kościelnicki13c54432009-12-14 20:38:17 +0000664 nv_wr32(dev, NV04_PGRAPH_CTX_CACHE1 + (subc<<2), tmp);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000665}
666
667static void
Ben Skeggsb8c157d2010-10-20 10:39:35 +1000668nv04_graph_set_ctx_val(struct nouveau_channel *chan, u32 mask, u32 value)
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000669{
670 struct drm_device *dev = chan->dev;
Ben Skeggsb8c157d2010-10-20 10:39:35 +1000671 u32 instance = (nv_rd32(dev, NV04_PGRAPH_CTX_SWITCH4) & 0xffff) << 4;
672 u32 tmp, ctx1;
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000673 int class, op, valid = 1;
674
675 ctx1 = nv_ri32(dev, instance);
676 class = ctx1 & 0xff;
677 op = (ctx1 >> 15) & 7;
678 tmp = nv_ri32(dev, instance + 0xc);
679 tmp &= ~mask;
680 tmp |= value;
681 nv_wi32(dev, instance + 0xc, tmp);
682
683 /* check for valid surf2d/surf_dst/surf_color */
684 if (!(tmp & 0x02000000))
685 valid = 0;
686 /* check for valid surf_src/surf_zeta */
687 if ((class == 0x1f || class == 0x48) && !(tmp & 0x04000000))
688 valid = 0;
689
690 switch (op) {
691 /* SRCCOPY_AND, SRCCOPY: no extra objects required */
692 case 0:
693 case 3:
694 break;
695 /* ROP_AND: requires pattern and rop */
696 case 1:
697 if (!(tmp & 0x18000000))
698 valid = 0;
699 break;
700 /* BLEND_AND: requires beta1 */
701 case 2:
702 if (!(tmp & 0x20000000))
703 valid = 0;
704 break;
705 /* SRCCOPY_PREMULT, BLEND_PREMULT: beta4 required */
706 case 4:
707 case 5:
708 if (!(tmp & 0x40000000))
709 valid = 0;
710 break;
711 }
712
713 nv04_graph_set_ctx1(chan, 0x01000000, valid << 24);
714}
715
716static int
Ben Skeggsb8c157d2010-10-20 10:39:35 +1000717nv04_graph_mthd_set_operation(struct nouveau_channel *chan,
718 u32 class, u32 mthd, u32 data)
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000719{
720 if (data > 5)
721 return 1;
722 /* Old versions of the objects only accept first three operations. */
Ben Skeggsb8c157d2010-10-20 10:39:35 +1000723 if (data > 2 && class < 0x40)
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000724 return 1;
725 nv04_graph_set_ctx1(chan, 0x00038000, data << 15);
726 /* changing operation changes set of objects needed for validation */
727 nv04_graph_set_ctx_val(chan, 0, 0);
Ben Skeggs6ee73862009-12-11 19:24:15 +1000728 return 0;
729}
730
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000731static int
Ben Skeggsb8c157d2010-10-20 10:39:35 +1000732nv04_graph_mthd_surf3d_clip_h(struct nouveau_channel *chan,
733 u32 class, u32 mthd, u32 data)
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000734{
735 uint32_t min = data & 0xffff, max;
736 uint32_t w = data >> 16;
737 if (min & 0x8000)
738 /* too large */
739 return 1;
740 if (w & 0x8000)
741 /* yes, it accepts negative for some reason. */
742 w |= 0xffff0000;
743 max = min + w;
744 max &= 0x3ffff;
745 nv_wr32(chan->dev, 0x40053c, min);
746 nv_wr32(chan->dev, 0x400544, max);
747 return 0;
748}
749
750static int
Ben Skeggsb8c157d2010-10-20 10:39:35 +1000751nv04_graph_mthd_surf3d_clip_v(struct nouveau_channel *chan,
752 u32 class, u32 mthd, u32 data)
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000753{
754 uint32_t min = data & 0xffff, max;
755 uint32_t w = data >> 16;
756 if (min & 0x8000)
757 /* too large */
758 return 1;
759 if (w & 0x8000)
760 /* yes, it accepts negative for some reason. */
761 w |= 0xffff0000;
762 max = min + w;
763 max &= 0x3ffff;
764 nv_wr32(chan->dev, 0x400540, min);
765 nv_wr32(chan->dev, 0x400548, max);
766 return 0;
767}
768
769static int
Ben Skeggsb8c157d2010-10-20 10:39:35 +1000770nv04_graph_mthd_bind_surf2d(struct nouveau_channel *chan,
771 u32 class, u32 mthd, u32 data)
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000772{
773 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
774 case 0x30:
775 nv04_graph_set_ctx1(chan, 0x00004000, 0);
776 nv04_graph_set_ctx_val(chan, 0x02000000, 0);
777 return 0;
778 case 0x42:
779 nv04_graph_set_ctx1(chan, 0x00004000, 0);
780 nv04_graph_set_ctx_val(chan, 0x02000000, 0x02000000);
781 return 0;
782 }
783 return 1;
784}
785
786static int
Ben Skeggsb8c157d2010-10-20 10:39:35 +1000787nv04_graph_mthd_bind_surf2d_swzsurf(struct nouveau_channel *chan,
788 u32 class, u32 mthd, u32 data)
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000789{
790 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
791 case 0x30:
792 nv04_graph_set_ctx1(chan, 0x00004000, 0);
793 nv04_graph_set_ctx_val(chan, 0x02000000, 0);
794 return 0;
795 case 0x42:
796 nv04_graph_set_ctx1(chan, 0x00004000, 0);
797 nv04_graph_set_ctx_val(chan, 0x02000000, 0x02000000);
798 return 0;
799 case 0x52:
800 nv04_graph_set_ctx1(chan, 0x00004000, 0x00004000);
801 nv04_graph_set_ctx_val(chan, 0x02000000, 0x02000000);
802 return 0;
803 }
804 return 1;
805}
806
807static int
Ben Skeggsb8c157d2010-10-20 10:39:35 +1000808nv04_graph_mthd_bind_nv01_patt(struct nouveau_channel *chan,
809 u32 class, u32 mthd, u32 data)
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000810{
811 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
812 case 0x30:
813 nv04_graph_set_ctx_val(chan, 0x08000000, 0);
814 return 0;
815 case 0x18:
816 nv04_graph_set_ctx_val(chan, 0x08000000, 0x08000000);
817 return 0;
818 }
819 return 1;
820}
821
822static int
Ben Skeggsb8c157d2010-10-20 10:39:35 +1000823nv04_graph_mthd_bind_nv04_patt(struct nouveau_channel *chan,
824 u32 class, u32 mthd, u32 data)
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000825{
826 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
827 case 0x30:
828 nv04_graph_set_ctx_val(chan, 0x08000000, 0);
829 return 0;
830 case 0x44:
831 nv04_graph_set_ctx_val(chan, 0x08000000, 0x08000000);
832 return 0;
833 }
834 return 1;
835}
836
837static int
Ben Skeggsb8c157d2010-10-20 10:39:35 +1000838nv04_graph_mthd_bind_rop(struct nouveau_channel *chan,
839 u32 class, u32 mthd, u32 data)
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000840{
841 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
842 case 0x30:
843 nv04_graph_set_ctx_val(chan, 0x10000000, 0);
844 return 0;
845 case 0x43:
846 nv04_graph_set_ctx_val(chan, 0x10000000, 0x10000000);
847 return 0;
848 }
849 return 1;
850}
851
852static int
Ben Skeggsb8c157d2010-10-20 10:39:35 +1000853nv04_graph_mthd_bind_beta1(struct nouveau_channel *chan,
854 u32 class, u32 mthd, u32 data)
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000855{
856 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
857 case 0x30:
858 nv04_graph_set_ctx_val(chan, 0x20000000, 0);
859 return 0;
860 case 0x12:
861 nv04_graph_set_ctx_val(chan, 0x20000000, 0x20000000);
862 return 0;
863 }
864 return 1;
865}
866
867static int
Ben Skeggsb8c157d2010-10-20 10:39:35 +1000868nv04_graph_mthd_bind_beta4(struct nouveau_channel *chan,
869 u32 class, u32 mthd, u32 data)
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000870{
871 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
872 case 0x30:
873 nv04_graph_set_ctx_val(chan, 0x40000000, 0);
874 return 0;
875 case 0x72:
876 nv04_graph_set_ctx_val(chan, 0x40000000, 0x40000000);
877 return 0;
878 }
879 return 1;
880}
881
882static int
Ben Skeggsb8c157d2010-10-20 10:39:35 +1000883nv04_graph_mthd_bind_surf_dst(struct nouveau_channel *chan,
884 u32 class, u32 mthd, u32 data)
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000885{
886 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
887 case 0x30:
888 nv04_graph_set_ctx_val(chan, 0x02000000, 0);
889 return 0;
890 case 0x58:
891 nv04_graph_set_ctx_val(chan, 0x02000000, 0x02000000);
892 return 0;
893 }
894 return 1;
895}
896
897static int
Ben Skeggsb8c157d2010-10-20 10:39:35 +1000898nv04_graph_mthd_bind_surf_src(struct nouveau_channel *chan,
899 u32 class, u32 mthd, u32 data)
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000900{
901 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
902 case 0x30:
903 nv04_graph_set_ctx_val(chan, 0x04000000, 0);
904 return 0;
905 case 0x59:
906 nv04_graph_set_ctx_val(chan, 0x04000000, 0x04000000);
907 return 0;
908 }
909 return 1;
910}
911
912static int
Ben Skeggsb8c157d2010-10-20 10:39:35 +1000913nv04_graph_mthd_bind_surf_color(struct nouveau_channel *chan,
914 u32 class, u32 mthd, u32 data)
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000915{
916 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
917 case 0x30:
918 nv04_graph_set_ctx_val(chan, 0x02000000, 0);
919 return 0;
920 case 0x5a:
921 nv04_graph_set_ctx_val(chan, 0x02000000, 0x02000000);
922 return 0;
923 }
924 return 1;
925}
926
927static int
Ben Skeggsb8c157d2010-10-20 10:39:35 +1000928nv04_graph_mthd_bind_surf_zeta(struct nouveau_channel *chan,
929 u32 class, u32 mthd, u32 data)
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000930{
931 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
932 case 0x30:
933 nv04_graph_set_ctx_val(chan, 0x04000000, 0);
934 return 0;
935 case 0x5b:
936 nv04_graph_set_ctx_val(chan, 0x04000000, 0x04000000);
937 return 0;
938 }
939 return 1;
940}
941
942static int
Ben Skeggsb8c157d2010-10-20 10:39:35 +1000943nv04_graph_mthd_bind_clip(struct nouveau_channel *chan,
944 u32 class, u32 mthd, u32 data)
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000945{
946 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
947 case 0x30:
948 nv04_graph_set_ctx1(chan, 0x2000, 0);
949 return 0;
950 case 0x19:
951 nv04_graph_set_ctx1(chan, 0x2000, 0x2000);
952 return 0;
953 }
954 return 1;
955}
956
957static int
Ben Skeggsb8c157d2010-10-20 10:39:35 +1000958nv04_graph_mthd_bind_chroma(struct nouveau_channel *chan,
959 u32 class, u32 mthd, u32 data)
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000960{
961 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
962 case 0x30:
963 nv04_graph_set_ctx1(chan, 0x1000, 0);
964 return 0;
965 /* Yes, for some reason even the old versions of objects
966 * accept 0x57 and not 0x17. Consistency be damned.
967 */
968 case 0x57:
969 nv04_graph_set_ctx1(chan, 0x1000, 0x1000);
970 return 0;
971 }
972 return 1;
973}
974
Ben Skeggsb8c157d2010-10-20 10:39:35 +1000975static int
976nv04_graph_register(struct drm_device *dev)
977{
978 struct drm_nouveau_private *dev_priv = dev->dev_private;
Ben Skeggs6ee73862009-12-11 19:24:15 +1000979
Ben Skeggsb8c157d2010-10-20 10:39:35 +1000980 if (dev_priv->engine.graph.registered)
981 return 0;
Ben Skeggs6ee73862009-12-11 19:24:15 +1000982
Ben Skeggsb8c157d2010-10-20 10:39:35 +1000983 /* dvd subpicture */
984 NVOBJ_CLASS(dev, 0x0038, GR);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000985
Ben Skeggsb8c157d2010-10-20 10:39:35 +1000986 /* m2mf */
987 NVOBJ_CLASS(dev, 0x0039, GR);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000988
Ben Skeggsb8c157d2010-10-20 10:39:35 +1000989 /* nv03 gdirect */
990 NVOBJ_CLASS(dev, 0x004b, GR);
991 NVOBJ_MTHD (dev, 0x004b, 0x0184, nv04_graph_mthd_bind_nv01_patt);
992 NVOBJ_MTHD (dev, 0x004b, 0x0188, nv04_graph_mthd_bind_rop);
993 NVOBJ_MTHD (dev, 0x004b, 0x018c, nv04_graph_mthd_bind_beta1);
994 NVOBJ_MTHD (dev, 0x004b, 0x0190, nv04_graph_mthd_bind_surf_dst);
995 NVOBJ_MTHD (dev, 0x004b, 0x02fc, nv04_graph_mthd_set_operation);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +0000996
Ben Skeggsb8c157d2010-10-20 10:39:35 +1000997 /* nv04 gdirect */
998 NVOBJ_CLASS(dev, 0x004a, GR);
999 NVOBJ_MTHD (dev, 0x004a, 0x0188, nv04_graph_mthd_bind_nv04_patt);
1000 NVOBJ_MTHD (dev, 0x004a, 0x018c, nv04_graph_mthd_bind_rop);
1001 NVOBJ_MTHD (dev, 0x004a, 0x0190, nv04_graph_mthd_bind_beta1);
1002 NVOBJ_MTHD (dev, 0x004a, 0x0194, nv04_graph_mthd_bind_beta4);
1003 NVOBJ_MTHD (dev, 0x004a, 0x0198, nv04_graph_mthd_bind_surf2d);
1004 NVOBJ_MTHD (dev, 0x004a, 0x02fc, nv04_graph_mthd_set_operation);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +00001005
Ben Skeggsb8c157d2010-10-20 10:39:35 +10001006 /* nv01 imageblit */
1007 NVOBJ_CLASS(dev, 0x001f, GR);
1008 NVOBJ_MTHD (dev, 0x001f, 0x0184, nv04_graph_mthd_bind_chroma);
1009 NVOBJ_MTHD (dev, 0x001f, 0x0188, nv04_graph_mthd_bind_clip);
1010 NVOBJ_MTHD (dev, 0x001f, 0x018c, nv04_graph_mthd_bind_nv01_patt);
1011 NVOBJ_MTHD (dev, 0x001f, 0x0190, nv04_graph_mthd_bind_rop);
1012 NVOBJ_MTHD (dev, 0x001f, 0x0194, nv04_graph_mthd_bind_beta1);
1013 NVOBJ_MTHD (dev, 0x001f, 0x0198, nv04_graph_mthd_bind_surf_dst);
1014 NVOBJ_MTHD (dev, 0x001f, 0x019c, nv04_graph_mthd_bind_surf_src);
1015 NVOBJ_MTHD (dev, 0x001f, 0x02fc, nv04_graph_mthd_set_operation);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +00001016
Ben Skeggsb8c157d2010-10-20 10:39:35 +10001017 /* nv04 imageblit */
1018 NVOBJ_CLASS(dev, 0x005f, GR);
1019 NVOBJ_MTHD (dev, 0x005f, 0x0184, nv04_graph_mthd_bind_chroma);
1020 NVOBJ_MTHD (dev, 0x005f, 0x0188, nv04_graph_mthd_bind_clip);
1021 NVOBJ_MTHD (dev, 0x005f, 0x018c, nv04_graph_mthd_bind_nv04_patt);
1022 NVOBJ_MTHD (dev, 0x005f, 0x0190, nv04_graph_mthd_bind_rop);
1023 NVOBJ_MTHD (dev, 0x005f, 0x0194, nv04_graph_mthd_bind_beta1);
1024 NVOBJ_MTHD (dev, 0x005f, 0x0198, nv04_graph_mthd_bind_beta4);
1025 NVOBJ_MTHD (dev, 0x005f, 0x019c, nv04_graph_mthd_bind_surf2d);
1026 NVOBJ_MTHD (dev, 0x005f, 0x02fc, nv04_graph_mthd_set_operation);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +00001027
Ben Skeggsb8c157d2010-10-20 10:39:35 +10001028 /* nv04 iifc */
1029 NVOBJ_CLASS(dev, 0x0060, GR);
1030 NVOBJ_MTHD (dev, 0x0060, 0x0188, nv04_graph_mthd_bind_chroma);
1031 NVOBJ_MTHD (dev, 0x0060, 0x018c, nv04_graph_mthd_bind_clip);
1032 NVOBJ_MTHD (dev, 0x0060, 0x0190, nv04_graph_mthd_bind_nv04_patt);
1033 NVOBJ_MTHD (dev, 0x0060, 0x0194, nv04_graph_mthd_bind_rop);
1034 NVOBJ_MTHD (dev, 0x0060, 0x0198, nv04_graph_mthd_bind_beta1);
1035 NVOBJ_MTHD (dev, 0x0060, 0x019c, nv04_graph_mthd_bind_beta4);
1036 NVOBJ_MTHD (dev, 0x0060, 0x01a0, nv04_graph_mthd_bind_surf2d_swzsurf);
1037 NVOBJ_MTHD (dev, 0x0060, 0x03e4, nv04_graph_mthd_set_operation);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +00001038
Ben Skeggsb8c157d2010-10-20 10:39:35 +10001039 /* nv05 iifc */
1040 NVOBJ_CLASS(dev, 0x0064, GR);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +00001041
Ben Skeggsb8c157d2010-10-20 10:39:35 +10001042 /* nv01 ifc */
1043 NVOBJ_CLASS(dev, 0x0021, GR);
1044 NVOBJ_MTHD (dev, 0x0021, 0x0184, nv04_graph_mthd_bind_chroma);
1045 NVOBJ_MTHD (dev, 0x0021, 0x0188, nv04_graph_mthd_bind_clip);
1046 NVOBJ_MTHD (dev, 0x0021, 0x018c, nv04_graph_mthd_bind_nv01_patt);
1047 NVOBJ_MTHD (dev, 0x0021, 0x0190, nv04_graph_mthd_bind_rop);
1048 NVOBJ_MTHD (dev, 0x0021, 0x0194, nv04_graph_mthd_bind_beta1);
1049 NVOBJ_MTHD (dev, 0x0021, 0x0198, nv04_graph_mthd_bind_surf_dst);
1050 NVOBJ_MTHD (dev, 0x0021, 0x02fc, nv04_graph_mthd_set_operation);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +00001051
Ben Skeggsb8c157d2010-10-20 10:39:35 +10001052 /* nv04 ifc */
1053 NVOBJ_CLASS(dev, 0x0061, GR);
1054 NVOBJ_MTHD (dev, 0x0061, 0x0184, nv04_graph_mthd_bind_chroma);
1055 NVOBJ_MTHD (dev, 0x0061, 0x0188, nv04_graph_mthd_bind_clip);
1056 NVOBJ_MTHD (dev, 0x0061, 0x018c, nv04_graph_mthd_bind_nv04_patt);
1057 NVOBJ_MTHD (dev, 0x0061, 0x0190, nv04_graph_mthd_bind_rop);
1058 NVOBJ_MTHD (dev, 0x0061, 0x0194, nv04_graph_mthd_bind_beta1);
1059 NVOBJ_MTHD (dev, 0x0061, 0x0198, nv04_graph_mthd_bind_beta4);
1060 NVOBJ_MTHD (dev, 0x0061, 0x019c, nv04_graph_mthd_bind_surf2d);
1061 NVOBJ_MTHD (dev, 0x0061, 0x02fc, nv04_graph_mthd_set_operation);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +00001062
Ben Skeggsb8c157d2010-10-20 10:39:35 +10001063 /* nv05 ifc */
1064 NVOBJ_CLASS(dev, 0x0065, GR);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +00001065
Ben Skeggsb8c157d2010-10-20 10:39:35 +10001066 /* nv03 sifc */
1067 NVOBJ_CLASS(dev, 0x0036, GR);
1068 NVOBJ_MTHD (dev, 0x0036, 0x0184, nv04_graph_mthd_bind_chroma);
1069 NVOBJ_MTHD (dev, 0x0036, 0x0188, nv04_graph_mthd_bind_nv01_patt);
1070 NVOBJ_MTHD (dev, 0x0036, 0x018c, nv04_graph_mthd_bind_rop);
1071 NVOBJ_MTHD (dev, 0x0036, 0x0190, nv04_graph_mthd_bind_beta1);
1072 NVOBJ_MTHD (dev, 0x0036, 0x0194, nv04_graph_mthd_bind_surf_dst);
1073 NVOBJ_MTHD (dev, 0x0036, 0x02fc, nv04_graph_mthd_set_operation);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +00001074
Ben Skeggsb8c157d2010-10-20 10:39:35 +10001075 /* nv04 sifc */
1076 NVOBJ_CLASS(dev, 0x0076, GR);
1077 NVOBJ_MTHD (dev, 0x0076, 0x0184, nv04_graph_mthd_bind_chroma);
1078 NVOBJ_MTHD (dev, 0x0076, 0x0188, nv04_graph_mthd_bind_nv04_patt);
1079 NVOBJ_MTHD (dev, 0x0076, 0x018c, nv04_graph_mthd_bind_rop);
1080 NVOBJ_MTHD (dev, 0x0076, 0x0190, nv04_graph_mthd_bind_beta1);
1081 NVOBJ_MTHD (dev, 0x0076, 0x0194, nv04_graph_mthd_bind_beta4);
1082 NVOBJ_MTHD (dev, 0x0076, 0x0198, nv04_graph_mthd_bind_surf2d);
1083 NVOBJ_MTHD (dev, 0x0076, 0x02fc, nv04_graph_mthd_set_operation);
Marcin Kościelnickif23d4cf2010-04-11 18:41:38 +00001084
Ben Skeggsb8c157d2010-10-20 10:39:35 +10001085 /* nv05 sifc */
1086 NVOBJ_CLASS(dev, 0x0066, GR);
Ben Skeggs6ee73862009-12-11 19:24:15 +10001087
Ben Skeggsb8c157d2010-10-20 10:39:35 +10001088 /* nv03 sifm */
1089 NVOBJ_CLASS(dev, 0x0037, GR);
1090 NVOBJ_MTHD (dev, 0x0037, 0x0188, nv04_graph_mthd_bind_nv01_patt);
1091 NVOBJ_MTHD (dev, 0x0037, 0x018c, nv04_graph_mthd_bind_rop);
1092 NVOBJ_MTHD (dev, 0x0037, 0x0190, nv04_graph_mthd_bind_beta1);
1093 NVOBJ_MTHD (dev, 0x0037, 0x0194, nv04_graph_mthd_bind_surf_dst);
1094 NVOBJ_MTHD (dev, 0x0037, 0x0304, nv04_graph_mthd_set_operation);
1095
1096 /* nv04 sifm */
1097 NVOBJ_CLASS(dev, 0x0077, GR);
1098 NVOBJ_MTHD (dev, 0x0077, 0x0188, nv04_graph_mthd_bind_nv04_patt);
1099 NVOBJ_MTHD (dev, 0x0077, 0x018c, nv04_graph_mthd_bind_rop);
1100 NVOBJ_MTHD (dev, 0x0077, 0x0190, nv04_graph_mthd_bind_beta1);
1101 NVOBJ_MTHD (dev, 0x0077, 0x0194, nv04_graph_mthd_bind_beta4);
1102 NVOBJ_MTHD (dev, 0x0077, 0x0198, nv04_graph_mthd_bind_surf2d_swzsurf);
1103 NVOBJ_MTHD (dev, 0x0077, 0x0304, nv04_graph_mthd_set_operation);
1104
1105 /* null */
1106 NVOBJ_CLASS(dev, 0x0030, GR);
1107
1108 /* surf2d */
1109 NVOBJ_CLASS(dev, 0x0042, GR);
1110
1111 /* rop */
1112 NVOBJ_CLASS(dev, 0x0043, GR);
1113
1114 /* beta1 */
1115 NVOBJ_CLASS(dev, 0x0012, GR);
1116
1117 /* beta4 */
1118 NVOBJ_CLASS(dev, 0x0072, GR);
1119
1120 /* cliprect */
1121 NVOBJ_CLASS(dev, 0x0019, GR);
1122
1123 /* nv01 pattern */
1124 NVOBJ_CLASS(dev, 0x0018, GR);
1125
1126 /* nv04 pattern */
1127 NVOBJ_CLASS(dev, 0x0044, GR);
1128
1129 /* swzsurf */
1130 NVOBJ_CLASS(dev, 0x0052, GR);
1131
1132 /* surf3d */
1133 NVOBJ_CLASS(dev, 0x0053, GR);
1134 NVOBJ_MTHD (dev, 0x0053, 0x02f8, nv04_graph_mthd_surf3d_clip_h);
1135 NVOBJ_MTHD (dev, 0x0053, 0x02fc, nv04_graph_mthd_surf3d_clip_v);
1136
1137 /* nv03 tex_tri */
1138 NVOBJ_CLASS(dev, 0x0048, GR);
1139 NVOBJ_MTHD (dev, 0x0048, 0x0188, nv04_graph_mthd_bind_clip);
1140 NVOBJ_MTHD (dev, 0x0048, 0x018c, nv04_graph_mthd_bind_surf_color);
1141 NVOBJ_MTHD (dev, 0x0048, 0x0190, nv04_graph_mthd_bind_surf_zeta);
1142
1143 /* tex_tri */
1144 NVOBJ_CLASS(dev, 0x0054, GR);
1145
1146 /* multitex_tri */
1147 NVOBJ_CLASS(dev, 0x0055, GR);
1148
1149 /* nv01 chroma */
1150 NVOBJ_CLASS(dev, 0x0017, GR);
1151
1152 /* nv04 chroma */
1153 NVOBJ_CLASS(dev, 0x0057, GR);
1154
1155 /* surf_dst */
1156 NVOBJ_CLASS(dev, 0x0058, GR);
1157
1158 /* surf_src */
1159 NVOBJ_CLASS(dev, 0x0059, GR);
1160
1161 /* surf_color */
1162 NVOBJ_CLASS(dev, 0x005a, GR);
1163
1164 /* surf_zeta */
1165 NVOBJ_CLASS(dev, 0x005b, GR);
1166
1167 /* nv01 line */
1168 NVOBJ_CLASS(dev, 0x001c, GR);
1169 NVOBJ_MTHD (dev, 0x001c, 0x0184, nv04_graph_mthd_bind_clip);
1170 NVOBJ_MTHD (dev, 0x001c, 0x0188, nv04_graph_mthd_bind_nv01_patt);
1171 NVOBJ_MTHD (dev, 0x001c, 0x018c, nv04_graph_mthd_bind_rop);
1172 NVOBJ_MTHD (dev, 0x001c, 0x0190, nv04_graph_mthd_bind_beta1);
1173 NVOBJ_MTHD (dev, 0x001c, 0x0194, nv04_graph_mthd_bind_surf_dst);
1174 NVOBJ_MTHD (dev, 0x001c, 0x02fc, nv04_graph_mthd_set_operation);
1175
1176 /* nv04 line */
1177 NVOBJ_CLASS(dev, 0x005c, GR);
1178 NVOBJ_MTHD (dev, 0x005c, 0x0184, nv04_graph_mthd_bind_clip);
1179 NVOBJ_MTHD (dev, 0x005c, 0x0188, nv04_graph_mthd_bind_nv04_patt);
1180 NVOBJ_MTHD (dev, 0x005c, 0x018c, nv04_graph_mthd_bind_rop);
1181 NVOBJ_MTHD (dev, 0x005c, 0x0190, nv04_graph_mthd_bind_beta1);
1182 NVOBJ_MTHD (dev, 0x005c, 0x0194, nv04_graph_mthd_bind_beta4);
1183 NVOBJ_MTHD (dev, 0x005c, 0x0198, nv04_graph_mthd_bind_surf2d);
1184 NVOBJ_MTHD (dev, 0x005c, 0x02fc, nv04_graph_mthd_set_operation);
1185
1186 /* nv01 tri */
1187 NVOBJ_CLASS(dev, 0x001d, GR);
1188 NVOBJ_MTHD (dev, 0x001d, 0x0184, nv04_graph_mthd_bind_clip);
1189 NVOBJ_MTHD (dev, 0x001d, 0x0188, nv04_graph_mthd_bind_nv01_patt);
1190 NVOBJ_MTHD (dev, 0x001d, 0x018c, nv04_graph_mthd_bind_rop);
1191 NVOBJ_MTHD (dev, 0x001d, 0x0190, nv04_graph_mthd_bind_beta1);
1192 NVOBJ_MTHD (dev, 0x001d, 0x0194, nv04_graph_mthd_bind_surf_dst);
1193 NVOBJ_MTHD (dev, 0x001d, 0x02fc, nv04_graph_mthd_set_operation);
1194
1195 /* nv04 tri */
1196 NVOBJ_CLASS(dev, 0x005d, GR);
1197 NVOBJ_MTHD (dev, 0x005d, 0x0184, nv04_graph_mthd_bind_clip);
1198 NVOBJ_MTHD (dev, 0x005d, 0x0188, nv04_graph_mthd_bind_nv04_patt);
1199 NVOBJ_MTHD (dev, 0x005d, 0x018c, nv04_graph_mthd_bind_rop);
1200 NVOBJ_MTHD (dev, 0x005d, 0x0190, nv04_graph_mthd_bind_beta1);
1201 NVOBJ_MTHD (dev, 0x005d, 0x0194, nv04_graph_mthd_bind_beta4);
1202 NVOBJ_MTHD (dev, 0x005d, 0x0198, nv04_graph_mthd_bind_surf2d);
1203 NVOBJ_MTHD (dev, 0x005d, 0x02fc, nv04_graph_mthd_set_operation);
1204
1205 /* nv01 rect */
1206 NVOBJ_CLASS(dev, 0x001e, GR);
1207 NVOBJ_MTHD (dev, 0x001e, 0x0184, nv04_graph_mthd_bind_clip);
1208 NVOBJ_MTHD (dev, 0x001e, 0x0188, nv04_graph_mthd_bind_nv01_patt);
1209 NVOBJ_MTHD (dev, 0x001e, 0x018c, nv04_graph_mthd_bind_rop);
1210 NVOBJ_MTHD (dev, 0x001e, 0x0190, nv04_graph_mthd_bind_beta1);
1211 NVOBJ_MTHD (dev, 0x001e, 0x0194, nv04_graph_mthd_bind_surf_dst);
1212 NVOBJ_MTHD (dev, 0x001e, 0x02fc, nv04_graph_mthd_set_operation);
1213
1214 /* nv04 rect */
1215 NVOBJ_CLASS(dev, 0x005e, GR);
1216 NVOBJ_MTHD (dev, 0x005e, 0x0184, nv04_graph_mthd_bind_clip);
1217 NVOBJ_MTHD (dev, 0x005e, 0x0188, nv04_graph_mthd_bind_nv04_patt);
1218 NVOBJ_MTHD (dev, 0x005e, 0x018c, nv04_graph_mthd_bind_rop);
1219 NVOBJ_MTHD (dev, 0x005e, 0x0190, nv04_graph_mthd_bind_beta1);
1220 NVOBJ_MTHD (dev, 0x005e, 0x0194, nv04_graph_mthd_bind_beta4);
1221 NVOBJ_MTHD (dev, 0x005e, 0x0198, nv04_graph_mthd_bind_surf2d);
1222 NVOBJ_MTHD (dev, 0x005e, 0x02fc, nv04_graph_mthd_set_operation);
1223
1224 /* nvsw */
1225 NVOBJ_CLASS(dev, 0x506e, SW);
1226 NVOBJ_MTHD (dev, 0x506e, 0x0150, nv04_graph_mthd_set_ref);
Francisco Jerez332b2422010-10-20 23:35:40 +02001227 NVOBJ_MTHD (dev, 0x506e, 0x0500, nv04_graph_mthd_page_flip);
Ben Skeggsb8c157d2010-10-20 10:39:35 +10001228
1229 dev_priv->engine.graph.registered = true;
1230 return 0;
1231};
Ben Skeggs274fec92010-11-03 13:16:18 +10001232
1233static struct nouveau_bitfield nv04_graph_intr[] = {
1234 { NV_PGRAPH_INTR_NOTIFY, "NOTIFY" },
1235 {}
1236};
1237
1238static struct nouveau_bitfield nv04_graph_nstatus[] =
1239{
1240 { NV04_PGRAPH_NSTATUS_STATE_IN_USE, "STATE_IN_USE" },
1241 { NV04_PGRAPH_NSTATUS_INVALID_STATE, "INVALID_STATE" },
1242 { NV04_PGRAPH_NSTATUS_BAD_ARGUMENT, "BAD_ARGUMENT" },
1243 { NV04_PGRAPH_NSTATUS_PROTECTION_FAULT, "PROTECTION_FAULT" },
1244 {}
1245};
1246
1247struct nouveau_bitfield nv04_graph_nsource[] =
1248{
1249 { NV03_PGRAPH_NSOURCE_NOTIFICATION, "NOTIFICATION" },
1250 { NV03_PGRAPH_NSOURCE_DATA_ERROR, "DATA_ERROR" },
1251 { NV03_PGRAPH_NSOURCE_PROTECTION_ERROR, "PROTECTION_ERROR" },
1252 { NV03_PGRAPH_NSOURCE_RANGE_EXCEPTION, "RANGE_EXCEPTION" },
1253 { NV03_PGRAPH_NSOURCE_LIMIT_COLOR, "LIMIT_COLOR" },
1254 { NV03_PGRAPH_NSOURCE_LIMIT_ZETA, "LIMIT_ZETA" },
1255 { NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD, "ILLEGAL_MTHD" },
1256 { NV03_PGRAPH_NSOURCE_DMA_R_PROTECTION, "DMA_R_PROTECTION" },
1257 { NV03_PGRAPH_NSOURCE_DMA_W_PROTECTION, "DMA_W_PROTECTION" },
1258 { NV03_PGRAPH_NSOURCE_FORMAT_EXCEPTION, "FORMAT_EXCEPTION" },
1259 { NV03_PGRAPH_NSOURCE_PATCH_EXCEPTION, "PATCH_EXCEPTION" },
1260 { NV03_PGRAPH_NSOURCE_STATE_INVALID, "STATE_INVALID" },
1261 { NV03_PGRAPH_NSOURCE_DOUBLE_NOTIFY, "DOUBLE_NOTIFY" },
1262 { NV03_PGRAPH_NSOURCE_NOTIFY_IN_USE, "NOTIFY_IN_USE" },
1263 { NV03_PGRAPH_NSOURCE_METHOD_CNT, "METHOD_CNT" },
1264 { NV03_PGRAPH_NSOURCE_BFR_NOTIFICATION, "BFR_NOTIFICATION" },
1265 { NV03_PGRAPH_NSOURCE_DMA_VTX_PROTECTION, "DMA_VTX_PROTECTION" },
1266 { NV03_PGRAPH_NSOURCE_DMA_WIDTH_A, "DMA_WIDTH_A" },
1267 { NV03_PGRAPH_NSOURCE_DMA_WIDTH_B, "DMA_WIDTH_B" },
1268 {}
1269};
1270
1271static void
1272nv04_graph_isr(struct drm_device *dev)
1273{
1274 u32 stat;
1275
1276 while ((stat = nv_rd32(dev, NV03_PGRAPH_INTR))) {
1277 u32 nsource = nv_rd32(dev, NV03_PGRAPH_NSOURCE);
1278 u32 nstatus = nv_rd32(dev, NV03_PGRAPH_NSTATUS);
1279 u32 addr = nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR);
1280 u32 chid = (addr & 0x0f000000) >> 24;
1281 u32 subc = (addr & 0x0000e000) >> 13;
1282 u32 mthd = (addr & 0x00001ffc);
1283 u32 data = nv_rd32(dev, NV04_PGRAPH_TRAPPED_DATA);
1284 u32 class = nv_rd32(dev, 0x400180 + subc * 4) & 0xff;
1285 u32 show = stat;
1286
1287 if (stat & NV_PGRAPH_INTR_NOTIFY) {
1288 if (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD) {
1289 if (!nouveau_gpuobj_mthd_call2(dev, chid, class, mthd, data))
1290 show &= ~NV_PGRAPH_INTR_NOTIFY;
1291 }
1292 }
1293
1294 if (stat & NV_PGRAPH_INTR_CONTEXT_SWITCH) {
1295 nv_wr32(dev, NV03_PGRAPH_INTR, NV_PGRAPH_INTR_CONTEXT_SWITCH);
1296 stat &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH;
1297 show &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH;
1298 nv04_graph_context_switch(dev);
1299 }
1300
1301 nv_wr32(dev, NV03_PGRAPH_INTR, stat);
1302 nv_wr32(dev, NV04_PGRAPH_FIFO, 0x00000001);
1303
1304 if (show && nouveau_ratelimit()) {
1305 NV_INFO(dev, "PGRAPH -");
1306 nouveau_bitfield_print(nv04_graph_intr, show);
1307 printk(" nsource:");
1308 nouveau_bitfield_print(nv04_graph_nsource, nsource);
1309 printk(" nstatus:");
1310 nouveau_bitfield_print(nv04_graph_nstatus, nstatus);
1311 printk("\n");
1312 NV_INFO(dev, "PGRAPH - ch %d/%d class 0x%04x "
1313 "mthd 0x%04x data 0x%08x\n",
1314 chid, subc, class, mthd, data);
1315 }
1316 }
1317}