diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2012-04-30 12:34:10 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2012-05-24 02:55:43 -0400 |
commit | 35bcf5d55540e47091a67e5962f12b88d51d7131 (patch) | |
tree | 162d17e735b85817c8c6c881093995a2e6eef336 | |
parent | 20abd1634a6e2eedb84ca977adea56b8aa06cc3e (diff) |
drm/nouveau: move flip-related channel setup to software engine
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_drv.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_object.c | 58 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_software.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nv04_software.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nv50_display.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nv50_software.c | 28 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvc0_software.c | 49 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvd0_display.c | 4 |
8 files changed, 84 insertions, 62 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 8b0e07740291..dce621555433 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h | |||
@@ -295,8 +295,6 @@ struct nouveau_channel { | |||
295 | 295 | ||
296 | uint32_t sw_subchannel[8]; | 296 | uint32_t sw_subchannel[8]; |
297 | 297 | ||
298 | struct nouveau_vma dispc_vma[4]; | ||
299 | |||
300 | struct { | 298 | struct { |
301 | bool active; | 299 | bool active; |
302 | char name[32]; | 300 | char name[32]; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c index 637636b55c73..8e0b38f35975 100644 --- a/drivers/gpu/drm/nouveau/nouveau_object.c +++ b/drivers/gpu/drm/nouveau/nouveau_object.c | |||
@@ -37,7 +37,6 @@ | |||
37 | #include "nouveau_ramht.h" | 37 | #include "nouveau_ramht.h" |
38 | #include "nouveau_software.h" | 38 | #include "nouveau_software.h" |
39 | #include "nouveau_vm.h" | 39 | #include "nouveau_vm.h" |
40 | #include "nv50_display.h" | ||
41 | 40 | ||
42 | struct nouveau_gpuobj_method { | 41 | struct nouveau_gpuobj_method { |
43 | struct list_head head; | 42 | struct list_head head; |
@@ -556,11 +555,10 @@ nouveau_gpuobj_channel_init_pramin(struct nouveau_channel *chan) | |||
556 | static int | 555 | static int |
557 | nvc0_gpuobj_channel_init(struct nouveau_channel *chan, struct nouveau_vm *vm) | 556 | nvc0_gpuobj_channel_init(struct nouveau_channel *chan, struct nouveau_vm *vm) |
558 | { | 557 | { |
559 | struct drm_nouveau_private *dev_priv = chan->dev->dev_private; | ||
560 | struct drm_device *dev = chan->dev; | 558 | struct drm_device *dev = chan->dev; |
561 | struct nouveau_gpuobj *pgd = NULL; | 559 | struct nouveau_gpuobj *pgd = NULL; |
562 | struct nouveau_vm_pgd *vpgd; | 560 | struct nouveau_vm_pgd *vpgd; |
563 | int ret, i; | 561 | int ret; |
564 | 562 | ||
565 | ret = nouveau_gpuobj_new(dev, NULL, 4096, 0x1000, 0, &chan->ramin); | 563 | ret = nouveau_gpuobj_new(dev, NULL, 4096, 0x1000, 0, &chan->ramin); |
566 | if (ret) | 564 | if (ret) |
@@ -585,19 +583,6 @@ nvc0_gpuobj_channel_init(struct nouveau_channel *chan, struct nouveau_vm *vm) | |||
585 | nv_wo32(chan->ramin, 0x0208, 0xffffffff); | 583 | nv_wo32(chan->ramin, 0x0208, 0xffffffff); |
586 | nv_wo32(chan->ramin, 0x020c, 0x000000ff); | 584 | nv_wo32(chan->ramin, 0x020c, 0x000000ff); |
587 | 585 | ||
588 | /* map display semaphore buffers into channel's vm */ | ||
589 | for (i = 0; i < dev->mode_config.num_crtc; i++) { | ||
590 | struct nouveau_bo *bo; | ||
591 | if (dev_priv->card_type >= NV_D0) | ||
592 | bo = nvd0_display_crtc_sema(dev, i); | ||
593 | else | ||
594 | bo = nv50_display(dev)->crtc[i].sem.bo; | ||
595 | |||
596 | ret = nouveau_bo_vma_add(bo, chan->vm, &chan->dispc_vma[i]); | ||
597 | if (ret) | ||
598 | return ret; | ||
599 | } | ||
600 | |||
601 | return 0; | 586 | return 0; |
602 | } | 587 | } |
603 | 588 | ||
@@ -610,7 +595,7 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan, | |||
610 | struct nouveau_fpriv *fpriv = nouveau_fpriv(chan->file_priv); | 595 | struct nouveau_fpriv *fpriv = nouveau_fpriv(chan->file_priv); |
611 | struct nouveau_vm *vm = fpriv ? fpriv->vm : dev_priv->chan_vm; | 596 | struct nouveau_vm *vm = fpriv ? fpriv->vm : dev_priv->chan_vm; |
612 | struct nouveau_gpuobj *vram = NULL, *tt = NULL; | 597 | struct nouveau_gpuobj *vram = NULL, *tt = NULL; |
613 | int ret, i; | 598 | int ret; |
614 | 599 | ||
615 | NV_DEBUG(dev, "ch%d vram=0x%08x tt=0x%08x\n", chan->id, vram_h, tt_h); | 600 | NV_DEBUG(dev, "ch%d vram=0x%08x tt=0x%08x\n", chan->id, vram_h, tt_h); |
616 | if (dev_priv->card_type >= NV_C0) | 601 | if (dev_priv->card_type >= NV_C0) |
@@ -658,25 +643,6 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan, | |||
658 | nouveau_gpuobj_ref(NULL, &ramht); | 643 | nouveau_gpuobj_ref(NULL, &ramht); |
659 | if (ret) | 644 | if (ret) |
660 | return ret; | 645 | return ret; |
661 | |||
662 | /* dma objects for display sync channel semaphore blocks */ | ||
663 | for (i = 0; i < dev->mode_config.num_crtc; i++) { | ||
664 | struct nouveau_gpuobj *sem = NULL; | ||
665 | struct nv50_display_crtc *dispc = | ||
666 | &nv50_display(dev)->crtc[i]; | ||
667 | u64 offset = dispc->sem.bo->bo.offset; | ||
668 | |||
669 | ret = nouveau_gpuobj_dma_new(chan, 0x3d, offset, 0xfff, | ||
670 | NV_MEM_ACCESS_RW, | ||
671 | NV_MEM_TARGET_VRAM, &sem); | ||
672 | if (ret) | ||
673 | return ret; | ||
674 | |||
675 | ret = nouveau_ramht_insert(chan, NvEvoSema0 + i, sem); | ||
676 | nouveau_gpuobj_ref(NULL, &sem); | ||
677 | if (ret) | ||
678 | return ret; | ||
679 | } | ||
680 | } | 646 | } |
681 | 647 | ||
682 | /* VRAM ctxdma */ | 648 | /* VRAM ctxdma */ |
@@ -736,25 +702,7 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan, | |||
736 | void | 702 | void |
737 | nouveau_gpuobj_channel_takedown(struct nouveau_channel *chan) | 703 | nouveau_gpuobj_channel_takedown(struct nouveau_channel *chan) |
738 | { | 704 | { |
739 | struct drm_device *dev = chan->dev; | 705 | NV_DEBUG(chan->dev, "ch%d\n", chan->id); |
740 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
741 | int i; | ||
742 | |||
743 | NV_DEBUG(dev, "ch%d\n", chan->id); | ||
744 | |||
745 | if (dev_priv->card_type >= NV_D0) { | ||
746 | for (i = 0; i < dev->mode_config.num_crtc; i++) { | ||
747 | struct nouveau_bo *bo = nvd0_display_crtc_sema(dev, i); | ||
748 | nouveau_bo_vma_del(bo, &chan->dispc_vma[i]); | ||
749 | } | ||
750 | } else | ||
751 | if (dev_priv->card_type >= NV_50) { | ||
752 | struct nv50_display *disp = nv50_display(dev); | ||
753 | for (i = 0; i < dev->mode_config.num_crtc; i++) { | ||
754 | struct nv50_display_crtc *dispc = &disp->crtc[i]; | ||
755 | nouveau_bo_vma_del(dispc->sem.bo, &chan->dispc_vma[i]); | ||
756 | } | ||
757 | } | ||
758 | 706 | ||
759 | nouveau_vm_ref(NULL, &chan->vm, chan->vm_pd); | 707 | nouveau_vm_ref(NULL, &chan->vm, chan->vm_pd); |
760 | nouveau_gpuobj_ref(NULL, &chan->vm_pd); | 708 | nouveau_gpuobj_ref(NULL, &chan->vm_pd); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_software.h b/drivers/gpu/drm/nouveau/nouveau_software.h index fe30a8f47f8c..e60bc6ce9003 100644 --- a/drivers/gpu/drm/nouveau/nouveau_software.h +++ b/drivers/gpu/drm/nouveau/nouveau_software.h | |||
@@ -64,5 +64,6 @@ nouveau_software_class(struct drm_device *dev) | |||
64 | int nv04_software_create(struct drm_device *); | 64 | int nv04_software_create(struct drm_device *); |
65 | int nv50_software_create(struct drm_device *); | 65 | int nv50_software_create(struct drm_device *); |
66 | int nvc0_software_create(struct drm_device *); | 66 | int nvc0_software_create(struct drm_device *); |
67 | u64 nvc0_software_crtc(struct nouveau_channel *, int crtc); | ||
67 | 68 | ||
68 | #endif | 69 | #endif |
diff --git a/drivers/gpu/drm/nouveau/nv04_software.c b/drivers/gpu/drm/nouveau/nv04_software.c index d37de6e3c3b2..a91cec6030a5 100644 --- a/drivers/gpu/drm/nouveau/nv04_software.c +++ b/drivers/gpu/drm/nouveau/nv04_software.c | |||
@@ -23,6 +23,7 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include "drmP.h" | 25 | #include "drmP.h" |
26 | |||
26 | #include "nouveau_drv.h" | 27 | #include "nouveau_drv.h" |
27 | #include "nouveau_ramht.h" | 28 | #include "nouveau_ramht.h" |
28 | #include "nouveau_software.h" | 29 | #include "nouveau_software.h" |
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 362a4d7cd566..5c41612723b4 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include "nouveau_fb.h" | 32 | #include "nouveau_fb.h" |
33 | #include "nouveau_fbcon.h" | 33 | #include "nouveau_fbcon.h" |
34 | #include "nouveau_ramht.h" | 34 | #include "nouveau_ramht.h" |
35 | #include "nouveau_software.h" | ||
35 | #include "drm_crtc_helper.h" | 36 | #include "drm_crtc_helper.h" |
36 | 37 | ||
37 | static void nv50_display_isr(struct drm_device *); | 38 | static void nv50_display_isr(struct drm_device *); |
@@ -491,7 +492,7 @@ nv50_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb, | |||
491 | else | 492 | else |
492 | OUT_RING (chan, chan->vram_handle); | 493 | OUT_RING (chan, chan->vram_handle); |
493 | } else { | 494 | } else { |
494 | u64 offset = chan->dispc_vma[nv_crtc->index].offset; | 495 | u64 offset = nvc0_software_crtc(chan, nv_crtc->index); |
495 | offset += dispc->sem.offset; | 496 | offset += dispc->sem.offset; |
496 | BEGIN_NVC0(chan, 0, 0x0010, 4); | 497 | BEGIN_NVC0(chan, 0, 0x0010, 4); |
497 | OUT_RING (chan, upper_32_bits(offset)); | 498 | OUT_RING (chan, upper_32_bits(offset)); |
diff --git a/drivers/gpu/drm/nouveau/nv50_software.c b/drivers/gpu/drm/nouveau/nv50_software.c index 0e64d80d5363..114d2517d4a8 100644 --- a/drivers/gpu/drm/nouveau/nv50_software.c +++ b/drivers/gpu/drm/nouveau/nv50_software.c | |||
@@ -23,10 +23,13 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include "drmP.h" | 25 | #include "drmP.h" |
26 | |||
26 | #include "nouveau_drv.h" | 27 | #include "nouveau_drv.h" |
27 | #include "nouveau_ramht.h" | 28 | #include "nouveau_ramht.h" |
28 | #include "nouveau_software.h" | 29 | #include "nouveau_software.h" |
29 | 30 | ||
31 | #include "nv50_display.h" | ||
32 | |||
30 | struct nv50_software_priv { | 33 | struct nv50_software_priv { |
31 | struct nouveau_software_priv base; | 34 | struct nouveau_software_priv base; |
32 | }; | 35 | }; |
@@ -103,7 +106,10 @@ mthd_flip(struct nouveau_channel *chan, u32 class, u32 mthd, u32 data) | |||
103 | static int | 106 | static int |
104 | nv50_software_context_new(struct nouveau_channel *chan, int engine) | 107 | nv50_software_context_new(struct nouveau_channel *chan, int engine) |
105 | { | 108 | { |
109 | struct nv50_software_priv *psw = nv_engine(chan->dev, NVOBJ_ENGINE_SW); | ||
110 | struct nv50_display *pdisp = nv50_display(chan->dev); | ||
106 | struct nv50_software_chan *pch; | 111 | struct nv50_software_chan *pch; |
112 | int ret = 0, i; | ||
107 | 113 | ||
108 | pch = kzalloc(sizeof(*pch), GFP_KERNEL); | 114 | pch = kzalloc(sizeof(*pch), GFP_KERNEL); |
109 | if (!pch) | 115 | if (!pch) |
@@ -111,9 +117,27 @@ nv50_software_context_new(struct nouveau_channel *chan, int engine) | |||
111 | 117 | ||
112 | nouveau_software_context_new(&pch->base); | 118 | nouveau_software_context_new(&pch->base); |
113 | pch->base.vblank.bo = chan->notifier_bo; | 119 | pch->base.vblank.bo = chan->notifier_bo; |
114 | |||
115 | chan->engctx[engine] = pch; | 120 | chan->engctx[engine] = pch; |
116 | return 0; | 121 | |
122 | /* dma objects for display sync channel semaphore blocks */ | ||
123 | for (i = 0; i < chan->dev->mode_config.num_crtc; i++) { | ||
124 | struct nv50_display_crtc *dispc = &pdisp->crtc[i]; | ||
125 | struct nouveau_gpuobj *obj = NULL; | ||
126 | |||
127 | ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, | ||
128 | dispc->sem.bo->bo.offset, 0x1000, | ||
129 | NV_MEM_ACCESS_RW, | ||
130 | NV_MEM_TARGET_VRAM, &obj); | ||
131 | if (ret) | ||
132 | break; | ||
133 | |||
134 | ret = nouveau_ramht_insert(chan, NvEvoSema0 + i, obj); | ||
135 | nouveau_gpuobj_ref(NULL, &obj); | ||
136 | } | ||
137 | |||
138 | if (ret) | ||
139 | psw->base.base.context_del(chan, engine); | ||
140 | return ret; | ||
117 | } | 141 | } |
118 | 142 | ||
119 | static void | 143 | static void |
diff --git a/drivers/gpu/drm/nouveau/nvc0_software.c b/drivers/gpu/drm/nouveau/nvc0_software.c index a1b43f580995..93e8c164fec6 100644 --- a/drivers/gpu/drm/nouveau/nvc0_software.c +++ b/drivers/gpu/drm/nouveau/nvc0_software.c | |||
@@ -23,22 +23,37 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include "drmP.h" | 25 | #include "drmP.h" |
26 | |||
26 | #include "nouveau_drv.h" | 27 | #include "nouveau_drv.h" |
27 | #include "nouveau_ramht.h" | 28 | #include "nouveau_ramht.h" |
28 | #include "nouveau_software.h" | 29 | #include "nouveau_software.h" |
29 | 30 | ||
31 | #include "nv50_display.h" | ||
32 | |||
30 | struct nvc0_software_priv { | 33 | struct nvc0_software_priv { |
31 | struct nouveau_software_priv base; | 34 | struct nouveau_software_priv base; |
32 | }; | 35 | }; |
33 | 36 | ||
34 | struct nvc0_software_chan { | 37 | struct nvc0_software_chan { |
35 | struct nouveau_software_chan base; | 38 | struct nouveau_software_chan base; |
39 | struct nouveau_vma dispc_vma[4]; | ||
36 | }; | 40 | }; |
37 | 41 | ||
42 | u64 | ||
43 | nvc0_software_crtc(struct nouveau_channel *chan, int crtc) | ||
44 | { | ||
45 | struct nvc0_software_chan *pch = chan->engctx[NVOBJ_ENGINE_SW]; | ||
46 | return pch->dispc_vma[crtc].offset; | ||
47 | } | ||
48 | |||
38 | static int | 49 | static int |
39 | nvc0_software_context_new(struct nouveau_channel *chan, int engine) | 50 | nvc0_software_context_new(struct nouveau_channel *chan, int engine) |
40 | { | 51 | { |
52 | struct drm_device *dev = chan->dev; | ||
53 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
54 | struct nvc0_software_priv *psw = nv_engine(dev, NVOBJ_ENGINE_SW); | ||
41 | struct nvc0_software_chan *pch; | 55 | struct nvc0_software_chan *pch; |
56 | int ret = 0, i; | ||
42 | 57 | ||
43 | pch = kzalloc(sizeof(*pch), GFP_KERNEL); | 58 | pch = kzalloc(sizeof(*pch), GFP_KERNEL); |
44 | if (!pch) | 59 | if (!pch) |
@@ -46,13 +61,45 @@ nvc0_software_context_new(struct nouveau_channel *chan, int engine) | |||
46 | 61 | ||
47 | nouveau_software_context_new(&pch->base); | 62 | nouveau_software_context_new(&pch->base); |
48 | chan->engctx[engine] = pch; | 63 | chan->engctx[engine] = pch; |
49 | return 0; | 64 | |
65 | /* map display semaphore buffers into channel's vm */ | ||
66 | for (i = 0; !ret && i < dev->mode_config.num_crtc; i++) { | ||
67 | struct nouveau_bo *bo; | ||
68 | if (dev_priv->card_type >= NV_D0) | ||
69 | bo = nvd0_display_crtc_sema(dev, i); | ||
70 | else | ||
71 | bo = nv50_display(dev)->crtc[i].sem.bo; | ||
72 | |||
73 | ret = nouveau_bo_vma_add(bo, chan->vm, &pch->dispc_vma[i]); | ||
74 | } | ||
75 | |||
76 | if (ret) | ||
77 | psw->base.base.context_del(chan, engine); | ||
78 | return ret; | ||
50 | } | 79 | } |
51 | 80 | ||
52 | static void | 81 | static void |
53 | nvc0_software_context_del(struct nouveau_channel *chan, int engine) | 82 | nvc0_software_context_del(struct nouveau_channel *chan, int engine) |
54 | { | 83 | { |
84 | struct drm_device *dev = chan->dev; | ||
85 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
55 | struct nvc0_software_chan *pch = chan->engctx[engine]; | 86 | struct nvc0_software_chan *pch = chan->engctx[engine]; |
87 | int i; | ||
88 | |||
89 | if (dev_priv->card_type >= NV_D0) { | ||
90 | for (i = 0; i < dev->mode_config.num_crtc; i++) { | ||
91 | struct nouveau_bo *bo = nvd0_display_crtc_sema(dev, i); | ||
92 | nouveau_bo_vma_del(bo, &pch->dispc_vma[i]); | ||
93 | } | ||
94 | } else | ||
95 | if (dev_priv->card_type >= NV_50) { | ||
96 | struct nv50_display *disp = nv50_display(dev); | ||
97 | for (i = 0; i < dev->mode_config.num_crtc; i++) { | ||
98 | struct nv50_display_crtc *dispc = &disp->crtc[i]; | ||
99 | nouveau_bo_vma_del(dispc->sem.bo, &pch->dispc_vma[i]); | ||
100 | } | ||
101 | } | ||
102 | |||
56 | chan->engctx[engine] = NULL; | 103 | chan->engctx[engine] = NULL; |
57 | kfree(pch); | 104 | kfree(pch); |
58 | } | 105 | } |
diff --git a/drivers/gpu/drm/nouveau/nvd0_display.c b/drivers/gpu/drm/nouveau/nvd0_display.c index 7307d3fe992f..c486d3ce3c2c 100644 --- a/drivers/gpu/drm/nouveau/nvd0_display.c +++ b/drivers/gpu/drm/nouveau/nvd0_display.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include "nouveau_crtc.h" | 33 | #include "nouveau_crtc.h" |
34 | #include "nouveau_dma.h" | 34 | #include "nouveau_dma.h" |
35 | #include "nouveau_fb.h" | 35 | #include "nouveau_fb.h" |
36 | #include "nouveau_software.h" | ||
36 | #include "nv50_display.h" | 37 | #include "nv50_display.h" |
37 | 38 | ||
38 | #define EVO_DMA_NR 9 | 39 | #define EVO_DMA_NR 9 |
@@ -298,7 +299,8 @@ nvd0_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb, | |||
298 | if (ret) | 299 | if (ret) |
299 | return ret; | 300 | return ret; |
300 | 301 | ||
301 | offset = chan->dispc_vma[nv_crtc->index].offset; | 302 | |
303 | offset = nvc0_software_crtc(chan, nv_crtc->index); | ||
302 | offset += evo->sem.offset; | 304 | offset += evo->sem.offset; |
303 | 305 | ||
304 | BEGIN_NVC0(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); | 306 | BEGIN_NVC0(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); |