/* mga_dma.c -- DMA support for mga g200/g400 -*- linux-c -*-
 * Created: Mon Dec 13 01:50:01 1999 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
 * PRECISION INSIGHT 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.
 */

/*
 * \file mga_dma.c
 * DMA support for MGA G200 / G400.
 *
 * \author Rickard E. (Rik) Faith <faith@valinux.com>
 * \author Jeff Hartmann <jhartmann@valinux.com>
 * \author Keith Whitwell <keith@tungstengraphics.com>
 * \author Gareth Hughes <gareth@valinux.com>
 */

#include <linux/delay.h>

#include "mga_drv.h"

#define MGA_DEFAULT_USEC_TIMEOUT	10000
#define MGA_FREELIST_DEBUG		0

#define MINIMAL_CLEANUP 0
#define FULL_CLEANUP 1
static int mga_do_cleanup_dma(struct drm_device *dev, int full_cleanup);

/* ================================================================
 * Engine control
 */

int mga_do_wait_for_idle(drm_mga_private_t *dev_priv)
{
	u32 status = 0;
	int i;
	DRM_DEBUG("\n");

	for (i = 0; i < dev_priv->usec_timeout; i++) {
		status = MGA_READ(MGA_STATUS) & MGA_ENGINE_IDLE_MASK;
		if (status == MGA_ENDPRDMASTS) {
			MGA_WRITE8(MGA_CRTC_INDEX, 0);
			return 0;
		}
		udelay(1);
	}

#if MGA_DMA_DEBUG
	DRM_ERROR("failed!\n");
	DRM_INFO("   status=0x%08x\n", status);
#endif
	return -EBUSY;
}

static int mga_do_dma_reset(drm_mga_private_t *dev_priv)
{
	drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
	drm_mga_primary_buffer_t *primary = &dev_priv->prim;

	DRM_DEBUG("\n");

	/* The primary DMA stream should look like new right about now.
	 */
	primary->tail = 0;
	primary->space = primary->size;
	primary->last_flush = 0;

	sarea_priv->last_wrap = 0;

	/* FIXME: Reset counters, buffer ages etc...
	 */

	/* FIXME: What else do we need to reinitialize?  WARP stuff?
	 */

	return 0;
}

/* ================================================================
 * Primary DMA stream
 */

void mga_do_dma_flush(drm_mga_private_t *dev_priv)
{
	drm_mga_primary_buffer_t *primary = &dev_priv->prim;
	u32 head, tail;
	u32 status = 0;
	int i;
	DMA_LOCALS;
	DRM_DEBUG("\n");

	/* We need to wait so that we can do an safe flush */
	for (i = 0; i < dev_priv->usec_timeout; i++) {
		status = MGA_READ(MGA_STATUS) & MGA_ENGINE_IDLE_MASK;
		if (status == MGA_ENDPRDMASTS)
			break;
		udelay(1);
	}

	if (primary->tail == primary->last_flush) {
		DRM_DEBUG("   bailing out...\n");
		return;
	}

	tail = primary->tail + dev_priv->primary->offset;

	/* We need to pad the stream between flushes, as the card
	 * actually (partially?) reads the first of these commands.
	 * See page 4-16 in the G400 manual, middle of the page or so.
	 */
	BEGIN_DMA(1);

	DMA_BLOCK(MGA_DMAPAD, 0x00000000,
		  MGA_DMAPAD, 0x00000000,
		  MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000);

	ADVANCE_DMA();

	primary->last_flush = primary->tail;

	head = MGA_READ(MGA_PRIMADDRESS);

	if (head <= tail)
		primary->space = primary->size - primary->tail;
	else
		primary->space = head - tail;

	DRM_DEBUG("   head = 0x%06lx\n", (unsigned long)(head - dev_priv->primary->offset));
	DRM_DEBUG("   tail = 0x%06lx\n", (unsigned long)(tail - dev_priv->primary->offset));
	DRM_DEBUG("  space = 0x%06x\n", primary->space);

	mga_flush_write_combine();
	MGA_WRITE(MGA_PRIMEND, tail | dev_priv->dma_access);

	DRM_DEBUG("done.\n");
}

void mga_do_dma_wrap_start(drm_mga_private_t *dev_priv)
{
	drm_mga_primary_buffer_t *primary = &dev_priv->prim;
	u32 head, tail;
	DMA_LOCALS;
	DRM_DEBUG("\n");

	BEGIN_DMA_WRAP();

	DMA_BLOCK(MGA_DMAPAD, 0x00000000,
		  MGA_DMAPAD, 0x00000000,
		  MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000);

	ADVANCE_DMA();

	tail = primary->tail + dev_priv->primary->offset;

	primary->tail = 0;
	primary->last_flush = 0;
	primary->last_wrap++;

	head = MGA_READ(MGA_PRIMADDRESS);

	if (head == dev_priv->primary->offset)
		primary->space = primary->size;
	else
		primary->space = head - dev_priv->primary->offset;

	DRM_DEBUG("   head = 0x%06lx\n", (unsigned long)(head - dev_priv->primary->offset));
	DRM_DEBUG("   tail = 0x%06x\n", primary->tail);
	DRM_DEBUG("   wrap = %d\n", primary->last_wrap);
	DRM_DEBUG("  space = 0x%06x\n", primary->space);

	mga_flush_write_combine();
	MGA_WRITE(MGA_PRIMEND, tail | dev_priv->dma_access);

	set_bit(0, &primary->wrapped);
	DRM_DEBUG("done.\n");
}

void mga_do_dma_wrap_end(drm_mga_private_t *dev_priv)
{
	drm_mga_primary_buffer_t *primary = &dev_priv->prim;
	drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
	u32 head = dev_priv->primary->offset;
	DRM_DEBUG("\n");

	sarea_priv->last_wrap++;
	DRM_DEBUG("   wrap = %d\n", sarea_priv->last_wrap);

	mga_flush_write_combine();
	MGA_WRITE(MGA_PRIMADDRESS, head | MGA_DMA_GENERAL);

	clear_bit(0, &primary->wrapped);
	DRM_DEBUG("done.\n");
}

/* ================================================================
 * Freelist management
 */

#define MGA_BUFFER_USED		(~0)
#define MGA_BUFFER_FREE		0

#if MGA_FREELIST_DEBUG
static void mga_freelist_print(struct drm_device *dev)
{
	drm_mga_private_t *dev_priv = dev->dev_private;
	drm_mga_freelist_t *entry;

	DRM_INFO("\n");
	DRM_INFO("current dispatch: last=0x%x done=0x%x\n",
		 dev_priv->sarea_priv->last_dispatch,
		 (unsigned int)(MGA_READ(MGA_PRIMADDRESS) -
				dev_priv->primary->offset));
	DRM_INFO("current freelist:\n");

	for (entry = dev_priv->head->next; entry; entry = entry->next) {
		DRM_INFO("   %p   idx=%2d  age=0x%x 0x%06lx\n",
			 entry, entry->buf->idx, entry->age.head,
			 (unsigned long)(entry->age.head - dev_priv->primary->offset));
	}
	DRM_INFO("\n");
}
#endif

static int mga_freelist_init(struct drm_device *dev, drm_mga_private_t *dev_priv)
{
	struct drm_device_dma *dma = dev->dma;
	struct drm_buf *buf;
	drm_mga_buf_priv_t *buf_priv;
	drm_mga_freelist_t *entry;
	int i;
	DRM_DEBUG("count=%d\n", dma->buf_count);

	dev_priv->head = kzalloc(sizeof(drm_mga_freelist_t), GFP_KERNEL);
	if (dev_priv->head == NULL)
		return -ENOMEM;

	SET_AGE(&dev_priv->head->age, MGA_BUFFER_USED, 0);

	for (i = 0; i < dma->buf_count; i++) {
		buf = dma->buflist[i];
		buf_priv = buf->dev_private;

		entry = kzalloc(sizeof(drm_mga_freelist_t), GFP_KERNEL);
		if (entry == NULL)
			return -ENOMEM;

		entry->next = dev_priv->head->next;
		entry->prev = dev_priv->head;
		SET_AGE(&entry->age, MGA_BUFFER_FREE, 0);
		entry->buf = buf;

		if (dev_priv->head->next != NULL)
			dev_priv->head->next->prev = entry;
		if (entry->next == NULL)
			dev_priv->tail = entry;

		buf_priv->list_entry = entry;
		buf_priv->discard = 0;
		buf_priv->dispatched = 0;

		dev_priv->head->next = entry;
	}

	return 0;
}

static void mga_freelist_cleanup(struct drm_device *dev)
{
	drm_mga_private_t *dev_priv = dev->dev_private;
	drm_mga_freelist_t *entry;
	drm_mga_freelist_t *next;
	DRM_DEBUG("\n");

	entry = dev_priv->head;
	while (entry) {
		next = entry->next;
		kfree(entry);
		entry = next;
	}

	dev_priv->head = dev_priv->tail = NULL;
}

#if 0
/* FIXME: Still needed?
 */
static void mga_freelist_reset(struct drm_device *dev)
{
	struct drm_device_dma *dma = dev->dma;
	struct drm_buf *buf;
	drm_mga_buf_priv_t *buf_priv;
	int i;

	for (i = 0; i < dma->buf_count; i++) {
		buf = dma->buflist[i];
		buf_priv = buf->dev_private;
		SET_AGE(&buf_priv->list_entry->age, MGA_BUFFER_FREE, 0);
	}
}
#endif

static struct drm_buf *mga_freelist_get(struct drm_device * dev)
{
	drm_mga_private_t *dev_priv = dev->dev_private;
	drm_mga_freelist_t *next;
	drm_mga_freelist_t *prev;
	drm_mga_freelist_t *tail = dev_priv->tail;
	u32 head, wrap;
	DRM_DEBUG("\n");

	head = MGA_READ(MGA_PRIMADDRESS);
	wrap = dev_priv->sarea_priv->last_wrap;

	DRM_DEBUG("   tail=0x%06lx %d\n",
		  tail->age.head ?
		  (unsigned long)(tail->age.head - dev_priv->primary->offset) : 0,
		  tail->age.wrap);
	DRM_DEBUG("   head=0x%06lx %d\n",
		  (unsigned long)(head - dev_priv->primary->offset), wrap);

	if (TEST_AGE(&tail->age, head, wrap)) {
		prev = dev_priv->tail->prev;
		next = dev_priv->tail;
		prev->next = NULL;
		next->prev = next->next = NULL;
		dev_priv->tail = prev;
		SET_AGE(&next->age, MGA_BUFFER_USED, 0);
		return next->buf;
	}

	DRM_DEBUG("returning NULL!\n");
	return NULL;
}

int mga_freelist_put(struct drm_device *dev, struct drm_buf *buf)
{
	drm_mga_private_t *dev_priv = dev->dev_private;
	drm_mga_buf_priv_t *buf_priv = buf->dev_private;
	drm_mga_freelist_t *head, *entry, *prev;

	DRM_DEBUG("age=0x%06lx wrap=%d\n",
		  (unsigned long)(buf_priv->list_entry->age.head -
				  dev_priv->primary->offset),
		  buf_priv->list_entry->age.wrap);

	entry = buf_priv->list_entry;
	head = dev_priv->head;

	if (buf_priv->list_entry->age.head == MGA_BUFFER_USED) {
		SET_AGE(&entry->age, MGA_BUFFER_FREE, 0);
		prev = dev_priv->tail;
		prev->next = entry;
		entry->prev = prev;
		entry->next = NULL;
	} else {
		prev = head->next;
		head->next = entry;
		prev->prev = entry;
		entry->prev = head;
		entry->next = prev;
	}

	return 0;
}

/* ================================================================
 * DMA initialization, cleanup
 */

int mga_driver_load(struct drm_device *dev, unsigned long flags)
{
	drm_mga_private_t *dev_priv;
	int ret;

	/* There are PCI versions of the G450.  These cards have the
	 * same PCI ID as the AGP G450, but have an additional PCI-to-PCI
	 * bridge chip.  We detect these cards, which are not currently
	 * supported by this driver, by looking at the device ID of the
	 * bus the "card" is on.  If vendor is 0x3388 (Hint Corp) and the
	 * device is 0x0021 (HB6 Universal PCI-PCI bridge), we reject the
	 * device.
	 */
	if ((dev->pdev->device == 0x0525) && dev->pdev->bus->self
	    && (dev->pdev->bus->self->vendor == 0x3388)
	    && (dev->pdev->bus->self->device == 0x0021)
	    && dev->agp) {
		/* FIXME: This should be quirked in the pci core, but oh well
		 * the hw probably stopped existing. */
		arch_phys_wc_del(dev->agp->agp_mtrr);
		kfree(dev->agp);
		dev->agp = NULL;
	}
	dev_priv = kzalloc(sizeof(drm_mga_private_t), GFP_KERNEL);
	if (!dev_priv)
		return -ENOMEM;

	dev->dev_private = (void *)dev_priv;

	dev_priv->usec_timeout = MGA_DEFAULT_USEC_TIMEOUT;
	dev_priv->chipset = flags;

	pci_set_master(dev->pdev);

	dev_priv->mmio_base = pci_resource_start(dev->pdev, 1);
	dev_priv->mmio_size = pci_resource_len(dev->pdev, 1);

	ret = drm_vblank_init(dev, 1);

	if (ret) {
		(void) mga_driver_unload(dev);
		return ret;
	}

	return 0;
}

#if IS_ENABLED(CONFIG_AGP)
/*
 * Bootstrap the driver for AGP DMA.
 *
 * \todo
 * Investigate whether there is any benefit to storing the WARP microcode in
 * AGP memory.  If not, the microcode may as well always be put in PCI
 * memory.
 *
 * \todo
 * This routine needs to set dma_bs->agp_mode to the mode actually configured
 * in the hardware.  Looking just at the Linux AGP driver code, I don't see
 * an easy way to determine this.
 *
 * \sa mga_do_dma_bootstrap, mga_do_pci_dma_bootstrap
 */
