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>
This commit is contained in:
parent
00fc6f6f73
commit
9b234db378
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue