diff options
author | Maarten Lankhorst <maarten.lankhorst@canonical.com> | 2013-07-07 04:45:43 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2013-07-09 20:48:07 -0400 |
commit | 9b234db37825860b833ba110673301e2009f0546 (patch) | |
tree | debf6e352430cdf9e751332620cf12c436649ac6 /drivers/gpu | |
parent | 00fc6f6f731efb7b76b839598e494b01890d901d (diff) |
drm/nouveau: add falcon interrupt handler
This prevents 100% cpu usage on fermi cards when the exit interrupt
from the secret scrubber is not acked.
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@canonical.com>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/bsp/nvc0.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/bsp/nve0.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/falcon.c | 19 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/ppp/nvc0.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/vp/nvc0.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/vp/nve0.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/include/engine/falcon.h | 2 |
7 files changed, 26 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nouveau/core/engine/bsp/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/bsp/nvc0.c index 262c9f5f5f60..ce860de43e61 100644 --- a/drivers/gpu/drm/nouveau/core/engine/bsp/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/bsp/nvc0.c | |||
@@ -90,6 +90,7 @@ nvc0_bsp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | |||
90 | return ret; | 90 | return ret; |
91 | 91 | ||
92 | nv_subdev(priv)->unit = 0x00008000; | 92 | nv_subdev(priv)->unit = 0x00008000; |
93 | nv_subdev(priv)->intr = nouveau_falcon_intr; | ||
93 | nv_engine(priv)->cclass = &nvc0_bsp_cclass; | 94 | nv_engine(priv)->cclass = &nvc0_bsp_cclass; |
94 | nv_engine(priv)->sclass = nvc0_bsp_sclass; | 95 | nv_engine(priv)->sclass = nvc0_bsp_sclass; |
95 | return 0; | 96 | return 0; |
diff --git a/drivers/gpu/drm/nouveau/core/engine/bsp/nve0.c b/drivers/gpu/drm/nouveau/core/engine/bsp/nve0.c index c46882c83982..ba6aeca0285e 100644 --- a/drivers/gpu/drm/nouveau/core/engine/bsp/nve0.c +++ b/drivers/gpu/drm/nouveau/core/engine/bsp/nve0.c | |||
@@ -90,6 +90,7 @@ nve0_bsp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | |||
90 | return ret; | 90 | return ret; |
91 | 91 | ||
92 | nv_subdev(priv)->unit = 0x00008000; | 92 | nv_subdev(priv)->unit = 0x00008000; |
93 | nv_subdev(priv)->intr = nouveau_falcon_intr; | ||
93 | nv_engine(priv)->cclass = &nve0_bsp_cclass; | 94 | nv_engine(priv)->cclass = &nve0_bsp_cclass; |
94 | nv_engine(priv)->sclass = nve0_bsp_sclass; | 95 | nv_engine(priv)->sclass = nve0_bsp_sclass; |
95 | return 0; | 96 | return 0; |
diff --git a/drivers/gpu/drm/nouveau/core/engine/falcon.c b/drivers/gpu/drm/nouveau/core/engine/falcon.c index 3c7a31f7590e..e03fc8e4dc1d 100644 --- a/drivers/gpu/drm/nouveau/core/engine/falcon.c +++ b/drivers/gpu/drm/nouveau/core/engine/falcon.c | |||
@@ -23,6 +23,25 @@ | |||
23 | #include <engine/falcon.h> | 23 | #include <engine/falcon.h> |
24 | #include <subdev/timer.h> | 24 | #include <subdev/timer.h> |
25 | 25 | ||
26 | void | ||
27 | nouveau_falcon_intr(struct nouveau_subdev *subdev) | ||
28 | { | ||
29 | struct nouveau_falcon *falcon = (void *)subdev; | ||
30 | u32 dispatch = nv_ro32(falcon, 0x01c); | ||
31 | u32 intr = nv_ro32(falcon, 0x008) & dispatch & ~(dispatch >> 16); | ||
32 | |||
33 | if (intr & 0x00000010) { | ||
34 | nv_debug(falcon, "ucode halted\n"); | ||
35 | nv_wo32(falcon, 0x004, 0x00000010); | ||
36 | intr &= ~0x00000010; | ||
37 | } | ||
38 | |||
39 | if (intr) { | ||
40 | nv_error(falcon, "unhandled intr 0x%08x\n", intr); | ||
41 | nv_wo32(falcon, 0x004, intr); | ||
42 | } | ||
43 | } | ||
44 | |||
26 | u32 | 45 | u32 |
27 | _nouveau_falcon_rd32(struct nouveau_object *object, u64 addr) | 46 | _nouveau_falcon_rd32(struct nouveau_object *object, u64 addr) |
28 | { | 47 | { |
diff --git a/drivers/gpu/drm/nouveau/core/engine/ppp/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/ppp/nvc0.c index 98072c1ff360..73719aaa62d6 100644 --- a/drivers/gpu/drm/nouveau/core/engine/ppp/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/ppp/nvc0.c | |||
@@ -90,6 +90,7 @@ nvc0_ppp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | |||
90 | return ret; | 90 | return ret; |
91 | 91 | ||
92 | nv_subdev(priv)->unit = 0x00000002; | 92 | nv_subdev(priv)->unit = 0x00000002; |
93 | nv_subdev(priv)->intr = nouveau_falcon_intr; | ||
93 | nv_engine(priv)->cclass = &nvc0_ppp_cclass; | 94 | nv_engine(priv)->cclass = &nvc0_ppp_cclass; |
94 | nv_engine(priv)->sclass = nvc0_ppp_sclass; | 95 | nv_engine(priv)->sclass = nvc0_ppp_sclass; |
95 | return 0; | 96 | return 0; |
diff --git a/drivers/gpu/drm/nouveau/core/engine/vp/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/vp/nvc0.c index 1879229b60eb..ac1f62aace72 100644 --- a/drivers/gpu/drm/nouveau/core/engine/vp/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/vp/nvc0.c | |||
@@ -90,6 +90,7 @@ nvc0_vp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | |||
90 | return ret; | 90 | return ret; |
91 | 91 | ||
92 | nv_subdev(priv)->unit = 0x00020000; | 92 | nv_subdev(priv)->unit = 0x00020000; |
93 | nv_subdev(priv)->intr = nouveau_falcon_intr; | ||
93 | nv_engine(priv)->cclass = &nvc0_vp_cclass; | 94 | nv_engine(priv)->cclass = &nvc0_vp_cclass; |
94 | nv_engine(priv)->sclass = nvc0_vp_sclass; | 95 | nv_engine(priv)->sclass = nvc0_vp_sclass; |
95 | return 0; | 96 | return 0; |
diff --git a/drivers/gpu/drm/nouveau/core/engine/vp/nve0.c b/drivers/gpu/drm/nouveau/core/engine/vp/nve0.c index d28ecbf7bc49..d4c3108479c9 100644 --- a/drivers/gpu/drm/nouveau/core/engine/vp/nve0.c +++ b/drivers/gpu/drm/nouveau/core/engine/vp/nve0.c | |||
@@ -90,6 +90,7 @@ nve0_vp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | |||
90 | return ret; | 90 | return ret; |
91 | 91 | ||
92 | nv_subdev(priv)->unit = 0x00020000; | 92 | nv_subdev(priv)->unit = 0x00020000; |
93 | nv_subdev(priv)->intr = nouveau_falcon_intr; | ||
93 | nv_engine(priv)->cclass = &nve0_vp_cclass; | 94 | nv_engine(priv)->cclass = &nve0_vp_cclass; |
94 | nv_engine(priv)->sclass = nve0_vp_sclass; | 95 | nv_engine(priv)->sclass = nve0_vp_sclass; |
95 | return 0; | 96 | return 0; |
diff --git a/drivers/gpu/drm/nouveau/core/include/engine/falcon.h b/drivers/gpu/drm/nouveau/core/include/engine/falcon.h index 1edec386ab36..181aa7da524d 100644 --- a/drivers/gpu/drm/nouveau/core/include/engine/falcon.h +++ b/drivers/gpu/drm/nouveau/core/include/engine/falcon.h | |||
@@ -72,6 +72,8 @@ int nouveau_falcon_create_(struct nouveau_object *, struct nouveau_object *, | |||
72 | struct nouveau_oclass *, u32, bool, const char *, | 72 | struct nouveau_oclass *, u32, bool, const char *, |
73 | const char *, int, void **); | 73 | const char *, int, void **); |
74 | 74 | ||
75 | void nouveau_falcon_intr(struct nouveau_subdev *subdev); | ||
76 | |||
75 | #define _nouveau_falcon_dtor _nouveau_engine_dtor | 77 | #define _nouveau_falcon_dtor _nouveau_engine_dtor |
76 | int _nouveau_falcon_init(struct nouveau_object *); | 78 | int _nouveau_falcon_init(struct nouveau_object *); |
77 | int _nouveau_falcon_fini(struct nouveau_object *, bool); | 79 | int _nouveau_falcon_fini(struct nouveau_object *, bool); |