commit 36a6b8ff28418c33c7b13a0e4cef655432028ba6 Author: Pierre Moreau Date: Tue Dec 2 22:22:47 2014 +0100 fb/nvaa: Enable non-isometric poller on NVAA/NVAC diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.h b/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.h index c5e5a88..0b20975 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.h +++ b/drivers/gpu/drm/nouveau/core/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/drivers/gpu/drm/nouveau/core/subdev/fb/nvaa.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nvaa.c index cba8e68..b70ab2f 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/nvaa.c +++ b/drivers/gpu/drm/nouveau/core/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/drivers/gpu/drm/nouveau/core/subdev/fb/nvaa.h b/drivers/gpu/drm/nouveau/core/subdev/fb/nvaa.h new file mode 100644 index 0000000..84e1eca --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/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