summaryrefslogtreecommitdiff
path: root/shared-core/nv40_graph.c
diff options
context:
space:
mode:
Diffstat (limited to 'shared-core/nv40_graph.c')
-rw-r--r--shared-core/nv40_graph.c124
1 files changed, 47 insertions, 77 deletions
diff --git a/shared-core/nv40_graph.c b/shared-core/nv40_graph.c
index 6ef02bf9..2540fc5f 100644
--- a/shared-core/nv40_graph.c
+++ b/shared-core/nv40_graph.c
@@ -28,22 +28,6 @@
#include "drm.h"
#include "nouveau_drv.h"
-/* The sizes are taken from the difference between the start of two
- * grctx addresses while running the nvidia driver. Probably slightly
- * larger than they actually are, because of other objects being created
- * between the contexts
- */
-#define NV40_GRCTX_SIZE (175*1024)
-#define NV41_GRCTX_SIZE (92*1024)
-#define NV43_GRCTX_SIZE (70*1024)
-#define NV46_GRCTX_SIZE (70*1024) /* probably ~64KiB */
-#define NV47_GRCTX_SIZE (125*1024)
-#define NV49_GRCTX_SIZE (164640)
-#define NV4A_GRCTX_SIZE (64*1024)
-#define NV4B_GRCTX_SIZE (164640)
-#define NV4C_GRCTX_SIZE (25*1024)
-#define NV4E_GRCTX_SIZE (25*1024)
-
/*TODO: deciper what each offset in the context represents. The below
* contexts are taken from dumps just after the 3D object is
* created.
@@ -1471,61 +1455,60 @@ nv40_graph_create_context(struct nouveau_channel *chan)
struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
void (*ctx_init)(struct drm_device *, struct nouveau_gpuobj *);
- unsigned int ctx_size;
int ret;
+ /* These functions populate the graphics context with a whole heap
+ * of default state. All these functions are very similar, with
+ * a minimal amount of chipset-specific changes. However, as we're
+ * currently dependant on the context programs used by the NVIDIA
+ * binary driver these functions must match the layout expected by
+ * them. Hopefully at some point this will all change.
+ */
switch (dev_priv->chipset) {
case 0x40:
- ctx_size = NV40_GRCTX_SIZE;
ctx_init = nv40_graph_context_init;
break;
case 0x41:
case 0x42:
- ctx_size = NV41_GRCTX_SIZE;
ctx_init = nv41_graph_context_init;
break;
case 0x43:
- ctx_size = NV43_GRCTX_SIZE;
ctx_init = nv43_graph_context_init;
break;
case 0x46:
- ctx_size = NV46_GRCTX_SIZE;
ctx_init = nv46_graph_context_init;
break;
case 0x47:
- DRM_INFO("NV47 warning: If your card behaves strangely, please come to the irc channel\n");
- ctx_size = NV47_GRCTX_SIZE;
ctx_init = nv47_graph_context_init;
break;
case 0x49:
- ctx_size = NV49_GRCTX_SIZE;
ctx_init = nv49_graph_context_init;
break;
case 0x44:
case 0x4a:
- ctx_size = NV4A_GRCTX_SIZE;
ctx_init = nv4a_graph_context_init;
break;
case 0x4b:
- ctx_size = NV4B_GRCTX_SIZE;
ctx_init = nv4b_graph_context_init;
break;
case 0x4c:
case 0x67:
- ctx_size = NV4C_GRCTX_SIZE;
ctx_init = nv4c_graph_context_init;
break;
case 0x4e:
- ctx_size = NV4E_GRCTX_SIZE;
ctx_init = nv4e_graph_context_init;
break;
default:
- ctx_size = NV40_GRCTX_SIZE;
ctx_init = nv40_graph_context_init;
break;
}
- if ((ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, ctx_size, 16,
+ /* Allocate a 175KiB block of PRAMIN to store the context. This
+ * is massive overkill for a lot of chipsets, but it should be safe
+ * until we're able to implement this properly (will happen at more
+ * or less the same time we're able to write our own context programs.
+ */
+ if ((ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, 175*1024, 16,
NVOBJ_FLAG_ZERO_ALLOC,
&chan->ramin_grctx)))
return ret;
@@ -1634,25 +1617,12 @@ nv40_graph_load_context(struct nouveau_channel *chan)
return 0;
}
-/* Some voodoo that makes context switching work without the binary driver
- * initialising the card first.
- *
- * It is possible to effect how the context is saved from PGRAPH into a block
- * of instance memory by altering the values in these tables. This may mean
- * that the context layout of each chipset is slightly different (at least
- * NV40 and C51 are different). It would also be possible for chipsets to
- * have an identical context layout, but pull the data from different PGRAPH
- * registers.
- *
- * TODO: decode the meaning of the magic values, may provide clues about the
- * differences between the various NV40 chipsets.
- * TODO: one we have a better idea of how each chipset differs, perhaps think
- * about unifying these instead of providing a separate table for each
- * chip.
- *
- * mmio-trace dumps from other nv4x/g7x/c5x cards very welcome :)
+/* These blocks of "magic numbers" are actually a microcode that the GPU uses
+ * to control how graphics contexts get saved and restored between PRAMIN
+ * and PGRAPH during a context switch. We're currently using values seen
+ * in mmio-traces of the binary driver.
*/
-static uint32_t nv40_ctx_voodoo[] = {
+static uint32_t nv40_ctx_prog[] = {
0x00400889, 0x00200000, 0x0060000a, 0x00200000, 0x00300000, 0x00800001,
0x00700009, 0x0060000e, 0x00400d64, 0x00400d05, 0x00408f65, 0x00409406,
0x0040a268, 0x00200000, 0x0060000a, 0x00700000, 0x00106000, 0x00700080,
@@ -1684,7 +1654,7 @@ static uint32_t nv40_ctx_voodoo[] = {
~0
};
-static uint32_t nv41_ctx_voodoo[] = {
+static uint32_t nv41_ctx_prog[] = {
0x00400889, 0x00200000, 0x0060000a, 0x00200000, 0x00300000, 0x00800001,
0x00700009, 0x0060000e, 0x00400d64, 0x00400d05, 0x00408f65, 0x00409306,
0x0040a068, 0x0040198f, 0x00200001, 0x0060000a, 0x00700080, 0x00104042,
@@ -1715,7 +1685,7 @@ static uint32_t nv41_ctx_voodoo[] = {
0x00600009, 0x00700005, 0x00700006, 0x0060000e, ~0
};
-static uint32_t nv43_ctx_voodoo[] = {
+static uint32_t nv43_ctx_prog[] = {
0x00400889, 0x00200000, 0x0060000a, 0x00200000, 0x00300000, 0x00800001,
0x00700009, 0x0060000e, 0x00400d64, 0x00400d05, 0x00409565, 0x00409a06,
0x0040a868, 0x00200000, 0x0060000a, 0x00700000, 0x00106000, 0x00700080,
@@ -1748,7 +1718,7 @@ static uint32_t nv43_ctx_voodoo[] = {
~0
};
-static uint32_t nv44_ctx_voodoo[] = {
+static uint32_t nv44_ctx_prog[] = {
0x00400889, 0x00200000, 0x0060000a, 0x00200000, 0x00300000, 0x00800001,
0x00700009, 0x0060000e, 0x00400d64, 0x00400d05, 0x00409a65, 0x00409f06,
0x0040ac68, 0x0040248f, 0x00200001, 0x0060000a, 0x00700080, 0x00104042,
@@ -1781,7 +1751,7 @@ static uint32_t nv44_ctx_voodoo[] = {
0x00600009, 0x00700005, 0x00700006, 0x0060000e, ~0
};
-static uint32_t nv46_ctx_voodoo[] = {
+static uint32_t nv46_ctx_prog[] = {
0x00400889, 0x00200000, 0x0060000a, 0x00200000, 0x00300000, 0x00800001,
0x00700009, 0x0060000e, 0x00400d64, 0x00400d05, 0x00408f65, 0x00409306,
0x0040a068, 0x0040198f, 0x00200001, 0x0060000a, 0x00700080, 0x00104042,
@@ -1812,7 +1782,7 @@ static uint32_t nv46_ctx_voodoo[] = {
0x00600009, 0x00700005, 0x00700006, 0x0060000e, ~0
};
-static uint32_t nv47_ctx_voodoo[] = {
+static uint32_t nv47_ctx_prog[] = {
0x00400889, 0x00200000, 0x0060000a, 0x00200000, 0x00300000, 0x00800001,
0x00700009, 0x0060000e, 0x00400d64, 0x00400d05, 0x00409265, 0x00409606,
0x0040a368, 0x0040198f, 0x00200001, 0x0060000a, 0x00700080, 0x00104042,
@@ -1845,7 +1815,7 @@ static uint32_t nv47_ctx_voodoo[] = {
};
//this is used for nv49 and nv4b
-static uint32_t nv49_4b_ctx_voodoo[] ={
+static uint32_t nv49_4b_ctx_prog[] ={
0x00400564, 0x00400505, 0x00408165, 0x00408206, 0x00409e68, 0x00200020,
0x0060000a, 0x00700080, 0x00104042, 0x00200020, 0x0060000a, 0x00700000,
0x001040c5, 0x00400f26, 0x00401068, 0x0060000d, 0x0070008f, 0x0070000e,
@@ -1877,7 +1847,7 @@ static uint32_t nv49_4b_ctx_voodoo[] ={
};
-static uint32_t nv4a_ctx_voodoo[] = {
+static uint32_t nv4a_ctx_prog[] = {
0x00400889, 0x00200000, 0x0060000a, 0x00200000, 0x00300000, 0x00800001,
0x00700009, 0x0060000e, 0x00400d64, 0x00400d05, 0x00409965, 0x00409e06,
0x0040ac68, 0x00200000, 0x0060000a, 0x00700000, 0x00106000, 0x00700080,
@@ -1910,7 +1880,7 @@ static uint32_t nv4a_ctx_voodoo[] = {
0x00600009, 0x00700005, 0x00700006, 0x0060000e, ~0
};
-static uint32_t nv4c_ctx_voodoo[] = {
+static uint32_t nv4c_ctx_prog[] = {
0x00400889, 0x00200000, 0x0060000a, 0x00200000, 0x00300000, 0x00800001,
0x00700009, 0x0060000e, 0x00400d64, 0x00400d05, 0x00409065, 0x00409406,
0x0040a168, 0x0040198f, 0x00200001, 0x0060000a, 0x00700080, 0x00104042,
@@ -1941,7 +1911,7 @@ static uint32_t nv4c_ctx_voodoo[] = {
0x0040a405, 0x00600009, 0x00700005, 0x00700006, 0x0060000e, ~0
};
-static uint32_t nv4e_ctx_voodoo[] = {
+static uint32_t nv4e_ctx_prog[] = {
0x00400889, 0x00200000, 0x0060000a, 0x00200000, 0x00300000, 0x00800001,
0x00700009, 0x0060000e, 0x00400d64, 0x00400d05, 0x00409565, 0x00409a06,
0x0040a868, 0x00200000, 0x0060000a, 0x00700000, 0x00106000, 0x00700080,
@@ -1988,7 +1958,7 @@ nv40_graph_init(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv =
(struct drm_nouveau_private *)dev->dev_private;
- uint32_t *ctx_voodoo;
+ uint32_t *ctx_prog;
uint32_t vramsz, tmp;
int i, j;
@@ -1998,34 +1968,34 @@ nv40_graph_init(struct drm_device *dev)
NV_PMC_ENABLE_PGRAPH);
switch (dev_priv->chipset) {
- case 0x40: ctx_voodoo = nv40_ctx_voodoo; break;
+ case 0x40: ctx_prog = nv40_ctx_prog; break;
case 0x41:
- case 0x42: ctx_voodoo = nv41_ctx_voodoo; break;
- case 0x43: ctx_voodoo = nv43_ctx_voodoo; break;
- case 0x44: ctx_voodoo = nv44_ctx_voodoo; break;
- case 0x46: ctx_voodoo = nv46_ctx_voodoo; break;
- case 0x47: ctx_voodoo = nv47_ctx_voodoo; break;
- case 0x49: ctx_voodoo = nv49_4b_ctx_voodoo; break;
- case 0x4a: ctx_voodoo = nv4a_ctx_voodoo; break;
- case 0x4b: ctx_voodoo = nv49_4b_ctx_voodoo; break;
+ case 0x42: ctx_prog = nv41_ctx_prog; break;
+ case 0x43: ctx_prog = nv43_ctx_prog; break;
+ case 0x44: ctx_prog = nv44_ctx_prog; break;
+ case 0x46: ctx_prog = nv46_ctx_prog; break;
+ case 0x47: ctx_prog = nv47_ctx_prog; break;
+ case 0x49: ctx_prog = nv49_4b_ctx_prog; break;
+ case 0x4a: ctx_prog = nv4a_ctx_prog; break;
+ case 0x4b: ctx_prog = nv49_4b_ctx_prog; break;
case 0x4c:
- case 0x67: ctx_voodoo = nv4c_ctx_voodoo; break;
- case 0x4e: ctx_voodoo = nv4e_ctx_voodoo; break;
+ case 0x67: ctx_prog = nv4c_ctx_prog; break;
+ case 0x4e: ctx_prog = nv4e_ctx_prog; break;
default:
- DRM_ERROR("Unknown ctx_voodoo for chipset 0x%02x\n",
- dev_priv->chipset);
- ctx_voodoo = NULL;
+ DRM_ERROR("Context program for 0x%02x unavailable\n",
+ dev_priv->chipset);
+ ctx_prog = NULL;
break;
}
- /* Load the context voodoo onto the card */
- if (ctx_voodoo) {
- DRM_DEBUG("Loading context-switch voodoo\n");
+ /* Load the context program onto the card */
+ if (ctx_prog) {
+ DRM_DEBUG("Loading context program\n");
i = 0;
NV_WRITE(NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0);
- while (ctx_voodoo[i] != ~0) {
- NV_WRITE(NV40_PGRAPH_CTXCTL_UCODE_DATA, ctx_voodoo[i]);
+ while (ctx_prog[i] != ~0) {
+ NV_WRITE(NV40_PGRAPH_CTXCTL_UCODE_DATA, ctx_prog[i]);
i++;
}
}