Commit d36a99d2 authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau/fb: transition nvkm_ram away from being based on nvkm_object

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent a8dae9fe
......@@ -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
......@@ -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
......@@ -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
......
......@@ -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;
......
......@@ -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);
......
......@@ -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);
......
......@@ -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
......
......@@ -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;
}
......@@ -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;
......@@ -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;
......
......@@ -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
......
......@@ -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;
#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
......@@ -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;
......@@ -22,6 +22,7 @@
* Authors: Ben Skeggs
*/
#include "gf100.h"
#include "ram.h"
struct nvkm_oclass *
gm107_fb_oclass = &(struct nvkm_fb_impl) {
......@@ -33,5 +34,5 @@ gm107_fb_oclass = &(struct nvkm_fb_impl) {
.fini = _nvkm_fb_fini,
},
.memtype = gf100_fb_memtype_valid,
.ram = &gm107_ram_oclass,
.ram_new = gm107_ram_new,
}.base;
......@@ -22,6 +22,7 @@
* Authors: Ben Skeggs
*/
#include "nv50.h"
#include "ram.h"
struct nvkm_oclass *
gt215_fb_oclass = &(struct nv50_fb_impl) {
......@@ -33,6 +34,6 @@ gt215_fb_oclass = &(struct nv50_fb_impl) {
.fini = _nvkm_fb_fini,
},
.base.memtype = nv50_fb_memtype_valid,
.base.ram = &gt215_ram_oclass,
.base.ram_new = gt215_ram_new,
.trap = 0x000d0fff,
}.base.base;
......@@ -22,6 +22,7 @@
* Authors: Ben Skeggs
*/
#include "nv50.h"
#include "ram.h"
struct nvkm_oclass *
mcp77_fb_oclass = &(struct nv50_fb_impl) {
......@@ -33,6 +34,6 @@ mcp77_fb_oclass = &(struct nv50_fb_impl) {
.fini = _nvkm_fb_fini,
},
.base.memtype = nv50_fb_memtype_valid,
.base.ram = &mcp77_ram_oclass,
.base.ram_new = mcp77_ram_new,
.trap = 0x001d07ff,
}.base.base;
......@@ -22,6 +22,7 @@
* Authors: Ben Skeggs
*/
#include "nv50.h"
#include "ram.h"
struct nvkm_oclass *
mcp89_fb_oclass = &(struct nv50_fb_impl) {
......@@ -33,6 +34,6 @@ mcp89_fb_oclass = &(struct nv50_fb_impl) {
.fini = _nvkm_fb_fini,
},
.base.memtype = nv50_fb_memtype_valid,
.base.ram = &mcp77_ram_oclass,
.base.ram_new = mcp77_ram_new,
.trap = 0x089d1fff,
}.base.base;
......@@ -22,6 +22,7 @@
* Authors: Ben Skeggs
*/
#include "nv04.h"
#include "ram.h"
#include "regsnv04.h"
bool
......@@ -84,5 +85,5 @@ nv04_fb_oclass = &(struct nv04_fb_impl) {
.fini = _nvkm_fb_fini,
},
.base.memtype = nv04_fb_memtype_valid,
.base.ram = &nv04_ram_oclass,
.base.ram_new = nv04_ram_new,
}.base.base;
......@@ -24,6 +24,7 @@
*
*/
#include "nv04.h"
#include "ram.h"
void
nv10_fb_tile_init(struct nvkm_fb *fb, int i, u32 addr, u32 size, u32 pitch,
......@@ -63,7 +64,7 @@ nv10_fb_oclass = &(struct nv04_fb_impl) {
.fini = _nvkm_fb_fini,
},
.base.memtype = nv04_fb_memtype_valid,
.base.ram = &nv10_ram_oclass,
.base.ram_new = nv10_ram_new,
.tile.regions = 8,
.tile.init = nv10_fb_tile_init,
.tile.fini = nv10_fb_tile_fini,
......
......@@ -24,6 +24,7 @@
*
*/
#include "nv04.h"
#include "ram.h"
struct nvkm_oclass *
nv1a_fb_oclass = &(struct nv04_fb_impl) {
......@@ -35,7 +36,7 @@ nv1a_fb_oclass = &(struct nv04_fb_impl) {
.fini = _nvkm_fb_fini,
},
.base.memtype = nv04_fb_memtype_valid,
.base.ram = &nv1a_ram_oclass,
.base.ram_new = nv1a_ram_new,
.tile.regions = 8,
.tile.init = nv10_fb_tile_init,
.tile.fini = nv10_fb_tile_fini,
......
......@@ -24,6 +24,7 @@
*
*/
#include "nv04.h"
#include "ram.h"
void
nv20_fb_tile_init(struct nvkm_fb *fb, int i, u32 addr, u32 size, u32 pitch,
......@@ -44,7 +45,7 @@ nv20_fb_tile_comp(struct nvkm_fb *fb, int i, u32 size, u32 flags,
{
u32 tiles = DIV_ROUND_UP(size, 0x40);
u32 tags = round_up(tiles / fb->ram->parts, 0x40);
if (!nvkm_mm_head(&fb->tags, 0, 1, tags, tags, 1, &tile->tag)) {
if (!nvkm_mm_head(&fb->ram->tags, 0, 1, tags, tags, 1, &tile->tag)) {
if (!(flags & 2)) tile->zcomp = 0x00000000; /* Z16 */
else tile->zcomp = 0x04000000; /* Z24S8 */
tile->zcomp |= tile->tag->offset;
......@@ -62,7 +63,7 @@ nv20_fb_tile_fini(struct nvkm_fb *fb, int i, struct nvkm_fb_tile *tile)
tile->limit = 0;
tile->pitch = 0;
tile->zcomp = 0;
nvkm_mm_free(&fb->tags, &tile->tag);
nvkm_mm_free(&fb->ram->tags, &tile->tag);
}
void
......@@ -86,7 +87,7 @@ nv20_fb_oclass = &(struct nv04_fb_impl) {
.fini = _nvkm_fb_fini,
},
.base.memtype = nv04_fb_memtype_valid,
.base.ram = &nv20_ram_oclass,
.base.ram_new = nv20_ram_new,
.tile.regions = 8,
.tile.init = nv20_fb_tile_init,
.tile.comp = nv20_fb_tile_comp,
......
......@@ -24,6 +24,7 @@
*
*/
#include "nv04.h"
#include "ram.h"
static void
nv25_fb_tile_comp(struct nvkm_fb *fb, int i, u32 size, u32 flags,
......@@ -31,7 +32,7 @@ nv25_fb_tile_comp(struct nvkm_fb *fb, int i, u32 size, u32 flags,
{
u32 tiles = DIV_ROUND_UP(size, 0x40);
u32 tags = round_up(tiles / fb->ram->parts, 0x40);
if (!nvkm_mm_head(&fb->tags, 0, 1, tags, tags, 1, &tile->tag)) {
if (!nvkm_mm_head(&fb->ram->tags, 0, 1, tags, tags, 1, &tile->tag)) {
if (!(flags & 2)) tile->zcomp = 0x00100000; /* Z16 */
else tile->zcomp = 0x00200000; /* Z24S8 */
tile->zcomp |= tile->tag->offset;
......@@ -51,7 +52,7 @@ nv25_fb_oclass = &(struct nv04_fb_impl) {
.fini = _nvkm_fb_fini,
},
.base.memtype = nv04_fb_memtype_valid,
.base.ram = &nv20_ram_oclass,
.base.ram_new = nv20_ram_new,
.tile.regions = 8,
.tile.init = nv20_fb_tile_init,
.tile.comp = nv25_fb_tile_comp,
......
......@@ -24,6 +24,7 @@
*
*/
#include "nv04.h"
#include "ram.h"
void
nv30_fb_tile_init(struct nvkm_fb *fb, int i, u32 addr, u32 size, u32 pitch,
......@@ -50,7 +51,7 @@ nv30_fb_tile_comp(struct nvkm_fb *fb, int i, u32 size, u32 flags,
{
u32 tiles = DIV_ROUND_UP(size, 0x40);
u32 tags = round_up(tiles / fb->ram->parts, 0x40);
if (!nvkm_mm_head(&fb->tags, 0, 1, tags, tags, 1, &tile->tag)) {
if (!nvkm_mm_head(&fb->ram->tags, 0, 1, tags, tags, 1, &tile->tag)) {
if (flags & 2) tile->zcomp |= 0x01000000; /* Z16 */
else tile->zcomp |= 0x02000000; /* Z24S8 */
tile->zcomp |= ((tile->tag->offset ) >> 6);
......@@ -130,7 +131,7 @@ nv30_fb_oclass = &(struct nv04_fb_impl) {
.fini = _nvkm_fb_fini,
},
.base.memtype = nv04_fb_memtype_valid,
.base.ram = &nv20_ram_oclass,
.base.ram_new = nv20_ram_new,
.tile.regions = 8,
.tile.init = nv30_fb_tile_init,
.tile.comp = nv30_fb_tile_comp,
......
......@@ -24,6 +24,7 @@
*
*/
#include "nv04.h"
#include "ram.h"
static void
nv35_fb_tile_comp(struct nvkm_fb *fb, int i, u32 size, u32 flags,
......@@ -31,7 +32,7 @@ nv35_fb_tile_comp(struct nvkm_fb *fb, int i, u32 size, u32 flags,
{
u32 tiles = DIV_ROUND_UP(size, 0x40);
u32 tags = round_up(tiles / fb->ram->parts, 0x40);
if (!nvkm_mm_head(&fb->tags, 0, 1, tags, tags, 1, &tile->tag)) {
if (!nvkm_mm_head(&fb->ram->tags, 0, 1, tags, tags, 1, &tile->tag)) {
if (flags & 2) tile->zcomp |= 0x04000000; /* Z16 */
else tile->zcomp |= 0x08000000; /* Z24S8 */
tile->zcomp |= ((tile->tag->offset ) >> 6);
......@@ -52,7 +53,7 @@ nv35_fb_oclass = &(struct nv04_fb_impl) {
.fini = _nvkm_fb_fini,
},
.base.memtype = nv04_fb_memtype_valid,
.base.ram = &nv20_ram_oclass,
.base.ram_new = nv20_ram_new,
.tile.regions = 8,
.tile.init = nv30_fb_tile_init,
.tile.comp = nv35_fb_tile_comp,
......
......@@ -24,6 +24,7 @@
*
*/
#include "nv04.h"
#include "ram.h"
static void
nv36_fb_tile_comp(struct nvkm_fb *fb, int i, u32 size, u32 flags,
......@@ -31,7 +32,7 @@ nv36_fb_tile_comp(struct nvkm_fb *fb, int i, u32 size, u32 flags,
{
u32 tiles = DIV_ROUND_UP(size, 0x40);
u32 tags = round_up(tiles / fb->ram->parts, 0x40);
if (!nvkm_mm_head(&fb->tags, 0, 1, tags, tags, 1, &tile->tag)) {
if (!nvkm_mm_head(&fb->ram->tags, 0, 1, tags, tags, 1, &tile->tag)) {
if (flags & 2) tile->zcomp |= 0x10000000; /* Z16 */
else tile->zcomp |= 0x20000000; /* Z24S8 */
tile->zcomp |= ((tile->tag->offset ) >> 6);
......@@ -52,7 +53,7 @@ nv36_fb_oclass = &(struct nv04_fb_impl) {
.fini = _nvkm_fb_fini,
},
.base.memtype = nv04_fb_memtype_valid,
.base.ram = &nv20_ram_oclass,
.base.ram_new = nv20_ram_new,
.tile.regions = 8,
.tile.init = nv30_fb_tile_init,
.tile.comp = nv36_fb_tile_comp,
......
......@@ -24,6 +24,7 @@
*
*/
#include "nv04.h"
#include "ram.h"
void
nv40_fb_tile_comp(struct nvkm_fb *fb, int i, u32 size, u32 flags,
......@@ -32,7 +33,7 @@ nv40_fb_tile_comp(struct nvkm_fb *fb, int i, u32 size, u32 flags,
u32 tiles = DIV_ROUND_UP(size, 0x80);
u32 tags = round_up(tiles / fb->ram->parts, 0x100);
if ( (flags & 2) &&
!nvkm_mm_head(&fb->tags, 0, 1, tags, tags, 1, &tile->tag)) {
!nvkm_mm_head(&fb->ram->tags, 0, 1, tags, tags, 1, &tile->tag)) {
tile->zcomp = 0x28000000; /* Z24S8_SPLIT_GRAD */
tile->zcomp |= ((tile->tag->offset ) >> 8);
tile->zcomp |= ((tile->tag->offset + tags - 1) >> 8) << 13;
......@@ -67,7 +68,7 @@ nv40_fb_oclass = &(struct nv04_fb_impl) {
.fini = _nvkm_fb_fini,
},
.base.memtype = nv04_fb_memtype_valid,
.base.ram = &nv40_ram_oclass,
.base.ram_new = nv40_ram_new,
.tile.regions = 8,
.tile.init = nv30_fb_tile_init,
.tile.comp = nv40_fb_tile_comp,
......
#ifndef __NVKM_FB_NV40_H__
#define __NVKM_FB_NV40_H__
#include "priv.h"
struct nv40_ram {
struct nvkm_ram base;
u32 ctrl;
u32 coef;
};
int nv40_ram_calc(struct nvkm_fb *, u32);
int nv40_ram_prog(struct nvkm_fb *);
void nv40_ram_tidy(struct nvkm_fb *);
#endif
......@@ -24,6 +24,7 @@
*
*/
#include "nv04.h"
#include "ram.h"
void
nv41_fb_tile_prog(struct nvkm_fb *fb, int i, struct nvkm_fb_tile *tile)
......@@ -61,7 +62,7 @@ nv41_fb_oclass = &(struct nv04_fb_impl) {
.fini = _nvkm_fb_fini,
},
.base.memtype = nv04_fb_memtype_valid,
.base.ram = &nv41_ram_oclass,
.base.ram_new = nv41_ram_new,
.tile.regions = 12,
.tile.init = nv30_fb_tile_init,
.tile.comp = nv40_fb_tile_comp,
......
......@@ -24,6 +24,7 @@
*
*/
#include "nv04.h"
#include "ram.h"
static void
nv44_fb_tile_init(struct nvkm_fb *fb, int i, u32 addr, u32 size, u32 pitch,
......@@ -71,7 +72,7 @@ nv44_fb_oclass = &(struct nv04_fb_impl) {
.fini = _nvkm_fb_fini,
},
.base.memtype = nv04_fb_memtype_valid,
.base.ram = &nv44_ram_oclass,
.base.ram_new = nv44_ram_new,
.tile.regions = 12,
.tile.init = nv44_fb_tile_init,
.tile.fini = nv20_fb_tile_fini,
......
......@@ -24,6 +24,7 @@
*
*/
#include "nv04.h"
#include "ram.h"
void
nv46_fb_tile_init(struct nvkm_fb *fb, int i, u32 addr, u32 size, u32 pitch,
......@@ -49,7 +50,7 @@ nv46_fb_oclass = &(struct nv04_fb_impl) {
.fini = _nvkm_fb_fini,
},
.base.memtype = nv04_fb_memtype_valid,
.base.ram = &nv44_ram_oclass,
.base.ram_new = nv44_ram_new,
.tile.regions = 15,
.tile.init = nv46_fb_tile_init,
.tile.fini = nv20_fb_tile_fini,
......
......@@ -24,6 +24,7 @@
*
*/
#include "nv04.h"
#include "ram.h"
struct nvkm_oclass *
nv47_fb_oclass = &(struct nv04_fb_impl) {
......@@ -35,7 +36,7 @@ nv47_fb_oclass = &(struct nv04_fb_impl) {
.fini = _nvkm_fb_fini,
},
.base.memtype = nv04_fb_memtype_valid,
.base.ram = &nv41_ram_oclass,
.base.ram_new = nv41_ram_new,
.tile.regions = 15,
.tile.init = nv30_fb_tile_init,
.tile.comp = nv40_fb_tile_comp,
......
......@@ -24,6 +24,7 @@
*
*/
#include "nv04.h"
#include "ram.h"
struct nvkm_oclass *
nv49_fb_oclass = &(struct nv04_fb_impl) {
......@@ -35,7 +36,7 @@ nv49_fb_oclass = &(struct nv04_fb_impl) {
.fini = _nvkm_fb_fini,
},
.base.memtype = nv04_fb_memtype_valid,
.base.ram = &nv49_ram_oclass,
.base.ram_new = nv49_ram_new,
.tile.regions = 15,
.tile.init = nv30_fb_tile_init,
.tile.comp = nv40_fb_tile_comp,
......
......@@ -24,6 +24,7 @@
*
*/
#include "nv04.h"
#include "ram.h"
struct nvkm_oclass *
nv4e_fb_oclass = &(struct nv04_fb_impl) {
......@@ -35,7 +36,7 @@ nv4e_fb_oclass = &(struct nv04_fb_impl) {
.fini = _nvkm_fb_fini,
},
.base.memtype = nv04_fb_memtype_valid,
.base.ram = &nv4e_ram_oclass,
.base.ram_new = nv4e_ram_new,
.tile.regions = 12,
.tile.init = nv46_fb_tile_init,
.tile.fini = nv20_fb_tile_fini,
......
......@@ -22,6 +22,7 @@
* Authors: Ben Skeggs
*/
#include "nv50.h"
#include "ram.h"
#include <core/client.h>
#include <core/engctx.h>
......@@ -299,6 +300,6 @@ nv50_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 = 0x000707ff,
}.base.base;
......@@ -19,13 +19,5 @@ struct nv50_fb_impl {
u32 trap;
};
#define nv50_ram_create(p,e,o,d) \
nv50_ram_create_((p), (e), (o), sizeof(**d), (void **)d)
int nv50_ram_create_(struct nvkm_object *, struct nvkm_object *,
struct nvkm_oclass *, int, void **);
int nv50_ram_get(struct nvkm_fb *, u64 size, u32 align, u32 ncmin,
u32 memtype, struct nvkm_mem **);
void nv50_ram_put(struct nvkm_fb *, struct nvkm_mem **);
void __nv50_ram_put(struct nvkm_fb *, struct nvkm_mem *);
extern int nv50_fb_memtype[0x80];
#endif
......@@ -3,42 +3,6 @@
#include <subdev/fb.h>
struct nvkm_bios;
#define nvkm_ram_create(p,e,o,d) \
nvkm_object_create_((p), (e), (o), 0, sizeof(**d), (void **)d)
#define nvkm_ram_destroy(p) \
nvkm_object_destroy(&(p)->base)
#define nvkm_ram_init(p) \
nvkm_object_init(&(p)->base)
#define nvkm_ram_fini(p,s) \
nvkm_object_fini(&(p)->base, (s))
#define nvkm_ram_create_(p,e,o,s,d) \
nvkm_object_create_((p), (e), (o), 0, (s), (void **)d)
#define _nvkm_ram_dtor nvkm_object_destroy
#define _nvkm_ram_init nvkm_object_init
#define _nvkm_ram_fini nvkm_object_fini
extern struct nvkm_oclass nv04_ram_oclass;
extern struct nvkm_oclass nv10_ram_oclass;
extern struct nvkm_oclass nv1a_ram_oclass;
extern struct nvkm_oclass nv20_ram_oclass;
extern struct nvkm_oclass nv40_ram_oclass;
extern struct nvkm_oclass nv41_ram_oclass;
extern struct nvkm_oclass nv44_ram_oclass;
extern struct nvkm_oclass nv49_ram_oclass;
extern struct nvkm_oclass nv4e_ram_oclass;
extern struct nvkm_oclass nv50_ram_oclass;
extern struct nvkm_oclass gt215_ram_oclass;
extern struct nvkm_oclass mcp77_ram_oclass;
extern struct nvkm_oclass gf100_ram_oclass;
extern struct nvkm_oclass gk104_ram_oclass;
extern struct nvkm_oclass gm107_ram_oclass;
int nvkm_sddr2_calc(struct nvkm_ram *ram);
int nvkm_sddr3_calc(struct nvkm_ram *ram);
int nvkm_gddr3_calc(struct nvkm_ram *ram);
int nvkm_gddr5_calc(struct nvkm_ram *ram, bool nuts);
#define nvkm_fb_create(p,e,c,d) \
nvkm_fb_create_((p), (e), (c), sizeof(**d), (void **)d)
#define nvkm_fb_destroy(p) ({ \
......@@ -62,7 +26,7 @@ int _nvkm_fb_fini(struct nvkm_object *, bool);
struct nvkm_fb_impl {
struct nvkm_oclass base;
struct nvkm_oclass *ram;
int (*ram_new)(struct nvkm_fb *, struct nvkm_ram **);
bool (*memtype)(struct nvkm_fb *, u32);
};
......
/*
* Copyright 2015 Red Hat Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: Ben Skeggs <bskeggs@redhat.com>
*/
#include "ram.h"
int
nvkm_ram_init(struct nvkm_ram *ram)
{
if (ram->func->init)
return ram->func->init(ram);
return 0;
}
void
nvkm_ram_del(struct nvkm_ram **pram)
{
struct nvkm_ram *ram = *pram;
if (ram && !WARN_ON(!ram->func)) {
if (ram->func->dtor)
*pram = ram->func->dtor(ram);
nvkm_mm_fini(&ram->tags);
nvkm_mm_fini(&ram->vram);
kfree(*pram);
*pram = NULL;
}
}
int
nvkm_ram_ctor(const struct nvkm_ram_func *func, struct nvkm_fb *fb,
enum nvkm_ram_type type, u64 size, u32 tags,
struct nvkm_ram *ram)
{
static const char *name[] = {
[NVKM_RAM_TYPE_UNKNOWN] = "of unknown memory type",
[NVKM_RAM_TYPE_STOLEN ] = "stolen system memory",
[NVKM_RAM_TYPE_SGRAM ] = "SGRAM",
[NVKM_RAM_TYPE_SDRAM ] = "SDRAM",
[NVKM_RAM_TYPE_DDR1 ] = "DDR1",
[NVKM_RAM_TYPE_DDR2 ] = "DDR2",
[NVKM_RAM_TYPE_DDR3 ] = "DDR3",
[NVKM_RAM_TYPE_GDDR2 ] = "GDDR2",
[NVKM_RAM_TYPE_GDDR3 ] = "GDDR3",
[NVKM_RAM_TYPE_GDDR4 ] = "GDDR4",
[NVKM_RAM_TYPE_GDDR5 ] = "GDDR5",
};
struct nvkm_subdev *subdev = &fb->subdev;
int ret;
nvkm_info(subdev, "%d MiB %s\n", (int)(size >> 20), name[type]);
ram->func = func;
ram->fb = fb;
ram->type = type;
ram->size = size;
if (!nvkm_mm_initialised(&ram->vram)) {
ret = nvkm_mm_init(&ram->vram, 0, size >> NVKM_RAM_MM_SHIFT, 1);
if (ret)
return ret;
}
if (!nvkm_mm_initialised(&ram->tags)) {
ret = nvkm_mm_init(&ram->tags, 0, tags ? ++tags : 0, 1);
if (ret)
return ret;
nvkm_debug(subdev, "%d compression tags\n", tags);
}
return 0;
}
int
nvkm_ram_new_(const struct nvkm_ram_func *func, struct nvkm_fb *fb,
enum nvkm_ram_type type, u64 size, u32 tags,
struct nvkm_ram **pram)
{
if (!(*pram = kzalloc(sizeof(**pram), GFP_KERNEL)))
return -ENOMEM;
return nvkm_ram_ctor(func, fb, type, size, tags, *pram);
}
#ifndef __NVKM_FB_RAM_PRIV_H__
#define __NVKM_FB_RAM_PRIV_H__
#include "priv.h"
int nvkm_ram_ctor(const struct nvkm_ram_func *, struct nvkm_fb *,
enum nvkm_ram_type, u64 size, u32 tags,
struct nvkm_ram *);
int nvkm_ram_new_(const struct nvkm_ram_func *, struct nvkm_fb *,
enum nvkm_ram_type, u64 size, u32 tags,
struct nvkm_ram **);
void nvkm_ram_del(struct nvkm_ram **);
int nvkm_ram_init(struct nvkm_ram *);
extern const struct nvkm_ram_func nv04_ram_func;
int nv50_ram_ctor(const struct nvkm_ram_func *, struct nvkm_fb *,
struct nvkm_ram *);
int nv50_ram_get(struct nvkm_ram *, u64, u32, u32, u32, struct nvkm_mem **);
void nv50_ram_put(struct nvkm_ram *, struct nvkm_mem **);
void __nv50_ram_put(struct nvkm_ram *, struct nvkm_mem *);
int gf100_ram_ctor(const struct nvkm_ram_func *, struct nvkm_fb *,
u32, struct nvkm_ram *);
int gf100_ram_get(struct nvkm_ram *, u64, u32, u32, u32, struct nvkm_mem **);
void gf100_ram_put(struct nvkm_ram *, struct nvkm_mem **);
int gk104_ram_init(struct nvkm_ram *ram);
/* RAM type-specific MR calculation routines */
int nvkm_sddr2_calc(struct nvkm_ram *);
int nvkm_sddr3_calc(struct nvkm_ram *);
int nvkm_gddr3_calc(struct nvkm_ram *);
int nvkm_gddr5_calc(struct nvkm_ram *, bool nuts);
int nv04_ram_new(struct nvkm_fb *, struct nvkm_ram **);
int nv10_ram_new(struct nvkm_fb *, struct nvkm_ram **);
int nv1a_ram_new(struct nvkm_fb *, struct nvkm_ram **);
int nv20_ram_new(struct nvkm_fb *, struct nvkm_ram **);
int nv40_ram_new(struct nvkm_fb *, struct nvkm_ram **);
int nv41_ram_new(struct nvkm_fb *, struct nvkm_ram **);
int nv44_ram_new(struct nvkm_fb *, struct nvkm_ram **);
int nv49_ram_new(struct nvkm_fb *, struct nvkm_ram **);
int nv4e_ram_new(struct nvkm_fb *, struct nvkm_ram **);
int nv50_ram_new(struct nvkm_fb *, struct nvkm_ram **);
int gt215_ram_new(struct nvkm_fb *, struct nvkm_ram **);
int mcp77_ram_new(struct nvkm_fb *, struct nvkm_ram **);
int gf100_ram_new(struct nvkm_fb *, struct nvkm_ram **);
int gk104_ram_new(struct nvkm_fb *, struct nvkm_ram **);
int gm107_ram_new(struct nvkm_fb *, struct nvkm_ram **);
#endif
......@@ -21,31 +21,20 @@
*
* Authors: Ben Skeggs
*/
#include "gf100.h"
#include "ram.h"
static int
gm107_ram_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
struct nvkm_oclass *oclass, void *data, u32 size,
struct nvkm_object **pobject)
{
struct nvkm_ram *ram;
int ret;
static const struct nvkm_ram_func
gm107_ram_func = {
.init = gk104_ram_init,
.get = gf100_ram_get,
.put = gf100_ram_put,
};
ret = gf100_ram_create(parent, engine, oclass, 0x021c14, &ram);
*pobject = nv_object(ram);
if (ret)
return ret;
int
gm107_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram)
{
if (!(*pram = kzalloc(sizeof(**pram), GFP_KERNEL)))
return -ENOMEM;
return 0;
return gf100_ram_ctor(&gm107_ram_func, fb, 0x021c14, *pram);
}
struct nvkm_oclass
gm107_ram_oclass = {
.handle = 0,
.ofuncs = &(struct nvkm_ofuncs) {
.ctor = gm107_ram_ctor,
.dtor = _nvkm_ram_dtor,
.init = gk104_ram_init,
.fini = _nvkm_ram_fini,
}
};
......@@ -21,7 +21,8 @@
*
* Authors: Ben Skeggs
*/
#include "nv50.h"
#define mcp77_ram(p) container_of((p), struct mcp77_ram, base)
#include "ram.h"
struct mcp77_ram {
struct nvkm_ram base;
......@@ -29,56 +30,13 @@ struct mcp77_ram {
};
static int
mcp77_ram_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
struct nvkm_oclass *oclass, void *data, u32 datasize,
struct nvkm_object **pobject)
mcp77_ram_init(struct nvkm_ram *base)
{
u32 rsvd_head = ( 256 * 1024); /* vga memory */
u32 rsvd_tail = (1024 * 1024); /* vbios etc */
struct nvkm_fb *fb = nvkm_fb(parent);
struct nvkm_device *device = fb->subdev.device;
struct mcp77_ram *ram;
int ret;
ret = nvkm_ram_create(parent, engine, oclass, &ram);
*pobject = nv_object(fb);
if (ret)
return ret;
ram->base.type = NV_MEM_TYPE_STOLEN;
ram->base.stolen = (u64)nvkm_rd32(device, 0x100e10) << 12;
ram->base.size = (u64)nvkm_rd32(device, 0x100e14) << 12;
rsvd_tail += 0x1000;
ram->poller_base = ram->base.size - rsvd_tail;
ret = nvkm_mm_init(&fb->vram, rsvd_head >> 12,
(ram->base.size - (rsvd_head + rsvd_tail)) >> 12,
1);
if (ret)
return ret;
ram->base.get = nv50_ram_get;
ram->base.put = nv50_ram_put;
return 0;
}
static int
mcp77_ram_init(struct nvkm_object *object)
{
struct nvkm_fb *fb = nvkm_fb(object);
struct nvkm_device *device = fb->subdev.device;
struct mcp77_ram *ram = (void *)object;
int ret;
u64 dniso, hostnb, flush;
ret = nvkm_ram_init(&ram->base);
if (ret)
return ret;
dniso = ((ram->base.size - (ram->poller_base + 0x00)) >> 5) - 1;
hostnb = ((ram->base.size - (ram->poller_base + 0x20)) >> 5) - 1;
flush = ((ram->base.size - (ram->poller_base + 0x40)) >> 5) - 1;
struct mcp77_ram *ram = mcp77_ram(base);
struct nvkm_device *device = ram->base.fb->subdev.device;
u32 dniso = ((ram->base.size - (ram->poller_base + 0x00)) >> 5) - 1;
u32 hostnb = ((ram->base.size - (ram->poller_base + 0x20)) >> 5) - 1;
u32 flush = ((ram->base.size - (ram->poller_base + 0x40)) >> 5) - 1;
/* Enable NISO poller for various clients and set their associated
* read address, only for MCP77/78 and MCP79/7A. (fd#25701)
......@@ -92,12 +50,38 @@ mcp77_ram_init(struct nvkm_object *object)
return 0;
}
struct nvkm_oclass
mcp77_ram_oclass = {
.ofuncs = &(struct nvkm_ofuncs) {
.ctor = mcp77_ram_ctor,
.dtor = _nvkm_ram_dtor,
.init = mcp77_ram_init,
.fini = _nvkm_ram_fini,
},
static const struct nvkm_ram_func
mcp77_ram_func = {
.init = mcp77_ram_init,
.get = nv50_ram_get,
.put = nv50_ram_put,
};
int
mcp77_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram)
{
struct nvkm_device *device = fb->subdev.device;
u32 rsvd_head = ( 256 * 1024); /* vga memory */
u32 rsvd_tail = (1024 * 1024) + 0x1000; /* vbios etc + poller mem */
u64 base = (u64)nvkm_rd32(device, 0x100e10) << 12;
u64 size = (u64)nvkm_rd32(device, 0x100e14) << 12;
struct mcp77_ram *ram;
int ret;
if (!(ram = kzalloc(sizeof(*ram), GFP_KERNEL)))
return -ENOMEM;
*pram = &ram->base;
ret = nvkm_ram_ctor(&mcp77_ram_func, fb, NVKM_RAM_TYPE_STOLEN,
size, 0, &ram->base);
if (ret)
return ret;
ram->poller_base = size - rsvd_tail;
ram->base.stolen = base;
nvkm_mm_fini(&ram->base.vram);
return nvkm_mm_init(&ram->base.vram, rsvd_head >> NVKM_RAM_MM_SHIFT,
(size - rsvd_head - rsvd_tail) >>
NVKM_RAM_MM_SHIFT, 1);
}
......@@ -21,60 +21,45 @@
*
* Authors: Ben Skeggs
*/
#include "priv.h"
#include "ram.h"
#include "regsnv04.h"
static int
nv04_ram_create(struct nvkm_object *parent, struct nvkm_object *engine,
struct nvkm_oclass *oclass, void *data, u32 size,
struct nvkm_object **pobject)
const struct nvkm_ram_func
nv04_ram_func = {
};
int
nv04_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram)
{
struct nvkm_fb *fb = nvkm_fb(parent);
struct nvkm_ram *ram;
struct nvkm_device *device = fb->subdev.device;
u32 boot0 = nvkm_rd32(device, NV04_PFB_BOOT_0);
int ret;
ret = nvkm_ram_create(parent, engine, oclass, &ram);
*pobject = nv_object(ram);
if (ret)
return ret;
u64 size;
enum nvkm_ram_type type;
if (boot0 & 0x00000100) {
ram->size = ((boot0 >> 12) & 0xf) * 2 + 2;
ram->size *= 1024 * 1024;
size = ((boot0 >> 12) & 0xf) * 2 + 2;
size *= 1024 * 1024;
} else {
switch (boot0 & NV04_PFB_BOOT_0_RAM_AMOUNT) {
case NV04_PFB_BOOT_0_RAM_AMOUNT_32MB:
ram->size = 32 * 1024 * 1024;
size = 32 * 1024 * 1024;
break;
case NV04_PFB_BOOT_0_RAM_AMOUNT_16MB:
ram->size = 16 * 1024 * 1024;
size = 16 * 1024 * 1024;
break;
case NV04_PFB_BOOT_0_RAM_AMOUNT_8MB:
ram->size = 8 * 1024 * 1024;
size = 8 * 1024 * 1024;
break;
case NV04_PFB_BOOT_0_RAM_AMOUNT_4MB:
ram->size = 4 * 1024 * 1024;
size = 4 * 1024 * 1024;
break;
}
}
if ((boot0 & 0x00000038) <= 0x10)
ram->type = NV_MEM_TYPE_SGRAM;
type = NVKM_RAM_TYPE_SGRAM;
else
ram->type = NV_MEM_TYPE_SDRAM;
type = NVKM_RAM_TYPE_SDRAM;
return 0;
return nvkm_ram_new_(&nv04_ram_func, fb, type, size, 0, pram);
}
struct nvkm_oclass
nv04_ram_oclass = {
.handle = 0,
.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv04_ram_create,
.dtor = _nvkm_ram_dtor,
.init = _nvkm_ram_init,
.fini = _nvkm_ram_fini,
}
};
......@@ -21,40 +21,20 @@
*
* Authors: Ben Skeggs
*/
#include "priv.h"
#include "ram.h"
static int
nv10_ram_create(struct nvkm_object *parent, struct nvkm_object *engine,
struct nvkm_oclass *oclass, void *data, u32 size,
struct nvkm_object **pobject)
int
nv10_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram)
{
struct nvkm_fb *fb = nvkm_fb(parent);
struct nvkm_ram *ram;
struct nvkm_device *device = fb->subdev.device;
u32 size = nvkm_rd32(device, 0x10020c) & 0xff000000;
u32 cfg0 = nvkm_rd32(device, 0x100200);
int ret;
ret = nvkm_ram_create(parent, engine, oclass, &ram);
*pobject = nv_object(ram);
if (ret)
return ret;
enum nvkm_ram_type type;
if (cfg0 & 0x00000001)
ram->type = NV_MEM_TYPE_DDR1;
type = NVKM_RAM_TYPE_DDR1;
else
ram->type = NV_MEM_TYPE_SDRAM;
type = NVKM_RAM_TYPE_SDRAM;
ram->size = nvkm_rd32(device, 0x10020c) & 0xff000000;
return 0;
return nvkm_ram_new_(&nv04_ram_func, fb, type, size, 0, pram);
}
struct nvkm_oclass
nv10_ram_oclass = {
.handle = 0,
.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv10_ram_create,
.dtor = _nvkm_ram_dtor,
.init = _nvkm_ram_init,
.fini = _nvkm_ram_fini,
}
};
......@@ -21,18 +21,13 @@
*
* Authors: Ben Skeggs
*/
#include "priv.h"
#include "ram.h"
static int
nv1a_ram_create(struct nvkm_object *parent, struct nvkm_object *engine,
struct nvkm_oclass *oclass, void *data, u32 size,
struct nvkm_object **pobject)
int
nv1a_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram)
{
struct nvkm_fb *fb = nvkm_fb(parent);
struct nvkm_ram *ram;
struct pci_dev *bridge;
u32 mem, mib;
int ret;
bridge = pci_get_bus_and_slot(0, PCI_DEVFN(0, 1));
if (!bridge) {
......@@ -40,12 +35,7 @@ nv1a_ram_create(struct nvkm_object *parent, struct nvkm_object *engine,
return -ENODEV;
}
ret = nvkm_ram_create(parent, engine, oclass, &ram);
*pobject = nv_object(ram);
if (ret)
return ret;
if (nv_device(fb)->chipset == 0x1a) {
if (fb->subdev.device->chipset == 0x1a) {
pci_read_config_dword(bridge, 0x7c, &mem);
mib = ((mem >> 6) & 31) + 1;
} else {
......@@ -53,18 +43,6 @@ nv1a_ram_create(struct nvkm_object *parent, struct nvkm_object *engine,
mib = ((mem >> 4) & 127) + 1;
}
ram->type = NV_MEM_TYPE_STOLEN;
ram->size = mib * 1024 * 1024;
return 0;
return nvkm_ram_new_(&nv04_ram_func, fb, NVKM_RAM_TYPE_STOLEN,
mib * 1024 * 1024, 0, pram);
}
struct nvkm_oclass
nv1a_ram_oclass = {
.handle = 0,
.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv1a_ram_create,
.dtor = _nvkm_ram_dtor,
.init = _nvkm_ram_init,
.fini = _nvkm_ram_fini,
}
};
......@@ -21,43 +21,29 @@
*
* Authors: Ben Skeggs
*/
#include "priv.h"
#include "ram.h"
static int
nv20_ram_create(struct nvkm_object *parent, struct nvkm_object *engine,
struct nvkm_oclass *oclass, void *data, u32 size,
struct nvkm_object **pobject)
int
nv20_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram)
{
struct nvkm_fb *fb = nvkm_fb(parent);
struct nvkm_ram *ram;
struct nvkm_device *device = fb->subdev.device;
u32 pbus1218 = nvkm_rd32(device, 0x001218);
u32 pbus1218 = nvkm_rd32(device, 0x001218);
u32 size = (nvkm_rd32(device, 0x10020c) & 0xff000000);
u32 tags = nvkm_rd32(device, 0x100320);
enum nvkm_ram_type type = NVKM_RAM_TYPE_UNKNOWN;
int ret;
ret = nvkm_ram_create(parent, engine, oclass, &ram);
*pobject = nv_object(ram);
switch (pbus1218 & 0x00000300) {
case 0x00000000: type = NVKM_RAM_TYPE_SDRAM; break;
case 0x00000100: type = NVKM_RAM_TYPE_DDR1 ; break;
case 0x00000200: type = NVKM_RAM_TYPE_GDDR3; break;
case 0x00000300: type = NVKM_RAM_TYPE_GDDR2; break;
}
ret = nvkm_ram_new_(&nv04_ram_func, fb, type, size, tags, pram);
if (ret)
return ret;
switch (pbus1218 & 0x00000300) {
case 0x00000000: ram->type = NV_MEM_TYPE_SDRAM; break;
case 0x00000100: ram->type = NV_MEM_TYPE_DDR1; break;
case 0x00000200: ram->type = NV_MEM_TYPE_GDDR3; break;
case 0x00000300: ram->type = NV_MEM_TYPE_GDDR2; break;
}
ram->size = (nvkm_rd32(device, 0x10020c) & 0xff000000);
ram->parts = (nvkm_rd32(device, 0x100200) & 0x00000003) + 1;
ram->tags = nvkm_rd32(device, 0x100320);
(*pram)->parts = (nvkm_rd32(device, 0x100200) & 0x00000003) + 1;
return 0;
}
struct nvkm_oclass
nv20_ram_oclass = {
.handle = 0,
.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv20_ram_create,
.dtor = _nvkm_ram_dtor,
.init = _nvkm_ram_init,
.fini = _nvkm_ram_fini,
}
};
......@@ -21,7 +21,7 @@
*
* Authors: Ben Skeggs
*/
#include "nv40.h"
#include "ramnv40.h"
#include <subdev/bios.h>
#include <subdev/bios/bit.h>
......@@ -30,12 +30,12 @@
#include <subdev/clk/pll.h>
#include <subdev/timer.h>
int
nv40_ram_calc(struct nvkm_fb *fb, u32 freq)
static int
nv40_ram_calc(struct nvkm_ram *base, u32 freq)
{
struct nvkm_subdev *subdev = &fb->subdev;
struct nv40_ram *ram = nv40_ram(base);
struct nvkm_subdev *subdev = &ram->base.fb->subdev;
struct nvkm_bios *bios = subdev->device->bios;
struct nv40_ram *ram = (void *)fb->ram;
struct nvbios_pll pll;
int N1, M1, N2, M2;
int log2P, ret;
......@@ -46,8 +46,7 @@ nv40_ram_calc(struct nvkm_fb *fb, u32 freq)
return ret;
}
ret = nv04_pll_calc(nv_subdev(fb), &pll, freq,
&N1, &M1, &N2, &M2, &log2P);
ret = nv04_pll_calc(subdev, &pll, freq, &N1, &M1, &N2, &M2, &log2P);
if (ret < 0)
return ret;
......@@ -64,12 +63,13 @@ nv40_ram_calc(struct nvkm_fb *fb, u32 freq)
return 0;
}
int
nv40_ram_prog(struct nvkm_fb *fb)
static int
nv40_ram_prog(struct nvkm_ram *base)
{
struct nvkm_device *device = fb->subdev.device;
struct nv40_ram *ram = nv40_ram(base);
struct nvkm_subdev *subdev = &ram->base.fb->subdev;
struct nvkm_device *device = subdev->device;
struct nvkm_bios *bios = device->bios;
struct nv40_ram *ram = (void *)fb->ram;
struct bit_entry M;
u32 crtc_mask = 0;
u8 sr1[2];
......@@ -152,7 +152,7 @@ nv40_ram_prog(struct nvkm_fb *fb)
/* execute memory reset script from vbios */
if (!bit_entry(bios, 'M', &M)) {
struct nvbios_init init = {
.subdev = nv_subdev(fb),
.subdev = subdev,
.bios = bios,
.offset = nvbios_rd16(bios, M.offset + 0x00),
.execute = 1,
......@@ -181,51 +181,50 @@ nv40_ram_prog(struct nvkm_fb *fb)
return 0;
}
void
nv40_ram_tidy(struct nvkm_fb *fb)
static void
nv40_ram_tidy(struct nvkm_ram *base)
{
}
static int
nv40_ram_create(struct nvkm_object *parent, struct nvkm_object *engine,
struct nvkm_oclass *oclass, void *data, u32 size,
struct nvkm_object **pobject)
static const struct nvkm_ram_func
nv40_ram_func = {
.calc = nv40_ram_calc,
.prog = nv40_ram_prog,
.tidy = nv40_ram_tidy,
};
int
nv40_ram_new_(struct nvkm_fb *fb, enum nvkm_ram_type type, u64 size,
u32 tags, struct nvkm_ram **pram)
{
struct nvkm_fb *fb = nvkm_fb(parent);
struct nv40_ram *ram;
if (!(ram = kzalloc(sizeof(*ram), GFP_KERNEL)))
return -ENOMEM;
*pram = &ram->base;
return nvkm_ram_ctor(&nv40_ram_func, fb, type, size, tags, &ram->base);
}
int
nv40_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram)
{
struct nvkm_device *device = fb->subdev.device;
u32 pbus1218 = nvkm_rd32(device, 0x001218);
u32 size = nvkm_rd32(device, 0x10020c) & 0xff000000;
u32 tags = nvkm_rd32(device, 0x100320);
enum nvkm_ram_type type = NVKM_RAM_TYPE_UNKNOWN;
int ret;
ret = nvkm_ram_create(parent, engine, oclass, &ram);
*pobject = nv_object(ram);
if (ret)
return ret;
switch (pbus1218 & 0x00000300) {
case 0x00000000: ram->base.type = NV_MEM_TYPE_SDRAM; break;
case 0x00000100: ram->base.type = NV_MEM_TYPE_DDR1; break;
case 0x00000200: ram->base.type = NV_MEM_TYPE_GDDR3; break;
case 0x00000300: ram->base.type = NV_MEM_TYPE_DDR2; break;
case 0x00000000: type = NVKM_RAM_TYPE_SDRAM; break;
case 0x00000100: type = NVKM_RAM_TYPE_DDR1 ; break;
case 0x00000200: type = NVKM_RAM_TYPE_GDDR3; break;
case 0x00000300: type = NVKM_RAM_TYPE_DDR2 ; break;
}
ram->base.size = nvkm_rd32(device, 0x10020c) & 0xff000000;
ram->base.parts = (nvkm_rd32(device, 0x100200) & 0x00000003) + 1;
ram->base.tags = nvkm_rd32(device, 0x100320);
ram->base.calc = nv40_ram_calc;
ram->base.prog = nv40_ram_prog;
ram->base.tidy = nv40_ram_tidy;
ret = nv40_ram_new_(fb, type, size, tags, pram);
if (ret)
return ret;
(*pram)->parts = (nvkm_rd32(device, 0x100200) & 0x00000003) + 1;
return 0;
}
struct nvkm_oclass
nv40_ram_oclass = {
.handle = 0,
.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv40_ram_create,
.dtor = _nvkm_ram_dtor,
.init = _nvkm_ram_init,
.fini = _nvkm_ram_fini,
}
};
#ifndef __NV40_FB_RAM_H__
#define __NV40_FB_RAM_H__
#define nv40_ram(p) container_of((p), struct nv40_ram, base)
#include "ram.h"
struct nv40_ram {
struct nvkm_ram base;
u32 ctrl;
u32 coef;
};
int nv40_ram_new_(struct nvkm_fb *fb, enum nvkm_ram_type, u64, u32,
struct nvkm_ram **);
#endif
......@@ -21,47 +21,29 @@
*
* Authors: Ben Skeggs
*/
#include "nv40.h"
#include "ramnv40.h"
static int
nv41_ram_create(struct nvkm_object *parent, struct nvkm_object *engine,
struct nvkm_oclass *oclass, void *data, u32 size,
struct nvkm_object **pobject)
int
nv41_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram)
{
struct nvkm_fb *fb = nvkm_fb(parent);
struct nv40_ram *ram;
struct nvkm_device *device = fb->subdev.device;
u32 size = nvkm_rd32(device, 0x10020c) & 0xff000000;
u32 tags = nvkm_rd32(device, 0x100320);
u32 fb474 = nvkm_rd32(device, 0x100474);
enum nvkm_ram_type type = NVKM_RAM_TYPE_UNKNOWN;
int ret;
ret = nvkm_ram_create(parent, engine, oclass, &ram);
*pobject = nv_object(ram);
if (ret)
return ret;
if (fb474 & 0x00000004)
ram->base.type = NV_MEM_TYPE_GDDR3;
type = NVKM_RAM_TYPE_GDDR3;
if (fb474 & 0x00000002)
ram->base.type = NV_MEM_TYPE_DDR2;
type = NVKM_RAM_TYPE_DDR2;
if (fb474 & 0x00000001)
ram->base.type = NV_MEM_TYPE_DDR1;
type = NVKM_RAM_TYPE_DDR1;
ram->base.size = nvkm_rd32(device, 0x10020c) & 0xff000000;
ram->base.parts = (nvkm_rd32(device, 0x100200) & 0x00000003) + 1;
ram->base.tags = nvkm_rd32(device, 0x100320);
ram->base.calc = nv40_ram_calc;
ram->base.prog = nv40_ram_prog;
ram->base.tidy = nv40_ram_tidy;
ret = nv40_ram_new_(fb, type, size, tags, pram);
if (ret)
return ret;
(*pram)->parts = (nvkm_rd32(device, 0x100200) & 0x00000003) + 1;
return 0;
}
struct nvkm_oclass
nv41_ram_oclass = {
.handle = 0,
.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv41_ram_create,
.dtor = _nvkm_ram_dtor,
.init = _nvkm_ram_init,
.fini = _nvkm_ram_fini,
}
};
......@@ -21,45 +21,22 @@
*
* Authors: Ben Skeggs
*/
#include "nv40.h"
#include "ramnv40.h"
static int
nv44_ram_create(struct nvkm_object *parent, struct nvkm_object *engine,
struct nvkm_oclass *oclass, void *data, u32 size,
struct nvkm_object **pobject)
int
nv44_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram)
{
struct nvkm_fb *fb = nvkm_fb(parent);
struct nv40_ram *ram;
struct nvkm_device *device = fb->subdev.device;
u32 size = nvkm_rd32(device, 0x10020c) & 0xff000000;
u32 fb474 = nvkm_rd32(device, 0x100474);
int ret;
ret = nvkm_ram_create(parent, engine, oclass, &ram);
*pobject = nv_object(ram);
if (ret)
return ret;
enum nvkm_ram_type type = NVKM_RAM_TYPE_UNKNOWN;
if (fb474 & 0x00000004)
ram->base.type = NV_MEM_TYPE_GDDR3;
type = NVKM_RAM_TYPE_GDDR3;
if (fb474 & 0x00000002)
ram->base.type = NV_MEM_TYPE_DDR2;
type = NVKM_RAM_TYPE_DDR2;
if (fb474 & 0x00000001)
ram->base.type = NV_MEM_TYPE_DDR1;
type = NVKM_RAM_TYPE_DDR1;
ram->base.size = nvkm_rd32(device, 0x10020c) & 0xff000000;
ram->base.calc = nv40_ram_calc;
ram->base.prog = nv40_ram_prog;
ram->base.tidy = nv40_ram_tidy;
return 0;
return nv40_ram_new_(fb, type, size, 0, pram);
}
struct nvkm_oclass
nv44_ram_oclass = {
.handle = 0,
.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv44_ram_create,
.dtor = _nvkm_ram_dtor,
.init = _nvkm_ram_init,
.fini = _nvkm_ram_fini,
}
};
......@@ -21,47 +21,29 @@
*
* Authors: Ben Skeggs
*/
#include "nv40.h"
#include "ramnv40.h"
static int
nv49_ram_create(struct nvkm_object *parent, struct nvkm_object *engine,
struct nvkm_oclass *oclass, void *data, u32 size,
struct nvkm_object **pobject)
int
nv49_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram)
{
struct nvkm_fb *fb = nvkm_fb(parent);
struct nv40_ram *ram;
struct nvkm_device *device = fb->subdev.device;
u32 size = nvkm_rd32(device, 0x10020c) & 0xff000000;
u32 tags = nvkm_rd32(device, 0x100320);
u32 fb914 = nvkm_rd32(device, 0x100914);
enum nvkm_ram_type type = NVKM_RAM_TYPE_UNKNOWN;
int ret;
ret = nvkm_ram_create(parent, engine, oclass, &ram);
*pobject = nv_object(ram);
if (ret)
return ret;
switch (fb914 & 0x00000003) {
case 0x00000000: ram->base.type = NV_MEM_TYPE_DDR1; break;
case 0x00000001: ram->base.type = NV_MEM_TYPE_DDR2; break;
case 0x00000002: ram->base.type = NV_MEM_TYPE_GDDR3; break;
case 0x00000000: type = NVKM_RAM_TYPE_DDR1 ; break;
case 0x00000001: type = NVKM_RAM_TYPE_DDR2 ; break;
case 0x00000002: type = NVKM_RAM_TYPE_GDDR3; break;
case 0x00000003: break;
}
ram->base.size = nvkm_rd32(device, 0x10020c) & 0xff000000;
ram->base.parts = (nvkm_rd32(device, 0x100200) & 0x00000003) + 1;
ram->base.tags = nvkm_rd32(device, 0x100320);
ram->base.calc = nv40_ram_calc;
ram->base.prog = nv40_ram_prog;
ram->base.tidy = nv40_ram_tidy;
ret = nv40_ram_new_(fb, type, size, tags, pram);
if (ret)
return ret;
(*pram)->parts = (nvkm_rd32(device, 0x100200) & 0x00000003) + 1;
return 0;
}
struct nvkm_oclass
nv49_ram_oclass = {
.handle = 0,
.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv49_ram_create,
.dtor = _nvkm_ram_dtor,
.init = _nvkm_ram_init,
.fini = _nvkm_ram_fini,
}
};
......@@ -21,35 +21,13 @@
*
* Authors: Ben Skeggs
*/
#include "priv.h"
#include "ram.h"
static int
nv4e_ram_create(struct nvkm_object *parent, struct nvkm_object *engine,
struct nvkm_oclass *oclass, void *data, u32 size,
struct nvkm_object **pobject)
int
nv4e_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram)
{
struct nvkm_fb *fb = nvkm_fb(parent);
struct nvkm_ram *ram;
struct nvkm_device *device = fb->subdev.device;
int ret;
ret = nvkm_ram_create(parent, engine, oclass, &ram);
*pobject = nv_object(ram);
if (ret)
return ret;
ram->size = nvkm_rd32(device, 0x10020c) & 0xff000000;
ram->type = NV_MEM_TYPE_STOLEN;
return 0;
u32 size = nvkm_rd32(device, 0x10020c) & 0xff000000;
return nvkm_ram_new_(&nv04_ram_func, fb, NVKM_RAM_TYPE_UNKNOWN,
size, 0, pram);
}
struct nvkm_oclass
nv4e_ram_oclass = {
.handle = 0,
.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv4e_ram_create,
.dtor = _nvkm_ram_dtor,
.init = _nvkm_ram_init,
.fini = _nvkm_ram_fini,
}
};
......@@ -84,8 +84,8 @@ static void
nv50_instobj_dtor(struct nvkm_object *object)
{
struct nv50_instobj *node = (void *)object;
struct nvkm_fb *fb = nvkm_fb(object);
fb->ram->put(fb, &node->mem);
struct nvkm_ram *ram = nvkm_fb(object)->ram;
ram->func->put(ram, &node->mem);
nvkm_instobj_destroy(&node->base);
}
......@@ -94,7 +94,7 @@ nv50_instobj_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
struct nvkm_oclass *oclass, void *data, u32 size,
struct nvkm_object **pobject)
{
struct nvkm_fb *fb = nvkm_fb(parent);
struct nvkm_ram *ram = nvkm_fb(parent)->ram;
struct nvkm_instobj_args *args = data;
struct nv50_instobj *node;
int ret;
......@@ -107,7 +107,8 @@ nv50_instobj_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
if (ret)
return ret;
ret = fb->ram->get(fb, args->size, args->align, 0, 0x800, &node->mem);
ret = ram->func->get(ram, args->size, args->align, 0, 0x800,
&node->mem);
if (ret)
return ret;
......
......@@ -145,12 +145,12 @@ gf100_ltc_init(struct nvkm_object *object)
void
gf100_ltc_dtor(struct nvkm_object *object)
{
struct nvkm_fb *fb = nvkm_fb(object);
struct nvkm_ltc_priv *ltc = (void *)object;
struct nvkm_ram *ram = ltc->base.subdev.device->fb->ram;
nvkm_mm_fini(&ltc->tags);
if (fb->ram)
nvkm_mm_free(&fb->vram, &ltc->tag_ram);
if (ram)
nvkm_mm_free(&ram->vram, &ltc->tag_ram);
nvkm_ltc_destroy(ltc);
}
......@@ -158,19 +158,20 @@ gf100_ltc_dtor(struct nvkm_object *object)
/* TODO: Figure out tag memory details and drop the over-cautious allocation.
*/
int
gf100_ltc_init_tag_ram(struct nvkm_fb *fb, struct nvkm_ltc_priv *ltc)
gf100_ltc_init_tag_ram(struct nvkm_ltc_priv *ltc)
{
struct nvkm_ram *ram = ltc->base.subdev.device->fb->ram;
u32 tag_size, tag_margin, tag_align;
int ret;
/* No VRAM, no tags for now. */
if (!fb->ram) {
if (!ram) {
ltc->num_tags = 0;
goto mm_init;
}
/* tags for 1/4 of VRAM should be enough (8192/4 per GiB of VRAM) */
ltc->num_tags = (fb->ram->size >> 17) / 4;
ltc->num_tags = (ram->size >> 17) / 4;
if (ltc->num_tags > (1 << 17))
ltc->num_tags = 1 << 17; /* we have 17 bits in PTE */
ltc->num_tags = (ltc->num_tags + 63) & ~63; /* round up to 64 */
......@@ -190,7 +191,7 @@ gf100_ltc_init_tag_ram(struct nvkm_fb *fb, struct nvkm_ltc_priv *ltc)
tag_size += tag_align;
tag_size = (tag_size + 0xfff) >> 12; /* round up */
ret = nvkm_mm_tail(&fb->vram, 1, 1, tag_size, tag_size, 1,
ret = nvkm_mm_tail(&ram->vram, 1, 1, tag_size, tag_size, 1,
&ltc->tag_ram);
if (ret) {
ltc->num_tags = 0;
......@@ -214,7 +215,6 @@ gf100_ltc_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
struct nvkm_object **pobject)
{
struct nvkm_device *device = (void *)parent;
struct nvkm_fb *fb = device->fb;
struct nvkm_ltc_priv *ltc;
u32 parts, mask;
int ret, i;
......@@ -232,7 +232,7 @@ gf100_ltc_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
}
ltc->lts_nr = nvkm_rd32(device, 0x17e8dc) >> 28;
ret = gf100_ltc_init_tag_ram(fb, ltc);
ret = gf100_ltc_init_tag_ram(ltc);
if (ret)
return ret;
......
......@@ -124,7 +124,6 @@ gm107_ltc_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
struct nvkm_object **pobject)
{
struct nvkm_device *device = (void *)parent;
struct nvkm_fb *fb = device->fb;
struct nvkm_ltc_priv *ltc;
u32 parts, mask;
int ret, i;
......@@ -142,7 +141,7 @@ gm107_ltc_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
}
ltc->lts_nr = nvkm_rd32(device, 0x17e280) >> 28;
ret = gf100_ltc_init_tag_ram(fb, ltc);
ret = gf100_ltc_init_tag_ram(ltc);
if (ret)
return ret;
......
......@@ -45,7 +45,7 @@ int gf100_ltc_ctor(struct nvkm_object *, struct nvkm_object *,
struct nvkm_oclass *, void *, u32,
struct nvkm_object **);
void gf100_ltc_dtor(struct nvkm_object *);
int gf100_ltc_init_tag_ram(struct nvkm_fb *, struct nvkm_ltc_priv *);
int gf100_ltc_init_tag_ram(struct nvkm_ltc_priv *);
int gf100_ltc_tags_alloc(struct nvkm_ltc *, u32, struct nvkm_mm_node **);
void gf100_ltc_tags_free(struct nvkm_ltc *, struct nvkm_mm_node **);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment