aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2013-01-30 22:51:20 -0500
committerBen Skeggs <bskeggs@redhat.com>2013-02-20 01:00:46 -0500
commit9bd2ddbaa241274cd11191838d080fc308ecf6c7 (patch)
tree0e8ba52fb2034de4f3fcd977589e3a9bdad79b26 /drivers/gpu/drm/nouveau
parent1d7c71a3e2f77336df536855b0efd2dc5bdeb41b (diff)
drm/nouveau/fifo/nvc0-: use interrupt 31 as an event trigger
Generated if you try and use fifo method 0x20 on any subchannel, appears that it can be safely masked off without stalling the whole GPU. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau')
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/fifo/base.c6
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c24
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c27
-rw-r--r--drivers/gpu/drm/nouveau/core/include/engine/fifo.h2
4 files changed, 56 insertions, 3 deletions
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/base.c b/drivers/gpu/drm/nouveau/core/engine/fifo/base.c
index ca1057a6613c..7341ebe131fa 100644
--- a/drivers/gpu/drm/nouveau/core/engine/fifo/base.c
+++ b/drivers/gpu/drm/nouveau/core/engine/fifo/base.c
@@ -25,6 +25,7 @@
25#include <core/client.h> 25#include <core/client.h>
26#include <core/object.h> 26#include <core/object.h>
27#include <core/handle.h> 27#include <core/handle.h>
28#include <core/event.h>
28#include <core/class.h> 29#include <core/class.h>
29 30
30#include <engine/dmaobj.h> 31#include <engine/dmaobj.h>
@@ -165,6 +166,7 @@ void
165nouveau_fifo_destroy(struct nouveau_fifo *priv) 166nouveau_fifo_destroy(struct nouveau_fifo *priv)
166{ 167{
167 kfree(priv->channel); 168 kfree(priv->channel);
169 nouveau_event_destroy(&priv->uevent);
168 nouveau_engine_destroy(&priv->base); 170 nouveau_engine_destroy(&priv->base);
169} 171}
170 172
@@ -189,6 +191,10 @@ nouveau_fifo_create_(struct nouveau_object *parent,
189 if (!priv->channel) 191 if (!priv->channel)
190 return -ENOMEM; 192 return -ENOMEM;
191 193
194 ret = nouveau_event_create(1, &priv->uevent);
195 if (ret)
196 return ret;
197
192 priv->chid = nouveau_fifo_chid; 198 priv->chid = nouveau_fifo_chid;
193 spin_lock_init(&priv->lock); 199 spin_lock_init(&priv->lock);
194 return 0; 200 return 0;
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c
index 2a9919bbf77c..bf86f40b8a83 100644
--- a/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c
@@ -27,6 +27,7 @@
27#include <core/namedb.h> 27#include <core/namedb.h>
28#include <core/gpuobj.h> 28#include <core/gpuobj.h>
29#include <core/engctx.h> 29#include <core/engctx.h>
30#include <core/event.h>
30#include <core/class.h> 31#include <core/class.h>
31#include <core/math.h> 32#include <core/math.h>
32#include <core/enum.h> 33#include <core/enum.h>
@@ -583,7 +584,8 @@ nvc0_fifo_intr(struct nouveau_subdev *subdev)
583 584
584 if (stat & 0x80000000) { 585 if (stat & 0x80000000) {
585 u32 intr = nv_mask(priv, 0x0025a8, 0x00000000, 0x00000000); 586 u32 intr = nv_mask(priv, 0x0025a8, 0x00000000, 0x00000000);
586 nv_warn(priv, "INTR 0x80000000: 0x%08x\n", intr); 587 nouveau_event_trigger(priv->base.uevent, 0);
588 nv_debug(priv, "INTR 0x80000000: 0x%08x\n", intr);
587 stat &= ~0x80000000; 589 stat &= ~0x80000000;
588 } 590 }
589 591
@@ -594,6 +596,20 @@ nvc0_fifo_intr(struct nouveau_subdev *subdev)
594 } 596 }
595} 597}
596 598
599static void
600nvc0_fifo_uevent_enable(struct nouveau_event *event, int index)
601{
602 struct nvc0_fifo_priv *priv = event->priv;
603 nv_mask(priv, 0x002140, 0x80000000, 0x80000000);
604}
605
606static void
607nvc0_fifo_uevent_disable(struct nouveau_event *event, int index)
608{
609 struct nvc0_fifo_priv *priv = event->priv;
610 nv_mask(priv, 0x002140, 0x80000000, 0x00000000);
611}
612
597static int 613static int
598nvc0_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine, 614nvc0_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
599 struct nouveau_oclass *oclass, void *data, u32 size, 615 struct nouveau_oclass *oclass, void *data, u32 size,
@@ -627,6 +643,10 @@ nvc0_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
627 if (ret) 643 if (ret)
628 return ret; 644 return ret;
629 645
646 priv->base.uevent->enable = nvc0_fifo_uevent_enable;
647 priv->base.uevent->disable = nvc0_fifo_uevent_disable;
648 priv->base.uevent->priv = priv;
649
630 nv_subdev(priv)->unit = 0x00000100; 650 nv_subdev(priv)->unit = 0x00000100;
631 nv_subdev(priv)->intr = nvc0_fifo_intr; 651 nv_subdev(priv)->intr = nvc0_fifo_intr;
632 nv_engine(priv)->cclass = &nvc0_fifo_cclass; 652 nv_engine(priv)->cclass = &nvc0_fifo_cclass;
@@ -685,7 +705,7 @@ nvc0_fifo_init(struct nouveau_object *object)
685 705
686 nv_wr32(priv, 0x002a00, 0xffffffff); /* clears PFIFO.INTR bit 30 */ 706 nv_wr32(priv, 0x002a00, 0xffffffff); /* clears PFIFO.INTR bit 30 */
687 nv_wr32(priv, 0x002100, 0xffffffff); 707 nv_wr32(priv, 0x002100, 0xffffffff);
688 nv_wr32(priv, 0x002140, 0xbfffffff); 708 nv_wr32(priv, 0x002140, 0x3fffffff);
689 return 0; 709 return 0;
690} 710}
691 711
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c
index 410c6e2c9f0e..4419e40d88e9 100644
--- a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c
@@ -27,6 +27,7 @@
27#include <core/namedb.h> 27#include <core/namedb.h>
28#include <core/gpuobj.h> 28#include <core/gpuobj.h>
29#include <core/engctx.h> 29#include <core/engctx.h>
30#include <core/event.h>
30#include <core/class.h> 31#include <core/class.h>
31#include <core/math.h> 32#include <core/math.h>
32#include <core/enum.h> 33#include <core/enum.h>
@@ -554,6 +555,12 @@ nve0_fifo_intr(struct nouveau_subdev *subdev)
554 stat &= ~0x40000000; 555 stat &= ~0x40000000;
555 } 556 }
556 557
558 if (stat & 0x80000000) {
559 nouveau_event_trigger(priv->base.uevent, 0);
560 nv_wr32(priv, 0x002100, 0x80000000);
561 stat &= ~0x80000000;
562 }
563
557 if (stat) { 564 if (stat) {
558 nv_fatal(priv, "unhandled status 0x%08x\n", stat); 565 nv_fatal(priv, "unhandled status 0x%08x\n", stat);
559 nv_wr32(priv, 0x002100, stat); 566 nv_wr32(priv, 0x002100, stat);
@@ -561,6 +568,20 @@ nve0_fifo_intr(struct nouveau_subdev *subdev)
561 } 568 }
562} 569}
563 570
571static void
572nve0_fifo_uevent_enable(struct nouveau_event *event, int index)
573{
574 struct nve0_fifo_priv *priv = event->priv;
575 nv_mask(priv, 0x002140, 0x80000000, 0x80000000);
576}
577
578static void
579nve0_fifo_uevent_disable(struct nouveau_event *event, int index)
580{
581 struct nve0_fifo_priv *priv = event->priv;
582 nv_mask(priv, 0x002140, 0x80000000, 0x00000000);
583}
584
564static int 585static int
565nve0_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine, 586nve0_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
566 struct nouveau_oclass *oclass, void *data, u32 size, 587 struct nouveau_oclass *oclass, void *data, u32 size,
@@ -584,6 +605,10 @@ nve0_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
584 if (ret) 605 if (ret)
585 return ret; 606 return ret;
586 607
608 priv->base.uevent->enable = nve0_fifo_uevent_enable;
609 priv->base.uevent->disable = nve0_fifo_uevent_disable;
610 priv->base.uevent->priv = priv;
611
587 nv_subdev(priv)->unit = 0x00000100; 612 nv_subdev(priv)->unit = 0x00000100;
588 nv_subdev(priv)->intr = nve0_fifo_intr; 613 nv_subdev(priv)->intr = nve0_fifo_intr;
589 nv_engine(priv)->cclass = &nve0_fifo_cclass; 614 nv_engine(priv)->cclass = &nve0_fifo_cclass;
@@ -634,7 +659,7 @@ nve0_fifo_init(struct nouveau_object *object)
634 659
635 nv_wr32(priv, 0x002a00, 0xffffffff); 660 nv_wr32(priv, 0x002a00, 0xffffffff);
636 nv_wr32(priv, 0x002100, 0xffffffff); 661 nv_wr32(priv, 0x002100, 0xffffffff);
637 nv_wr32(priv, 0x002140, 0xbfffffff); 662 nv_wr32(priv, 0x002140, 0x3fffffff);
638 return 0; 663 return 0;
639} 664}
640 665
diff --git a/drivers/gpu/drm/nouveau/core/include/engine/fifo.h b/drivers/gpu/drm/nouveau/core/include/engine/fifo.h
index 543e4ef80f6b..b46c197709f3 100644
--- a/drivers/gpu/drm/nouveau/core/include/engine/fifo.h
+++ b/drivers/gpu/drm/nouveau/core/include/engine/fifo.h
@@ -65,6 +65,8 @@ struct nouveau_fifo_base {
65struct nouveau_fifo { 65struct nouveau_fifo {
66 struct nouveau_engine base; 66 struct nouveau_engine base;
67 67
68 struct nouveau_event *uevent;
69
68 struct nouveau_object **channel; 70 struct nouveau_object **channel;
69 spinlock_t lock; 71 spinlock_t lock;
70 u16 min; 72 u16 min;