/*
 * Copyright (C) 2006 Ben Skeggs.
 *
 * 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 THE COPYRIGHT OWNER(S) 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:
 *   Ben Skeggs <darktama@iinet.net.au>
 */

#include "drmP.h"
#include "drm.h"
#include "nouveau_drv.h"
#include "nouveau_drm.h"

/* NVidia uses context objects to drive drawing operations.

   Context objects can be selected into 8 subchannels in the FIFO,
   and then used via DMA command buffers.

   A context object is referenced by a user defined handle (CARD32). The HW
   looks up graphics objects in a hash table in the instance RAM.

   An entry in the hash table consists of 2 CARD32. The first CARD32 contains
   the handle, the second one a bitfield, that contains the address of the
   object in instance RAM.

   The format of the second CARD32 seems to be:

   NV4 to NV30:

   15: 0  instance_addr >> 4
   17:16  engine (here uses 1 = graphics)
   28:24  channel id (here uses 0)
   31	  valid (use 1)

   NV40:

   15: 0  instance_addr >> 4   (maybe 19-0)
   21:20  engine (here uses 1 = graphics)
   I'm unsure about the other bits, but using 0 seems to work.

   The key into the hash table depends on the object handle and channel id and
   is given as:
*/
static uint32_t
nouveau_ramht_hash_handle(struct drm_device *dev, int channel, uint32_t handle)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	uint32_t hash = 0;
	int i;

	NV_DEBUG(dev, "ch%d handle=0x%08x\n", channel, handle);

	for (i = 32; i > 0; i -= dev_priv->ramht_bits) {
		hash ^= (handle & ((1 << dev_priv->ramht_bits) - 1));
		handle >>= dev_priv->ramht_bits;
	}

	if (dev_priv->card_type < NV_50)
		hash ^= channel << (dev_priv->ramht_bits - 4);
	hash <<= 3;

	NV_DEBUG(dev, "hash=0x%08x\n", hash);
	return hash;
}

static int
nouveau_ramht_entry_valid(struct drm_device *dev, struct nouveau_gpuobj *ramht,
			  uint32_t offset)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	uint32_t ctx = nv_ro32(dev, ramht, (offset + 4)/4);

	if (dev_priv->card_type < NV_40)
		return ((ctx & NV_RAMHT_CONTEXT_VALID) != 0);
	return (ctx != 0);
}

static int
nouveau_ramht_insert(struct drm_device *dev, struct nouveau_gpuobj_ref *ref)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem;
	struct nouveau_channel *chan = ref->channel;
	struct nouveau_gpuobj *ramht = chan->ramht ? chan->ramht->gpuobj : NULL;
	uint32_t ctx, co, ho;

	if (!ramht) {
		NV_ERROR(dev, "No hash table!\n");
		return -EINVAL;
	}

	if (dev_priv->card_type < NV_40) {
		ctx = NV_RAMHT_CONTEXT_VALID | (ref->instance >> 4) |
		      (chan->id << NV_RAMHT_CONTEXT_CHANNEL_SHIFT) |
		      (ref->gpuobj->engine << NV_RAMHT_CONTEXT_ENGINE_SHIFT);
	} else
	if (dev_priv->card_type < NV_50) {
		ctx = (ref->instance >> 4) |
		      (chan->id << NV40_RAMHT_CONTEXT_CHANNEL_SHIFT) |
		      (ref->gpuobj->engine << NV40_RAMHT_CONTEXT_ENGINE_SHIFT);
	} else {
		if (ref->gpuobj->engine == NVOBJ_ENGINE_DISPLAY) {
			ctx = (ref->instance << 10) | 2;
		} else {
			ctx = (ref->instance >> 4) |
			      ((ref->gpuobj->engine <<
				NV40_RAMHT_CONTEXT_ENGINE_SHIFT));
		}
	}

	co = ho = nouveau_ramht_hash_handle(dev, chan->id, ref->handle);
	do {
		if (!nouveau_ramht_entry_valid(dev, ramht, co)) {
			NV_DEBUG(dev,
				 "insert ch%d 0x%08x: h=0x%08x, c=0x%08x\n",
				 chan->id, co, ref->handle, ctx);
			nv_wo32(dev, ramht, (co + 0)/4, ref->handle);
			nv_wo32(dev, ramht, (co + 4)/4, ctx);

			list_add_tail(&ref->list, &chan->ramht_refs);
			instmem->flush(dev);
			return 0;
		}
		NV_DEBUG(dev, "collision ch%d 0x%08x: h=0x%08x\n",
			 chan->id, co, nv_ro32(dev, ramht, co/4));

		co += 8;
		if (co >= dev_priv->ramht_size)
			co = 0;
	} while (co != ho);

	NV_ERROR(dev, "RAMHT space exhausted. ch=%d\n", chan->id);
	return -ENOMEM;
}

