aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nouveau_object.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_object.c')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_object.c118
1 files changed, 16 insertions, 102 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c
index 67a16e01ffa..8f97016f5b2 100644
--- a/drivers/gpu/drm/nouveau/nouveau_object.c
+++ b/drivers/gpu/drm/nouveau/nouveau_object.c
@@ -361,20 +361,6 @@ nouveau_gpuobj_new_fake(struct drm_device *dev, u32 pinst, u64 vinst,
361 return 0; 361 return 0;
362} 362}
363 363
364
365static uint32_t
366nouveau_gpuobj_class_instmem_size(struct drm_device *dev, int class)
367{
368 struct drm_nouveau_private *dev_priv = dev->dev_private;
369
370 /*XXX: dodgy hack for now */
371 if (dev_priv->card_type >= NV_50)
372 return 24;
373 if (dev_priv->card_type >= NV_40)
374 return 32;
375 return 16;
376}
377
378/* 364/*
379 DMA objects are used to reference a piece of memory in the 365 DMA objects are used to reference a piece of memory in the
380 framebuffer, PCI or AGP address space. Each object is 16 bytes big 366 framebuffer, PCI or AGP address space. Each object is 16 bytes big
@@ -606,11 +592,11 @@ nouveau_gpuobj_dma_new(struct nouveau_channel *chan, int class, u64 base,
606 set to 0? 592 set to 0?
607*/ 593*/
608static int 594static int
609nouveau_gpuobj_sw_new(struct nouveau_channel *chan, int class, 595nouveau_gpuobj_sw_new(struct nouveau_channel *chan, u32 handle, u16 class)
610 struct nouveau_gpuobj **gpuobj_ret)
611{ 596{
612 struct drm_nouveau_private *dev_priv = chan->dev->dev_private; 597 struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
613 struct nouveau_gpuobj *gpuobj; 598 struct nouveau_gpuobj *gpuobj;
599 int ret;
614 600
615 gpuobj = kzalloc(sizeof(*gpuobj), GFP_KERNEL); 601 gpuobj = kzalloc(sizeof(*gpuobj), GFP_KERNEL);
616 if (!gpuobj) 602 if (!gpuobj)
@@ -624,8 +610,10 @@ nouveau_gpuobj_sw_new(struct nouveau_channel *chan, int class,
624 spin_lock(&dev_priv->ramin_lock); 610 spin_lock(&dev_priv->ramin_lock);
625 list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list); 611 list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list);
626 spin_unlock(&dev_priv->ramin_lock); 612 spin_unlock(&dev_priv->ramin_lock);
627 *gpuobj_ret = gpuobj; 613
628 return 0; 614 ret = nouveau_ramht_insert(chan, handle, gpuobj);
615 nouveau_gpuobj_ref(NULL, &gpuobj);
616 return ret;
629} 617}
630 618
631int 619int
@@ -634,101 +622,30 @@ nouveau_gpuobj_gr_new(struct nouveau_channel *chan, u32 handle, int class)
634 struct drm_nouveau_private *dev_priv = chan->dev->dev_private; 622 struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
635 struct drm_device *dev = chan->dev; 623 struct drm_device *dev = chan->dev;
636 struct nouveau_gpuobj_class *oc; 624 struct nouveau_gpuobj_class *oc;
637 struct nouveau_gpuobj *gpuobj;
638 int ret; 625 int ret;
639 626
640 NV_DEBUG(dev, "ch%d class=0x%04x\n", chan->id, class); 627 NV_DEBUG(dev, "ch%d class=0x%04x\n", chan->id, class);
641 628
642 list_for_each_entry(oc, &dev_priv->classes, head) { 629 list_for_each_entry(oc, &dev_priv->classes, head) {
643 if (oc->id == class) 630 struct nouveau_exec_engine *eng = dev_priv->eng[oc->engine];
644 goto found;
645 }
646
647 NV_ERROR(dev, "illegal object class: 0x%x\n", class);
648 return -EINVAL;
649 631
650found: 632 if (oc->id != class)
651 switch (oc->engine) { 633 continue;
652 case NVOBJ_ENGINE_SW:
653 if (dev_priv->card_type < NV_C0) {
654 ret = nouveau_gpuobj_sw_new(chan, class, &gpuobj);
655 if (ret)
656 return ret;
657 goto insert;
658 }
659 break;
660 case NVOBJ_ENGINE_GR:
661 if ((dev_priv->card_type >= NV_20 && !chan->ramin_grctx) ||
662 (dev_priv->card_type < NV_20 && !chan->pgraph_ctx)) {
663 struct nouveau_pgraph_engine *pgraph =
664 &dev_priv->engine.graph;
665 634
666 ret = pgraph->create_context(chan); 635 if (oc->engine == NVOBJ_ENGINE_SW)
667 if (ret) 636 return nouveau_gpuobj_sw_new(chan, handle, class);
668 return ret;
669 }
670 break;
671 case NVOBJ_ENGINE_CRYPT:
672 if (!chan->crypt_ctx) {
673 struct nouveau_crypt_engine *pcrypt =
674 &dev_priv->engine.crypt;
675 637
676 ret = pcrypt->create_context(chan); 638 if (!chan->engctx[oc->engine]) {
639 ret = eng->context_new(chan, oc->engine);
677 if (ret) 640 if (ret)
678 return ret; 641 return ret;
679 } 642 }
680 break;
681 }
682
683 /* we're done if this is fermi */
684 if (dev_priv->card_type >= NV_C0)
685 return 0;
686
687 ret = nouveau_gpuobj_new(dev, chan,
688 nouveau_gpuobj_class_instmem_size(dev, class),
689 16,
690 NVOBJ_FLAG_ZERO_ALLOC | NVOBJ_FLAG_ZERO_FREE,
691 &gpuobj);
692 if (ret) {
693 NV_ERROR(dev, "error creating gpuobj: %d\n", ret);
694 return ret;
695 }
696 643
697 if (dev_priv->card_type >= NV_50) { 644 return eng->object_new(chan, oc->engine, handle, class);
698 nv_wo32(gpuobj, 0, class);
699 nv_wo32(gpuobj, 20, 0x00010000);
700 } else {
701 switch (class) {
702 case NV_CLASS_NULL:
703 nv_wo32(gpuobj, 0, 0x00001030);
704 nv_wo32(gpuobj, 4, 0xFFFFFFFF);
705 break;
706 default:
707 if (dev_priv->card_type >= NV_40) {
708 nv_wo32(gpuobj, 0, class);
709#ifdef __BIG_ENDIAN
710 nv_wo32(gpuobj, 8, 0x01000000);
711#endif
712 } else {
713#ifdef __BIG_ENDIAN
714 nv_wo32(gpuobj, 0, class | 0x00080000);
715#else
716 nv_wo32(gpuobj, 0, class);
717#endif
718 }
719 }
720 } 645 }
721 dev_priv->engine.instmem.flush(dev);
722
723 gpuobj->engine = oc->engine;
724 gpuobj->class = oc->id;
725 646
726insert: 647 NV_ERROR(dev, "illegal object class: 0x%x\n", class);
727 ret = nouveau_ramht_insert(chan, handle, gpuobj); 648 return -EINVAL;
728 if (ret)
729 NV_ERROR(dev, "error adding gpuobj to RAMHT: %d\n", ret);
730 nouveau_gpuobj_ref(NULL, &gpuobj);
731 return ret;
732} 649}
733 650
734static int 651static int
@@ -746,9 +663,6 @@ nouveau_gpuobj_channel_init_pramin(struct nouveau_channel *chan)
746 size = 0x2000; 663 size = 0x2000;
747 base = 0; 664 base = 0;
748 665
749 /* PGRAPH context */
750 size += dev_priv->engine.graph.grctx_size;
751
752 if (dev_priv->card_type == NV_50) { 666 if (dev_priv->card_type == NV_50) {
753 /* Various fixed table thingos */ 667 /* Various fixed table thingos */
754 size += 0x1400; /* mostly unknown stuff */ 668 size += 0x1400; /* mostly unknown stuff */