[Nouveau] [PATCH v3 2/2] fb/nvaa: Enable non-isometric poller on NVAA/NVAC
Ben Skeggs
skeggsb at gmail.com
Wed Dec 10 19:42:24 PST 2014
On Wed, Dec 10, 2014 at 5:53 PM, Pierre Moreau <pierre.morrow at free.fr> wrote:
> (This is a v3 of patch "drm/nouveau/fb/nv50: Add PFB writes")
>
> This fix a GPU lockup on 9400M (NVAC) when using acceleration, see
> https://bugs.freedesktop.org/show_bug.cgi?id=27501
>
> v2:
> - Move code to subdev/fb/nv50.c as suggested by Roy Spliet;
> - Remove arbitrary writes to 100c18/100c24
> - Replace write to 100c1c of arbitrary value by the address of a scratch page
> as proposed by Ilia Mirkin;
> - Remove enabling of bits 16 and 0 as they don't yield in any changes.
>
> v3:
> - Move code to subdev/fb/nvaa.c as suggested by Ilia Mirkin.
> The following changes were made thanks to information provided by Robert Morell
> from NVidia:
> - Allocate a dma page for use by the pollers;
> - Re-enable pollers at bits 16 and 0;
> - Set pollers address to a proper value.
Hey Pierre,
This patch is incorrect. As Robert pointed out in an older thread,
the registers don't take the physical address of a page, but a
somewhat odd "negative offset from the end of carveout".
See this example (referring to Robert's last email):
220.926392 read32 #3 +0x00100e10 -> 0x00070000
220.926406 read32 #3 +0x00100e14 -> 0x00010000
carveout_base = 0x70000000
carveout_size = 0x10000000
-- snip --
223.300495 read32 #3 +0x00100c14 -> 0x00000000
223.300521 read32 #3 +0x00100c18 -> 0x00000000
223.300547 write32 #3 +0x00100c18 <- 0x000027ff
base = (0x70000000 + 0x10000000) - ((0x27ff + 1) << 5)
base = 0x7ffb0000 << in carveout
223.300573 read32 #3 +0x00100c14 -> 0x00000000
223.300599 write32 #3 +0x00100c14 <- 0x00000001
223.300625 read32 #3 +0x00100c1c -> 0x00000002
223.300651 write32 #3 +0x00100c1c <- 0x000027fe
base = (0x70000000 + 0x10000000) - ((0x27fe + 1) << 5)
base = 0x7ffb0020 << in carveout
223.300677 read32 #3 +0x00100c14 -> 0x00000001
223.300702 write32 #3 +0x00100c14 <- 0x00000003
223.300728 read32 #3 +0x00100c24 -> 0x00000004
223.300754 write32 #3 +0x00100c24 <- 0x000027fd
base = (0x70000000 + 0x10000000) - ((0x27ff + 1) << 5)
base = 0x7ffb0040 << in carveout
223.300780 read32 #3 +0x00100c14 -> 0x00000003
223.300806 write32 #3 +0x00100c14 <- 0x00010003
It's a bit tricky at that point in the nouveau init process to
allocate device memory, but, we already reserve 1MiB of memory at the
end of "VRAM" (carveout / stolen memory) so we can make use of that.
I've attached 3 patches. The first two of them, I'll probably merge as-is.
The third patch is an example of how this should probably be done, in
case you want to continue tackling this some more :)
Cheers,
Ben.
>
> Signed-off-by: Pierre Moreau <pierre.morrow at free.fr>
> ---
> drm/core/subdev/fb/nvaa.h | 1 +
> nvkm/subdev/fb/nv50.h | 4 +++
> nvkm/subdev/fb/nvaa.c | 74 ++++++++++++++++++++++++++++++++++++++++++++---
> nvkm/subdev/fb/nvaa.h | 19 ++++++++++++
> 4 files changed, 94 insertions(+), 4 deletions(-)
> create mode 120000 drm/core/subdev/fb/nvaa.h
> create mode 100644 nvkm/subdev/fb/nvaa.h
>
> diff --git a/drm/core/subdev/fb/nvaa.h b/drm/core/subdev/fb/nvaa.h
> new file mode 120000
> index 0000000..b450e8c
> --- /dev/null
> +++ b/drm/core/subdev/fb/nvaa.h
> @@ -0,0 +1 @@
> +../../../../nvkm/subdev/fb/nvaa.h
> \ No newline at end of file
> diff --git a/nvkm/subdev/fb/nv50.h b/nvkm/subdev/fb/nv50.h
> index c5e5a88..0b20975 100644
> --- a/nvkm/subdev/fb/nv50.h
> +++ b/nvkm/subdev/fb/nv50.h
> @@ -9,6 +9,10 @@ struct nv50_fb_priv {
> dma_addr_t r100c08;
> };
>
> +#define nv50_fb_create(p,e,c,d,o) \
> + nv50_fb_ctor((p), (e), (c), (d), sizeof(**o), \
> + (struct nouveau_object **)o)
> +
> int nv50_fb_ctor(struct nouveau_object *, struct nouveau_object *,
> struct nouveau_oclass *, void *, u32,
> struct nouveau_object **);
> diff --git a/nvkm/subdev/fb/nvaa.c b/nvkm/subdev/fb/nvaa.c
> index cba8e68..b70ab2f 100644
> --- a/nvkm/subdev/fb/nvaa.c
> +++ b/nvkm/subdev/fb/nvaa.c
> @@ -22,15 +22,81 @@
> * Authors: Ben Skeggs
> */
>
> -#include "nv50.h"
> +#include "nvaa.h"
> +
> +int
> +nvaa_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
> + struct nouveau_oclass *oclass, void *data, u32 size,
> + struct nouveau_object **pobject)
> +{
> + struct nouveau_device *device = nv_device(parent);
> + struct nvaa_fb_priv *priv;
> + int ret;
> +
> + ret = nv50_fb_create(parent, engine, oclass, data, &priv);
> + *pobject = nv_object(priv);
> + if (ret)
> + return ret;
> +
> + priv = (struct nvaa_fb_priv *)(*pobject);
> +
> + priv->r100c18_page = alloc_page(GFP_KERNEL | __GFP_ZERO);
> + if (priv->r100c18_page) {
> + priv->r100c18 = dma_map_page(nv_device_base(device),
> + priv->r100c18_page, 0, PAGE_SIZE,
> + DMA_BIDIRECTIONAL);
> + if (dma_mapping_error(nv_device_base(device), priv->r100c18))
> + return -EFAULT;
> + } else {
> + nv_warn(priv, "failed 0x100c18 page alloc\n");
> + }
> + return 0;
> +}
> +
> +void
> +nvaa_fb_dtor(struct nouveau_object *object)
> +{
> + struct nouveau_device *device = nv_device(object);
> + struct nvaa_fb_priv *priv = (void *)object;
> +
> + if (priv->r100c18_page) {
> + dma_unmap_page(nv_device_base(device), priv->r100c18, PAGE_SIZE,
> + DMA_BIDIRECTIONAL);
> + __free_page(priv->r100c18_page);
> + }
> +
> + nv50_fb_dtor(object);
> +}
> +
> +int
> +nvaa_fb_init(struct nouveau_object *object)
> +{
> + struct nvaa_fb_priv *priv = (void *)object;
> + int ret;
> +
> + ret = nv50_fb_init(object);
> + if (ret)
> + return ret;
> +
> + /* Enable NISO poller for various clients and set their associated
> + * read address, only for MCP77/78 and MCP79/7A. (fd#25701)
> + */
> + nv_wr32(priv, 0x100c18, priv->r100c18 >> 8);
> + nv_mask(priv, 0x100c14, 0x00000000, 0x00000001);
> + nv_wr32(priv, 0x100c1c, (priv->r100c18 >> 8) + 1);
> + nv_mask(priv, 0x100c14, 0x00000000, 0x00000002);
> + nv_wr32(priv, 0x100c24, (priv->r100c18 >> 8) + 2);
> + nv_mask(priv, 0x100c14, 0x00000000, 0x00010000);
> + return 0;
> +}
>
> struct nouveau_oclass *
> nvaa_fb_oclass = &(struct nv50_fb_impl) {
> .base.base.handle = NV_SUBDEV(FB, 0xaa),
> .base.base.ofuncs = &(struct nouveau_ofuncs) {
> - .ctor = nv50_fb_ctor,
> - .dtor = nv50_fb_dtor,
> - .init = nv50_fb_init,
> + .ctor = nvaa_fb_ctor,
> + .dtor = nvaa_fb_dtor,
> + .init = nvaa_fb_init,
> .fini = _nouveau_fb_fini,
> },
> .base.memtype = nv50_fb_memtype_valid,
> diff --git a/nvkm/subdev/fb/nvaa.h b/nvkm/subdev/fb/nvaa.h
> new file mode 100644
> index 0000000..84e1eca
> --- /dev/null
> +++ b/nvkm/subdev/fb/nvaa.h
> @@ -0,0 +1,19 @@
> +#ifndef __NVKM_FB_NVAA_H__
> +#define __NVKM_FB_NVAA_H__
> +
> +#include "nv50.h"
> +
> +struct nvaa_fb_priv {
> + struct nv50_fb_priv base;
> + struct page *r100c18_page;
> + dma_addr_t r100c18;
> +};
> +
> +int nvaa_fb_ctor(struct nouveau_object *, struct nouveau_object *,
> + struct nouveau_oclass *, void *, u32,
> + struct nouveau_object **);
> +void nvaa_fb_dtor(struct nouveau_object *);
> +int nvaa_fb_init(struct nouveau_object *);
> +
> +
> +#endif
> --
> 2.1.3
>
> _______________________________________________
> Nouveau mailing list
> Nouveau at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/nouveau
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-fb-ram-mcp77-subclass-nouveau_ram.patch
Type: text/x-patch
Size: 2106 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/nouveau/attachments/20141211/06b4b60d/attachment-0003.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0002-fb-ram-mcp77-use-carveout-reg-to-determine-size.patch
Type: text/x-patch
Size: 1261 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/nouveau/attachments/20141211/06b4b60d/attachment-0004.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0003-EXAMPLEfb-ram-mcp77-niso-poller-setup.patch
Type: text/x-patch
Size: 2463 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/nouveau/attachments/20141211/06b4b60d/attachment-0005.bin>
More information about the Nouveau
mailing list