static void
nouveau_ramht_remove(struct drm_device *dev, struct nouveau_gpuobj_ref *ref)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem;
	struct nouveau_channel *chan = ref->channel;
	struct nouveau_gpuobj *ramht = chan->ramht ? chan->ramht->gpuobj : NULL;
	uint32_t co, ho;

	if (!ramht) {
		NV_ERROR(dev, "No hash table!\n");
		return;
	}

	co = ho = nouveau_ramht_hash_handle(dev, chan->id, ref->handle);
	do {
		if (nouveau_ramht_entry_valid(dev, ramht, co) &&
		    (ref->handle == nv_ro32(dev, ramht, (co/4)))) {
			NV_DEBUG(dev,
				 "remove ch%d 0x%08x: h=0x%08x, c=0x%08x\n",
				 chan->id, co, ref->handle,
				 nv_ro32(dev, ramht, (co + 4)));
			nv_wo32(dev, ramht, (co + 0)/4, 0x00000000);
			nv_wo32(dev, ramht, (co + 4)/4, 0x00000000);

			list_del(&ref->list);
			instmem->flush(dev);
			return;
		}

		co += 8;
		if (co >= dev_priv->ramht_size)
			co = 0;
	} while (co != ho);
	list_del(&ref->list);

	NV_ERROR(dev, "RAMHT entry not found. ch=%d, handle=0x%08x\n",
		 chan->id, ref->handle);
}

int
nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan,
		   uint32_t size, int align, uint32_t flags,
		   struct nouveau_gpuobj **gpuobj_ret)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_engine *engine = &dev_priv->engine;
	struct nouveau_gpuobj *gpuobj;
	struct drm_mm *pramin = NULL;
	int ret;

	NV_DEBUG(dev, "ch%d size=%u align=%d flags=0x%08x\n",
		 chan ? chan->id : -1, size, align, flags);

	if (!dev_priv || !gpuobj_ret || *gpuobj_ret != NULL)
		return -EINVAL;

	gpuobj = kzalloc(sizeof(*gpuobj), GFP_KERNEL);
	if (!gpuobj)
		return -ENOMEM;
	NV_DEBUG(dev, "gpuobj %p\n", gpuobj);
	gpuobj->flags = flags;
	gpuobj->im_channel = chan;

	list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list);

	/* Choose between global instmem heap, and per-channel private
	 * instmem heap.  On <NV50 allow requests for private instmem
	 * to be satisfied from global heap if no per-channel area
	 * available.
	 */
	if (chan) {
		NV_DEBUG(dev, "channel heap\n");
		pramin = &chan->ramin_heap;
	} else {
		NV_DEBUG(dev, "global heap\n");
		pramin = &dev_priv->ramin_heap;

		ret = engine->instmem.populate(dev, gpuobj, &size);
		if (ret) {
			nouveau_gpuobj_del(dev, &gpuobj);
			return ret;
		}
	}

	/* Allocate a chunk of the PRAMIN aperture */
	gpuobj->im_pramin = drm_mm_search_free(pramin, size, align, 0);
	if (gpuobj->im_pramin)
		gpuobj->im_pramin = drm_mm_get_block(gpuobj->im_pramin, size, align);

	if (!gpuobj->im_pramin) {
		nouveau_gpuobj_del(dev, &gpuobj);
		return -ENOMEM;
	}

	if (!chan) {
		ret = engine->instmem.bind(dev, gpuobj);
		if (ret) {
			nouveau_gpuobj_del(dev, &gpuobj);
			return ret;
		}
	}

	if (gpuobj->flags & NVOBJ_FLAG_ZERO_ALLOC) {
		int i;

		for (i = 0; i < gpuobj->im_pramin->size; i += 4)
			nv_wo32(dev, gpuobj, i/4, 0);
		engine->instmem.flush(dev);
	}

	*gpuobj_ret = gpuobj;
	return 0;
}

int
nouveau_gpuobj_early_init(struct drm_device *dev)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;

	NV_DEBUG(dev, "\n");

	INIT_LIST_HEAD(&dev_priv->gpuobj_list);

	return 0;
}

int
nouveau_gpuobj_init(struct drm_device *dev)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	int ret;

	NV_DEBUG(dev, "\n");

	if (dev_priv->card_type < NV_50) {
		ret = nouveau_gpuobj_new_fake(dev,
			dev_priv->ramht_offset, ~0, dev_priv->ramht_size,
			NVOBJ_FLAG_ZERO_ALLOC | NVOBJ_FLAG_ALLOW_NO_REFS,
						&dev_priv->ramht, NULL);
		if (ret)
			return ret;
	}

	return 0;
}

void
nouveau_gpuobj_takedown(struct drm_device *dev)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;

	NV_DEBUG(dev, "\n");

	nouveau_gpuobj_del(dev, &dev_priv->ramht);
}

void
nouveau_gpuobj_late_takedown(struct drm_device *dev)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_gpuobj *gpuobj = NULL;
	struct list_head *entry, *tmp;

	NV_DEBUG(dev, "\n");

	list_for_each_safe(entry, tmp, &dev_priv->gpuobj_list) {
		gpuobj = list_entry(entry, struct nouveau_gpuobj, list);

		NV_ERROR(dev, "gpuobj %p still exists at takedown, refs=%d\n",
			 gpuobj, gpuobj->refcount);
		gpuobj->refcount = 0;
		nouveau_gpuobj_del(dev, &gpuobj);
	}
}

int
nouveau_gpuobj_del(struct drm_device *dev, struct nouveau_gpuobj **pgpuobj)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_engine *engine = &dev_priv->engine;
	struct nouveau_gpuobj *gpuobj;
	int i;

	NV_DEBUG(dev, "gpuobj %p\n", pgpuobj ? *pgpuobj : NULL);

	if (!dev_priv || !pgpuobj || !(*pgpuobj))
		return -EINVAL;
	gpuobj = *pgpuobj;

	if (gpuobj->refcount != 0) {
		NV_ERROR(dev, "gpuobj refcount is %d\n", gpuobj->refcount);
		return -EINVAL;
	}

	if (gpuobj->im_pramin && (gpuobj->flags & NVOBJ_FLAG_ZERO_FREE)) {
		for (i = 0; i < gpuobj->im_pramin->size; i += 4)
			nv_wo32(dev, gpuobj, i/4, 0);
		engine->instmem.flush(dev);
	}

	if (gpuobj->dtor)
		gpuobj->dtor(dev, gpuobj);

	if (gpuobj->im_backing && !(gpuobj->flags & NVOBJ_FLAG_FAKE))
		engine->instmem.clear(dev, gpuobj);

	if (gpuobj->im_pramin) {
		if (gpuobj->flags & NVOBJ_FLAG_FAKE)
			kfree(gpuobj->im_pramin);
		else
			drm_mm_put_block(gpuobj->im_pramin);
	}

	list_del(&gpuobj->list);

	*pgpuobj = NULL;
	kfree(gpuobj);
	return 0;
}

static int
nouveau_gpuobj_instance_get(struct drm_device *dev,
			    struct nouveau_channel *chan,
			    struct nouveau_gpuobj *gpuobj, uint32_t *inst)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_gpuobj *cpramin;

	/* <NV50 use PRAMIN address everywhere */
	if (dev_priv->card_type < NV_50) {
		*inst = gpuobj->im_pramin->start;
		return 0;
	}

	if (chan && gpuobj->im_channel != chan) {
		NV_ERROR(dev, "Channel mismatch: obj %d, ref %d\n",
			 gpuobj->im_channel->id, chan->id);
		return -EINVAL;
	}

	/* NV50 channel-local instance */
	if (chan) {
		cpramin = chan->ramin->gpuobj;
		*inst = gpuobj->im_pramin->start - cpramin->im_pramin->start;
		return 0;
	}

	/* NV50 global (VRAM) instance */
	if (!gpuobj->im_channel) {
		/* ...from global heap */
		if (!gpuobj->im_backing) {
			NV_ERROR(dev, "AII, no VRAM backing gpuobj\n");
			return -EINVAL;
		}
		*inst = gpuobj->im_backing_start;
		return 0;
	} else {
		/* ...from local heap */
		cpramin = gpuobj->im_channel->ramin->gpuobj;
		*inst = cpramin->im_backing_start +
			(gpuobj->im_pramin->start - cpramin->im_pramin->start);
		return 0;
	}

	return -EINVAL;
}

int
nouveau_gpuobj_ref_add(struct drm_device *dev, struct nouveau_channel *chan,
		       uint32_t handle, struct nouveau_gpuobj *gpuobj,
		       struct nouveau_gpuobj_ref **ref_ret)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_gpuobj_ref *ref;
	uint32_t instance;
	int ret;

	NV_DEBUG(dev, "ch%d h=0x%08x gpuobj=%p\n",
		 chan ? chan->id : -1, handle, gpuobj);

	if (!dev_priv || !gpuobj || (ref_ret && *ref_ret != NULL))
		return -EINVAL;

	if (!chan && !ref_ret)
		return -EINVAL;

	if (gpuobj->engine == NVOBJ_ENGINE_SW && !gpuobj->im_pramin) {
		/* sw object */
		instance = 0x40;
	} else {
		ret = nouveau_gpuobj_instance_get(dev, chan, gpuobj, &instance);
		if (ret)
			return ret;
	}

	ref = kzalloc(sizeof(*ref), GFP_KERNEL);
	if (!ref)
		return -ENOMEM;
	INIT_LIST_HEAD(&ref->list);
	ref->gpuobj   = gpuobj;
	ref->channel  = chan;
	ref->instance = instance;

	if (!ref_ret) {
		ref->handle = handle;

		ret = nouveau_ramht_insert(dev, ref);
		if (ret) {
			kfree(ref);
			return ret;
		}
	} else {
		ref->handle = ~0;
		*ref_ret = ref;
	}

	ref->gpuobj->refcount++;
	return 0;
}

int nouveau_gpuobj_ref_del(struct drm_device *dev, struct nouveau_gpuobj_ref **pref)
{
	struct nouveau_gpuobj_ref *ref;

	NV_DEBUG(dev, "ref %p\n", pref ? *pref : NULL);

	if (!dev || !pref || *pref == NULL)
		return -EINVAL;
	ref = *pref;

	if (ref->handle != ~0)
		nouveau_ramht_remove(dev, ref);

	if (ref->gpuobj) {
		ref->gpuobj->refcount--;

		if (ref->gpuobj->refcount == 0) {
			if (!(ref->gpuobj->flags & NVOBJ_FLAG_ALLOW_NO_REFS))
				nouveau_gpuobj_del(dev, &ref->gpuobj);
		}
	}

	*pref = NULL;
	kfree(ref);
	return 0;
}

int
nouveau_gpuobj_new_ref(struct drm_device *dev,
		       struct nouveau_channel *oc, struct nouveau_channel *rc,
		       uint32_t handle, uint32_t size, int align,
		       uint32_t flags, struct nouveau_gpuobj_ref **ref)
{
	struct nouveau_gpuobj *gpuobj = NULL;
	int ret;

	ret = nouveau_gpuobj_new(dev, oc, size, align, flags, &gpuobj);
	if (ret)
		return ret;

	ret = nouveau_gpuobj_ref_add(dev, rc, handle, gpuobj, ref);
	if (ret) {
		nouveau_gpuobj_del(dev, &gpuobj);
		return ret;
	}

	return 0;
}

int
nouveau_gpuobj_ref_find(struct nouveau_channel *chan, uint32_t handle,
			struct nouveau_gpuobj_ref **ref_ret)
{
	struct nouveau_gpuobj_ref *ref;
	struct list_head *entry, *tmp;

	list_for_each_safe(entry, tmp, &chan->ramht_refs) {
		ref = list_entry(entry, struct nouveau_gpuobj_ref, list);

		if (ref->handle == handle) {
			if (ref_ret)
				*ref_ret = ref;
			return 0;
		}
	}

	return -EINVAL;
}

int
nouveau_gpuobj_new_fake(struct drm_device *dev, uint32_t p_offset,
			uint32_t b_offset, uint32_t size,
			uint32_t flags, struct nouveau_gpuobj **pgpuobj,
			struct nouveau_gpuobj_ref **pref)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_gpuobj *gpuobj = NULL;
	int i;

	NV_DEBUG(dev,
		 "p_offset=0x%08x b_offset=0x%08x size=0x%08x flags=0x%08x\n",
		 p_offset, b_offset, size, flags);

	gpuobj = kzalloc(sizeof(*gpuobj), GFP_KERNEL);
	if (!gpuobj)
		return -ENOMEM;
	NV_DEBUG(dev, "gpuobj %p\n", gpuobj);
	gpuobj->im_channel = NULL;
	gpuobj->flags      = flags | NVOBJ_FLAG_FAKE;

	list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list);

	if (p_offset != ~0) {
		gpuobj->im_pramin = kzalloc(sizeof(struct drm_mm_node),
					    GFP_KERNEL);
		if (!gpuobj->im_pramin) {
			nouveau_gpuobj_del(dev, &gpuobj);
			return -ENOMEM;
		}
		gpuobj->im_pramin->start = p_offset;
		gpuobj->im_pramin->size  = size;
	}

	if (b_offset != ~0) {
		gpuobj->im_backing = (struct nouveau_bo *)-1;
		gpuobj->im_backing_start = b_offset;
	}

	if (gpuobj->flags & NVOBJ_FLAG_ZERO_ALLOC) {
		for (i = 0; i < gpuobj->im_pramin->size; i += 4)
			nv_wo32(dev, gpuobj, i/4, 0);
		dev_priv->engine.instmem.flush(dev);
	}

	if (pref) {
		i = nouveau_gpuobj_ref_add(dev, NULL, 0, gpuobj, pref);
		if (i) {
			nouveau_gpuobj_del(dev, &gpuobj);
			return i;
		}
	}

	if (pgpuobj)
		*pgpuobj = gpuobj;
	return 0;
}


static uint32_t
nouveau_gpuobj_class_instmem_size(struct drm_device *dev, int class)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;

	/*XXX: dodgy hack for now */
	if (dev_priv->card_type >= NV_50)
		return 24;
	if (dev_priv->card_type >= NV_40)
		return 32;
	return 16;
}

