diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_state.c | 5 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nv31_mpeg.c | 39 |
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 | ||
| 29 | struct nv31_mpeg_engine { | 29 | struct nv31_mpeg_engine { |
| 30 | struct nouveau_exec_engine base; | 30 | struct nouveau_exec_engine base; |
| 31 | atomic_t refcount; | ||
| 31 | }; | 32 | }; |
| 32 | 33 | ||
| 34 | |||
| 35 | static int | ||
| 36 | nv31_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 | |||
| 47 | static void | ||
| 48 | nv31_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 | |||
| 33 | static int | 55 | static int |
| 34 | nv40_mpeg_context_new(struct nouveau_channel *chan, int engine) | 56 | nv40_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) | |||
| 275 | int | 301 | int |
| 276 | nv31_mpeg_create(struct drm_device *dev) | 302 | nv31_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 |