static int mga_do_agp_dma_bootstrap(struct drm_device *dev,
				    drm_mga_dma_bootstrap_t *dma_bs)
{
	drm_mga_private_t *const dev_priv =
	    (drm_mga_private_t *) dev->dev_private;
	unsigned int warp_size = MGA_WARP_UCODE_SIZE;
	int err;
	unsigned offset;
	const unsigned secondary_size = dma_bs->secondary_bin_count
	    * dma_bs->secondary_bin_size;
	const unsigned agp_size = (dma_bs->agp_size << 20);
	struct drm_buf_desc req;
	struct drm_agp_mode mode;
	struct drm_agp_info info;
	struct drm_agp_buffer agp_req;
	struct drm_agp_binding bind_req;

	/* Acquire AGP. */
	err = drm_agp_acquire(dev);
	if (err) {
		DRM_ERROR("Unable to acquire AGP: %d\n", err);
		return err;
	}

	err = drm_agp_info(dev, &info);
	if (err) {
		DRM_ERROR("Unable to get AGP info: %d\n", err);
		return err;
	}

	mode.mode = (info.mode & ~0x07) | dma_bs->agp_mode;
	err = drm_agp_enable(dev, mode);
	if (err) {
		DRM_ERROR("Unable to enable AGP (mode = 0x%lx)\n", mode.mode);
		return err;
	}

	/* In addition to the usual AGP mode configuration, the G200 AGP cards
	 * need to have the AGP mode "manually" set.
	 */

	if (dev_priv->chipset == MGA_CARD_TYPE_G200) {
		if (mode.mode & 0x02)
			MGA_WRITE(MGA_AGP_PLL, MGA_AGP2XPLL_ENABLE);
		else
			MGA_WRITE(MGA_AGP_PLL, MGA_AGP2XPLL_DISABLE);
	}

	/* Allocate and bind AGP memory. */
	agp_req.size = agp_size;
	agp_req.type = 0;
	err = drm_agp_alloc(dev, &agp_req);
	if (err) {
		dev_priv->agp_size = 0;
		DRM_ERROR("Unable to allocate %uMB AGP memory\n",
			  dma_bs->agp_size);
		return err;
	}

	dev_priv->agp_size = agp_size;
	dev_priv->agp_handle = agp_req.handle;

	bind_req.handle = agp_req.handle;
	bind_req.offset = 0;
	err = drm_agp_bind(dev, &bind_req);
	if (err) {
		DRM_ERROR("Unable to bind AGP memory: %d\n", err);
		return err;
	}

	/* Make drm_legacy_addbufs happy by not trying to create a mapping for
	 * less than a page.
	 */
	if (warp_size < PAGE_SIZE)
		warp_size = PAGE_SIZE;

	offset = 0;
	err = drm_legacy_addmap(dev, offset, warp_size,
				_DRM_AGP, _DRM_READ_ONLY, &dev_priv->warp);
	if (err) {
		DRM_ERROR("Unable to map WARP microcode: %d\n", err);
		return err;
	}

	offset += warp_size;
	err = drm_legacy_addmap(dev, offset, dma_bs->primary_size,
				_DRM_AGP, _DRM_READ_ONLY, &dev_priv->primary);
	if (err) {
		DRM_ERROR("Unable to map primary DMA region: %d\n", err);
		return err;
	}

	offset += dma_bs->primary_size;
	err = drm_legacy_addmap(dev, offset, secondary_size,
				_DRM_AGP, 0, &dev->agp_buffer_map);
	if (err) {
		DRM_ERROR("Unable to map secondary DMA region: %d\n", err);
		return err;
	}

	(void)memset(&req, 0, sizeof(req));
	req.count = dma_bs->secondary_bin_count;
	req.size = dma_bs->secondary_bin_size;
	req.flags = _DRM_AGP_BUFFER;
	req.agp_start = offset;

	err = drm_legacy_addbufs_agp(dev, &req);
	if (err) {
		DRM_ERROR("Unable to add secondary DMA buffers: %d\n", err);
		return err;
	}

	{
		struct drm_map_list *_entry;
		unsigned long agp_token = 0;

		list_for_each_entry(_entry, &dev->maplist, head) {
			if (_entry->map == dev->agp_buffer_map)
				agp_token = _entry->user_token;
		}
		if (!agp_token)
			return -EFAULT;

		dev->agp_buffer_token = agp_token;
	}

	offset += secondary_size;
	err = drm_legacy_addmap(dev, offset, agp_size - offset,
				_DRM_AGP, 0, &dev_priv->agp_textures);
	if (err) {
		DRM_ERROR("Unable to map AGP texture region %d\n", err);
		return err;
	}

	drm_legacy_ioremap(dev_priv->warp, dev);
	drm_legacy_ioremap(dev_priv->primary, dev);
	drm_legacy_ioremap(dev->agp_buffer_map, dev);

	if (!dev_priv->warp->handle ||
	    !dev_priv->primary->handle || !dev->agp_buffer_map->handle) {
		DRM_ERROR("failed to ioremap agp regions! (%p, %p, %p)\n",
			  dev_priv->warp->handle, dev_priv->primary->handle,
			  dev->agp_buffer_map->handle);
		return -ENOMEM;
	}

	dev_priv->dma_access = MGA_PAGPXFER;
	dev_priv->wagp_enable = MGA_WAGP_ENABLE;

	DRM_INFO("Initialized card for AGP DMA.\n");
	return 0;
}
#else
static int mga_do_agp_dma_bootstrap(struct drm_device *dev,
				    drm_mga_dma_bootstrap_t *dma_bs)
{
	return -EINVAL;
}
#endif

/*
 * Bootstrap the driver for PCI DMA.
 *
 * \todo
 * The algorithm for decreasing the size of the primary DMA buffer could be
 * better.  The size should be rounded up to the nearest page size, then
 * decrease the request size by a single page each pass through the loop.
 *
 * \todo
 * Determine whether the maximum address passed to drm_pci_alloc is correct.
 * The same goes for drm_legacy_addbufs_pci.
 *
 * \sa mga_do_dma_bootstrap, mga_do_agp_dma_bootstrap
 */
static int mga_do_pci_dma_bootstrap(struct drm_device *dev,
				    drm_mga_dma_bootstrap_t *dma_bs)
{
	drm_mga_private_t *const dev_priv =
	    (drm_mga_private_t *) dev->dev_private;
	unsigned int warp_size = MGA_WARP_UCODE_SIZE;
	unsigned int primary_size;
	unsigned int bin_count;
	int err;
	struct drm_buf_desc req;

	if (dev->dma == NULL) {
		DRM_ERROR("dev->dma is NULL\n");
		return -EFAULT;
	}

	/* Make drm_legacy_addbufs happy by not trying to create a mapping for
	 * less than a page.
	 */
	if (warp_size < PAGE_SIZE)
		warp_size = PAGE_SIZE;

	/* The proper alignment is 0x100 for this mapping */
	err = drm_legacy_addmap(dev, 0, warp_size, _DRM_CONSISTENT,
				_DRM_READ_ONLY, &dev_priv->warp);
	if (err != 0) {
		DRM_ERROR("Unable to create mapping for WARP microcode: %d\n",
			  err);
		return err;
	}

	/* Other than the bottom two bits being used to encode other
	 * information, there don't appear to be any restrictions on the
	 * alignment of the primary or secondary DMA buffers.
	 */

	for (primary_size = dma_bs->primary_size; primary_size != 0;
	     primary_size >>= 1) {
		/* The proper alignment for this mapping is 0x04 */
		err = drm_legacy_addmap(dev, 0, primary_size, _DRM_CONSISTENT,
					_DRM_READ_ONLY, &dev_priv->primary);
		if (!err)
			break;
	}

	if (err != 0) {
		DRM_ERROR("Unable to allocate primary DMA region: %d\n", err);
		return -ENOMEM;
	}

	if (dev_priv->primary->size != dma_bs->primary_size) {
		DRM_INFO("Primary DMA buffer size reduced from %u to %u.\n",
			 dma_bs->primary_size,
			 (unsigned)dev_priv->primary->size);
		dma_bs->primary_size = dev_priv->primary->size;
	}

	for (bin_count = dma_bs->secondary_bin_count; bin_count > 0;
	     bin_count--) {
		(void)memset(&req, 0, sizeof(req));
		req.count = bin_count;
		req.size = dma_bs->secondary_bin_size;

		err = drm_legacy_addbufs_pci(dev, &req);
		if (!err)
			break;
	}

	if (bin_count == 0) {
		DRM_ERROR("Unable to add secondary DMA buffers: %d\n", err);
		return err;
	}

	if (bin_count != dma_bs->secondary_bin_count) {
		DRM_INFO("Secondary PCI DMA buffer bin count reduced from %u "
			 "to %u.\n", dma_bs->secondary_bin_count, bin_count);

		dma_bs->secondary_bin_count = bin_count;
	}

	dev_priv->dma_access = 0;
	dev_priv->wagp_enable = 0;

	dma_bs->agp_mode = 0;

	DRM_INFO("Initialized card for PCI DMA.\n");
	return 0;
}

static int mga_do_dma_bootstrap(struct drm_device *dev,
				drm_mga_dma_bootstrap_t *dma_bs)
{
	const int is_agp = (dma_bs->agp_mode != 0) && dev->agp;
	int err;
	drm_mga_private_t *const dev_priv =
	    (drm_mga_private_t *) dev->dev_private;

	dev_priv->used_new_dma_init = 1;

	/* The first steps are the same for both PCI and AGP based DMA.  Map
	 * the cards MMIO registers and map a status page.
	 */
	err = drm_legacy_addmap(dev, dev_priv->mmio_base, dev_priv->mmio_size,
				_DRM_REGISTERS, _DRM_READ_ONLY,
				&dev_priv->mmio);
	if (err) {
		DRM_ERROR("Unable to map MMIO region: %d\n", err);
		return err;
	}

	err = drm_legacy_addmap(dev, 0, SAREA_MAX, _DRM_SHM,
				_DRM_READ_ONLY | _DRM_LOCKED | _DRM_KERNEL,
			 &dev_priv->status);
	if (err) {
		DRM_ERROR("Unable to map status region: %d\n", err);
		return err;
	}

	/* The DMA initialization procedure is slightly different for PCI and
	 * AGP cards.  AGP cards just allocate a large block of AGP memory and
	 * carve off portions of it for internal uses.  The remaining memory
	 * is returned to user-mode to be used for AGP textures.
	 */
	if (is_agp)
		err = mga_do_agp_dma_bootstrap(dev, dma_bs);

	/* If we attempted to initialize the card for AGP DMA but failed,
	 * clean-up any mess that may have been created.
	 */

	if (err)
		mga_do_cleanup_dma(dev, MINIMAL_CLEANUP);

	/* Not only do we want to try and initialized PCI cards for PCI DMA,
	 * but we also try to initialized AGP cards that could not be
	 * initialized for AGP DMA.  This covers the case where we have an AGP
	 * card in a system with an unsupported AGP chipset.  In that case the
	 * card will be detected as AGP, but we won't be able to allocate any
	 * AGP memory, etc.
	 */

	if (!is_agp || err)
		err = mga_do_pci_dma_bootstrap(dev, dma_bs);

	return err;
}

int mga_dma_bootstrap(struct drm_device *dev, void *data,
		      struct drm_file *file_priv)
{
	drm_mga_dma_bootstrap_t *bootstrap = data;
	int err;
	static const int modes[] = { 0, 1, 2, 2, 4, 4, 4, 4 };
	const drm_mga_private_t *const dev_priv =
		(drm_mga_private_t *) dev->dev_private;

	err = mga_do_dma_bootstrap(dev, bootstrap);
	if (err) {
		mga_do_cleanup_dma(dev, FULL_CLEANUP);
		return err;
	}

	if (dev_priv->agp_textures != NULL) {
		bootstrap->texture_handle = dev_priv->agp_textures->offset;
		bootstrap->texture_size = dev_priv->agp_textures->size;
	} else {
		bootstrap->texture_handle = 0;
		bootstrap->texture_size = 0;
	}

	bootstrap->agp_mode = modes[bootstrap->agp_mode & 0x07];

	return err;
}

