/* 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)
{
	struct pci_dev *pdev = to_pci_dev(dev->dev);
	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 ((pdev->device == 0x0525) && pdev->bus->self
	    && (pdev->bus->self->vendor == 0x3388)
	    && (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(pdev);

	dev_priv->mmio_base = pci_resource_start(pdev, 1);
	dev_priv->mmio_size = pci_resource_len(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_legacy_agp_acquire(dev);
	if (err) {
		DRM_ERROR("Unable to acquire AGP: %d\n", err);
		return err;
	}

	err = drm_legacy_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_legacy_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_legacy_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_legacy_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_legacy_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_legacy_agp_unbind(dev, &unbind_req);

				free_req.handle = dev_priv->agp_handle;
				drm_legacy_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_legacy_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);
}