/*
   DMA objects are used to reference a piece of memory in the
   framebuffer, PCI or AGP address space. Each object is 16 bytes big
   and looks as follows:

   entry[0]
   11:0  class (seems like I can always use 0 here)
   12    page table present?
   13    page entry linear?
   15:14 access: 0 rw, 1 ro, 2 wo
   17:16 target: 0 NV memory, 1 NV memory tiled, 2 PCI, 3 AGP
   31:20 dma adjust (bits 0-11 of the address)
   entry[1]
   dma limit (size of transfer)
   entry[X]
   1     0 readonly, 1 readwrite
   31:12 dma frame address of the page (bits 12-31 of the address)
   entry[N]
   page table terminator, same value as the first pte, as does nvidia
   rivatv uses 0xffffffff

   Non linear page tables need a list of frame addresses afterwards,
   the rivatv project has some info on this.

   The method below creates a DMA object in instance RAM and returns a handle
   to it that can be used to set up context objects.
*/
int
nouveau_gpuobj_dma_new(struct nouveau_channel *chan, int class,
		       uint64_t offset, uint64_t size, int access,
		       int target, struct nouveau_gpuobj **gpuobj)
{
	struct drm_device *dev = chan->dev;
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem;
	int ret;

	NV_DEBUG(dev, "ch%d class=0x%04x offset=0x%llx size=0x%llx\n",
		 chan->id, class, offset, size);
	NV_DEBUG(dev, "access=%d target=%d\n", access, target);

	switch (target) {
	case NV_DMA_TARGET_AGP:
		offset += dev_priv->gart_info.aper_base;
		break;
	default:
		break;
	}

	ret = nouveau_gpuobj_new(dev, chan,
				 nouveau_gpuobj_class_instmem_size(dev, class),
				 16, NVOBJ_FLAG_ZERO_ALLOC |
				 NVOBJ_FLAG_ZERO_FREE, gpuobj);
	if (ret) {
		NV_ERROR(dev, "Error creating gpuobj: %d\n", ret);
		return ret;
	}

	if (dev_priv->card_type < NV_50) {
		uint32_t frame, adjust, pte_flags = 0;

		if (access != NV_DMA_ACCESS_RO)
			pte_flags |= (1<<1);
		adjust = offset &  0x00000fff;
		frame  = offset & ~0x00000fff;

		nv_wo32(dev, *gpuobj, 0, ((1<<12) | (1<<13) |
				(adjust << 20) |
				 (access << 14) |
				 (target << 16) |
				  class));
		nv_wo32(dev, *gpuobj, 1, size - 1);
		nv_wo32(dev, *gpuobj, 2, frame | pte_flags);
		nv_wo32(dev, *gpuobj, 3, frame | pte_flags);
	} else {
		uint64_t limit = offset + size - 1;
		uint32_t flags0, flags5;

		if (target == NV_DMA_TARGET_VIDMEM) {
			flags0 = 0x00190000;
			flags5 = 0x00010000;
		} else {
			flags0 = 0x7fc00000;
			flags5 = 0x00080000;
		}

		nv_wo32(dev, *gpuobj, 0, flags0 | class);
		nv_wo32(dev, *gpuobj, 1, lower_32_bits(limit));
		nv_wo32(dev, *gpuobj, 2, lower_32_bits(offset));
		nv_wo32(dev, *gpuobj, 3, ((upper_32_bits(limit) & 0xff) << 24) |
					(upper_32_bits(offset) & 0xff));
		nv_wo32(dev, *gpuobj, 5, flags5);
	}

	instmem->flush(dev);

	(*gpuobj)->engine = NVOBJ_ENGINE_SW;
	(*gpuobj)->class  = class;
	return 0;
}

int
nouveau_gpuobj_gart_dma_new(struct nouveau_channel *chan,
			    uint64_t offset, uint64_t size, int access,
			    struct nouveau_gpuobj **gpuobj,
			    uint32_t *o_ret)
{
	struct drm_device *dev = chan->dev;
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	int ret;

	if (dev_priv->gart_info.type == NOUVEAU_GART_AGP ||
	    (dev_priv->card_type >= NV_50 &&
	     dev_priv->gart_info.type == NOUVEAU_GART_SGDMA)) {
		ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY,
					     offset + dev_priv->vm_gart_base,
					     size, access, NV_DMA_TARGET_AGP,
					     gpuobj);
		if (o_ret)
			*o_ret = 0;
	} else
	if (dev_priv->gart_info.type == NOUVEAU_GART_SGDMA) {
		*gpuobj = dev_priv->gart_info.sg_ctxdma;
		if (offset & ~0xffffffffULL) {
			NV_ERROR(dev, "obj offset exceeds 32-bits\n");
			return -EINVAL;
		}
		if (o_ret)
			*o_ret = (uint32_t)offset;
		ret = (*gpuobj != NULL) ? 0 : -EINVAL;
	} else {
		NV_ERROR(dev, "Invalid GART type %d\n", dev_priv->gart_info.type);
		return -EINVAL;
	}

	return ret;
}

/* Context objects in the instance RAM have the following structure.
 * On NV40 they are 32 byte long, on NV30 and smaller 16 bytes.

   NV4 - NV30:

   entry[0]
   11:0 class
   12   chroma key enable
   13   user clip enable
   14   swizzle enable
   17:15 patch config:
       scrcopy_and, rop_and, blend_and, scrcopy, srccopy_pre, blend_pre
   18   synchronize enable
   19   endian: 1 big, 0 little
   21:20 dither mode
   23    single step enable
   24    patch status: 0 invalid, 1 valid
   25    context_surface 0: 1 valid
   26    context surface 1: 1 valid
   27    context pattern: 1 valid
   28    context rop: 1 valid
   29,30 context beta, beta4
   entry[1]
   7:0   mono format
   15:8  color format
   31:16 notify instance address
   entry[2]
   15:0  dma 0 instance address
   31:16 dma 1 instance address
   entry[3]
   dma method traps

   NV40:
   No idea what the exact format is. Here's what can be deducted:

   entry[0]:
   11:0  class  (maybe uses more bits here?)
   17    user clip enable
   21:19 patch config
   25    patch status valid ?
   entry[1]:
   15:0  DMA notifier  (maybe 20:0)
   entry[2]:
   15:0  DMA 0 instance (maybe 20:0)
   24    big endian
   entry[3]:
   15:0  DMA 1 instance (maybe 20:0)
   entry[4]:
   entry[5]:
   set to 0?
*/
int
nouveau_gpuobj_gr_new(struct nouveau_channel *chan, int class,
		      struct nouveau_gpuobj **gpuobj)
{
	struct drm_device *dev = chan->dev;
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	int ret;

	NV_DEBUG(dev, "ch%d class=0x%04x\n", chan->id, class);

	ret = nouveau_gpuobj_new(dev, chan,
				 nouveau_gpuobj_class_instmem_size(dev, class),
				 16,
				 NVOBJ_FLAG_ZERO_ALLOC | NVOBJ_FLAG_ZERO_FREE,
				 gpuobj);
	if (ret) {
		NV_ERROR(dev, "Error creating gpuobj: %d\n", ret);
		return ret;
	}

	if (dev_priv->card_type >= NV_50) {
		nv_wo32(dev, *gpuobj, 0, class);
		nv_wo32(dev, *gpuobj, 5, 0x00010000);
	} else {
		switch (class) {
		case NV_CLASS_NULL:
			nv_wo32(dev, *gpuobj, 0, 0x00001030);
			nv_wo32(dev, *gpuobj, 1, 0xFFFFFFFF);
			break;
		default:
			if (dev_priv->card_type >= NV_40) {
				nv_wo32(dev, *gpuobj, 0, class);
#ifdef __BIG_ENDIAN
				nv_wo32(dev, *gpuobj, 2, 0x01000000);
#endif
			} else {
#ifdef __BIG_ENDIAN
				nv_wo32(dev, *gpuobj, 0, class | 0x00080000);
#else
				nv_wo32(dev, *gpuobj, 0, class);
#endif
			}
		}
	}
	dev_priv->engine.instmem.flush(dev);

	(*gpuobj)->engine = NVOBJ_ENGINE_GR;
	(*gpuobj)->class  = class;
	return 0;
}

int
nouveau_gpuobj_sw_new(struct nouveau_channel *chan, int class,
		      struct nouveau_gpuobj **gpuobj_ret)
{
	struct drm_nouveau_private *dev_priv;
	struct nouveau_gpuobj *gpuobj;

	if (!chan || !gpuobj_ret || *gpuobj_ret != NULL)
		return -EINVAL;
	dev_priv = chan->dev->dev_private;

	gpuobj = kzalloc(sizeof(*gpuobj), GFP_KERNEL);
	if (!gpuobj)
		return -ENOMEM;
	gpuobj->engine = NVOBJ_ENGINE_SW;
	gpuobj->class = class;

	list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list);
	*gpuobj_ret = gpuobj;
	return 0;
}

static int
nouveau_gpuobj_channel_init_pramin(struct nouveau_channel *chan)
{
	struct drm_device *dev = chan->dev;
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_gpuobj *pramin = NULL;
	uint32_t size;
	uint32_t base;
	int ret;

	NV_DEBUG(dev, "ch%d\n", chan->id);

	/* Base amount for object storage (4KiB enough?) */
	size = 0x1000;
	base = 0;

	/* PGRAPH context */
	size += dev_priv->engine.graph.grctx_size;

	if (dev_priv->card_type == NV_50) {
		/* Various fixed table thingos */
		size += 0x1400; /* mostly unknown stuff */
		size += 0x4000; /* vm pd */
		base  = 0x6000;
		/* RAMHT, not sure about setting size yet, 32KiB to be safe */
		size += 0x8000;
		/* RAMFC */
		size += 0x1000;
	}

	ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, size, 0x1000, 0,
				     &chan->ramin);
	if (ret) {
		NV_ERROR(dev, "Error allocating channel PRAMIN: %d\n", ret);
		return ret;
	}
	pramin = chan->ramin->gpuobj;

	ret = drm_mm_init(&chan->ramin_heap, pramin->im_pramin->start + base, size);
	if (ret) {
		NV_ERROR(dev, "Error creating PRAMIN heap: %d\n", ret);
		nouveau_gpuobj_ref_del(dev, &chan->ramin);
		return ret;
	}

	return 0;
}