static int mga_do_init_dma(struct drm_device *dev, drm_mga_init_t *init)
{
	drm_mga_private_t *dev_priv;
	int ret;
	DRM_DEBUG("\n");

	dev_priv = dev->dev_private;

	if (init->sgram)
		dev_priv->clear_cmd = MGA_DWGCTL_CLEAR | MGA_ATYPE_BLK;
	else
		dev_priv->clear_cmd = MGA_DWGCTL_CLEAR | MGA_ATYPE_RSTR;
	dev_priv->maccess = init->maccess;

	dev_priv->fb_cpp = init->fb_cpp;
	dev_priv->front_offset = init->front_offset;
	dev_priv->front_pitch = init->front_pitch;
	dev_priv->back_offset = init->back_offset;
	dev_priv->back_pitch = init->back_pitch;

	dev_priv->depth_cpp = init->depth_cpp;
	dev_priv->depth_offset = init->depth_offset;
	dev_priv->depth_pitch = init->depth_pitch;

	/* FIXME: Need to support AGP textures...
	 */
	dev_priv->texture_offset = init->texture_offset[0];
	dev_priv->texture_size = init->texture_size[0];

	dev_priv->sarea = drm_legacy_getsarea(dev);
	if (!dev_priv->sarea) {
		DRM_ERROR("failed to find sarea!\n");
		return -EINVAL;
	}

	if (!dev_priv->used_new_dma_init) {

		dev_priv->dma_access = MGA_PAGPXFER;
		dev_priv->wagp_enable = MGA_WAGP_ENABLE;

		dev_priv->status = drm_legacy_findmap(dev, init->status_offset);
		if (!dev_priv->status) {
			DRM_ERROR("failed to find status page!\n");
			return -EINVAL;
		}
		dev_priv->mmio = drm_legacy_findmap(dev, init->mmio_offset);
		if (!dev_priv->mmio) {
			DRM_ERROR("failed to find mmio region!\n");
			return -EINVAL;
		}
		dev_priv->warp = drm_legacy_findmap(dev, init->warp_offset);
		if (!dev_priv->warp) {
			DRM_ERROR("failed to find warp microcode region!\n");
			return -EINVAL;
		}
		dev_priv->primary = drm_legacy_findmap(dev, init->primary_offset);
		if (!dev_priv->primary) {
			DRM_ERROR("failed to find primary dma region!\n");
			return -EINVAL;
		}
		dev->agp_buffer_token = init->buffers_offset;
		dev->agp_buffer_map =
		    drm_legacy_findmap(dev, init->buffers_offset);
		if (!dev->agp_buffer_map) {
			DRM_ERROR("failed to find dma buffer region!\n");
			return -EINVAL;
		}

		drm_legacy_ioremap(dev_priv->warp, dev);
		drm_legacy_ioremap(dev_priv->primary, dev);
		drm_legacy_ioremap(dev->agp_buffer_map, dev);
	}

	dev_priv->sarea_priv =
	    (drm_mga_sarea_t *) ((u8 *) dev_priv->sarea->handle +
				 init->sarea_priv_offset);

	if (!dev_priv->warp->handle ||
	    !dev_priv->primary->handle ||
	    ((dev_priv->dma_access != 0) &&
	     ((dev->agp_buffer_map == NULL) ||
	      (dev->agp_buffer_map->handle == NULL)))) {
		DRM_ERROR("failed to ioremap agp regions!\n");
		return -ENOMEM;
	}

	ret = mga_warp_install_microcode(dev_priv);
	if (ret < 0) {
		DRM_ERROR("failed to install WARP ucode!: %d\n", ret);
		return ret;
	}

	ret = mga_warp_init(dev_priv);
	if (ret < 0) {
		DRM_ERROR("failed to init WARP engine!: %d\n", ret);
		return ret;
	}

	dev_priv->prim.status = (u32 *) dev_priv->status->handle;

	mga_do_wait_for_idle(dev_priv);

	/* Init the primary DMA registers.
	 */
	MGA_WRITE(MGA_PRIMADDRESS, dev_priv->primary->offset | MGA_DMA_GENERAL);
#if 0
	MGA_WRITE(MGA_PRIMPTR, virt_to_bus((void *)dev_priv->prim.status) | MGA_PRIMPTREN0 |	/* Soft trap, SECEND, SETUPEND */
		  MGA_PRIMPTREN1);	/* DWGSYNC */
#endif

	dev_priv->prim.start = (u8 *) dev_priv->primary->handle;
	dev_priv->prim.end = ((u8 *) dev_priv->primary->handle
			      + dev_priv->primary->size);
	dev_priv->prim.size = dev_priv->primary->size;

	dev_priv->prim.tail = 0;
	dev_priv->prim.space = dev_priv->prim.size;
	dev_priv->prim.wrapped = 0;

	dev_priv->prim.last_flush = 0;
	dev_priv->prim.last_wrap = 0;

	dev_priv->prim.high_mark = 256 * DMA_BLOCK_SIZE;

	dev_priv->prim.status[0] = dev_priv->primary->offset;
	dev_priv->prim.status[1] = 0;

	dev_priv->sarea_priv->last_wrap = 0;
	dev_priv->sarea_priv->last_frame.head = 0;
	dev_priv->sarea_priv->last_frame.wrap = 0;

	if (mga_freelist_init(dev, dev_priv) < 0) {
		DRM_ERROR("could not initialize freelist\n");
		return -ENOMEM;
	}

	return 0;
}

static int mga_do_cleanup_dma(struct drm_device *dev, int full_cleanup)
{
	int err = 0;
	DRM_DEBUG("\n");

	/* Make sure interrupts are disabled here because the uninstall ioctl
	 * may not have been called from userspace and after dev_private
	 * is freed, it's too late.
	 */
	if (dev->irq_enabled)
		drm_irq_uninstall(dev);

	if (dev->dev_private) {
		drm_mga_private_t *dev_priv = dev->dev_private;

		if ((dev_priv->warp != NULL)
		    && (dev_priv->warp->type != _DRM_CONSISTENT))
			drm_legacy_ioremapfree(dev_priv->warp, dev);

		if ((dev_priv->primary != NULL)
		    && (dev_priv->primary->type != _DRM_CONSISTENT))
			drm_legacy_ioremapfree(dev_priv->primary, dev);

		if (dev->agp_buffer_map != NULL)
			drm_legacy_ioremapfree(dev->agp_buffer_map, dev);

		if (dev_priv->used_new_dma_init) {
#if IS_ENABLED(CONFIG_AGP)
			if (dev_priv->agp_handle != 0) {
				struct drm_agp_binding unbind_req;
				struct drm_agp_buffer free_req;

				unbind_req.handle = dev_priv->agp_handle;
				drm_agp_unbind(dev, &unbind_req);

				free_req.handle = dev_priv->agp_handle;
				drm_agp_free(dev, &free_req);

				dev_priv->agp_textures = NULL;
				dev_priv->agp_size = 0;
				dev_priv->agp_handle = 0;
			}

			if ((dev->agp != NULL) && dev->agp->acquired)
				err = drm_agp_release(dev);
#endif
		}

		dev_priv->warp = NULL;
		dev_priv->primary = NULL;
		dev_priv->sarea = NULL;
		dev_priv->sarea_priv = NULL;
		dev->agp_buffer_map = NULL;

		if (full_cleanup) {
			dev_priv->mmio = NULL;
			dev_priv->status = NULL;
			dev_priv->used_new_dma_init = 0;
		}

		memset(&dev_priv->prim, 0, sizeof(dev_priv->prim));
		dev_priv->warp_pipe = 0;
		memset(dev_priv->warp_pipe_phys, 0,
		       sizeof(dev_priv->warp_pipe_phys));

		if (dev_priv->head != NULL)
			mga_freelist_cleanup(dev);
	}

	return err;
}

