diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2011-03-30 23:44:16 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2011-05-15 20:47:52 -0400 |
commit | 4ea52f8974392b39ffb192fd31de80dc65b52657 (patch) | |
tree | 594e2a1cc6649768ee23bcb9958b091f8c0ea0c3 /drivers/gpu/drm/nouveau/nouveau_object.c | |
parent | 475feffabe7d42d3333bf9a17167f38f3c467d11 (diff) |
drm/nouveau: move engine object creation into per-engine hooks
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_object.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_object.c | 95 |
1 files changed, 13 insertions, 82 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c index 67a16e01ffa6..f7b806f26f2f 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 | |||
365 | static uint32_t | ||
366 | nouveau_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 | */ |
608 | static int | 594 | static int |
609 | nouveau_gpuobj_sw_new(struct nouveau_channel *chan, int class, | 595 | nouveau_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,17 +610,20 @@ 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 | ||
631 | int | 619 | int |
632 | nouveau_gpuobj_gr_new(struct nouveau_channel *chan, u32 handle, int class) | 620 | nouveau_gpuobj_gr_new(struct nouveau_channel *chan, u32 handle, int class) |
633 | { | 621 | { |
634 | struct drm_nouveau_private *dev_priv = chan->dev->dev_private; | 622 | struct drm_nouveau_private *dev_priv = chan->dev->dev_private; |
623 | struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; | ||
624 | struct nouveau_crypt_engine *pcrypt = &dev_priv->engine.crypt; | ||
635 | struct drm_device *dev = chan->dev; | 625 | struct drm_device *dev = chan->dev; |
636 | struct nouveau_gpuobj_class *oc; | 626 | struct nouveau_gpuobj_class *oc; |
637 | struct nouveau_gpuobj *gpuobj; | ||
638 | int ret; | 627 | int ret; |
639 | 628 | ||
640 | NV_DEBUG(dev, "ch%d class=0x%04x\n", chan->id, class); | 629 | NV_DEBUG(dev, "ch%d class=0x%04x\n", chan->id, class); |
@@ -650,85 +639,27 @@ nouveau_gpuobj_gr_new(struct nouveau_channel *chan, u32 handle, int class) | |||
650 | found: | 639 | found: |
651 | switch (oc->engine) { | 640 | switch (oc->engine) { |
652 | case NVOBJ_ENGINE_SW: | 641 | case NVOBJ_ENGINE_SW: |
653 | if (dev_priv->card_type < NV_C0) { | 642 | return nouveau_gpuobj_sw_new(chan, handle, class); |
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: | 643 | case NVOBJ_ENGINE_GR: |
661 | if ((dev_priv->card_type >= NV_20 && !chan->ramin_grctx) || | 644 | if ((dev_priv->card_type >= NV_20 && !chan->ramin_grctx) || |
662 | (dev_priv->card_type < NV_20 && !chan->pgraph_ctx)) { | 645 | (dev_priv->card_type < NV_20 && !chan->pgraph_ctx)) { |
663 | struct nouveau_pgraph_engine *pgraph = | ||
664 | &dev_priv->engine.graph; | ||
665 | |||
666 | ret = pgraph->create_context(chan); | 646 | ret = pgraph->create_context(chan); |
667 | if (ret) | 647 | if (ret) |
668 | return ret; | 648 | return ret; |
669 | } | 649 | } |
670 | break; | 650 | |
651 | return pgraph->object_new(chan, handle, class); | ||
671 | case NVOBJ_ENGINE_CRYPT: | 652 | case NVOBJ_ENGINE_CRYPT: |
672 | if (!chan->crypt_ctx) { | 653 | if (!chan->crypt_ctx) { |
673 | struct nouveau_crypt_engine *pcrypt = | ||
674 | &dev_priv->engine.crypt; | ||
675 | |||
676 | ret = pcrypt->create_context(chan); | 654 | ret = pcrypt->create_context(chan); |
677 | if (ret) | 655 | if (ret) |
678 | return ret; | 656 | return ret; |
679 | } | 657 | } |
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 | 658 | ||
697 | if (dev_priv->card_type >= NV_50) { | 659 | return pcrypt->object_new(chan, 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 | } | 660 | } |
721 | dev_priv->engine.instmem.flush(dev); | ||
722 | 661 | ||
723 | gpuobj->engine = oc->engine; | 662 | BUG_ON(1); |
724 | gpuobj->class = oc->id; | ||
725 | |||
726 | insert: | ||
727 | ret = nouveau_ramht_insert(chan, handle, gpuobj); | ||
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 | } | 663 | } |
733 | 664 | ||
734 | static int | 665 | static int |