/* mga_state.c -- State support for MGA G200/G400 -*- linux-c -*-
* Created: Thu Jan 27 02:53:43 2000 by jhartmann@precisioninsight.com
*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
* Jeff Hartmann <jhartmann@valinux.com>
* Keith Whitwell <keith@tungstengraphics.com>
*
* Rewritten by:
* Gareth Hughes <gareth@valinux.com>
*/
#include <drm/drmP.h>
#include <drm/mga_drm.h>
#include "mga_drv.h"
/* ================================================================
* DMA hardware state programming functions
*/
static void mga_emit_clip_rect(drm_mga_private_t *dev_priv,
struct drm_clip_rect *box)
{
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
drm_mga_context_regs_t *ctx = &sarea_priv->context_state;
unsigned int pitch = dev_priv->front_pitch;
DMA_LOCALS;
BEGIN_DMA(2);
/* Force reset of DWGCTL on G400 (eliminates clip disable bit).
*/
if (dev_priv->chipset >= MGA_CARD_TYPE_G400) {
DMA_BLOCK(MGA_DWGCTL, ctx->dwgctl,
MGA_LEN + MGA_EXEC, 0x80000000,
MGA_DWGCTL, ctx->dwgctl,
MGA_LEN + MGA_EXEC, 0x80000000);
}
DMA_BLOCK(MGA_DMAPAD, 0x00000000,
MGA_CXBNDRY, ((box->x2 - 1) << 16) | box->x1,
MGA_YTOP, box->y1 * pitch, MGA_YBOT, (box->y2 - 1) * pitch);
ADVANCE_DMA();
}
static __inline__ void mga_g200_emit_context(drm_mga_private_t *dev_priv)
{
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
drm_mga_context_regs_t *ctx = &sarea_priv->context_state;
DMA_LOCALS;
BEGIN_DMA(3);
DMA_BLOCK(MGA_DSTORG, ctx->dstorg,
MGA_MACCESS, ctx->maccess,
MGA_PLNWT, ctx->plnwt, MGA_DWGCTL, ctx->dwgctl);
DMA_BLOCK(MGA_ALPHACTRL, ctx->alphactrl,
MGA_FOGCOL, ctx->fogcolor,
MGA_WFLAG, ctx->wflag, MGA_ZORG, dev_priv->depth_offset);
DMA_BLOCK(MGA_FCOL, ctx->fcol,
MGA_DMAPAD, 0x00000000,
MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000);
ADVANCE_DMA();
}
static __inline__ void mga_g400_emit_context(drm_mga_private_t *dev_priv)
{
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
drm_mga_context_regs_t *ctx = &sarea_priv->context_state;
DMA_LOCALS;
BEGIN_DMA(4);
DMA_BLOCK(MGA_DSTORG, ctx->dstorg,
MGA_MACCESS, ctx->maccess,
MGA_PLNWT, ctx->plnwt, MGA_DWGCTL, ctx->dwgctl);
DMA_BLOCK(MGA_ALPHACTRL, ctx->alphactrl,
MGA_FOGCOL, ctx->fogcolor,
MGA_WFLAG, ctx->wflag, MGA_ZORG, dev_priv->depth_offset);
DMA_BLOCK(MGA_WFLAG1, ctx->wflag,
MGA_TDUALSTAGE0, ctx->tdualstage0,
MGA_TDUALSTAGE1, ctx->tdualstage1, MGA_FCOL, ctx->fcol);
DMA_BLOCK(MGA_STENCIL, ctx->stencil,
MGA_STENCILCTL, ctx->stencilctl,
MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000);
ADVANCE_DMA();
}
static __inline__ void mga_g200_emit_tex0(drm_mga_private_t *dev_priv)
{
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[0];
DMA_LOCALS;
BEGIN_DMA(4);
DMA_BLOCK(MGA_TEXCTL2, tex->texctl2,
MGA_TEXCTL, tex->texctl,
MGA_TEXFILTER