int mga_dma_init(struct drm_device *dev, void *data,
		 struct drm_file *file_priv)
{
	drm_mga_init_t *init = data;
	int err;

	LOCK_TEST_WITH_RETURN(dev, file_priv);

	switch (init->func) {
	case MGA_INIT_DMA:
		err = mga_do_init_dma(dev, init);
		if (err)
			(void)mga_do_cleanup_dma(dev, FULL_CLEANUP);
		return err;
	case MGA_CLEANUP_DMA:
		return mga_do_cleanup_dma(dev, FULL_CLEANUP);
	}

	return -EINVAL;
}

/* ================================================================
 * Primary DMA stream management
 */

int mga_dma_flush(struct drm_device *dev, void *data,
		  struct drm_file *file_priv)
{
	drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
	struct drm_lock *lock = data;

	LOCK_TEST_WITH_RETURN(dev, file_priv);

	DRM_DEBUG("%s%s%s\n",
		  (lock->flags & _DRM_LOCK_FLUSH) ? "flush, " : "",
		  (lock->flags & _DRM_LOCK_FLUSH_ALL) ? "flush all, " : "",
		  (lock->flags & _DRM_LOCK_QUIESCENT) ? "idle, " : "");

	WRAP_WAIT_WITH_RETURN(dev_priv);

	if (lock->flags & (_DRM_LOCK_FLUSH | _DRM_LOCK_FLUSH_ALL))
		mga_do_dma_flush(dev_priv);

	if (lock->flags & _DRM_LOCK_QUIESCENT) {
#if MGA_DMA_DEBUG
		int ret = mga_do_wait_for_idle(dev_priv);
		if (ret < 0)
			DRM_INFO("-EBUSY\n");
		return ret;
#else
		return mga_do_wait_for_idle(dev_priv);
#endif
	} else {
		return 0;
	}
}

int mga_dma_reset(struct drm_device *dev, void *data,
		  struct drm_file *file_priv)
{
	drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;

	LOCK_TEST_WITH_RETURN(dev, file_priv);

	return mga_do_dma_reset(dev_priv);
}

/* ================================================================
 * DMA buffer management
 */

static int mga_dma_get_buffers(struct drm_device *dev,
			       struct drm_file *file_priv, struct drm_dma *d)
{
	struct drm_buf *buf;
	int i;

	for (i = d->granted_count; i < d->request_count; i++) {
		buf = mga_freelist_get(dev);
		if (!buf)
			return -EAGAIN;

		buf->file_priv = file_priv;

		if (copy_to_user(&d->request_indices[i],
				     &buf->idx, sizeof(buf->idx)))
			return -EFAULT;
		if (copy_to_user(&d->request_sizes[i],
				     &buf->total, sizeof(buf->total)))
			return -EFAULT;

		d->granted_count++;
	}
	return 0;
}

int mga_dma_buffers(struct drm_device *dev, void *data,
		    struct drm_file *file_priv)
{
	struct drm_device_dma *dma = dev->dma;
	drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
	struct drm_dma *d = data;
	int ret = 0;

	LOCK_TEST_WITH_RETURN(dev, file_priv);

	/* Please don't send us buffers.
	 */
	if (d->send_count != 0) {
		DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n",
			  task_pid_nr(current), d->send_count);
		return -EINVAL;
	}

	/* We'll send you buffers.
	 */
	if (d->request_count < 0 || d->request_count > dma->buf_count) {
		DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n",
			  task_pid_nr(current), d->request_count,
			  dma->buf_count);
		return -EINVAL;
	}

	WRAP_TEST_WITH_RETURN(dev_priv);

	d->granted_count = 0;

	if (d->request_count)
		ret = mga_dma_get_buffers(dev, file_priv, d);

	return ret;
}

/*
 * Called just before the module is unloaded.
 */
void mga_driver_unload(struct drm_device *dev)
{
	kfree(dev->dev_private);
	dev->dev_private = NULL;
}

/*
 * Called when the last opener of the device is closed.
 */
void mga_driver_lastclose(struct drm_device *dev)
{
	mga_do_cleanup_dma(dev, FULL_CLEANUP);
}

int mga_driver_dma_quiescent(struct drm_device *dev)
{
	drm_mga_private_t *dev_priv = dev->dev_private;
	return mga_do_wait_for_idle(dev_priv);
}
