new file mode 120000
@@ -0,0 +1 @@
+../../../../nvkm/subdev/fb/nvaa.h
\ No newline at end of file
@@ -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 **);
@@ -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,
new file mode 100644
@@ -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
(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. Signed-off-by: Pierre Moreau <pierre.morrow@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