Alexandre Courbot
2015-Jun-08 08:53 UTC
[Nouveau] [PATCH 0/5][GIT PULL] Miscellaneous fixes for GF100+
Here are a few small fixes for issues we found while implementing support for GM20B. The first two are specific to Tegra/GK20A, but the last 3 patches may have a broader (hopefully beneficial) effect. Note that the newly introduced gf100_gr_wait_idle() function on patch 5/5 is exported on purpose. GK20A and GM20B drivers will soon make use of it. Ben, since you seemed to like these changes, a pull request follows in case you feel like playing! :) The following changes since commit 258eea3b7493a4e4e8831efbbb5d0a3e2b1a44aa: drm: Do not leak client objects (2015-06-06 23:36:56 +1000) are available in the git repository at: https://github.com/Gnurou/nouveau.git tegra-fixes for you to fetch changes up to a2c4aac405411b69913daf09cf4450f037d9e5fb: gr/gf100: wait for GR idle after GO_IDLE bundle (2015-06-08 17:42:27 +0900) ---------------------------------------------------------------- Alexandre Courbot (5): platform: fix compile error if !CONFIG_IOMMU ibus/gk20a: increase SM wait timeout fifo/gk104: kick channels when deactivating them gr/gf100: wait on bottom half of FE's pipeline gr/gf100: wait for GR idle after GO_IDLE bundle drm/nouveau/nouveau_platform.c | 16 +++++++++++++++ drm/nouveau/nvkm/engine/fifo/gk104.c | 29 +++++++++++++++++++-------- drm/nouveau/nvkm/engine/gr/gf100.c | 39 +++++++++++++++++++++++++++++++++++- drm/nouveau/nvkm/engine/gr/gf100.h | 1 + drm/nouveau/nvkm/subdev/ibus/gk20a.c | 8 ++++++++ 5 files changed, 84 insertions(+), 9 deletions(-) -- 2.4.2
Alexandre Courbot
2015-Jun-08 08:53 UTC
[Nouveau] [PATCH 1/5] platform: fix compile error if !CONFIG_IOMMU
The lack of IOMMU API support can make nouveau_platform_probe_iommu() fail to compile because struct iommu_ops is then empty. Fix this by skipping IOMMU probe in that case - lack of IOMMU on platform devices is sub-optimal, but is not an error. Signed-off-by: Alexandre Courbot <acourbot at nvidia.com> --- drm/nouveau/nouveau_platform.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drm/nouveau/nouveau_platform.c b/drm/nouveau/nouveau_platform.c index 775277f1edb0..dcfbbfaf1739 100644 --- a/drm/nouveau/nouveau_platform.c +++ b/drm/nouveau/nouveau_platform.c @@ -92,6 +92,8 @@ static int nouveau_platform_power_down(struct nouveau_platform_gpu *gpu) return 0; } +#if IS_ENABLED(CONFIG_IOMMU_API) + static void nouveau_platform_probe_iommu(struct device *dev, struct nouveau_platform_gpu *gpu) { @@ -158,6 +160,20 @@ static void nouveau_platform_remove_iommu(struct device *dev, } } +#else + +static void nouveau_platform_probe_iommu(struct device *dev, + struct nouveau_platform_gpu *gpu) +{ +} + +static void nouveau_platform_remove_iommu(struct device *dev, + struct nouveau_platform_gpu *gpu) +{ +} + +#endif + static int nouveau_platform_probe(struct platform_device *pdev) { struct nouveau_platform_gpu *gpu; -- 2.4.2
Alexandre Courbot
2015-Jun-08 08:53 UTC
[Nouveau] [PATCH 2/5] ibus/gk20a: increase SM wait timeout
Increase clock timeout for SYS, FPB and GPC in order to avoid operation failure at high gpcclk rate. Signed-off-by: Alexandre Courbot <acourbot at nvidia.com> --- drm/nouveau/nvkm/subdev/ibus/gk20a.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drm/nouveau/nvkm/subdev/ibus/gk20a.c b/drm/nouveau/nvkm/subdev/ibus/gk20a.c index c0fdb89e74ac..24dcdfb58a8d 100644 --- a/drm/nouveau/nvkm/subdev/ibus/gk20a.c +++ b/drm/nouveau/nvkm/subdev/ibus/gk20a.c @@ -38,6 +38,14 @@ gk20a_ibus_init_priv_ring(struct gk20a_ibus_priv *priv) nv_wr32(priv, 0x12004c, 0x4); nv_wr32(priv, 0x122204, 0x2); nv_rd32(priv, 0x122204); + + /* + * Bug: increase clock timeout to avoid operation failure at high + * gpcclk rate. + */ + nv_wr32(priv, 0x122354, 0x800); + nv_wr32(priv, 0x128328, 0x800); + nv_wr32(priv, 0x124320, 0x800); } static void -- 2.4.2
Alexandre Courbot
2015-Jun-08 08:53 UTC
[Nouveau] [PATCH 3/5] fifo/gk104: kick channels when deactivating them
Kicking channels is part of their deactivation process. Maxwell chips are particularly sensitive to this, and can start fetching the previous pushbuffer of a recycled channel if this is not done. While we are at it, improve the channel preemption code to only wait for bit 20 of 0x002634 to turn to 0, as it is the bit indicating a preempt is pending. Signed-off-by: Alexandre Courbot <acourbot at nvidia.com> --- drm/nouveau/nvkm/engine/fifo/gk104.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/drm/nouveau/nvkm/engine/fifo/gk104.c b/drm/nouveau/nvkm/engine/fifo/gk104.c index e10f9644140f..37a7cbe6b5ec 100644 --- a/drm/nouveau/nvkm/engine/fifo/gk104.c +++ b/drm/nouveau/nvkm/engine/fifo/gk104.c @@ -166,14 +166,30 @@ gk104_fifo_context_attach(struct nvkm_object *parent, } static int +gk104_fifo_chan_kick(struct gk104_fifo_chan *chan) +{ + struct nvkm_object *obj = (void *)chan; + struct gk104_fifo_priv *priv = (void *)obj->engine; + + nv_wr32(priv, 0x002634, chan->base.chid); + if (!nv_wait(priv, 0x002634, 0x100000, 0x000000)) { + nv_error(priv, "channel %d [%s] kick timeout\n", + chan->base.chid, nvkm_client_name(chan)); + return -EBUSY; + } + + return 0; +} + +static int gk104_fifo_context_detach(struct nvkm_object *parent, bool suspend, struct nvkm_object *object) { struct nvkm_bar *bar = nvkm_bar(parent); - struct gk104_fifo_priv *priv = (void *)parent->engine; struct gk104_fifo_base *base = (void *)parent->parent; struct gk104_fifo_chan *chan = (void *)parent; u32 addr; + int err; switch (nv_engidx(object->engine)) { case NVDEV_ENGINE_SW : return 0; @@ -188,13 +204,9 @@ gk104_fifo_context_detach(struct nvkm_object *parent, bool suspend, return -EINVAL; } - nv_wr32(priv, 0x002634, chan->base.chid); - if (!nv_wait(priv, 0x002634, 0xffffffff, chan->base.chid)) { - nv_error(priv, "channel %d [%s] kick timeout\n", - chan->base.chid, nvkm_client_name(chan)); - if (suspend) - return -EBUSY; - } + err = gk104_fifo_chan_kick(chan); + if (err && suspend) + return err; if (addr) { nv_wo32(base, addr + 0x00, 0x00000000); @@ -319,6 +331,7 @@ gk104_fifo_chan_fini(struct nvkm_object *object, bool suspend) gk104_fifo_runlist_update(priv, chan->engine); } + gk104_fifo_chan_kick(chan); nv_wr32(priv, 0x800000 + (chid * 8), 0x00000000); return nvkm_fifo_channel_fini(&chan->base, suspend); } -- 2.4.2
Alexandre Courbot
2015-Jun-08 08:53 UTC
[Nouveau] [PATCH 4/5] gr/gf100: wait on bottom half of FE's pipeline
When emitting the ICMD bundle, wait on the bottom half (bit 3 of the GR_STATUS register) instead of upper half (bit 2) to make sure methods are effectively emitted. Signed-off-by: Alexandre Courbot <acourbot at nvidia.com> --- drm/nouveau/nvkm/engine/gr/gf100.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drm/nouveau/nvkm/engine/gr/gf100.c b/drm/nouveau/nvkm/engine/gr/gf100.c index 5606c25e5d02..01efc2c96045 100644 --- a/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drm/nouveau/nvkm/engine/gr/gf100.c @@ -699,7 +699,7 @@ gf100_gr_icmd(struct gf100_gr_priv *priv, const struct gf100_gr_pack *p) while (addr < next) { nv_wr32(priv, 0x400200, addr); - nv_wait(priv, 0x400700, 0x00000002, 0x00000000); + nv_wait(priv, 0x400700, 0x00000004, 0x00000000); addr += init->pitch; } } -- 2.4.2
Alexandre Courbot
2015-Jun-08 08:53 UTC
[Nouveau] [PATCH 5/5] gr/gf100: wait for GR idle after GO_IDLE bundle
After submitting a GO_IDLE bundle, one must wait for GR to effectively be idle before submitting the next bundle. Failure to do so may result in undefined behavior in some rare cases. Signed-off-by: Alexandre Courbot <acourbot at nvidia.com> Reported-by: Kary Jin <karyj at nvidia.com> --- drm/nouveau/nvkm/engine/gr/gf100.c | 37 +++++++++++++++++++++++++++++++++++++ drm/nouveau/nvkm/engine/gr/gf100.h | 1 + 2 files changed, 38 insertions(+) diff --git a/drm/nouveau/nvkm/engine/gr/gf100.c b/drm/nouveau/nvkm/engine/gr/gf100.c index 01efc2c96045..ca11ddb6ed46 100644 --- a/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drm/nouveau/nvkm/engine/gr/gf100.c @@ -663,6 +663,37 @@ gf100_gr_zbc_init(struct gf100_gr_priv *priv) gf100_gr_zbc_clear_depth(priv, index); } +/** + * Wait until GR goes idle. GR is considered idle if it is disabled by the + * MC (0x200) register, or GR is not busy and a context switch is not in + * progress. + */ +int +gf100_gr_wait_idle(struct gf100_gr_priv *priv) +{ + unsigned long end_jiffies = jiffies + msecs_to_jiffies(2000); + bool gr_enabled, ctxsw_active, gr_busy; + + do { + /* + * required to make sure FIFO_ENGINE_STATUS (0x2640) is + * up-to-date + */ + nv_rd32(priv, 0x400700); + + gr_enabled = nv_rd32(priv, 0x200) & 0x1000; + ctxsw_active = nv_rd32(priv, 0x2640) & 0x8000; + gr_busy = nv_rd32(priv, 0x40060c) & 0x1; + + if (!gr_enabled || (!gr_busy && !ctxsw_active)) + return 0; + } while (time_before(jiffies, end_jiffies)); + + nv_error(priv, "wait for idle timeout (en: %d, ctxsw: %d, busy: %d)\n", + gr_enabled, ctxsw_active, gr_busy); + return -EAGAIN; +} + void gf100_gr_mmio(struct gf100_gr_priv *priv, const struct gf100_gr_pack *p) { @@ -699,6 +730,12 @@ gf100_gr_icmd(struct gf100_gr_priv *priv, const struct gf100_gr_pack *p) while (addr < next) { nv_wr32(priv, 0x400200, addr); + /** + * Wait for GR to go idle after submitting a + * GO_IDLE bundle + */ + if ((addr & 0xffff) == 0xe100) + gf100_gr_wait_idle(priv); nv_wait(priv, 0x400700, 0x00000004, 0x00000000); addr += init->pitch; } diff --git a/drm/nouveau/nvkm/engine/gr/gf100.h b/drm/nouveau/nvkm/engine/gr/gf100.h index 8af1a89eda84..c9533fdac4fc 100644 --- a/drm/nouveau/nvkm/engine/gr/gf100.h +++ b/drm/nouveau/nvkm/engine/gr/gf100.h @@ -181,6 +181,7 @@ struct gf100_gr_oclass { int ppc_nr; }; +int gf100_gr_wait_idle(struct gf100_gr_priv *); void gf100_gr_mmio(struct gf100_gr_priv *, const struct gf100_gr_pack *); void gf100_gr_icmd(struct gf100_gr_priv *, const struct gf100_gr_pack *); void gf100_gr_mthd(struct gf100_gr_priv *, const struct gf100_gr_pack *); -- 2.4.2
Ilia Mirkin
2015-Jun-08 11:04 UTC
[Nouveau] [PATCH 4/5] gr/gf100: wait on bottom half of FE's pipeline
A naive question from someone who knows nothing of icmd or bundles... Would it be better to wait for both bits to become 0 (I.e. 0x6)? On Jun 8, 2015 11:54 AM, "Alexandre Courbot" <acourbot at nvidia.com> wrote:> When emitting the ICMD bundle, wait on the bottom half (bit 3 of the > GR_STATUS register) instead of upper half (bit 2) to make sure methods > are effectively emitted. > > Signed-off-by: Alexandre Courbot <acourbot at nvidia.com> > --- > drm/nouveau/nvkm/engine/gr/gf100.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drm/nouveau/nvkm/engine/gr/gf100.c > b/drm/nouveau/nvkm/engine/gr/gf100.c > index 5606c25e5d02..01efc2c96045 100644 > --- a/drm/nouveau/nvkm/engine/gr/gf100.c > +++ b/drm/nouveau/nvkm/engine/gr/gf100.c > @@ -699,7 +699,7 @@ gf100_gr_icmd(struct gf100_gr_priv *priv, const struct > gf100_gr_pack *p) > > while (addr < next) { > nv_wr32(priv, 0x400200, addr); > - nv_wait(priv, 0x400700, 0x00000002, 0x00000000); > + nv_wait(priv, 0x400700, 0x00000004, 0x00000000); > addr += init->pitch; > } > } > -- > 2.4.2 > > _______________________________________________ > Nouveau mailing list > Nouveau at lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/nouveau >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.freedesktop.org/archives/nouveau/attachments/20150608/e8d66bc3/attachment.html>
Ben Skeggs
2015-Jun-08 21:45 UTC
[Nouveau] [PATCH 0/5][GIT PULL] Miscellaneous fixes for GF100+
On 8 June 2015 at 18:53, Alexandre Courbot <acourbot at nvidia.com> wrote:> Here are a few small fixes for issues we found while implementing > support for GM20B. The first two are specific to Tegra/GK20A, but > the last 3 patches may have a broader (hopefully beneficial) effect. > > Note that the newly introduced gf100_gr_wait_idle() function on patch 5/5 > is exported on purpose. GK20A and GM20B drivers will soon make use of it. > > Ben, since you seemed to like these changes, a pull request follows in > case you feel like playing! :)Great! All merged, thank you :)> > The following changes since commit 258eea3b7493a4e4e8831efbbb5d0a3e2b1a44aa: > > drm: Do not leak client objects (2015-06-06 23:36:56 +1000) > > are available in the git repository at: > > https://github.com/Gnurou/nouveau.git tegra-fixes > > for you to fetch changes up to a2c4aac405411b69913daf09cf4450f037d9e5fb: > > gr/gf100: wait for GR idle after GO_IDLE bundle (2015-06-08 17:42:27 +0900) > > ---------------------------------------------------------------- > Alexandre Courbot (5): > platform: fix compile error if !CONFIG_IOMMU > ibus/gk20a: increase SM wait timeout > fifo/gk104: kick channels when deactivating them > gr/gf100: wait on bottom half of FE's pipeline > gr/gf100: wait for GR idle after GO_IDLE bundle > > drm/nouveau/nouveau_platform.c | 16 +++++++++++++++ > drm/nouveau/nvkm/engine/fifo/gk104.c | 29 +++++++++++++++++++-------- > drm/nouveau/nvkm/engine/gr/gf100.c | 39 +++++++++++++++++++++++++++++++++++- > drm/nouveau/nvkm/engine/gr/gf100.h | 1 + > drm/nouveau/nvkm/subdev/ibus/gk20a.c | 8 ++++++++ > 5 files changed, 84 insertions(+), 9 deletions(-) > > -- > 2.4.2 > > _______________________________________________ > Nouveau mailing list > Nouveau at lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/nouveau
Seemingly Similar Threads
- [PATCH v2 0/6] Improve GK20A support, introduce GM20B, firmware paths
- [PATCH 0/6] Improve GK20A and introduce GM20B support
- [PATCH 4/5] gr/gf100: wait on bottom half of FE's pipeline
- [PATCH] graph/nvc0: Fix engine pointer retrieval
- [PATCH v3 00/11] nouveau: add secure boot support for dGPU and Tegra