drm/nouveau/devinit/gf100-: detect if BIOS invoked devinit
authorAlexandre Courbot <acourbot@nvidia.com>
Thu, 11 Feb 2016 02:10:04 +0000 (11:10 +0900)
committerBen Skeggs <bskeggs@redhat.com>
Mon, 14 Mar 2016 00:13:16 +0000 (10:13 +1000)
It is not advisable to perform devinit if it has already been done.
VBIOS will very likely have invoked devinit if the GPU is the primary
graphics device, but there is no accurate way to detect this fact yet.

This patch adds such a method for gf100 and later chips, by means of the
NV_PTOP_SCRATCH1_DEVINIT_COMPLETED bit. This bit is set to 1 by devinit,
and reset to 0 when the GPU is powered.

Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gf100.c
drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gm107.c
drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gm200.c
drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv50.h

index 22b0140e28c654eb10b5f781fdfb0ddc32e13c80..2923598b5fe99e239c6cde5e55d5c6af5cf77c7b 100644 (file)
@@ -90,9 +90,21 @@ gf100_devinit_disable(struct nvkm_devinit *init)
        return disable;
 }
 
+void
+gf100_devinit_preinit(struct nvkm_devinit *base)
+{
+       struct nv50_devinit *init = nv50_devinit(base);
+       struct nvkm_subdev *subdev = &init->base.subdev;
+       struct nvkm_device *device = subdev->device;
+
+       /* This bit is set by devinit, and flips back to 0 on suspend */
+       if (!base->post)
+               base->post = ((nvkm_rd32(device, 0x2240c) & BIT(1)) == 0);
+}
+
 static const struct nvkm_devinit_func
 gf100_devinit = {
-       .preinit = nv50_devinit_preinit,
+       .preinit = gf100_devinit_preinit,
        .init = nv50_devinit_init,
        .post = nv04_devinit_post,
        .pll_set = gf100_devinit_pll_set,
index 2be98bd78214458fb746002c78cab7ad7e61739b..28ca01be3d3825b4fd249f85c87c41782b10d5f5 100644 (file)
@@ -46,7 +46,7 @@ gm107_devinit_disable(struct nvkm_devinit *init)
 
 static const struct nvkm_devinit_func
 gm107_devinit = {
-       .preinit = nv50_devinit_preinit,
+       .preinit = gf100_devinit_preinit,
        .init = nv50_devinit_init,
        .post = nv04_devinit_post,
        .pll_set = gf100_devinit_pll_set,
index d3f2e4119e3312c3fa926a8568824771687eaaa7..a410c0db8a08a897167dc4b58a096acb684a294c 100644 (file)
@@ -166,7 +166,7 @@ gm200_devinit_post(struct nvkm_devinit *base, bool post)
 
 static const struct nvkm_devinit_func
 gm200_devinit = {
-       .preinit = nv50_devinit_preinit,
+       .preinit = gf100_devinit_preinit,
        .init = nv50_devinit_init,
        .post = gm200_devinit_post,
        .pll_set = gf100_devinit_pll_set,
index 5de70a8486b45bd3d65b3129311b196d043a45b3..25d2ae3af1c6ce5bac5bcd04af9366f3c080c90a 100644 (file)
@@ -20,6 +20,7 @@ int  gf100_devinit_ctor(struct nvkm_object *, struct nvkm_object *,
                        struct nvkm_oclass *, void *, u32,
                        struct nvkm_object **);
 int  gf100_devinit_pll_set(struct nvkm_devinit *, u32, u32);
+void gf100_devinit_preinit(struct nvkm_devinit *);
 
 u64  gm107_devinit_disable(struct nvkm_devinit *);
 #endif