aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2012-05-07 21:22:27 -0400
committerBen Skeggs <bskeggs@redhat.com>2012-07-25 20:28:16 -0400
commit0ade74b6c6843892b52e6c2a4ac02183242eec27 (patch)
tree6457434a0d81236d102dd4453b2ee66240f173a8 /drivers/gpu/drm/nouveau
parent2a259a3d84c4409918c5d094f0969da58283a947 (diff)
drm/nv50: extend vblank semaphore to generic dmaobj + offset pair
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h1
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_notifier.c18
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_software.h22
-rw-r--r--drivers/gpu/drm/nouveau/nv50_display.c25
-rw-r--r--drivers/gpu/drm/nouveau/nv50_software.c19
5 files changed, 32 insertions, 53 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index a5dc98495125..03da38373552 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -910,7 +910,6 @@ extern void nouveau_notifier_takedown_channel(struct nouveau_channel *);
910extern int nouveau_notifier_alloc(struct nouveau_channel *, uint32_t handle, 910extern int nouveau_notifier_alloc(struct nouveau_channel *, uint32_t handle,
911 int cout, uint32_t start, uint32_t end, 911 int cout, uint32_t start, uint32_t end,
912 uint32_t *offset); 912 uint32_t *offset);
913extern int nouveau_notifier_offset(struct nouveau_gpuobj *, uint32_t *);
914 913
915/* nouveau_channel.c */ 914/* nouveau_channel.c */
916extern void nouveau_channel_cleanup(struct drm_device *, struct drm_file *); 915extern void nouveau_channel_cleanup(struct drm_device *, struct drm_file *);
diff --git a/drivers/gpu/drm/nouveau/nouveau_notifier.c b/drivers/gpu/drm/nouveau/nouveau_notifier.c
index aa549155dcc1..69c93b864519 100644
--- a/drivers/gpu/drm/nouveau/nouveau_notifier.c
+++ b/drivers/gpu/drm/nouveau/nouveau_notifier.c
@@ -161,21 +161,3 @@ nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle,
161 *b_offset = mem->start; 161 *b_offset = mem->start;
162 return 0; 162 return 0;
163} 163}
164
165int
166nouveau_notifier_offset(struct nouveau_gpuobj *nobj, uint32_t *poffset)
167{
168 if (!nobj || nobj->dtor != nouveau_notifier_gpuobj_dtor)
169 return -EINVAL;
170
171 if (poffset) {
172 struct drm_mm_node *mem = nobj->priv;
173
174 if (*poffset >= mem->size)
175 return false;
176
177 *poffset += mem->start;
178 }
179
180 return 0;
181}
diff --git a/drivers/gpu/drm/nouveau/nouveau_software.h b/drivers/gpu/drm/nouveau/nouveau_software.h
index e60bc6ce9003..9914cf154f65 100644
--- a/drivers/gpu/drm/nouveau/nouveau_software.h
+++ b/drivers/gpu/drm/nouveau/nouveau_software.h
@@ -4,13 +4,15 @@
4struct nouveau_software_priv { 4struct nouveau_software_priv {
5 struct nouveau_exec_engine base; 5 struct nouveau_exec_engine base;
6 struct list_head vblank; 6 struct list_head vblank;
7 spinlock_t peephole_lock;
7}; 8};
8 9
9struct nouveau_software_chan { 10struct nouveau_software_chan {
10 struct list_head flip; 11 struct list_head flip;
11 struct { 12 struct {
12 struct list_head list; 13 struct list_head list;
13 struct nouveau_bo *bo; 14 u32 channel;
15 u32 ctxdma;
14 u32 offset; 16 u32 offset;
15 u32 value; 17 u32 value;
16 u32 head; 18 u32 head;
@@ -18,23 +20,6 @@ struct nouveau_software_chan {
18}; 20};
19 21
20static inline void 22static inline void
21nouveau_software_vblank(struct drm_device *dev, int crtc)
22{
23 struct nouveau_software_priv *psw = nv_engine(dev, NVOBJ_ENGINE_SW);
24 struct nouveau_software_chan *pch, *tmp;
25
26 list_for_each_entry_safe(pch, tmp, &psw->vblank, vblank.list) {
27 if (pch->vblank.head != crtc)
28 continue;
29
30 nouveau_bo_wr32(pch->vblank.bo, pch->vblank.offset,
31 pch->vblank.value);
32 list_del(&pch->vblank.list);
33 drm_vblank_put(dev, crtc);
34 }
35}
36
37static inline void
38nouveau_software_context_new(struct nouveau_software_chan *pch) 23nouveau_software_context_new(struct nouveau_software_chan *pch)
39{ 24{
40 INIT_LIST_HEAD(&pch->flip); 25 INIT_LIST_HEAD(&pch->flip);
@@ -44,6 +29,7 @@ static inline void
44nouveau_software_create(struct nouveau_software_priv *psw) 29nouveau_software_create(struct nouveau_software_priv *psw)
45{ 30{
46 INIT_LIST_HEAD(&psw->vblank); 31 INIT_LIST_HEAD(&psw->vblank);
32 spin_lock_init(&psw->peephole_lock);
47} 33}
48 34
49static inline u16 35static inline u16
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
index 5c41612723b4..b244d9968c5d 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.c
+++ b/drivers/gpu/drm/nouveau/nv50_display.c
@@ -646,7 +646,30 @@ nv50_display_script_select(struct drm_device *dev, struct dcb_entry *dcb,
646static void 646static void
647nv50_display_vblank_crtc_handler(struct drm_device *dev, int crtc) 647nv50_display_vblank_crtc_handler(struct drm_device *dev, int crtc)
648{ 648{
649 nouveau_software_vblank(dev, crtc); 649 struct drm_nouveau_private *dev_priv = dev->dev_private;
650 struct nouveau_software_priv *psw = nv_engine(dev, NVOBJ_ENGINE_SW);
651 struct nouveau_software_chan *pch, *tmp;
652
653 list_for_each_entry_safe(pch, tmp, &psw->vblank, vblank.list) {
654 if (pch->vblank.head != crtc)
655 continue;
656
657 spin_lock(&psw->peephole_lock);
658 nv_wr32(dev, 0x001704, pch->vblank.channel);
659 nv_wr32(dev, 0x001710, 0x80000000 | pch->vblank.ctxdma);
660 if (dev_priv->chipset == 0x50) {
661 nv_wr32(dev, 0x001570, pch->vblank.offset);
662 nv_wr32(dev, 0x001574, pch->vblank.value);
663 } else {
664 nv_wr32(dev, 0x060010, pch->vblank.offset);
665 nv_wr32(dev, 0x060014, pch->vblank.value);
666 }
667 spin_unlock(&psw->peephole_lock);
668
669 list_del(&pch->vblank.list);
670 drm_vblank_put(dev, crtc);
671 }
672
650 drm_handle_vblank(dev, crtc); 673 drm_handle_vblank(dev, crtc);
651} 674}
652 675
diff --git a/drivers/gpu/drm/nouveau/nv50_software.c b/drivers/gpu/drm/nouveau/nv50_software.c
index 114d2517d4a8..df554d9dacb8 100644
--- a/drivers/gpu/drm/nouveau/nv50_software.c
+++ b/drivers/gpu/drm/nouveau/nv50_software.c
@@ -36,9 +36,6 @@ struct nv50_software_priv {
36 36
37struct nv50_software_chan { 37struct nv50_software_chan {
38 struct nouveau_software_chan base; 38 struct nouveau_software_chan base;
39 struct {
40 struct nouveau_gpuobj *object;
41 } vblank;
42}; 39};
43 40
44static int 41static int
@@ -51,11 +48,7 @@ mthd_dma_vblsem(struct nouveau_channel *chan, u32 class, u32 mthd, u32 data)
51 if (!gpuobj) 48 if (!gpuobj)
52 return -ENOENT; 49 return -ENOENT;
53 50
54 if (nouveau_notifier_offset(gpuobj, NULL)) 51 pch->base.vblank.ctxdma = gpuobj->cinst >> 4;
55 return -EINVAL;
56
57 pch->vblank.object = gpuobj;
58 pch->base.vblank.offset = ~0;
59 return 0; 52 return 0;
60} 53}
61 54
@@ -63,11 +56,7 @@ static int
63mthd_vblsem_offset(struct nouveau_channel *chan, u32 class, u32 mthd, u32 data) 56mthd_vblsem_offset(struct nouveau_channel *chan, u32 class, u32 mthd, u32 data)
64{ 57{
65 struct nv50_software_chan *pch = chan->engctx[NVOBJ_ENGINE_SW]; 58 struct nv50_software_chan *pch = chan->engctx[NVOBJ_ENGINE_SW];
66 59 pch->base.vblank.offset = data;
67 if (nouveau_notifier_offset(pch->vblank.object, &data))
68 return -ERANGE;
69
70 pch->base.vblank.offset = data >> 2;
71 return 0; 60 return 0;
72} 61}
73 62
@@ -86,7 +75,7 @@ mthd_vblsem_release(struct nouveau_channel *chan, u32 class, u32 mthd, u32 data)
86 struct nv50_software_chan *pch = chan->engctx[NVOBJ_ENGINE_SW]; 75 struct nv50_software_chan *pch = chan->engctx[NVOBJ_ENGINE_SW];
87 struct drm_device *dev = chan->dev; 76 struct drm_device *dev = chan->dev;
88 77
89 if (!pch->vblank.object || pch->base.vblank.offset == ~0 || data > 1) 78 if (data > 1)
90 return -EINVAL; 79 return -EINVAL;
91 80
92 drm_vblank_get(dev, data); 81 drm_vblank_get(dev, data);
@@ -116,7 +105,7 @@ nv50_software_context_new(struct nouveau_channel *chan, int engine)
116 return -ENOMEM; 105 return -ENOMEM;
117 106
118 nouveau_software_context_new(&pch->base); 107 nouveau_software_context_new(&pch->base);
119 pch->base.vblank.bo = chan->notifier_bo; 108 pch->base.vblank.channel = chan->ramin->vinst >> 12;
120 chan->engctx[engine] = pch; 109 chan->engctx[engine] = pch;
121 110
122 /* dma objects for display sync channel semaphore blocks */ 111 /* dma objects for display sync channel semaphore blocks */