/* mga_warp.c -- Matrox G200/G400 WARP engine management -*- linux-c -*-
 * Created: Thu Jan 11 21:29:32 2001 by gareth@valinux.com
 *
 * 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:
 *    Gareth Hughes <gareth@valinux.com>
 */

#include "drmP.h"
#include "drm.h"
#include "mga_drm.h"
#include "mga_drv.h"
#include "mga_ucode.h"


#define MGA_WARP_CODE_ALIGN		256		/* in bytes */

#define WARP_UCODE_SIZE( which )					\
	((sizeof(which) / MGA_WARP_CODE_ALIGN + 1) * MGA_WARP_CODE_ALIGN)

#define WARP_UCODE_INSTALL( which, where )				\
do {									\
	DRM_DEBUG( " pcbase = 0x%08lx  vcbase = %p\n", pcbase, vcbase );\
	dev_priv->warp_pipe_phys[where] = pcbase;			\
	memcpy( vcbase, which, sizeof(which) );				\
	pcbase += WARP_UCODE_SIZE( which );				\
	vcbase += WARP_UCODE_SIZE( which );				\
} while (0)


static unsigned int mga_warp_g400_microcode_size( drm_mga_private_t *dev_priv )
{
	unsigned int size;

	size = ( WARP_UCODE_SIZE( warp_g400_tgz ) +
		 WARP_UCODE_SIZE( warp_g400_tgza ) +
		 WARP_UCODE_SIZE( warp_g400_tgzaf ) +
		 WARP_UCODE_SIZE( warp_g400_tgzf ) +
		 WARP_UCODE_SIZE( warp_g400_tgzs ) +
		 WARP_UCODE_SIZE( warp_g400_tgzsa ) +
		 WARP_UCODE_SIZE( warp_g400_tgzsaf ) +
		 WARP_UCODE_SIZE( warp_g400_tgzsf ) +
		 WARP_UCODE_SIZE( warp_g400_t2gz ) +
		 WARP_UCODE_SIZE( warp_g400_t2gza ) +
		 WARP_UCODE_SIZE( warp_g400_t2gzaf ) +
		 WARP_UCODE_SIZE( warp_g400_t2gzf ) +
		 WARP_UCODE_SIZE( warp_g400_t2gzs ) +
		 WARP_UCODE_SIZE( warp_g400_t2gzsa ) +
		 WARP_UCODE_SIZE( warp_g400_t2gzsaf ) +
		 WARP_UCODE_SIZE( warp_g400_t2gzsf ) );

	size = PAGE_ALIGN( size );

	DRM_DEBUG( "G400 ucode size = %d bytes\n", size );
	return size;
}

static unsigned int mga_warp_g200_microcode_size( drm_mga_private_t *dev_priv )
{
	unsigned int size;

	size = ( WARP_UCODE_SIZE( warp_g200_tgz ) +
		 WARP_UCODE_SIZE( warp_g200_tgza ) +
		 WARP_UCODE_SIZE( warp_g200_tgzaf ) +
		 WARP_UCODE_SIZE( warp_g200_tgzf ) +
		 WARP_UCODE_SIZE( warp_g200_tgzs ) +
		 WARP_UCODE_SIZE( warp_g200_tgzsa ) +
		 WARP_UCODE_SIZE( warp_g200_tgzsaf ) +
		 WARP_UCODE_SIZE( warp_g200_tgzsf ) );

	size = PAGE_ALIGN( size );

	DRM_DEBUG( "G200 ucode size = %d bytes\n", size );
	return size;
}

static int mga_warp_install_g400_microcode( drm_mga_private_t *dev_priv )
{
	unsigned char *vcbase = dev_priv->warp->handle;
	unsigned long pcbase = dev_priv->warp->offset;
	unsigned int size;

	size = mga_warp_g400_microcode_size( dev_priv );
	if ( size > dev_priv->warp->size ) {
		DRM_ERROR( "microcode too large! (%u > %lu)\n",
			   size, dev_priv->warp->size );
		return DRM_ERR(ENOMEM);
	}

	memset( dev_priv->warp_pipe_phys, 0,
		sizeof(dev_priv->warp_pipe_phys) );

	WARP_UCODE_INSTALL( warp_g400_tgz,	MGA_WARP_TGZ );
	WARP_UCODE_INSTALL( warp_g400_tgzf,	MGA_WARP_TGZF );
	WARP_UCODE_INSTALL( warp_g400_tgza,	MGA_WARP_TGZA );
	WARP_UCODE_INSTALL( warp_g400_tgzaf,	MGA_WARP_TGZAF );
	WARP_UCODE_INSTALL( warp_g400_tgzs,	MGA_WARP_TGZS );
	WARP_UCODE_INSTALL( warp_g400_tgzsf,	MGA_WARP_TGZSF );
	WARP_UCODE_INSTALL( warp_g400_tgzsa,	MGA_WARP_TGZSA );
	WARP_UCODE_INSTALL( warp_g400_tgzsaf,	MGA_WARP_TGZSAF );

	WARP_UCODE_INSTALL( warp_g400_t2gz,	MGA_WARP_T2GZ );
	WARP_UCODE_INSTALL( warp_g400_t2gzf,	MGA_WARP_T2GZF );
	WARP_UCODE_INSTALL( warp_g400_t2gza,	MGA_WARP_T2GZA );
	WARP_UCODE_INSTALL( warp_g400_t2gzaf,	MGA_WARP_T2GZAF );
	WARP_UCODE_INSTALL( warp_g400_t2gzs,	MGA_WARP_T2GZS );
	WARP_UCODE_INSTALL( warp_g400_t2gzsf,	MGA_WARP_T2GZSF );
	WARP_UCODE_INSTALL( warp_g400_t2gzsa,	MGA_WARP_T2GZSA );
	WARP_UCODE_INSTALL( warp_g400_t2gzsaf,	MGA_WARP_T2GZSAF );

	return 0;
}

static int mga_warp_install_g200_microcode( drm_mga_private_t *dev_priv )
{
	unsigned char *vcbase = dev_priv->warp->handle;
	unsigned long pcbase = dev_priv->warp->offset;
	unsigned int size;

	size = mga_warp_g200_microcode_size( dev_priv );
	if ( size > dev_priv->warp->size ) {
		DRM_ERROR( "microcode too large! (%u > %lu)\n",
			   size, dev_priv->warp->size );
		return DRM_ERR(ENOMEM);
	}

	memset( dev_priv->warp_pipe_phys, 0,
		sizeof(dev_priv->warp_pipe_phys) );

	WARP_UCODE_INSTALL( warp_g200_tgz,	MGA_WARP_TGZ );
	WARP_UCODE_INSTALL( warp_g200_tgzf,	MGA_WARP_TGZF );
	WARP_UCODE_INSTALL( warp_g200_tgza,	MGA_WARP_TGZA );
	WARP_UCODE_INSTALL( warp_g200_tgzaf,	MGA_WARP_TGZAF );
	WARP_UCODE_INSTALL( warp_g200_tgzs,	MGA_WARP_TGZS );
	WARP_UCODE_INSTALL( warp_g200_tgzsf,	MGA_WARP_TGZSF );
	WARP_UCODE_INSTALL( warp_g200_tgzsa,	MGA_WARP_TGZSA );
	WARP_UCODE_INSTALL( warp_g200_tgzsaf,	MGA_WARP_TGZSAF );

	return 0;
}

int mga_warp_install_microcode(	drm_mga_private_t *dev_priv )
{
	switch ( dev_priv->chipset ) {
	case MGA_CARD_TYPE_G400:
		return mga_warp_install_g400_microcode( dev_priv );
	case MGA_CARD_TYPE_G200:
		return mga_warp_install_g200_microcode( dev_priv );
	default:
		return DRM_ERR(EINVAL);
	}
}

#define WMISC_EXPECTED		(MGA_WUCODECACHE_ENABLE | MGA_WMASTER_ENABLE)

int mga_warp_init( drm_mga_private_t *dev_priv )
{
	u32 wmisc;

	/* FIXME: Get rid of these damned magic numbers...
	 */
	switch ( dev_priv->chipset ) {
	case MGA_CARD_TYPE_G400:
		MGA_WRITE( MGA_WIADDR2, MGA_WMODE_SUSPEND );
		MGA_WRITE( MGA_WGETMSB, 0x00000E00 );
		MGA_WRITE( MGA_WVRTXSZ, 0x00001807 );
		MGA_WRITE( MGA_WACCEPTSEQ, 0x18000000 );
		break;
	case MGA_CARD_TYPE_G200:
		MGA_WRITE( MGA_WIADDR, MGA_WMODE_SUSPEND );
		MGA_WRITE( MGA_WGETMSB, 0x1606 );
		MGA_WRITE( MGA_WVRTXSZ, 7 );
		break;
	default:
		return DRM_ERR(EINVAL);
	}

	MGA_WRITE( MGA_WMISC, (MGA_WUCODECACHE_ENABLE |
			       MGA_WMASTER_ENABLE |
			       MGA_WCACHEFLUSH_ENABLE) );
	wmisc = MGA_READ( MGA_WMISC );
	if ( wmisc != WMISC_EXPECTED ) {
		DRM_ERROR( "WARP engine config failed! 0x%x != 0x%x\n",
			   wmisc, WMISC_EXPECTED );
		return DRM_ERR(EINVAL);
	}

	return 0;
}
