diff options
| author | Ben Skeggs <bskeggs@redhat.com> | 2015-08-20 14:54:14 +1000 |
|---|---|---|
| committer | Ben Skeggs <bskeggs@redhat.com> | 2015-08-28 12:40:29 +1000 |
| commit | d36a99d2da22bdffebf644e4a5f811e8eff82360 (patch) | |
| tree | 67198dafc31c379c5e9c17e3e86230d59293406d | |
| parent | a8dae9fe0e8ad94de1bb2bfda90d288c1b9eb6e6 (diff) | |
| download | linux-d36a99d2da22bdffebf644e4a5f811e8eff82360.tar.gz linux-d36a99d2da22bdffebf644e4a5f811e8eff82360.tar.bz2 linux-d36a99d2da22bdffebf644e4a5f811e8eff82360.zip | |
drm/nouveau/fb: transition nvkm_ram away from being based on nvkm_object
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
59 files changed, 872 insertions, 1092 deletions
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/mm.h b/drivers/gpu/drm/nouveau/include/nvkm/core/mm.h index 096eb1a623ee..d92fd41e4056 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/mm.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/mm.h @@ -27,7 +27,7 @@ struct nvkm_mm { static inline bool nvkm_mm_initialised(struct nvkm_mm *mm) { - return mm->block_size != 0; + return mm->heap_nodes; } int nvkm_mm_init(struct nvkm_mm *, u32 offset, u32 length, u32 block); @@ -37,4 +37,5 @@ int nvkm_mm_head(struct nvkm_mm *, u8 heap, u8 type, u32 size_max, int nvkm_mm_tail(struct nvkm_mm *, u8 heap, u8 type, u32 size_max, u32 size_min, u32 align, struct nvkm_mm_node **); void nvkm_mm_free(struct nvkm_mm *, struct nvkm_mm_node **); +void nvkm_mm_dump(struct nvkm_mm *, const char *); #endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h index 344cc99f0dc1..f102cf97bb93 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h @@ -18,7 +18,7 @@ #define NV_MEM_TARGET_VM 3 #define NV_MEM_TARGET_GART 4 -#define NV_MEM_TYPE_VM 0x7f +#define NVKM_RAM_TYPE_VM 0x7f #define NV_MEM_COMP_VM 0x03 struct nvkm_mem { @@ -52,9 +52,6 @@ struct nvkm_fb { struct nvkm_ram *ram; - struct nvkm_mm vram; - struct nvkm_mm tags; - struct { struct nvkm_fb_tile region[16]; int regions; @@ -112,36 +109,35 @@ struct nvkm_ram_data { u32 freq; }; +enum nvkm_ram_type { + NVKM_RAM_TYPE_UNKNOWN = 0, + NVKM_RAM_TYPE_STOLEN, + NVKM_RAM_TYPE_SGRAM, + NVKM_RAM_TYPE_SDRAM, + NVKM_RAM_TYPE_DDR1, + NVKM_RAM_TYPE_DDR2, + NVKM_RAM_TYPE_DDR3, + NVKM_RAM_TYPE_GDDR2, + NVKM_RAM_TYPE_GDDR3, + NVKM_RAM_TYPE_GDDR4, + NVKM_RAM_TYPE_GDDR5 +}; + struct nvkm_ram { - struct nvkm_object base; - enum { - NV_MEM_TYPE_UNKNOWN = 0, - NV_MEM_TYPE_STOLEN, - NV_MEM_TYPE_SGRAM, - NV_MEM_TYPE_SDRAM, - NV_MEM_TYPE_DDR1, - NV_MEM_TYPE_DDR2, - NV_MEM_TYPE_DDR3, - NV_MEM_TYPE_GDDR2, - NV_MEM_TYPE_GDDR3, - NV_MEM_TYPE_GDDR4, - NV_MEM_TYPE_GDDR5 - } type; - u64 stolen; + const struct nvkm_ram_func *func; + struct nvkm_fb *fb; + enum nvkm_ram_type type; u64 size; - u32 tags; + +#define NVKM_RAM_MM_SHIFT 12 + struct nvkm_mm vram; + struct nvkm_mm tags; + u64 stolen; int ranks; int parts; int part_mask; - int (*get)(struct nvkm_fb *, u64 size, u32 align, u32 size_nc, - u32 type, struct nvkm_mem **); - void (*put)(struct nvkm_fb *, struct nvkm_mem **); - - int (*calc)(struct nvkm_fb *, u32 freq); - int (*prog)(struct nvkm_fb *); - void (*tidy)(struct nvkm_fb *); u32 freq; u32 mr[16]; u32 mr1_nuts; @@ -151,4 +147,17 @@ struct nvkm_ram { struct nvkm_ram_data xition; struct nvkm_ram_data target; }; + +struct nvkm_ram_func { + void *(*dtor)(struct nvkm_ram *); + int (*init)(struct nvkm_ram *); + + int (*get)(struct nvkm_ram *, u64 size, u32 align, u32 size_nc, + u32 type, struct nvkm_mem **); + void (*put)(struct nvkm_ram *, struct nvkm_mem **); + + int (*calc)(struct nvkm_ram *, u32 freq); + int (*prog)(struct nvkm_ram *); + void (*tidy)(struct nvkm_ram *); +}; #endif diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c index 44e878b5601a..d8999f71a798 100644 --- a/drivers/gpu/drm/nouveau/nouveau_ttm.c +++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c @@ -64,9 +64,9 @@ nouveau_vram_manager_del(struct ttm_mem_type_manager *man, struct ttm_mem_reg *mem) { struct nouveau_drm *drm = nouveau_bdev(man->bdev); - struct nvkm_fb *fb = nvxx_fb(&drm->device); + struct nvkm_ram *ram = nvxx_fb(&drm->device)->ram; nvkm_mem_node_cleanup(mem->mm_node); - fb->ram->put(fb, (struct nvkm_mem **)&mem->mm_node); + ram->func->put(ram, (struct nvkm_mem **)&mem->mm_node); } static int @@ -76,7 +76,7 @@ nouveau_vram_manager_new(struct ttm_mem_type_manager *man, struct ttm_mem_reg *mem) { struct nouveau_drm *drm = nouveau_bdev(man->bdev); - struct nvkm_fb *fb = nvxx_fb(&drm->device); + struct nvkm_ram *ram = nvxx_fb(&drm->device)->ram; struct nouveau_bo *nvbo = nouveau_bo(bo); struct nvkm_mem *node; u32 size_nc = 0; @@ -88,9 +88,9 @@ nouveau_vram_manager_new(struct ttm_mem_type_manager *man, if (nvbo->tile_flags & NOUVEAU_GEM_TILE_NONCONTIG) size_nc = 1 << nvbo->page_shift; - ret = fb->ram->get(fb, mem->num_pages << PAGE_SHIFT, - mem->page_alignment << PAGE_SHIFT, size_nc, - (nvbo->tile_flags >> 8) & 0x3ff, &node); + ret = ram->func->get(ram, mem->num_pages << PAGE_SHIFT, + mem->page_alignment << PAGE_SHIFT, size_nc, + (nvbo->tile_flags >> 8) & 0x3ff, &node); if (ret) { mem->mm_node = NULL; return (ret == -ENOSPC) ? 0 : ret; @@ -103,38 +103,11 @@ nouveau_vram_manager_new(struct ttm_mem_type_manager *man, return 0; } -static void -nouveau_vram_manager_debug(struct ttm_mem_type_manager *man, const char *prefix) -{ - struct nvkm_fb *fb = man->priv; - struct nvkm_mm *mm = &fb->vram; - struct nvkm_mm_node *r; - u32 total = 0, free = 0; - - mutex_lock(&nv_subdev(fb)->mutex); - list_for_each_entry(r, &mm->nodes, nl_entry) { - printk(KERN_DEBUG "%s %d: 0x%010llx 0x%010llx\n", - prefix, r->type, ((u64)r->offset << 12), - (((u64)r->offset + r->length) << 12)); - - total += r->length; - if (!r->type) - free += r->length; - } - mutex_unlock(&nv_subdev(fb)->mutex); - - printk(KERN_DEBUG "%s total: 0x%010llx free: 0x%010llx\n", - prefix, (u64)total << 12, (u64)free << 12); - printk(KERN_DEBUG "%s block: 0x%08x\n", - prefix, mm->block_size << 12); -} - const struct ttm_mem_type_manager_func nouveau_vram_manager = { nouveau_vram_manager_init, nouveau_vram_manager_fini, nouveau_vram_manager_new, nouveau_vram_manager_del, - nouveau_vram_manager_debug }; static int diff --git a/drivers/gpu/drm/nouveau/nvkm/core/mm.c b/drivers/gpu/drm/nouveau/nvkm/core/mm.c index 7f458dfd5608..09a1eee8fd33 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/mm.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/mm.c @@ -26,7 +26,7 @@ #define node(root, dir) ((root)->nl_entry.dir == &mm->nodes) ? NULL : \ list_entry((root)->nl_entry.dir, struct nvkm_mm_node, nl_entry) -static void +void nvkm_mm_dump(struct nvkm_mm *mm, const char *header) { struct nvkm_mm_node *node; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxnv50.c index 69561ee4e115..5bdb112dc945 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxnv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxnv50.c @@ -569,7 +569,7 @@ nv50_gr_construct_mmio(struct nvkm_grctx *ctx) else if (device->chipset < 0xa0) gr_def(ctx, 0x407d08, 0x00390040); else { - if (nvkm_fb(device)->ram->type != NV_MEM_TYPE_GDDR5) + if (nvkm_fb(device)->ram->type != NVKM_RAM_TYPE_GDDR5) gr_def(ctx, 0x407d08, 0x003d0040); else gr_def(ctx, 0x407d08, 0x003c0040); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c index a05ec57150c6..cfd1feed99c3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c @@ -174,7 +174,7 @@ static int nvkm_pstate_prog(struct nvkm_clk *clk, int pstatei) { struct nvkm_subdev *subdev = &clk->subdev; - struct nvkm_fb *fb = subdev->device->fb; + struct nvkm_ram *ram = subdev->device->fb->ram; struct nvkm_pstate *pstate; int ret, idx = 0; @@ -186,14 +186,14 @@ nvkm_pstate_prog(struct nvkm_clk *clk, int pstatei) nvkm_debug(subdev, "setting performance state %d\n", pstatei); clk->pstate = pstatei; - if (fb->ram && fb->ram->calc) { + if (ram && ram->func->calc) { int khz = pstate->base.domain[nv_clk_src_mem]; do { - ret = fb->ram->calc(fb, khz); + ret = ram->func->calc(ram, khz); if (ret == 0) - ret = fb->ram->prog(fb); + ret = ram->func->prog(ram); } while (ret > 0); - fb->ram->tidy(fb); + ram->func->tidy(ram); } return nvkm_cstate_prog(clk, pstate, 0); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild index d6be4c6c5408..08105701af7e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild @@ -23,6 +23,8 @@ nvkm-y += nvkm/subdev/fb/gf100.o nvkm-y += nvkm/subdev/fb/gk104.o nvkm-y += nvkm/subdev/fb/gk20a.o nvkm-y += nvkm/subdev/fb/gm107.o + +nvkm-y += nvkm/subdev/fb/ram.o nvkm-y += nvkm/subdev/fb/ramnv04.o nvkm-y += nvkm/subdev/fb/ramnv10.o nvkm-y += nvkm/subdev/fb/ramnv1a.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c index f0a5d197e7a0..328381b8f0ac 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c @@ -22,6 +22,7 @@ * Authors: Ben Skeggs */ #include "priv.h" +#include "ram.h" #include <subdev/bios.h> #include <subdev/bios/M0203.h> @@ -37,32 +38,24 @@ nvkm_fb_bios_memtype(struct nvkm_bios *bios) if (nvbios_M0203Em(bios, ramcfg, &ver, &hdr, &M0203E)) { switch (M0203E.type) { - case M0203E_TYPE_DDR2 : return NV_MEM_TYPE_DDR2; - case M0203E_TYPE_DDR3 : return NV_MEM_TYPE_DDR3; - case M0203E_TYPE_GDDR3: return NV_MEM_TYPE_GDDR3; - case M0203E_TYPE_GDDR5: return NV_MEM_TYPE_GDDR5; + case M0203E_TYPE_DDR2 : return NVKM_RAM_TYPE_DDR2; + case M0203E_TYPE_DDR3 : return NVKM_RAM_TYPE_DDR3; + case M0203E_TYPE_GDDR3: return NVKM_RAM_TYPE_GDDR3; + case M0203E_TYPE_GDDR5: return NVKM_RAM_TYPE_GDDR5; default: nvkm_warn(subdev, "M0203E type %02x\n", M0203E.type); - return NV_MEM_TYPE_UNKNOWN; + return NVKM_RAM_TYPE_UNKNOWN; } } nvkm_warn(subdev, "M0203E not matched!\n"); - return NV_MEM_TYPE_UNKNOWN; + return NVKM_RAM_TYPE_UNKNOWN; } int _nvkm_fb_fini(struct nvkm_object *object, bool suspend) { struct nvkm_fb *fb = (void *)object; - int ret; - - if (fb->ram) { - ret = nv_ofuncs(fb->ram)->fini(nv_object(fb->ram), suspend); - if (ret && suspend) - return ret; - } - return nvkm_subdev_fini(&fb->subdev, suspend); } @@ -76,11 +69,8 @@ _nvkm_fb_init(struct nvkm_object *object) if (ret) return ret; - if (fb->ram) { - ret = nv_ofuncs(fb->ram)->init(nv_object(fb->ram)); - if (ret) - return ret; - } + if (fb->ram) + nvkm_ram_init(fb->ram); for (i = 0; i < fb->tile.regions; i++) fb->tile.prog(fb, i, &fb->tile.region[i]); @@ -96,13 +86,8 @@ _nvkm_fb_dtor(struct nvkm_object *object) for (i = 0; i < fb->tile.regions; i++) fb->tile.fini(fb, i, &fb->tile.region[i]); - nvkm_mm_fini(&fb->tags); - - if (fb->ram) { - nvkm_mm_fini(&fb->vram); - nvkm_object_ref(NULL, (struct nvkm_object **)&fb->ram); - } + nvkm_ram_del(&fb->ram); nvkm_subdev_destroy(&fb->subdev); } @@ -111,20 +96,6 @@ nvkm_fb_create_(struct nvkm_object *parent, struct nvkm_object *engine, struct nvkm_oclass *oclass, int length, void **pobject) { struct nvkm_fb_impl *impl = (void *)oclass; - static const char *name[] = { - [NV_MEM_TYPE_UNKNOWN] = "of unknown memory type", - [NV_MEM_TYPE_STOLEN ] = "stolen system memory", - [NV_MEM_TYPE_SGRAM ] = "SGRAM", - [NV_MEM_TYPE_SDRAM ] = "SDRAM", - [NV_MEM_TYPE_DDR1 ] = "DDR1", - [NV_MEM_TYPE_DDR2 ] = "DDR2", - [NV_MEM_TYPE_DDR3 ] = "DDR3", - [NV_MEM_TYPE_GDDR2 ] = "GDDR2", - [NV_MEM_TYPE_GDDR3 ] = "GDDR3", - [NV_MEM_TYPE_GDDR4 ] = "GDDR4", - [NV_MEM_TYPE_GDDR5 ] = "GDDR5", - }; - struct nvkm_object *ram; struct nvkm_fb *fb; int ret; @@ -136,33 +107,14 @@ nvkm_fb_create_(struct nvkm_object *parent, struct nvkm_object *engine, fb->memtype_valid = impl->memtype; - if (!impl->ram) + if (!impl->ram_new) return 0; - ret = nvkm_object_ctor(nv_object(fb), NULL, impl->ram, NULL, 0, &ram); + ret = impl->ram_new(fb, &fb->ram); if (ret) { nvkm_error(&fb->subdev, "vram init failed, %d\n", ret); return ret; } - fb->ram = (void *)ram; - - if (!nvkm_mm_initialised(&fb->vram)) { - ret = nvkm_mm_init(&fb->vram, 0, fb->ram->size >> 12, 1); - if (ret) - return ret; - } - - if (!nvkm_mm_initialised(&fb->tags)) { - ret = nvkm_mm_init(&fb->tags, 0, fb->ram->tags ? - ++fb->ram->tags : 0, 1); - if (ret) - return ret; - - nvkm_debug(&fb->subdev, "%d compression tags\n", fb->ram->tags); - } - - nvkm_info(&fb->subdev, "%d MiB %s\n", (int)(fb->ram->size >> 20), - name[fb->ram->type]); return 0; } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/g84.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/g84.c index 6c968d1e98b3..1fdb6c3493c6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/g84.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/g84.c @@ -22,6 +22,7 @@ * Authors: Ben Skeggs */ #include "nv50.h" +#include "ram.h" struct nvkm_oclass * g84_fb_oclass = &(struct nv50_fb_impl) { @@ -33,6 +34,6 @@ g84_fb_oclass = &(struct nv50_fb_impl) { .fini = _nvkm_fb_fini, }, .base.memtype = nv50_fb_memtype_valid, - .base.ram = &nv50_ram_oclass, + .base.ram_new = nv50_ram_new, .trap = 0x001d07ff, }.base.base; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c index 4465446c8063..79b523aa52aa 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c @@ -22,7 +22,7 @@ * Authors: Ben Skeggs <bskeggs@redhat.com> * Roy Spliet <rspliet@eclipso.eu> */ -#include "priv.h" +#include "ram.h" struct ramxlat { int id; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr5.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr5.c index f6f9eee1dcd0..24f83b09e6a1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr5.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr5.c @@ -21,7 +21,7 @@ * * Authors: Ben Skeggs <bskeggs@redhat.com> */ -#include "priv.h" +#include "ram.h" /* binary driver only executes this path if the condition (a) is true * for any configuration (combination of rammap+ramcfg+timing) that diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c index 1ac7d746e476..b269f8f67eea 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c @@ -22,6 +22,7 @@ * Authors: Ben Skeggs */ #include "gf100.h" +#include "ram.h" extern const u8 gf100_pte_storage_type_map[256]; @@ -113,5 +114,5 @@ gf100_fb_oclass = &(struct nvkm_fb_impl) { .fini = _nvkm_fb_fini, }, .memtype = gf100_fb_memtype_valid, - .ram = &gf100_ram_oclass, + .ram_new = gf100_ram_new, }.base; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.h b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.h index add84641cd81..a0f6497d7a3f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.h @@ -1,7 +1,6 @@ #ifndef __NVKM_RAM_NVC0_H__ #define __NVKM_RAM_NVC0_H__ #include "priv.h" -#include "nv50.h" struct gf100_fb { struct nvkm_fb base; @@ -15,14 +14,4 @@ int gf100_fb_ctor(struct nvkm_object *, struct nvkm_object *, void gf100_fb_dtor(struct nvkm_object *); int gf100_fb_init(struct nvkm_object *); bool gf100_fb_memtype_valid(struct nvkm_fb *, u32); - -#define gf100_ram_create(p,e,o,m,d) \ - gf100_ram_create_((p), (e), (o), (m), sizeof(**d), (void **)d) -int gf100_ram_create_(struct nvkm_object *, struct nvkm_object *, - struct nvkm_oclass *, u32, int, void **); -int gf100_ram_get(struct nvkm_fb *, u64, u32, u32, u32, - struct nvkm_mem **); -void gf100_ram_put(struct nvkm_fb *, struct nvkm_mem **); - -int gk104_ram_init(struct nvkm_object*); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.c index 1c08317665bb..6ed6181a7b34 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.c @@ -22,6 +22,7 @@ * Authors: Ben Skeggs */ #include "gf100.h" +#include "ram.h" struct nvkm_oclass * gk104_fb_oclass = &(struct nvkm_fb_impl) { @@ -33,5 +34,5 @@ gk104_fb_oclass = &(struct nvkm_fb_impl) { .fini = _nvkm_fb_fini, }, .memtype = gf100_fb_memtype_valid, - .ram = &gk104_ram_oclass, + .ram_new = gk104_ram_new, }.base; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm107.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm107.c index 843f9356b360..71e3bd50848a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm107.c @@ -22,6 +22,7 @@ * Authors: Ben Skeggs |