int
nouveau_gpuobj_channel_init(struct nouveau_channel *chan,
			    uint32_t vram_h, uint32_t tt_h)
{
	struct drm_device *dev = chan->dev;
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem;
	struct nouveau_gpuobj *vram = NULL, *tt = NULL;
	int ret, i;

	INIT_LIST_HEAD(&chan->ramht_refs);

	NV_DEBUG(dev, "ch%d vram=0x%08x tt=0x%08x\n", chan->id, vram_h, tt_h);

	/* Allocate a chunk of memory for per-channel object storage */
	ret = nouveau_gpuobj_channel_init_pramin(chan);
	if (ret) {
		NV_ERROR(dev, "init pramin\n");
		return ret;
	}

	/* NV50 VM
	 *  - Allocate per-channel page-directory
	 *  - Map GART and VRAM into the channel's address space at the
	 *    locations determined during init.
	 */
	if (dev_priv->card_type >= NV_50) {
		uint32_t vm_offset, pde;

		vm_offset = (dev_priv->chipset & 0xf0) == 0x50 ? 0x1400 : 0x200;
		vm_offset += chan->ramin->gpuobj->im_pramin->start;

		ret = nouveau_gpuobj_new_fake(dev, vm_offset, ~0, 0x4000,
							0, &chan->vm_pd, NULL);
		if (ret)
			return ret;
		for (i = 0; i < 0x4000; i += 8) {
			nv_wo32(dev, chan->vm_pd, (i+0)/4, 0x00000000);
			nv_wo32(dev, chan->vm_pd, (i+4)/4, 0xdeadcafe);
		}

		pde = (dev_priv->vm_gart_base / (512*1024*1024)) * 2;
		ret = nouveau_gpuobj_ref_add(dev, NULL, 0,
					     dev_priv->gart_info.sg_ctxdma,
					     &chan->vm_gart_pt);
		if (ret)
			return ret;
		nv_wo32(dev, chan->vm_pd, pde++,
			    chan->vm_gart_pt->instance | 0x03);
		nv_wo32(dev, chan->vm_pd, pde++, 0x00000000);

		pde = (dev_priv->vm_vram_base / (512*1024*1024)) * 2;
		for (i = 0; i < dev_priv->vm_vram_pt_nr; i++) {
			ret = nouveau_gpuobj_ref_add(dev, NULL, 0,
						     dev_priv->vm_vram_pt[i],
						     &chan->vm_vram_pt[i]);
			if (ret)
				return ret;

			nv_wo32(dev, chan->vm_pd, pde++,
				    chan->vm_vram_pt[i]->instance | 0x61);
			nv_wo32(dev, chan->vm_pd, pde++, 0x00000000);
		}

		instmem->flush(dev);
	}

	/* RAMHT */
	if (dev_priv->card_type < NV_50) {
		ret = nouveau_gpuobj_ref_add(dev, NULL, 0, dev_priv->ramht,
					     &chan->ramht);
		if (ret)
			return ret;
	} else {
		ret = nouveau_gpuobj_new_ref(dev, chan, chan, 0,
					     0x8000, 16,
					     NVOBJ_FLAG_ZERO_ALLOC,
					     &chan->ramht);
		if (ret)
			return ret;
	}

	/* VRAM ctxdma */
	if (dev_priv->card_type >= NV_50) {
		ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY,
					     0, dev_priv->vm_end,
					     NV_DMA_ACCESS_RW,
					     NV_DMA_TARGET_AGP, &vram);
		if (ret) {
			NV_ERROR(dev, "Error creating VRAM ctxdma: %d\n", ret);
			return ret;
		}
	} else {
		ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY,
						0, dev_priv->fb_available_size,
						NV_DMA_ACCESS_RW,
						NV_DMA_TARGET_VIDMEM, &vram);
		if (ret) {
			NV_ERROR(dev, "Error creating VRAM ctxdma: %d\n", ret);
			return ret;
		}
	}

	ret = nouveau_gpuobj_ref_add(dev, chan, vram_h, vram, NULL);
	if (ret) {
		NV_ERROR(dev, "Error referencing VRAM ctxdma: %d\n", ret);
		return ret;
	}

	/* TT memory ctxdma */
	if (dev_priv->card_type >= NV_50) {
		tt = vram;
	} else
	if (dev_priv->gart_info.type != NOUVEAU_GART_NONE) {
		ret = nouveau_gpuobj_gart_dma_new(chan, 0,
						  dev_priv->gart_info.aper_size,
						  NV_DMA_ACCESS_RW, &tt, NULL);
	} else {
		NV_ERROR(dev, "Invalid GART type %d\n", dev_priv->gart_info.type);
		ret = -EINVAL;
	}

	if (ret) {
		NV_ERROR(dev, "Error creating TT ctxdma: %d\n", ret);
		return ret;
	}

	ret = nouveau_gpuobj_ref_add(dev, chan, tt_h, tt, NULL);
	if (ret) {
		NV_ERROR(dev, "Error referencing TT ctxdma: %d\n", ret);
		return ret;
	}

	return 0;
}

void
nouveau_gpuobj_channel_takedown(struct nouveau_channel *chan)
{
	struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
	struct drm_device *dev = chan->dev;
	struct list_head *entry, *tmp;
	struct nouveau_gpuobj_ref *ref;
	int i;

	NV_DEBUG(dev, "ch%d\n", chan->id);

	if (!chan->ramht_refs.next)
		return;

	list_for_each_safe(entry, tmp, &chan->ramht_refs) {
		ref = list_entry(entry, struct nouveau_gpuobj_ref, list);

		nouveau_gpuobj_ref_del(dev, &ref);
	}

	nouveau_gpuobj_ref_del(dev, &chan->ramht);

	nouveau_gpuobj_del(dev, &chan->vm_pd);
	nouveau_gpuobj_ref_del(dev, &chan->vm_gart_pt);
	for (i = 0; i < dev_priv->vm_vram_pt_nr; i++)
		nouveau_gpuobj_ref_del(dev, &chan->vm_vram_pt[i]);

	if (chan->ramin_heap.free_stack.next)
		drm_mm_takedown(&chan->ramin_heap);
	if (chan->ramin)
		nouveau_gpuobj_ref_del(dev, &chan->ramin);

}

int
nouveau_gpuobj_suspend(struct drm_device *dev)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_gpuobj *gpuobj;
	int i;

	if (dev_priv->card_type < NV_50) {
		dev_priv->susres.ramin_copy = vmalloc(dev_priv->ramin_rsvd_vram);
		if (!dev_priv->susres.ramin_copy)
			return -ENOMEM;

		for (i = 0; i < dev_priv->ramin_rsvd_vram; i += 4)
			dev_priv->susres.ramin_copy[i/4] = nv_ri32(dev, i);
		return 0;
	}

	list_for_each_entry(gpuobj, &dev_priv->gpuobj_list, list) {
		if (!gpuobj->im_backing || (gpuobj->flags & NVOBJ_FLAG_FAKE))
			continue;

		gpuobj->im_backing_suspend = vmalloc(gpuobj->im_pramin->size);
		if (!gpuobj->im_backing_suspend) {
			nouveau_gpuobj_resume(dev);
			return -ENOMEM;
		}

		for (i = 0; i < gpuobj->im_pramin->size / 4; i++)
			gpuobj->im_backing_suspend[i] = nv_ro32(dev, gpuobj, i);
	}

	return 0;
}

void
nouveau_gpuobj_suspend_cleanup(struct drm_device *dev)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_gpuobj *gpuobj;

	if (dev_priv->card_type < NV_50) {
		vfree(dev_priv->susres.ramin_copy);
		dev_priv->susres.ramin_copy = NULL;
		return;
	}

	list_for_each_entry(gpuobj, &dev_priv->gpuobj_list, list) {
		if (!gpuobj->im_backing_suspend)
			continue;

		vfree(gpuobj->im_backing_suspend);
		gpuobj->im_backing_suspend = NULL;
	}
}

void
nouveau_gpuobj_resume(struct drm_device *dev)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_gpuobj *gpuobj;
	int i;

	if (dev_priv->card_type < NV_50) {
		for (i = 0; i < dev_priv->ramin_rsvd_vram; i += 4)
			nv_wi32(dev, i, dev_priv->susres.ramin_copy[i/4]);
		nouveau_gpuobj_suspend_cleanup(dev);
		return;
	}

	list_for_each_entry(gpuobj, &dev_priv->gpuobj_list, list) {
		if (!gpuobj->im_backing_suspend)
			continue;

		for (i = 0; i < gpuobj->im_pramin->size / 4; i++)
			nv_wo32(dev, gpuobj, i, gpuobj->im_backing_suspend[i]);
		dev_priv->engine.instmem.flush(dev);
	}

	nouveau_gpuobj_suspend_cleanup(dev);
}

int nouveau_ioctl_grobj_alloc(struct drm_device *dev, void *data,
			      struct drm_file *file_priv)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct drm_nouveau_grobj_alloc *init = data;
	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
	struct nouveau_pgraph_object_class *grc;
	struct nouveau_gpuobj *gr = NULL;
	struct nouveau_channel *chan;
	int ret;

	NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(init->channel, file_priv, chan);

	if (init->handle == ~0)
		return -EINVAL;

	grc = pgraph->grclass;
	while (grc->id) {
		if (grc->id == init->class)
			break;
		grc++;
	}

	if (!grc->id) {
		NV_ERROR(dev, "Illegal object class: 0x%x\n", init->class);
		return -EPERM;
	}

	if (nouveau_gpuobj_ref_find(chan, init->handle, NULL) == 0)
		return -EEXIST;

	if (!grc->software)
		ret = nouveau_gpuobj_gr_new(chan, grc->id, &gr);
	else
		ret = nouveau_gpuobj_sw_new(chan, grc->id, &gr);

	if (ret) {
		NV_ERROR(dev, "Error creating object: %d (%d/0x%08x)\n",
			 ret, init->channel, init->handle);
		return ret;
	}

	ret = nouveau_gpuobj_ref_add(dev, chan, init->handle, gr, NULL);
	if (ret) {
		NV_ERROR(dev, "Error referencing object: %d (%d/0x%08x)\n",
			 ret, init->channel, init->handle);
		nouveau_gpuobj_del(dev, &gr);
		return ret;
	}

	return 0;
}

int nouveau_ioctl_gpuobj_free(struct drm_device *dev, void *data,
			      struct drm_file *file_priv)
{
	struct drm_nouveau_gpuobj_free *objfree = data;
	struct nouveau_gpuobj_ref *ref;
	struct nouveau_channel *chan;
	int ret;

	NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(objfree->channel, file_priv, chan);

	ret = nouveau_gpuobj_ref_find(chan, objfree->handle, &ref);
	if (ret)
		return ret;
	nouveau_gpuobj_ref_del(dev, &ref);

	return 0;
}
