diff options
author | Marcin KoĆcielnicki <koriakin@0x04.net> | 2010-02-24 19:54:02 -0500 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2010-02-25 00:09:38 -0500 |
commit | d5f3c90d4f3ad6b054f9855b7b69137b97bda131 (patch) | |
tree | 62d0fa97727229c1001bf1e9d38b04d0b159a955 /drivers/gpu/drm/nouveau/nv50_graph.c | |
parent | be079e97b5a6a569ceff73731aa9433b6113cb87 (diff) |
drm/nv50: Implement ctxprog/state generation.
This removes dependence on external firmware for NV50 generation cards.
If the generated ctxprogs don't work for you for some reason, please
report it.
Signed-off-by: Marcin KoĆcielnicki <koriakin@0x04.net>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nv50_graph.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nv50_graph.c | 74 |
1 files changed, 42 insertions, 32 deletions
diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c index 6d504801b514..857a09671a39 100644 --- a/drivers/gpu/drm/nouveau/nv50_graph.c +++ b/drivers/gpu/drm/nouveau/nv50_graph.c | |||
@@ -28,30 +28,7 @@ | |||
28 | #include "drm.h" | 28 | #include "drm.h" |
29 | #include "nouveau_drv.h" | 29 | #include "nouveau_drv.h" |
30 | 30 | ||
31 | MODULE_FIRMWARE("nouveau/nv50.ctxprog"); | 31 | #include "nouveau_grctx.h" |
32 | MODULE_FIRMWARE("nouveau/nv50.ctxvals"); | ||
33 | MODULE_FIRMWARE("nouveau/nv84.ctxprog"); | ||
34 | MODULE_FIRMWARE("nouveau/nv84.ctxvals"); | ||
35 | MODULE_FIRMWARE("nouveau/nv86.ctxprog"); | ||
36 | MODULE_FIRMWARE("nouveau/nv86.ctxvals"); | ||
37 | MODULE_FIRMWARE("nouveau/nv92.ctxprog"); | ||
38 | MODULE_FIRMWARE("nouveau/nv92.ctxvals"); | ||
39 | MODULE_FIRMWARE("nouveau/nv94.ctxprog"); | ||
40 | MODULE_FIRMWARE("nouveau/nv94.ctxvals"); | ||
41 | MODULE_FIRMWARE("nouveau/nv96.ctxprog"); | ||
42 | MODULE_FIRMWARE("nouveau/nv96.ctxvals"); | ||
43 | MODULE_FIRMWARE("nouveau/nv98.ctxprog"); | ||
44 | MODULE_FIRMWARE("nouveau/nv98.ctxvals"); | ||
45 | MODULE_FIRMWARE("nouveau/nva0.ctxprog"); | ||
46 | MODULE_FIRMWARE("nouveau/nva0.ctxvals"); | ||
47 | MODULE_FIRMWARE("nouveau/nva5.ctxprog"); | ||
48 | MODULE_FIRMWARE("nouveau/nva5.ctxvals"); | ||
49 | MODULE_FIRMWARE("nouveau/nva8.ctxprog"); | ||
50 | MODULE_FIRMWARE("nouveau/nva8.ctxvals"); | ||
51 | MODULE_FIRMWARE("nouveau/nvaa.ctxprog"); | ||
52 | MODULE_FIRMWARE("nouveau/nvaa.ctxvals"); | ||
53 | MODULE_FIRMWARE("nouveau/nvac.ctxprog"); | ||
54 | MODULE_FIRMWARE("nouveau/nvac.ctxvals"); | ||
55 | 32 | ||
56 | #define IS_G80 ((dev_priv->chipset & 0xf0) == 0x50) | 33 | #define IS_G80 ((dev_priv->chipset & 0xf0) == 0x50) |
57 | 34 | ||
@@ -111,9 +88,34 @@ nv50_graph_init_ctxctl(struct drm_device *dev) | |||
111 | 88 | ||
112 | NV_DEBUG(dev, "\n"); | 89 | NV_DEBUG(dev, "\n"); |
113 | 90 | ||
114 | nouveau_grctx_prog_load(dev); | 91 | if (nouveau_ctxfw) { |
115 | if (!dev_priv->engine.graph.ctxprog) | 92 | nouveau_grctx_prog_load(dev); |
116 | dev_priv->engine.graph.accel_blocked = true; | 93 | dev_priv->engine.graph.grctx_size = 0x70000; |
94 | } | ||
95 | if (!dev_priv->engine.graph.ctxprog) { | ||
96 | struct nouveau_grctx ctx = {}; | ||
97 | uint32_t *cp = kmalloc(512 * 4, GFP_KERNEL); | ||
98 | int i; | ||
99 | if (!cp) { | ||
100 | NV_ERROR(dev, "Couldn't alloc ctxprog! Disabling acceleration.\n"); | ||
101 | dev_priv->engine.graph.accel_blocked = true; | ||
102 | return 0; | ||
103 | } | ||
104 | ctx.dev = dev; | ||
105 | ctx.mode = NOUVEAU_GRCTX_PROG; | ||
106 | ctx.data = cp; | ||
107 | ctx.ctxprog_max = 512; | ||
108 | if (!nv50_grctx_init(&ctx)) { | ||
109 | dev_priv->engine.graph.grctx_size = ctx.ctxvals_pos * 4; | ||
110 | |||
111 | nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0); | ||
112 | for (i = 0; i < ctx.ctxprog_len; i++) | ||
113 | nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, cp[i]); | ||
114 | } else { | ||
115 | dev_priv->engine.graph.accel_blocked = true; | ||
116 | } | ||
117 | kfree(cp); | ||
118 | } | ||
117 | 119 | ||
118 | nv_wr32(dev, 0x400320, 4); | 120 | nv_wr32(dev, 0x400320, 4); |
119 | nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, 0); | 121 | nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, 0); |
@@ -193,13 +195,13 @@ nv50_graph_create_context(struct nouveau_channel *chan) | |||
193 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 195 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
194 | struct nouveau_gpuobj *ramin = chan->ramin->gpuobj; | 196 | struct nouveau_gpuobj *ramin = chan->ramin->gpuobj; |
195 | struct nouveau_gpuobj *ctx; | 197 | struct nouveau_gpuobj *ctx; |
196 | uint32_t grctx_size = 0x70000; | 198 | struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; |
197 | int hdr, ret; | 199 | int hdr, ret; |
198 | 200 | ||
199 | NV_DEBUG(dev, "ch%d\n", chan->id); | 201 | NV_DEBUG(dev, "ch%d\n", chan->id); |
200 | 202 | ||
201 | ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, grctx_size, 0x1000, | 203 | ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, pgraph->grctx_size, |
202 | NVOBJ_FLAG_ZERO_ALLOC | | 204 | 0x1000, NVOBJ_FLAG_ZERO_ALLOC | |
203 | NVOBJ_FLAG_ZERO_FREE, &chan->ramin_grctx); | 205 | NVOBJ_FLAG_ZERO_FREE, &chan->ramin_grctx); |
204 | if (ret) | 206 | if (ret) |
205 | return ret; | 207 | return ret; |
@@ -209,7 +211,7 @@ nv50_graph_create_context(struct nouveau_channel *chan) | |||
209 | dev_priv->engine.instmem.prepare_access(dev, true); | 211 | dev_priv->engine.instmem.prepare_access(dev, true); |
210 | nv_wo32(dev, ramin, (hdr + 0x00)/4, 0x00190002); | 212 | nv_wo32(dev, ramin, (hdr + 0x00)/4, 0x00190002); |
211 | nv_wo32(dev, ramin, (hdr + 0x04)/4, chan->ramin_grctx->instance + | 213 | nv_wo32(dev, ramin, (hdr + 0x04)/4, chan->ramin_grctx->instance + |
212 | grctx_size - 1); | 214 | pgraph->grctx_size - 1); |
213 | nv_wo32(dev, ramin, (hdr + 0x08)/4, chan->ramin_grctx->instance); | 215 | nv_wo32(dev, ramin, (hdr + 0x08)/4, chan->ramin_grctx->instance); |
214 | nv_wo32(dev, ramin, (hdr + 0x0c)/4, 0); | 216 | nv_wo32(dev, ramin, (hdr + 0x0c)/4, 0); |
215 | nv_wo32(dev, ramin, (hdr + 0x10)/4, 0); | 217 | nv_wo32(dev, ramin, (hdr + 0x10)/4, 0); |
@@ -217,7 +219,15 @@ nv50_graph_create_context(struct nouveau_channel *chan) | |||
217 | dev_priv->engine.instmem.finish_access(dev); | 219 | dev_priv->engine.instmem.finish_access(dev); |
218 | 220 | ||
219 | dev_priv->engine.instmem.prepare_access(dev, true); | 221 | dev_priv->engine.instmem.prepare_access(dev, true); |
220 | nouveau_grctx_vals_load(dev, ctx); | 222 | if (!pgraph->ctxprog) { |
223 | struct nouveau_grctx ctx = {}; | ||
224 | ctx.dev = chan->dev; | ||
225 | ctx.mode = NOUVEAU_GRCTX_VALS; | ||
226 | ctx.data = chan->ramin_grctx->gpuobj; | ||
227 | nv50_grctx_init(&ctx); | ||
228 | } else { | ||
229 | nouveau_grctx_vals_load(dev, ctx); | ||
230 | } | ||
221 | nv_wo32(dev, ctx, 0x00000/4, chan->ramin->instance >> 12); | 231 | nv_wo32(dev, ctx, 0x00000/4, chan->ramin->instance >> 12); |
222 | if ((dev_priv->chipset & 0xf0) == 0xa0) | 232 | if ((dev_priv->chipset & 0xf0) == 0xa0) |
223 | nv_wo32(dev, ctx, 0x00004/4, 0x00000000); | 233 | nv_wo32(dev, ctx, 0x00004/4, 0x00000000); |