nv04_instmem.c 3.8 KB
Newer Older
1 2 3
#include "drmP.h"
#include "drm.h"
#include "nouveau_drv.h"
4
#include "nouveau_ramht.h"
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70

/* returns the size of fifo context */
static int
nouveau_fifo_ctx_size(struct drm_device *dev)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;

	if (dev_priv->chipset >= 0x40)
		return 128;
	else
	if (dev_priv->chipset >= 0x17)
		return 64;

	return 32;
}

static void
nv04_instmem_configure_fixed_tables(struct drm_device *dev)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_engine *engine = &dev_priv->engine;

	/* 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); /* nr entries */
	dev_priv->ramht_size  *= 8; /* 2 32-bit values per entry in RAMHT */
	NV_DEBUG(dev, "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;
	NV_DEBUG(dev, "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
	 */
	dev_priv->ramfc_size = engine->fifo.channels *
						nouveau_fifo_ctx_size(dev);
	switch (dev_priv->card_type) {
	case NV_40:
		dev_priv->ramfc_offset = 0x20000;
		break;
	case NV_30:
	case NV_20:
	case NV_10:
	case NV_04:
	default:
		dev_priv->ramfc_offset = 0x11400;
		break;
	}
	NV_DEBUG(dev, "RAMFC offset=0x%x, size=%d\n", dev_priv->ramfc_offset,
						      dev_priv->ramfc_size);
}

int nv04_instmem_init(struct drm_device *dev)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
71
	struct nouveau_gpuobj *ramht = NULL;
72
	uint32_t offset;
73
	int ret;
74 75 76

	nv04_instmem_configure_fixed_tables(dev);

77 78 79 80 81 82 83 84 85 86 87 88
	/* Setup shared RAMHT */
	ret = nouveau_gpuobj_new_fake(dev, dev_priv->ramht_offset, ~0,
				      dev_priv->ramht_size,
				      NVOBJ_FLAG_ZERO_ALLOC, &ramht);
	if (ret)
		return ret;

	ret = nouveau_ramht_new(dev, ramht, &dev_priv->ramht);
	nouveau_gpuobj_ref(NULL, &ramht);
	if (ret)
		return ret;

89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
	/* 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;

	/* It appears RAMRO (or something?) is controlled by 0x2220/0x2230
	 * on certain NV4x chipsets as well as RAMFC.  When 0x2230 == 0
	 * ("new style" control) the upper 16-bits of 0x2220 points at this
	 * other mysterious table that's clobbering important things.
	 *
	 * We're now pointing this at RAMIN+0x30000 to avoid RAMFC getting
	 * smashed to pieces on us, so reserve 0x30000-0x40000 too..
	 */
	if (dev_priv->card_type >= NV_40) {
		if (offset < 0x40000)
			offset = 0x40000;
	}

107 108
	ret = drm_mm_init(&dev_priv->ramin_heap, offset,
			  dev_priv->ramin_rsvd_vram - offset);
109
	if (ret) {
110 111
		NV_ERROR(dev, "Failed to init RAMIN heap: %d\n", ret);
		return ret;
112 113
	}

114
	dev_priv->ramin_available = true;
115
	return 0;
116 117 118 119 120 121 122 123
}

void
nv04_instmem_takedown(struct drm_device *dev)
{
}

int
124 125
nv04_instmem_populate(struct drm_device *dev, struct nouveau_gpuobj *gpuobj,
		      uint32_t *sz)
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
{
	return 0;
}

void
nv04_instmem_clear(struct drm_device *dev, struct nouveau_gpuobj *gpuobj)
{
}

int
nv04_instmem_bind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj)
{
	return 0;
}

int
nv04_instmem_unbind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj)
{
	return 0;
}

void
148
nv04_instmem_flush(struct drm_device *dev)
149 150 151 152 153 154 155 156 157 158 159 160 161 162
{
}

int
nv04_instmem_suspend(struct drm_device *dev)
{
	return 0;
}

void
nv04_instmem_resume(struct drm_device *dev)
{
}