aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2011-06-23 02:44:05 -0400
committerBen Skeggs <bskeggs@redhat.com>2011-09-20 02:03:44 -0400
commit52d073318a4c32865e6439f7f6c247092a6f6af3 (patch)
tree9b7df0397728b970025d12bba04304391d3edd37 /drivers/gpu
parent323dcac552b39884cdeff26a38d5dd80854795a1 (diff)
drm/nv31/mpeg: support for a single class3174 user
Uncertain if/how the hw does multiple PMPEG channels, supporting one is better than none however. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_state.c5
-rw-r--r--drivers/gpu/drm/nouveau/nv31_mpeg.c39
2 files changed, 40 insertions, 4 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c
index 93a2e83d0246..07691c2eceac 100644
--- a/drivers/gpu/drm/nouveau/nouveau_state.c
+++ b/drivers/gpu/drm/nouveau/nouveau_state.c
@@ -633,7 +633,10 @@ nouveau_card_init(struct drm_device *dev)
633 break; 633 break;
634 } 634 }
635 635
636 if (dev_priv->card_type == NV_40) 636 if (dev_priv->card_type == NV_40 ||
637 dev_priv->chipset == 0x31 ||
638 dev_priv->chipset == 0x34 ||
639 dev_priv->chipset == 0x36)
637 nv31_mpeg_create(dev); 640 nv31_mpeg_create(dev);
638 else 641 else
639 if (dev_priv->card_type == NV_50 && 642 if (dev_priv->card_type == NV_50 &&
diff --git a/drivers/gpu/drm/nouveau/nv31_mpeg.c b/drivers/gpu/drm/nouveau/nv31_mpeg.c
index 72e86660258d..6f06a0713f00 100644
--- a/drivers/gpu/drm/nouveau/nv31_mpeg.c
+++ b/drivers/gpu/drm/nouveau/nv31_mpeg.c
@@ -28,8 +28,30 @@
28 28
29struct nv31_mpeg_engine { 29struct nv31_mpeg_engine {
30 struct nouveau_exec_engine base; 30 struct nouveau_exec_engine base;
31 atomic_t refcount;
31}; 32};
32 33
34
35static int
36nv31_mpeg_context_new(struct nouveau_channel *chan, int engine)
37{
38 struct nv31_mpeg_engine *pmpeg = nv_engine(chan->dev, engine);
39
40 if (!atomic_add_unless(&pmpeg->refcount, 1, 1))
41 return -EBUSY;
42
43 chan->engctx[engine] = (void *)0xdeadcafe;
44 return 0;
45}
46
47static void
48nv31_mpeg_context_del(struct nouveau_channel *chan, int engine)
49{
50 struct nv31_mpeg_engine *pmpeg = nv_engine(chan->dev, engine);
51 atomic_dec(&pmpeg->refcount);
52 chan->engctx[engine] = NULL;
53}
54
33static int 55static int
34nv40_mpeg_context_new(struct nouveau_channel *chan, int engine) 56nv40_mpeg_context_new(struct nouveau_channel *chan, int engine)
35{ 57{
@@ -121,7 +143,7 @@ nv31_mpeg_init(struct drm_device *dev, int engine)
121 /* PMPEG init */ 143 /* PMPEG init */
122 nv_wr32(dev, 0x00b32c, 0x00000000); 144 nv_wr32(dev, 0x00b32c, 0x00000000);
123 nv_wr32(dev, 0x00b314, 0x00000100); 145 nv_wr32(dev, 0x00b314, 0x00000100);
124 nv_wr32(dev, 0x00b220, 0x00000044); 146 nv_wr32(dev, 0x00b220, nv44_graph_class(dev) ? 0x00000044 : 0x00000031);
125 nv_wr32(dev, 0x00b300, 0x02001ec1); 147 nv_wr32(dev, 0x00b300, 0x02001ec1);
126 nv_mask(dev, 0x00b32c, 0x00000001, 0x00000001); 148 nv_mask(dev, 0x00b32c, 0x00000001, 0x00000001);
127 149
@@ -191,6 +213,10 @@ nv31_mpeg_isr_chid(struct drm_device *dev, u32 inst)
191 unsigned long flags; 213 unsigned long flags;
192 int i; 214 int i;
193 215
216 /* hardcode drm channel id on nv3x, so swmthd lookup works */
217 if (dev_priv->card_type < NV_40)
218 return 0;
219
194 spin_lock_irqsave(&dev_priv->channels.lock, flags); 220 spin_lock_irqsave(&dev_priv->channels.lock, flags);
195 for (i = 0; i < dev_priv->engine.fifo.channels; i++) { 221 for (i = 0; i < dev_priv->engine.fifo.channels; i++) {
196 if (!dev_priv->channels.ptr[i]) 222 if (!dev_priv->channels.ptr[i])
@@ -275,17 +301,24 @@ nv31_mpeg_destroy(struct drm_device *dev, int engine)
275int 301int
276nv31_mpeg_create(struct drm_device *dev) 302nv31_mpeg_create(struct drm_device *dev)
277{ 303{
304 struct drm_nouveau_private *dev_priv = dev->dev_private;
278 struct nv31_mpeg_engine *pmpeg; 305 struct nv31_mpeg_engine *pmpeg;
279 306
280 pmpeg = kzalloc(sizeof(*pmpeg), GFP_KERNEL); 307 pmpeg = kzalloc(sizeof(*pmpeg), GFP_KERNEL);
281 if (!pmpeg) 308 if (!pmpeg)
282 return -ENOMEM; 309 return -ENOMEM;
310 atomic_set(&pmpeg->refcount, 0);
283 311
284 pmpeg->base.destroy = nv31_mpeg_destroy; 312 pmpeg->base.destroy = nv31_mpeg_destroy;
285 pmpeg->base.init = nv31_mpeg_init; 313 pmpeg->base.init = nv31_mpeg_init;
286 pmpeg->base.fini = nv31_mpeg_fini; 314 pmpeg->base.fini = nv31_mpeg_fini;
287 pmpeg->base.context_new = nv40_mpeg_context_new; 315 if (dev_priv->card_type < NV_40) {
288 pmpeg->base.context_del = nv40_mpeg_context_del; 316 pmpeg->base.context_new = nv31_mpeg_context_new;
317 pmpeg->base.context_del = nv31_mpeg_context_del;
318 } else {
319 pmpeg->base.context_new = nv40_mpeg_context_new;
320 pmpeg->base.context_del = nv40_mpeg_context_del;
321 }
289 pmpeg->base.object_new = nv31_mpeg_object_new; 322 pmpeg->base.object_new = nv31_mpeg_object_new;
290 323
291 /* ISR vector, PMC_ENABLE bit, and TILE regs are shared between 324 /* ISR vector, PMC_ENABLE bit, and TILE regs are shared between