Commit 9b234db3 authored by Maarten Lankhorst's avatar Maarten Lankhorst Committed by Ben Skeggs

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: default avatarMaarten Lankhorst <maarten.lankhorst@canonical.com>
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 00fc6f6f
......@@ -90,6 +90,7 @@ nvc0_bsp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return ret;
nv_subdev(priv)->unit = 0x00008000;
nv_subdev(priv)->intr = nouveau_falcon_intr;
nv_engine(priv)->cclass = &nvc0_bsp_cclass;
nv_engine(priv)->sclass = nvc0_bsp_sclass;
return 0;
......
......@@ -90,6 +90,7 @@ nve0_bsp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return ret;
nv_subdev(priv)->unit = 0x00008000;
nv_subdev(priv)->intr = nouveau_falcon_intr;
nv_engine(priv)->cclass = &nve0_bsp_cclass;
nv_engine(priv)->sclass = nve0_bsp_sclass;
return 0;
......
......@@ -23,6 +23,25 @@
#include <engine/falcon.h>
#include <subdev/timer.h>
void
nouveau_falcon_intr(struct nouveau_subdev *subdev)
{
struct nouveau_falcon *falcon = (void *)subdev;
u32 dispatch = nv_ro32(falcon, 0x01c);
u32 intr = nv_ro32(falcon, 0x008) & dispatch & ~(dispatch >> 16);
if (intr & 0x00000010) {
nv_debug(falcon, "ucode halted\n");
nv_wo32(falcon, 0x004, 0x00000010);
intr &= ~0x00000010;
}
if (intr) {
nv_error(falcon, "unhandled intr 0x%08x\n", intr);
nv_wo32(falcon, 0x004, intr);
}
}
u32
_nouveau_falcon_rd32(struct nouveau_object *object, u64 addr)
{
......
......@@ -90,6 +90,7 @@ nvc0_ppp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return ret;
nv_subdev(priv)->unit = 0x00000002;
nv_subdev(priv)->intr = nouveau_falcon_intr;
nv_engine(priv)->cclass = &nvc0_ppp_cclass;
nv_engine(priv)->sclass = nvc0_ppp_sclass;
return 0;
......
......@@ -90,6 +90,7 @@ nvc0_vp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return ret;
nv_subdev(priv)->unit = 0x00020000;
nv_subdev(priv)->intr = nouveau_falcon_intr;
nv_engine(priv)->cclass = &nvc0_vp_cclass;
nv_engine(priv)->sclass = nvc0_vp_sclass;
return 0;
......
......@@ -90,6 +90,7 @@ nve0_vp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return ret;
nv_subdev(priv)->unit = 0x00020000;
nv_subdev(priv)->intr = nouveau_falcon_intr;
nv_engine(priv)->cclass = &nve0_vp_cclass;
nv_engine(priv)->sclass = nve0_vp_sclass;
return 0;
......
......@@ -72,6 +72,8 @@ int nouveau_falcon_create_(struct nouveau_object *, struct nouveau_object *,
struct nouveau_oclass *, u32, bool, const char *,
const char *, int, void **);
void nouveau_falcon_intr(struct nouveau_subdev *subdev);
#define _nouveau_falcon_dtor _nouveau_engine_dtor
int _nouveau_falcon_init(struct nouveau_object *);
int _nouveau_falcon_fini(struct nouveau_object *, bool);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment