aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nouveau_state.c
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2009-12-15 23:28:55 -0500
committerBen Skeggs <bskeggs@redhat.com>2009-12-16 02:05:57 -0500
commit0735f62e116fae1e4f36237a97de28e8a56b4c2c (patch)
tree3c43ff86368448a041fecd5c8841de3e8230a003 /drivers/gpu/drm/nouveau/nouveau_state.c
parent3c8868d3dbba5110bd43b49879f12d1a6b2a28ca (diff)
drm/nouveau: prevent all channel creation if accel not available
Previously, if there was no firmware available, the DRM would just disable channel creation from userspace, but still use a single channel for its own purposes. With a bit of care it should actually be possible to do this, due to the DRM's very limited use of the engine. It currently doesn't work correctly however, resulting in corrupted fbcon and hangs on a number of cards. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_state.c')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_state.c84
1 files changed, 50 insertions, 34 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c
index 9fc582432da..e76ec2d207a 100644
--- a/drivers/gpu/drm/nouveau/nouveau_state.c
+++ b/drivers/gpu/drm/nouveau/nouveau_state.c
@@ -299,12 +299,57 @@ nouveau_vga_set_decode(void *priv, bool state)
299 return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM; 299 return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
300} 300}
301 301
302static int
303nouveau_card_init_channel(struct drm_device *dev)
304{
305 struct drm_nouveau_private *dev_priv = dev->dev_private;
306 struct nouveau_gpuobj *gpuobj;
307 int ret;
308
309 ret = nouveau_channel_alloc(dev, &dev_priv->channel,
310 (struct drm_file *)-2,
311 NvDmaFB, NvDmaTT);
312 if (ret)
313 return ret;
314
315 gpuobj = NULL;
316 ret = nouveau_gpuobj_dma_new(dev_priv->channel, NV_CLASS_DMA_IN_MEMORY,
317 0, nouveau_mem_fb_amount(dev),
318 NV_DMA_ACCESS_RW, NV_DMA_TARGET_VIDMEM,
319 &gpuobj);
320 if (ret)
321 goto out_err;
322
323 ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, NvDmaVRAM,
324 gpuobj, NULL);
325 if (ret)
326 goto out_err;
327
328 gpuobj = NULL;
329 ret = nouveau_gpuobj_gart_dma_new(dev_priv->channel, 0,
330 dev_priv->gart_info.aper_size,
331 NV_DMA_ACCESS_RW, &gpuobj, NULL);
332 if (ret)
333 goto out_err;
334
335 ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, NvDmaGART,
336 gpuobj, NULL);
337 if (ret)
338 goto out_err;
339
340 return 0;
341out_err:
342 nouveau_gpuobj_del(dev, &gpuobj);
343 nouveau_channel_free(dev_priv->channel);
344 dev_priv->channel = NULL;
345 return ret;
346}
347
302int 348int
303nouveau_card_init(struct drm_device *dev) 349nouveau_card_init(struct drm_device *dev)
304{ 350{
305 struct drm_nouveau_private *dev_priv = dev->dev_private; 351 struct drm_nouveau_private *dev_priv = dev->dev_private;
306 struct nouveau_engine *engine; 352 struct nouveau_engine *engine;
307 struct nouveau_gpuobj *gpuobj;
308 int ret; 353 int ret;
309 354
310 NV_DEBUG(dev, "prev state = %d\n", dev_priv->init_state); 355 NV_DEBUG(dev, "prev state = %d\n", dev_priv->init_state);
@@ -387,39 +432,10 @@ nouveau_card_init(struct drm_device *dev)
387 432
388 /* what about PVIDEO/PCRTC/PRAMDAC etc? */ 433 /* what about PVIDEO/PCRTC/PRAMDAC etc? */
389 434
390 ret = nouveau_channel_alloc(dev, &dev_priv->channel, 435 if (!engine->graph.accel_blocked) {
391 (struct drm_file *)-2, 436 ret = nouveau_card_init_channel(dev);
392 NvDmaFB, NvDmaTT); 437 if (ret)
393 if (ret) 438 goto out_irq;
394 goto out_irq;
395
396 gpuobj = NULL;
397 ret = nouveau_gpuobj_dma_new(dev_priv->channel, NV_CLASS_DMA_IN_MEMORY,
398 0, nouveau_mem_fb_amount(dev),
399 NV_DMA_ACCESS_RW, NV_DMA_TARGET_VIDMEM,
400 &gpuobj);
401 if (ret)
402 goto out_irq;
403
404 ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, NvDmaVRAM,
405 gpuobj, NULL);
406 if (ret) {
407 nouveau_gpuobj_del(dev, &gpuobj);
408 goto out_irq;
409 }
410
411 gpuobj = NULL;
412 ret = nouveau_gpuobj_gart_dma_new(dev_priv->channel, 0,
413 dev_priv->gart_info.aper_size,
414 NV_DMA_ACCESS_RW, &gpuobj, NULL);
415 if (ret)
416 goto out_irq;
417
418 ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, NvDmaGART,
419 gpuobj, NULL);
420 if (ret) {
421 nouveau_gpuobj_del(dev, &gpuobj);
422 goto out_irq;
423 } 439 }
424 440
425 if (drm_core_check_feature(dev, DRIVER_MODESET)) { 441 if (drm_core_check_feature(dev, DRIVER_MODESET)) {