1 /* mga_state.c -- State support for mga g200/g400 -*- linux-c -*-
2 * Created: Thu Jan 27 02:53:43 2000 by jhartmann@precisioninsight.com
4 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
22 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 * DEALINGS IN THE SOFTWARE.
26 * Authors: Jeff Hartmann <jhartmann@precisioninsight.com>
27 * Keith Whitwell <keithw@precisioninsight.com>
33 #define __NO_VERSION__
38 static void mgaEmitClipRect( drm_mga_private_t *dev_priv,
39 drm_clip_rect_t *box )
41 drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
42 unsigned int *regs = sarea_priv->ContextState;
45 /* This takes 10 dwords */
46 PRIMGETPTR( dev_priv );
48 /* Force reset of dwgctl (eliminates clip disable) */
49 PRIMOUTREG( MGAREG_DMAPAD, 0 );
50 PRIMOUTREG( MGAREG_DWGSYNC, dev_priv->last_sync_tag - 1 );
51 PRIMOUTREG( MGAREG_DWGSYNC, dev_priv->last_sync_tag - 1 );
52 PRIMOUTREG( MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL] );
54 PRIMOUTREG( MGAREG_DMAPAD, 0 );
55 PRIMOUTREG( MGAREG_CXBNDRY, ((box->x2)<<16)|(box->x1) );
56 PRIMOUTREG( MGAREG_YTOP, box->y1 * dev_priv->stride/2 );
57 PRIMOUTREG( MGAREG_YBOT, box->y2 * dev_priv->stride/2 );
59 PRIMADVANCE( dev_priv );
62 static void mgaEmitContext(drm_mga_private_t *dev_priv )
64 drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
65 unsigned int *regs = sarea_priv->ContextState;
68 /* This takes a max of 15 dwords */
69 PRIMGETPTR( dev_priv );
71 PRIMOUTREG( MGAREG_DSTORG, regs[MGA_CTXREG_DSTORG] );
72 PRIMOUTREG( MGAREG_MACCESS, regs[MGA_CTXREG_MACCESS] );
73 PRIMOUTREG( MGAREG_PLNWT, regs[MGA_CTXREG_PLNWT] );
74 PRIMOUTREG( MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL] );
76 PRIMOUTREG( MGAREG_ALPHACTRL, regs[MGA_CTXREG_ALPHACTRL] );
77 PRIMOUTREG( MGAREG_FOGCOL, regs[MGA_CTXREG_FOGCOLOR] );
78 PRIMOUTREG( MGAREG_WFLAG, regs[MGA_CTXREG_WFLAG] );
79 PRIMOUTREG( MGAREG_ZORG, dev_priv->depthOffset ); /* invarient */
81 if (dev_priv->chipset == MGA_CARD_TYPE_G400) {
82 PRIMOUTREG( MGAREG_WFLAG1, regs[MGA_CTXREG_WFLAG] );
83 PRIMOUTREG( MGAREG_TDUALSTAGE0, regs[MGA_CTXREG_TDUAL0] );
84 PRIMOUTREG( MGAREG_TDUALSTAGE1, regs[MGA_CTXREG_TDUAL1] );
85 PRIMOUTREG( MGAREG_FCOL, regs[MGA_CTXREG_FCOL] );
87 PRIMOUTREG( MGAREG_FCOL, regs[MGA_CTXREG_FCOL] );
88 PRIMOUTREG( MGAREG_DMAPAD, 0);
89 PRIMOUTREG( MGAREG_DMAPAD, 0);
90 PRIMOUTREG( MGAREG_DMAPAD, 0);
93 PRIMADVANCE( dev_priv );
96 static void mgaG200EmitTex( drm_mga_private_t *dev_priv )
98 drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
99 unsigned int *regs = sarea_priv->TexState[0];
102 PRIMGETPTR( dev_priv );
104 /* This takes 20 dwords */
106 PRIMOUTREG(MGAREG_TEXCTL2, regs[MGA_TEXREG_CTL2] );
107 PRIMOUTREG(MGAREG_TEXCTL, regs[MGA_TEXREG_CTL] );
108 PRIMOUTREG(MGAREG_TEXFILTER, regs[MGA_TEXREG_FILTER] );
109 PRIMOUTREG(MGAREG_TEXBORDERCOL, regs[MGA_TEXREG_BORDERCOL] );
111 PRIMOUTREG(MGAREG_TEXORG, regs[MGA_TEXREG_ORG] );
112 PRIMOUTREG(MGAREG_TEXORG1, regs[MGA_TEXREG_ORG1] );
113 PRIMOUTREG(MGAREG_TEXORG2, regs[MGA_TEXREG_ORG2] );
114 PRIMOUTREG(MGAREG_TEXORG3, regs[MGA_TEXREG_ORG3] );
116 PRIMOUTREG(MGAREG_TEXORG4, regs[MGA_TEXREG_ORG4] );
117 PRIMOUTREG(MGAREG_TEXWIDTH, regs[MGA_TEXREG_WIDTH] );
118 PRIMOUTREG(MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT] );
119 PRIMOUTREG(0x2d00 + 24*4, regs[MGA_TEXREG_WIDTH] );
121 PRIMOUTREG(0x2d00 + 34*4, regs[MGA_TEXREG_HEIGHT] );
122 PRIMOUTREG( MGAREG_TEXTRANS, 0xffff );
123 PRIMOUTREG( MGAREG_TEXTRANSHIGH, 0xffff );
124 PRIMOUTREG( MGAREG_DMAPAD, 0 );
126 PRIMADVANCE( dev_priv );
129 static void mgaG400EmitTex0( drm_mga_private_t *dev_priv )
131 drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
132 unsigned int *regs = sarea_priv->TexState[0];
133 int multitex = sarea_priv->WarpPipe & MGA_T2;
136 PRIMGETPTR( dev_priv );
138 /* This takes a max of 30 dwords */
140 PRIMOUTREG(MGAREG_TEXCTL2, regs[MGA_TEXREG_CTL2] );
141 PRIMOUTREG(MGAREG_TEXCTL, regs[MGA_TEXREG_CTL] );
142 PRIMOUTREG(MGAREG_TEXFILTER, regs[MGA_TEXREG_FILTER] );
143 PRIMOUTREG(MGAREG_TEXBORDERCOL, regs[MGA_TEXREG_BORDERCOL] );
145 PRIMOUTREG(MGAREG_TEXORG, regs[MGA_TEXREG_ORG] );
146 PRIMOUTREG(MGAREG_TEXORG1, regs[MGA_TEXREG_ORG1] );
147 PRIMOUTREG(MGAREG_TEXORG2, regs[MGA_TEXREG_ORG2] );
148 PRIMOUTREG(MGAREG_TEXORG3, regs[MGA_TEXREG_ORG3] );
150 PRIMOUTREG(MGAREG_TEXORG4, regs[MGA_TEXREG_ORG4] );
151 PRIMOUTREG(MGAREG_TEXWIDTH, regs[MGA_TEXREG_WIDTH] );
152 PRIMOUTREG(MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT] );
153 PRIMOUTREG(0x2d00 + 49*4, 0);
155 PRIMOUTREG(0x2d00 + 57*4, 0);
156 PRIMOUTREG(0x2d00 + 53*4, 0);
157 PRIMOUTREG(0x2d00 + 61*4, 0);
158 PRIMOUTREG( MGAREG_DMAPAD, 0 );
161 PRIMOUTREG(0x2d00 + 52*4, 0x40 );
162 PRIMOUTREG(0x2d00 + 60*4, 0x40 );
163 PRIMOUTREG( MGAREG_DMAPAD, 0 );
164 PRIMOUTREG( MGAREG_DMAPAD, 0 );
167 PRIMOUTREG( 0x2d00 + 54*4, regs[MGA_TEXREG_WIDTH] | 0x40 );
168 PRIMOUTREG( 0x2d00 + 62*4, regs[MGA_TEXREG_HEIGHT] | 0x40 );
169 PRIMOUTREG( MGAREG_TEXTRANS, 0xffff );
170 PRIMOUTREG( MGAREG_TEXTRANSHIGH, 0xffff );
172 PRIMADVANCE( dev_priv );
175 #define TMC_map1_enable 0x80000000
177 static void mgaG400EmitTex1( drm_mga_private_t *dev_priv )
179 drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
180 unsigned int *regs = sarea_priv->TexState[1];
183 PRIMGETPTR(dev_priv);
185 /* This takes 25 dwords */
186 PRIMOUTREG(MGAREG_TEXCTL2, regs[MGA_TEXREG_CTL2] | TMC_map1_enable);
187 PRIMOUTREG(MGAREG_TEXCTL, regs[MGA_TEXREG_CTL] );
188 PRIMOUTREG(MGAREG_TEXFILTER, regs[MGA_TEXREG_FILTER] );
189 PRIMOUTREG(MGAREG_TEXBORDERCOL, regs[MGA_TEXREG_BORDERCOL] );
191 PRIMOUTREG(MGAREG_TEXORG, regs[MGA_TEXREG_ORG] );
192 PRIMOUTREG(MGAREG_TEXORG1, regs[MGA_TEXREG_ORG1] );
193 PRIMOUTREG(MGAREG_TEXORG2, regs[MGA_TEXREG_ORG2] );
194 PRIMOUTREG(MGAREG_TEXORG3, regs[MGA_TEXREG_ORG3] );
196 PRIMOUTREG(MGAREG_TEXORG4, regs[MGA_TEXREG_ORG4] );
197 PRIMOUTREG(MGAREG_TEXWIDTH, regs[MGA_TEXREG_WIDTH] );
198 PRIMOUTREG(MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT] );
199 PRIMOUTREG(0x2d00 + 49*4, 0);
201 PRIMOUTREG(0x2d00 + 57*4, 0);
202 PRIMOUTREG(0x2d00 + 53*4, 0);
203 PRIMOUTREG(0x2d00 + 61*4, 0);
204 PRIMOUTREG(0x2d00 + 52*4, regs[MGA_TEXREG_WIDTH] | 0x40 );
206 PRIMOUTREG(0x2d00 + 60*4, regs[MGA_TEXREG_HEIGHT] | 0x40 );
207 PRIMOUTREG( MGAREG_TEXTRANS, 0xffff );
208 PRIMOUTREG( MGAREG_TEXTRANSHIGH, 0xffff );
209 PRIMOUTREG(MGAREG_TEXCTL2, regs[MGA_TEXREG_CTL2] );
211 PRIMADVANCE( dev_priv );
214 static void mgaG400EmitPipe(drm_mga_private_t *dev_priv )
216 drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
217 unsigned int pipe = sarea_priv->WarpPipe;
218 float fParam = 12800.0f;
221 PRIMGETPTR(dev_priv);
223 /* This takes 25 dwords */
225 /* Establish vertex size.
228 PRIMOUTREG(MGAREG_WIADDR2, WIA_wmode_suspend);
229 PRIMOUTREG(MGAREG_WVRTXSZ, 0x00001e09);
230 PRIMOUTREG(MGAREG_WACCEPTSEQ, 0x1e000000);
231 PRIMOUTREG(MGAREG_WFLAG, 0);
233 PRIMOUTREG(MGAREG_WIADDR2, WIA_wmode_suspend);
234 PRIMOUTREG(MGAREG_WVRTXSZ, 0x00001807);
235 PRIMOUTREG(MGAREG_WACCEPTSEQ, 0x18000000);
236 PRIMOUTREG(MGAREG_WFLAG, 0);
239 PRIMOUTREG(MGAREG_WFLAG1, 0);
240 PRIMOUTREG(0x2d00 + 56*4, *((u32 *)(&fParam)));
241 PRIMOUTREG(MGAREG_DMAPAD, 0);
242 PRIMOUTREG(MGAREG_DMAPAD, 0);
244 PRIMOUTREG(0x2d00 + 49*4, 0); /* Tex stage 0 */
245 PRIMOUTREG(0x2d00 + 57*4, 0); /* Tex stage 0 */
246 PRIMOUTREG(0x2d00 + 53*4, 0); /* Tex stage 1 */
247 PRIMOUTREG(0x2d00 + 61*4, 0); /* Tex stage 1 */
249 PRIMOUTREG(0x2d00 + 54*4, 0x40); /* Tex stage 0 : w */
250 PRIMOUTREG(0x2d00 + 62*4, 0x40); /* Tex stage 0 : h */
251 PRIMOUTREG(0x2d00 + 52*4, 0x40); /* Tex stage 1 : w */
252 PRIMOUTREG(0x2d00 + 60*4, 0x40); /* Tex stage 1 : h */
254 /* Dma pading required due to hw bug */
255 PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff);
256 PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff);
257 PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff);
258 PRIMOUTREG(MGAREG_WIADDR2, (__u32)(dev_priv->WarpIndex[pipe].phys_addr |
259 WIA_wmode_start | WIA_wagp_agp));
260 PRIMADVANCE(dev_priv);
263 static void mgaG200EmitPipe( drm_mga_private_t *dev_priv )
265 drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
266 unsigned int pipe = sarea_priv->WarpPipe;
269 PRIMGETPTR(dev_priv);
271 /* This takes 15 dwords */
273 PRIMOUTREG(MGAREG_WIADDR, WIA_wmode_suspend);
274 PRIMOUTREG(MGAREG_WVRTXSZ, 7);
275 PRIMOUTREG(MGAREG_WFLAG, 0);
276 PRIMOUTREG(0x2d00 + 24*4, 0); /* tex w/h */
278 PRIMOUTREG(0x2d00 + 25*4, 0x100);
279 PRIMOUTREG(0x2d00 + 34*4, 0); /* tex w/h */
280 PRIMOUTREG(0x2d00 + 42*4, 0xFFFF);
281 PRIMOUTREG(0x2d00 + 60*4, 0xFFFF);
283 /* Dma pading required due to hw bug */
284 PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff);
285 PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff);
286 PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff);
287 PRIMOUTREG(MGAREG_WIADDR, (__u32)(dev_priv->WarpIndex[pipe].phys_addr |
288 WIA_wmode_start | WIA_wagp_agp));
290 PRIMADVANCE(dev_priv);
293 static void mgaEmitState( drm_mga_private_t *dev_priv )
295 drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
296 unsigned int dirty = sarea_priv->dirty;
298 if (dev_priv->chipset == MGA_CARD_TYPE_G400) {
299 int multitex = sarea_priv->WarpPipe & MGA_T2;
301 if (sarea_priv->WarpPipe != dev_priv->WarpPipe) {
302 mgaG400EmitPipe( dev_priv );
303 dev_priv->WarpPipe = sarea_priv->WarpPipe;
306 if (dirty & MGA_UPLOAD_CTX) {
307 mgaEmitContext( dev_priv );
308 sarea_priv->dirty &= ~MGA_UPLOAD_CTX;
311 if (dirty & MGA_UPLOAD_TEX0) {
312 mgaG400EmitTex0( dev_priv );
313 sarea_priv->dirty &= ~MGA_UPLOAD_TEX0;
316 if ((dirty & MGA_UPLOAD_TEX1) && multitex) {
317 mgaG400EmitTex1( dev_priv );
318 sarea_priv->dirty &= ~MGA_UPLOAD_TEX1;
321 if (sarea_priv->WarpPipe != dev_priv->WarpPipe) {
322 mgaG200EmitPipe( dev_priv );
323 dev_priv->WarpPipe = sarea_priv->WarpPipe;
326 if (dirty & MGA_UPLOAD_CTX) {
327 mgaEmitContext( dev_priv );
328 sarea_priv->dirty &= ~MGA_UPLOAD_CTX;
331 if (dirty & MGA_UPLOAD_TEX0) {
332 mgaG200EmitTex( dev_priv );
333 sarea_priv->dirty &= ~MGA_UPLOAD_TEX0;
339 /* Disallow all write destinations except the front and backbuffer.
341 static int mgaVerifyContext(drm_mga_private_t *dev_priv )
343 drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
344 unsigned int *regs = sarea_priv->ContextState;
346 if (regs[MGA_CTXREG_DSTORG] != dev_priv->frontOffset &&
347 regs[MGA_CTXREG_DSTORG] != dev_priv->backOffset) {
348 DRM_DEBUG("BAD DSTORG: %x (front %x, back %x)\n\n",
349 regs[MGA_CTXREG_DSTORG], dev_priv->frontOffset,
350 dev_priv->backOffset);
351 regs[MGA_CTXREG_DSTORG] = 0;
358 /* Disallow texture reads from PCI space.
360 static int mgaVerifyTex(drm_mga_private_t *dev_priv,
363 drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
365 if ((sarea_priv->TexState[unit][MGA_TEXREG_ORG] & 0x3) == 0x1) {
366 DRM_DEBUG("BAD TEXREG_ORG: %x, unit %d\n",
367 sarea_priv->TexState[unit][MGA_TEXREG_ORG],
369 sarea_priv->TexState[unit][MGA_TEXREG_ORG] = 0;
376 static int mgaVerifyState( drm_mga_private_t *dev_priv )
378 drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
379 unsigned int dirty = sarea_priv->dirty;
382 if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS)
383 sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS;
385 if (dirty & MGA_UPLOAD_CTX)
386 rv |= mgaVerifyContext( dev_priv );
388 if (dirty & MGA_UPLOAD_TEX0)
389 rv |= mgaVerifyTex( dev_priv, 0 );
391 if (dev_priv->chipset == MGA_CARD_TYPE_G400)
393 if (dirty & MGA_UPLOAD_TEX1)
394 rv |= mgaVerifyTex( dev_priv, 1 );
396 if (dirty & MGA_UPLOAD_PIPE)
397 rv |= (sarea_priv->WarpPipe > MGA_MAX_G400_PIPES);
401 if (dirty & MGA_UPLOAD_PIPE)
402 rv |= (sarea_priv->WarpPipe > MGA_MAX_G200_PIPES);
408 static int mgaVerifyIload( drm_mga_private_t *dev_priv,
409 unsigned long bus_address,
410 unsigned int dstOrg, int length )
412 if(dstOrg < dev_priv->textureOffset ||
414 (dev_priv->textureOffset + dev_priv->textureSize)) {
423 /* This copies a 64 byte aligned agp region to the frambuffer
424 * with a standard blit, the ioctl needs to do checking */
426 static void mga_dma_dispatch_tex_blit( drm_device_t *dev,
427 unsigned long bus_address,
429 unsigned int destOrg )
431 drm_mga_private_t *dev_priv = dev->dev_private;
432 int use_agp = PDEA_pagpxfer_enable | 0x00000001;
438 PRIM_OVERFLOW(dev, dev_priv, 30);
439 PRIMGETPTR( dev_priv );
441 dev_priv->last_sync_tag = mga_create_sync_tag(dev);
443 PRIMOUTREG( MGAREG_DSTORG, destOrg);
444 PRIMOUTREG( MGAREG_MACCESS, 0x00000000);
445 DRM_DEBUG("srcorg : %lx\n", bus_address | use_agp);
446 PRIMOUTREG( MGAREG_SRCORG, (u32) bus_address | use_agp);
447 PRIMOUTREG( MGAREG_AR5, 64);
449 PRIMOUTREG( MGAREG_PITCH, 64);
450 PRIMOUTREG( MGAREG_DMAPAD, 0);
451 PRIMOUTREG( MGAREG_DMAPAD, 0);
452 PRIMOUTREG( MGAREG_DWGCTL, MGA_COPY_CMD);
454 PRIMOUTREG(MGAREG_AR0, 63);
455 PRIMOUTREG(MGAREG_AR3, 0);
456 PRIMOUTREG(MGAREG_FXBNDRY, (63 << 16));
457 PRIMOUTREG(MGAREG_YDSTLEN+MGAREG_MGA_EXEC, y2);
459 PRIMOUTREG( MGAREG_SRCORG, 0);
460 PRIMOUTREG( MGAREG_PITCH, dev_priv->stride / dev_priv->cpp);
461 PRIMOUTREG( MGAREG_DMAPAD, 0);
462 PRIMOUTREG( MGAREG_DWGSYNC, dev_priv->last_sync_tag);
463 PRIMADVANCE(dev_priv);
466 static void mga_dma_dispatch_vertex(drm_device_t *dev,
469 drm_mga_private_t *dev_priv = dev->dev_private;
470 drm_mga_buf_priv_t *buf_priv = buf->dev_private;
471 drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
472 unsigned long address = (unsigned long)buf->bus_address;
473 int length = buf->used;
474 int use_agp = PDEA_pagpxfer_enable;
479 DRM_DEBUG("dispatch vertex %d addr 0x%lx, "
480 "length 0x%x nbox %d dirty %x\n",
481 buf->idx, address, length,
482 sarea_priv->nbox, sarea_priv->dirty);
485 dev_priv->last_sync_tag = mga_create_sync_tag(dev);
487 if (buf_priv->discard) {
488 buf_priv->my_freelist->age = dev_priv->last_sync_tag;
489 mga_freelist_put(dev, buf);
493 /* WARNING: if you change any of the state functions verify
494 * these numbers (Overestimating this doesn't hurt).
496 primary_needed = (25+15+30+25+
498 15 * MGA_NR_SAREA_CLIPRECTS);
501 PRIM_OVERFLOW(dev, dev_priv, primary_needed);
502 mgaEmitState( dev_priv );
506 if (i < sarea_priv->nbox) {
507 DRM_DEBUG("idx %d Emit box %d/%d:"
511 sarea_priv->boxes[i].x1,
512 sarea_priv->boxes[i].y1,
513 sarea_priv->boxes[i].x2,
514 sarea_priv->boxes[i].y2);
516 mgaEmitClipRect( dev_priv,
517 &sarea_priv->boxes[i] );
520 PRIMGETPTR(dev_priv);
521 PRIMOUTREG( MGAREG_DMAPAD, 0);
522 PRIMOUTREG( MGAREG_DMAPAD, 0);
523 PRIMOUTREG( MGAREG_SECADDRESS,
524 ((__u32)address) | TT_VERTEX);
525 PRIMOUTREG( MGAREG_SECEND,
526 (((__u32)(address + length)) |
528 PRIMADVANCE( dev_priv );
529 } while (++i < sarea_priv->nbox);
532 PRIMGETPTR( dev_priv );
533 PRIMOUTREG(MGAREG_DMAPAD, 0);
534 PRIMOUTREG(MGAREG_DMAPAD, 0);
535 PRIMOUTREG(MGAREG_DMAPAD, 0);
536 PRIMOUTREG(MGAREG_DWGSYNC, dev_priv->last_sync_tag);
537 PRIMADVANCE( dev_priv );
541 static void mga_dma_dispatch_clear( drm_device_t *dev, int flags,
542 unsigned int clear_color,
543 unsigned int clear_zval )
545 drm_mga_private_t *dev_priv = dev->dev_private;
546 drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
547 unsigned int *regs = sarea_priv->ContextState;
548 int nbox = sarea_priv->nbox;
549 drm_clip_rect_t *pbox = sarea_priv->boxes;
555 if ( dev_priv->sgram )
556 cmd = MGA_CLEAR_CMD | DC_atype_blk;
558 cmd = MGA_CLEAR_CMD | DC_atype_rstr;
560 primary_needed = nbox * 70;
561 if(primary_needed == 0) primary_needed = 70;
562 PRIM_OVERFLOW(dev, dev_priv, primary_needed);
563 PRIMGETPTR( dev_priv );
564 dev_priv->last_sync_tag = mga_create_sync_tag(dev);
566 for (i = 0 ; i < nbox ; i++) {
567 unsigned int height = pbox[i].y2 - pbox[i].y1;
569 DRM_DEBUG("dispatch clear %d,%d-%d,%d flags %x!\n",
570 pbox[i].x1, pbox[i].y1, pbox[i].x2,
573 if ( flags & MGA_FRONT ) {
574 DRM_DEBUG("clear front\n");
575 PRIMOUTREG( MGAREG_DMAPAD, 0);
576 PRIMOUTREG( MGAREG_DMAPAD, 0);
577 PRIMOUTREG(MGAREG_YDSTLEN, (pbox[i].y1<<16)|height);
578 PRIMOUTREG(MGAREG_FXBNDRY, (pbox[i].x2<<16)|pbox[i].x1);
580 PRIMOUTREG( MGAREG_DMAPAD, 0);
581 PRIMOUTREG(MGAREG_FCOL, clear_color);
582 PRIMOUTREG(MGAREG_DSTORG, dev_priv->frontOffset);
583 PRIMOUTREG(MGAREG_DWGCTL+MGAREG_MGA_EXEC, cmd );
586 if ( flags & MGA_BACK ) {
587 DRM_DEBUG("clear back\n");
588 PRIMOUTREG( MGAREG_DMAPAD, 0);
589 PRIMOUTREG( MGAREG_DMAPAD, 0);
590 PRIMOUTREG(MGAREG_YDSTLEN, (pbox[i].y1<<16)|height);
591 PRIMOUTREG(MGAREG_FXBNDRY, (pbox[i].x2<<16)|pbox[i].x1);
593 PRIMOUTREG( MGAREG_DMAPAD, 0);
594 PRIMOUTREG(MGAREG_FCOL, clear_color);
595 PRIMOUTREG(MGAREG_DSTORG, dev_priv->backOffset);
596 PRIMOUTREG(MGAREG_DWGCTL+MGAREG_MGA_EXEC, cmd );
599 if ( flags & MGA_DEPTH ) {
600 DRM_DEBUG("clear depth\n");
601 PRIMOUTREG( MGAREG_DMAPAD, 0);
602 PRIMOUTREG( MGAREG_DMAPAD, 0);
603 PRIMOUTREG(MGAREG_YDSTLEN, (pbox[i].y1<<16)|height);
604 PRIMOUTREG(MGAREG_FXBNDRY, (pbox[i].x2<<16)|pbox[i].x1);
606 PRIMOUTREG( MGAREG_DMAPAD, 0);
607 PRIMOUTREG(MGAREG_FCOL, clear_zval);
608 PRIMOUTREG(MGAREG_DSTORG, dev_priv->depthOffset);
609 PRIMOUTREG(MGAREG_DWGCTL+MGAREG_MGA_EXEC, cmd );
613 /* Force reset of DWGCTL */
614 PRIMOUTREG( MGAREG_DMAPAD, 0);
615 PRIMOUTREG( MGAREG_DMAPAD, 0);
616 PRIMOUTREG( MGAREG_DMAPAD, 0);
617 PRIMOUTREG( MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL] );
619 PRIMOUTREG( MGAREG_DMAPAD, 0);
620 PRIMOUTREG( MGAREG_DMAPAD, 0);
621 PRIMOUTREG( MGAREG_DMAPAD, 0);
622 PRIMOUTREG( MGAREG_DWGSYNC, dev_priv->last_sync_tag);
623 PRIMADVANCE(dev_priv);
626 static void mga_dma_dispatch_swap( drm_device_t *dev )
628 drm_mga_private_t *dev_priv = dev->dev_private;
629 drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
630 unsigned int *regs = sarea_priv->ContextState;
631 int nbox = sarea_priv->nbox;
632 drm_clip_rect_t *pbox = sarea_priv->boxes;
637 primary_needed = nbox * 5;
638 primary_needed += 60;
639 PRIM_OVERFLOW(dev, dev_priv, primary_needed);
640 PRIMGETPTR( dev_priv );
642 dev_priv->last_sync_tag = mga_create_sync_tag(dev);
644 PRIMOUTREG(MGAREG_DSTORG, dev_priv->frontOffset);
645 PRIMOUTREG(MGAREG_MACCESS, dev_priv->mAccess);
646 PRIMOUTREG(MGAREG_SRCORG, dev_priv->backOffset);
647 PRIMOUTREG(MGAREG_AR5, dev_priv->stride/2);
649 PRIMOUTREG( MGAREG_DMAPAD, 0);
650 PRIMOUTREG( MGAREG_DMAPAD, 0);
651 PRIMOUTREG( MGAREG_DMAPAD, 0);
652 PRIMOUTREG(MGAREG_DWGCTL, MGA_COPY_CMD);
654 for (i = 0 ; i < nbox; i++) {
655 unsigned int h = pbox[i].y2 - pbox[i].y1;
656 unsigned int start = pbox[i].y1 * dev_priv->stride/2;
658 DRM_DEBUG("dispatch swap %d,%d-%d,%d!\n",
659 pbox[i].x1, pbox[i].y1,
660 pbox[i].x2, pbox[i].y2);
662 PRIMOUTREG(MGAREG_AR0, start + pbox[i].x2 - 1);
663 PRIMOUTREG(MGAREG_AR3, start + pbox[i].x1);
664 PRIMOUTREG(MGAREG_FXBNDRY, pbox[i].x1|((pbox[i].x2 - 1)<<16));
665 PRIMOUTREG(MGAREG_YDSTLEN+MGAREG_MGA_EXEC, (pbox[i].y1<<16)|h);
668 /* Force reset of DWGCTL */
669 PRIMOUTREG( MGAREG_DMAPAD, 0);
670 PRIMOUTREG( MGAREG_DMAPAD, 0);
671 PRIMOUTREG( MGAREG_DMAPAD, 0);
672 PRIMOUTREG( MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL] );
674 PRIMOUTREG( MGAREG_SRCORG, 0);
675 PRIMOUTREG( MGAREG_DMAPAD, 0);
676 PRIMOUTREG( MGAREG_DMAPAD, 0);
677 PRIMOUTREG( MGAREG_DWGSYNC, dev_priv->last_sync_tag);
678 PRIMADVANCE(dev_priv);
681 int mga_clear_bufs(struct inode *inode, struct file *filp,
682 unsigned int cmd, unsigned long arg)
684 drm_file_t *priv = filp->private_data;
685 drm_device_t *dev = priv->dev;
686 drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
687 drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
688 __volatile__ unsigned int *status =
689 (__volatile__ unsigned int *)dev_priv->status_page;
690 drm_mga_clear_t clear;
692 copy_from_user_ret(&clear, (drm_mga_clear_t *)arg, sizeof(clear),
695 if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
696 DRM_ERROR("mga_clear_bufs called without lock held\n");
700 if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS)
701 sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS;
703 /* Make sure we restore the 3D state next time.
705 dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CTX;
706 mga_dma_dispatch_clear( dev, clear.flags,
709 PRIMUPDATE(dev_priv);
710 mga_dma_schedule(dev, 1);
711 sarea_priv->last_dispatch = status[1];
715 int mga_swap_bufs(struct inode *inode, struct file *filp,
716 unsigned int cmd, unsigned long arg)
718 drm_file_t *priv = filp->private_data;
719 drm_device_t *dev = priv->dev;
720 drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
721 drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
722 __volatile__ unsigned int *status =
723 (__volatile__ unsigned int *)dev_priv->status_page;
725 if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
726 DRM_ERROR("mga_swap_bufs called without lock held\n");
730 if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS)
731 sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS;
733 /* Make sure we restore the 3D state next time.
735 dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CTX;
736 mga_dma_dispatch_swap( dev );
737 PRIMUPDATE(dev_priv);
738 set_bit(0, &dev_priv->current_prim->swap_pending);
739 dev_priv->current_prim->swap_pending = 1;
740 mga_dma_schedule(dev, 1);
741 sarea_priv->last_dispatch = status[1];
745 int mga_iload(struct inode *inode, struct file *filp,
746 unsigned int cmd, unsigned long arg)
748 drm_file_t *priv = filp->private_data;
749 drm_device_t *dev = priv->dev;
750 drm_device_dma_t *dma = dev->dma;
751 drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
752 drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
753 __volatile__ unsigned int *status =
754 (__volatile__ unsigned int *)dev_priv->status_page;
756 drm_mga_buf_priv_t *buf_priv;
757 drm_mga_iload_t iload;
758 unsigned long bus_address;
760 DRM_DEBUG("Starting Iload\n");
761 copy_from_user_ret(&iload, (drm_mga_iload_t *)arg, sizeof(iload),
764 if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
765 DRM_ERROR("mga_iload called without lock held\n");
769 buf = dma->buflist[ iload.idx ];
770 buf_priv = buf->dev_private;
771 bus_address = buf->bus_address;
772 DRM_DEBUG("bus_address %lx, length %d, destorg : %x\n",
773 bus_address, iload.length, iload.destOrg);
775 if(mgaVerifyIload(dev_priv,
779 mga_freelist_put(dev, buf);
783 sarea_priv->dirty |= MGA_UPLOAD_CTX;
785 mga_dma_dispatch_tex_blit(dev, bus_address, iload.length,
787 buf_priv->my_freelist->age = dev_priv->last_sync_tag;
788 buf_priv->discard = 1;
789 mga_freelist_put(dev, buf);
790 mga_dma_schedule(dev, 1);
791 sarea_priv->last_dispatch = status[1];
795 int mga_vertex(struct inode *inode, struct file *filp,
796 unsigned int cmd, unsigned long arg)
798 drm_file_t *priv = filp->private_data;
799 drm_device_t *dev = priv->dev;
800 drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
801 drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
802 __volatile__ unsigned int *status =
803 (__volatile__ unsigned int *)dev_priv->status_page;
804 drm_device_dma_t *dma = dev->dma;
806 drm_mga_buf_priv_t *buf_priv;
807 drm_mga_vertex_t vertex;
809 copy_from_user_ret(&vertex, (drm_mga_vertex_t *)arg, sizeof(vertex),
812 if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
813 DRM_ERROR("mga_vertex called without lock held\n");
817 DRM_DEBUG("mga_vertex\n");
819 buf = dma->buflist[ vertex.idx ];
820 buf_priv = buf->dev_private;
822 buf->used = vertex.used;
823 buf_priv->discard = vertex.discard;
825 if (!mgaVerifyState(dev_priv)) {
826 if (vertex.discard) {
827 buf_priv->my_freelist->age = dev_priv->last_sync_tag;
828 mga_freelist_put(dev, buf);
833 mga_dma_dispatch_vertex(dev, buf);
835 PRIMUPDATE(dev_priv);
836 mga_dma_schedule(dev, 1);
837 sarea_priv->last_dispatch = status[1];
841 static int mga_dma_get_buffers(drm_device_t *dev, drm_dma_t *d)
846 for (i = d->granted_count; i < d->request_count; i++) {
847 buf = mga_freelist_get(dev);
849 buf->pid = current->pid;
850 copy_to_user_ret(&d->request_indices[i],
854 copy_to_user_ret(&d->request_sizes[i],
863 int mga_dma(struct inode *inode, struct file *filp, unsigned int cmd,
866 drm_file_t *priv = filp->private_data;
867 drm_device_t *dev = priv->dev;
868 drm_device_dma_t *dma = dev->dma;
869 drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
870 drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
871 __volatile__ unsigned int *status =
872 (__volatile__ unsigned int *)dev_priv->status_page;
876 copy_from_user_ret(&d, (drm_dma_t *)arg, sizeof(d), -EFAULT);
877 DRM_DEBUG("%d %d: %d send, %d req\n",
878 current->pid, d.context, d.send_count, d.request_count);
880 if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
881 DRM_ERROR("mga_dma called without lock held\n");
885 /* Please don't send us buffers.
887 if (d.send_count != 0) {
888 DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n",
889 current->pid, d.send_count);
893 /* We'll send you buffers.
895 if (d.request_count < 0 || d.request_count > dma->buf_count) {
896 DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n",
897 current->pid, d.request_count, dma->buf_count);
903 if (d.request_count) {
904 retcode = mga_dma_get_buffers(dev, &d);
907 DRM_DEBUG("%d returning, granted = %d\n",
908 current->pid, d.granted_count);
909 copy_to_user_ret((drm_dma_t *)arg, &d, sizeof(d), -EFAULT);
910 sarea_priv->last_dispatch = status[1];