Alexandre Courbot
2016-Feb-11 02:10 UTC
[Nouveau] [PATCH] devinit/gf100-: detect if BIOS invoked devinit
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 at nvidia.com> --- drm/nouveau/nvkm/subdev/devinit/gf100.c | 14 +++++++++++++- drm/nouveau/nvkm/subdev/devinit/gm107.c | 2 +- drm/nouveau/nvkm/subdev/devinit/gm204.c | 4 +++- drm/nouveau/nvkm/subdev/devinit/nv50.h | 1 + 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/drm/nouveau/nvkm/subdev/devinit/gf100.c b/drm/nouveau/nvkm/subdev/devinit/gf100.c index 22b0140..2923598 100644 --- a/drm/nouveau/nvkm/subdev/devinit/gf100.c +++ b/drm/nouveau/nvkm/subdev/devinit/gf100.c @@ -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, diff --git a/drm/nouveau/nvkm/subdev/devinit/gm107.c b/drm/nouveau/nvkm/subdev/devinit/gm107.c index 2be98bd..28ca01b 100644 --- a/drm/nouveau/nvkm/subdev/devinit/gm107.c +++ b/drm/nouveau/nvkm/subdev/devinit/gm107.c @@ -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, diff --git a/drm/nouveau/nvkm/subdev/devinit/gm204.c b/drm/nouveau/nvkm/subdev/devinit/gm204.c index 2b9c3f1..84451dd 100644 --- a/drm/nouveau/nvkm/subdev/devinit/gm204.c +++ b/drm/nouveau/nvkm/subdev/devinit/gm204.c @@ -162,11 +162,13 @@ gm204_devinit_post(struct nvkm_devinit *base, bool post) /* load and execute some other ucode image (bios therm?) */ return pmu_load(init, 0x01, post, NULL, NULL); + + } static const struct nvkm_devinit_func gm204_devinit = { - .preinit = nv50_devinit_preinit, + .preinit = gf100_devinit_preinit, .init = nv50_devinit_init, .post = gm204_devinit_post, .pll_set = gf100_devinit_pll_set, diff --git a/drm/nouveau/nvkm/subdev/devinit/nv50.h b/drm/nouveau/nvkm/subdev/devinit/nv50.h index 5de70a8..25d2ae3 100644 --- a/drm/nouveau/nvkm/subdev/devinit/nv50.h +++ b/drm/nouveau/nvkm/subdev/devinit/nv50.h @@ -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 -- 2.7.1
Ilia Mirkin
2017-Jan-28 00:41 UTC
[Nouveau] [PATCH] devinit/gf100-: detect if BIOS invoked devinit
On Wed, Feb 10, 2016 at 9:10 PM, Alexandre Courbot <gnurou at gmail.com> wrote:> 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 at nvidia.com>Does this patch bring any tangible benefits for pre-maxwell? Some VBIOSes[1], namely a bunch of GF104 and at least one GK107 shipped without setting this bit as part of the VBIOS init script sequence. Perhaps others, as it's not like we have a 100% complete VBIOS repo. This causes nouveau to re-run the VBIOS, with apparently rather negative effects on at least the GF104's in question. Perhaps this is only necessary starting GM200? Or something else? Can we add the rdvgac thing to the gf100 heuristic like it's used on nv50? Cheers, -ilia [1] https://bugs.freedesktop.org/show_bug.cgi?id=97620#c27> --- > drm/nouveau/nvkm/subdev/devinit/gf100.c | 14 +++++++++++++- > drm/nouveau/nvkm/subdev/devinit/gm107.c | 2 +- > drm/nouveau/nvkm/subdev/devinit/gm204.c | 4 +++- > drm/nouveau/nvkm/subdev/devinit/nv50.h | 1 + > 4 files changed, 18 insertions(+), 3 deletions(-) > > diff --git a/drm/nouveau/nvkm/subdev/devinit/gf100.c b/drm/nouveau/nvkm/subdev/devinit/gf100.c > index 22b0140..2923598 100644 > --- a/drm/nouveau/nvkm/subdev/devinit/gf100.c > +++ b/drm/nouveau/nvkm/subdev/devinit/gf100.c > @@ -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, > diff --git a/drm/nouveau/nvkm/subdev/devinit/gm107.c b/drm/nouveau/nvkm/subdev/devinit/gm107.c > index 2be98bd..28ca01b 100644 > --- a/drm/nouveau/nvkm/subdev/devinit/gm107.c > +++ b/drm/nouveau/nvkm/subdev/devinit/gm107.c > @@ -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, > diff --git a/drm/nouveau/nvkm/subdev/devinit/gm204.c b/drm/nouveau/nvkm/subdev/devinit/gm204.c > index 2b9c3f1..84451dd 100644 > --- a/drm/nouveau/nvkm/subdev/devinit/gm204.c > +++ b/drm/nouveau/nvkm/subdev/devinit/gm204.c > @@ -162,11 +162,13 @@ gm204_devinit_post(struct nvkm_devinit *base, bool post) > > /* load and execute some other ucode image (bios therm?) */ > return pmu_load(init, 0x01, post, NULL, NULL); > + > + > } > > static const struct nvkm_devinit_func > gm204_devinit = { > - .preinit = nv50_devinit_preinit, > + .preinit = gf100_devinit_preinit, > .init = nv50_devinit_init, > .post = gm204_devinit_post, > .pll_set = gf100_devinit_pll_set, > diff --git a/drm/nouveau/nvkm/subdev/devinit/nv50.h b/drm/nouveau/nvkm/subdev/devinit/nv50.h > index 5de70a8..25d2ae3 100644 > --- a/drm/nouveau/nvkm/subdev/devinit/nv50.h > +++ b/drm/nouveau/nvkm/subdev/devinit/nv50.h > @@ -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 > -- > 2.7.1 > > _______________________________________________ > Nouveau mailing list > Nouveau at lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/nouveau
Reasonably Related Threads
- [PATCH v2] drm/nouveau/devinit/gf100-: try to avoid double-running vbios scripts
- [PATCH] devinit/gf100: make devinit on resume safer
- [PATCH] devinit/nv50: remove unneeded variable
- [PATCH] drm/nouveau/devinit/gf100-: try to avoid double-running vbios scripts
- [PATCH 1/3] drm/nouveau: provide a way for devinit to mark engines as disabled