/* 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 const unsigned int mga_warp_g400_microcode_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));

static const unsigned int mga_warp_g200_microcode_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));


unsigned int mga_warp_microcode_size(const drm_mga_private_t * dev_priv)
{
	switch (dev_priv->chipset) {
	case MGA_CARD_TYPE_G400:
	case MGA_CARD_TYPE_G550:
		return PAGE_ALIGN(mga_warp_g400_microcode_size);
	case MGA_CARD_TYPE_G200:
		return PAGE_ALIGN(mga_warp_g200_microcode_size);
	default:
		return 0;
	}
}

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;

	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;

	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 )
{
	const unsigned int size = mga_warp_microcode_size(dev_priv);

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

	switch (dev_priv->chipset) {
	case MGA_CARD_TYPE_G400:
	case MGA_CARD_TYPE_G550:
		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:
	case MGA_CARD_TYPE_G550:
		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;
}
