summaryrefslogtreecommitdiff
path: root/bsd-core/drm_agpsupport.c
AgeCommit message (Expand)Author
2005-01-17Add detection of whether the device is AGP by walking the capabilitiesEric Anholt
2004-11-07Now that the memory debug code is gone, and all 3 BSDs have M_ZERO, stopEric Anholt
2004-11-06Commit first pieces of port to OpenBSD, done by Martin Lexa (martin atEric Anholt
2004-11-06Commit WIP of BSD conversion to core model. Compiles for r128, radeon, butEric Anholt
2003-08-19- Remove $FreeBSD$ tags as they weren't too useful and merges are now beingEric Anholt
2003-04-26Remove #if 0'ed code.Eric Anholt
2003-03-11Merge back from FreeBSD-current, adding FreeBSD ID tags to aid futureEric Anholt
2003-02-21Merge from bsd-4-0-0-branch.Eric Anholt
2002-09-26Fix one warning.Eric Anholt
2002-07-05merged bsd-3-0-0-branchAlan Hourihane
2002-01-27Import of XFree86 4.2.0David Dawes
id='n103' href='#n103'>103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
#include "drmP.h"
#include "drm.h"
#include "nouveau_drv.h"

static void
nv04_instmem_determine_amount(struct drm_device *dev)
{
	drm_nouveau_private_t *dev_priv = dev->dev_private;
	int i;

	/* Figure out how much instance memory we need */
	switch (dev_priv->card_type) {
	case NV_40:
		/* We'll want more instance memory than this on some NV4x cards.
		 * There's a 16MB aperture to play with that maps onto the end
		 * of vram.  For now, only reserve a small piece until we know
		 * more about what each chipset requires.
		 */
		dev_priv->ramin_rsvd_vram = (1*1024* 1024);
		break;
	default:
		/*XXX: what *are* the limits on <NV40 cards?, and does RAMIN
		 *     exist in vram on those cards as well?
		 */
		dev_priv->ramin_rsvd_vram = (512*1024);
		break;
	}
	DRM_DEBUG("RAMIN size: %dKiB\n", dev_priv->ramin_rsvd_vram>>10);

	/* Clear all of it, except the BIOS image that's in the first 64KiB */
	for (i=(64*1024); i<dev_priv->ramin_rsvd_vram; i+=4)
		NV_WI32(i, 0x00000000);
}

static void
nv04_instmem_configure_fixed_tables(struct drm_device *dev)
{
	drm_nouveau_private_t *dev_priv = dev->dev_private;

	/* FIFO hash table (RAMHT)
	 *   use 4k hash table at RAMIN+0x10000
	 *   TODO: extend the hash table
	 */
	dev_priv->ramht_offset = 0x10000;
	dev_priv->ramht_bits   = 9;
	dev_priv->ramht_size   = (1 << dev_priv->ramht_bits);
	DRM_DEBUG("RAMHT offset=0x%x, size=%d\n", dev_priv->ramht_offset,
						  dev_priv->ramht_size);

	/* FIFO runout table (RAMRO) - 512k at 0x11200 */
	dev_priv->ramro_offset = 0x11200;
	dev_priv->ramro_size   = 512;
	DRM_DEBUG("RAMRO offset=0x%x, size=%d\n", dev_priv->ramro_offset,
						  dev_priv->ramro_size);

	/* FIFO context table (RAMFC)
	 *   NV40  : Not sure exactly how to position RAMFC on some cards,
	 *           0x30002 seems to position it at RAMIN+0x20000 on these
	 *           cards.  RAMFC is 4kb (32 fifos, 128byte entries).
	 *   Others: Position RAMFC at RAMIN+0x11400
	 */
	switch(dev_priv->card_type)
	{
		case NV_40:
		case NV_44:
			dev_priv->ramfc_offset = 0x20000;
			dev_priv->ramfc_size   = nouveau_fifo_number(dev) *
				nouveau_fifo_ctx_size(dev);
			break;
		case NV_30:
		case NV_20:
		case NV_17:
		case NV_10:
		case NV_04:
		case NV_03:
		default:
			dev_priv->ramfc_offset = 0x11400;
			dev_priv->ramfc_size   = nouveau_fifo_number(dev) *
				nouveau_fifo_ctx_size(dev);
			break;
	}
	DRM_DEBUG("RAMFC offset=0x%x, size=%d\n", dev_priv->ramfc_offset,
						  dev_priv->ramfc_size);
}

int nv04_instmem_init(struct drm_device *dev)
{
	drm_nouveau_private_t *dev_priv = dev->dev_private;
	uint32_t offset;
	int ret = 0;

	nv04_instmem_determine_amount(dev);
	nv04_instmem_configure_fixed_tables(dev);

	if ((ret = nouveau_gpuobj_new_fake(dev, dev_priv->ramht_offset,
						dev_priv->ramht_size,
						NVOBJ_FLAG_ZERO_ALLOC |
						NVOBJ_FLAG_ALLOW_NO_REFS,
						&dev_priv->ramht, NULL)))
		return ret;

	/* Create a heap to manage RAMIN allocations, we don't allocate
	 * the space that was reserved for RAMHT/FC/RO.
	 */
	offset = dev_priv->ramfc_offset + dev_priv->ramfc_size;
	ret = nouveau_mem_init_heap(&dev_priv->ramin_heap,
				    offset, dev_priv->ramin_rsvd_vram - offset);
	if (ret) {
		dev_priv->ramin_heap = NULL;
		DRM_ERROR("Failed to init RAMIN heap\n");
	}

	return ret;
}

void
nv04_instmem_takedown(drm_device_t *dev)
{
	drm_nouveau_private_t *dev_priv = dev->dev_private;

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

int
nv04_instmem_populate(drm_device_t *dev, nouveau_gpuobj_t *gpuobj, uint32_t *sz)
{
	if (gpuobj->im_backing)
		return DRM_ERR(EINVAL);

	return 0;
}

void
nv04_instmem_clear(drm_device_t *dev, nouveau_gpuobj_t *gpuobj)
{
	drm_nouveau_private_t *dev_priv = dev->dev_private;

	if (gpuobj && gpuobj->im_backing) {
		if (gpuobj->im_bound)
			dev_priv->Engine.instmem.unbind(dev, gpuobj);
		nouveau_mem_free(dev, gpuobj->im_backing);
		gpuobj->im_backing = NULL;
	}	
}

int
nv04_instmem_bind(drm_device_t *dev, nouveau_gpuobj_t *gpuobj)
{
	if (!gpuobj->im_pramin || gpuobj->im_bound)
		return DRM_ERR(EINVAL);

	gpuobj->im_bound = 1;
	return 0;
}

int
nv04_instmem_unbind(drm_device_t *dev, nouveau_gpuobj_t *gpuobj)
{
	if (gpuobj->im_bound == 0)
		return DRM_ERR(EINVAL);

	gpuobj->im_bound = 0;
	return 0;
}