Skip to content

Commit

Permalink
drm/nouveau/fb: initialise vram controller as pfb sub-object
Browse files Browse the repository at this point in the history
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
  • Loading branch information
Ben Skeggs committed Jul 1, 2013
1 parent 54ecff3 commit dceef5d
Show file tree
Hide file tree
Showing 45 changed files with 1,313 additions and 733 deletions.
11 changes: 11 additions & 0 deletions drivers/gpu/drm/nouveau/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,17 @@ nouveau-y += core/subdev/fb/nv49.o
nouveau-y += core/subdev/fb/nv4e.o
nouveau-y += core/subdev/fb/nv50.o
nouveau-y += core/subdev/fb/nvc0.o
nouveau-y += core/subdev/fb/ramnv04.o
nouveau-y += core/subdev/fb/ramnv10.o
nouveau-y += core/subdev/fb/ramnv1a.o
nouveau-y += core/subdev/fb/ramnv20.o
nouveau-y += core/subdev/fb/ramnv40.o
nouveau-y += core/subdev/fb/ramnv41.o
nouveau-y += core/subdev/fb/ramnv44.o
nouveau-y += core/subdev/fb/ramnv49.o
nouveau-y += core/subdev/fb/ramnv4e.o
nouveau-y += core/subdev/fb/ramnv50.o
nouveau-y += core/subdev/fb/ramnvc0.o
nouveau-y += core/subdev/gpio/base.o
nouveau-y += core/subdev/gpio/nv10.o
nouveau-y += core/subdev/gpio/nv50.o
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/nouveau/core/engine/fifo/nv40.c
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ nv40_fifo_init(struct nouveau_object *object)
break;
default:
nv_wr32(priv, 0x002230, 0x00000000);
nv_wr32(priv, 0x002220, ((pfb->ram.size - 512 * 1024 +
nv_wr32(priv, 0x002220, ((pfb->ram->size - 512 * 1024 +
priv->ramfc->addr) >> 16) |
0x00030000);
break;
Expand Down
95 changes: 25 additions & 70 deletions drivers/gpu/drm/nouveau/core/include/subdev/fb.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,31 +53,7 @@ struct nouveau_fb {

bool (*memtype_valid)(struct nouveau_fb *, u32 memtype);

struct {
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;
u64 size;

int ranks;
int parts;

int (*init)(struct nouveau_fb *);
int (*get)(struct nouveau_fb *, u64 size, u32 align,
u32 size_nc, u32 type, struct nouveau_mem **);
void (*put)(struct nouveau_fb *, struct nouveau_mem **);
} ram;
struct nouveau_ram *ram;

struct nouveau_mm vram;
struct nouveau_mm tags;
Expand All @@ -102,18 +78,6 @@ nouveau_fb(void *obj)
return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_FB];
}

#define nouveau_fb_create(p,e,c,d) \
nouveau_subdev_create((p), (e), (c), 0, "PFB", "fb", (d))
int nouveau_fb_preinit(struct nouveau_fb *);
void nouveau_fb_destroy(struct nouveau_fb *);
int nouveau_fb_init(struct nouveau_fb *);
#define nouveau_fb_fini(p,s) \
nouveau_subdev_fini(&(p)->base, (s))

void _nouveau_fb_dtor(struct nouveau_object *);
int _nouveau_fb_init(struct nouveau_object *);
#define _nouveau_fb_fini _nouveau_subdev_fini

extern struct nouveau_oclass nv04_fb_oclass;
extern struct nouveau_oclass nv10_fb_oclass;
extern struct nouveau_oclass nv1a_fb_oclass;
Expand All @@ -132,40 +96,31 @@ extern struct nouveau_oclass nv4e_fb_oclass;
extern struct nouveau_oclass nv50_fb_oclass;
extern struct nouveau_oclass nvc0_fb_oclass;

struct nouveau_bios;
int nouveau_fb_bios_memtype(struct nouveau_bios *);

bool nv04_fb_memtype_valid(struct nouveau_fb *, u32 memtype);

void nv10_fb_tile_init(struct nouveau_fb *, int i, u32 addr, u32 size,
u32 pitch, u32 flags, struct nouveau_fb_tile *);
void nv10_fb_tile_fini(struct nouveau_fb *, int i, struct nouveau_fb_tile *);
void nv10_fb_tile_prog(struct nouveau_fb *, int, struct nouveau_fb_tile *);

int nv20_fb_vram_init(struct nouveau_fb *);
void nv20_fb_tile_init(struct nouveau_fb *, int i, u32 addr, u32 size,
u32 pitch, u32 flags, struct nouveau_fb_tile *);
void nv20_fb_tile_fini(struct nouveau_fb *, int i, struct nouveau_fb_tile *);
void nv20_fb_tile_prog(struct nouveau_fb *, int, struct nouveau_fb_tile *);

int nv30_fb_init(struct nouveau_object *);
void nv30_fb_tile_init(struct nouveau_fb *, int i, u32 addr, u32 size,
u32 pitch, u32 flags, struct nouveau_fb_tile *);

void nv40_fb_tile_comp(struct nouveau_fb *, int i, u32 size, u32 flags,
struct nouveau_fb_tile *);

int nv41_fb_vram_init(struct nouveau_fb *);
int nv41_fb_init(struct nouveau_object *);
void nv41_fb_tile_prog(struct nouveau_fb *, int, struct nouveau_fb_tile *);

int nv44_fb_vram_init(struct nouveau_fb *);
int nv44_fb_init(struct nouveau_object *);
void nv44_fb_tile_prog(struct nouveau_fb *, int, struct nouveau_fb_tile *);
struct nouveau_ram {
struct nouveau_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;
u64 size;
u32 tags;

void nv46_fb_tile_init(struct nouveau_fb *, int i, u32 addr, u32 size,
u32 pitch, u32 flags, struct nouveau_fb_tile *);
int ranks;
int parts;

void nv50_fb_vram_del(struct nouveau_fb *, struct nouveau_mem **);
int (*get)(struct nouveau_fb *, u64 size, u32 align,
u32 size_nc, u32 type, struct nouveau_mem **);
void (*put)(struct nouveau_fb *, struct nouveau_mem **);
};

#endif
125 changes: 74 additions & 51 deletions drivers/gpu/drm/nouveau/core/subdev/fb/base.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,57 @@ nouveau_fb_bios_memtype(struct nouveau_bios *bios)
}

int
nouveau_fb_preinit(struct nouveau_fb *pfb)
_nouveau_fb_fini(struct nouveau_object *object, bool suspend)
{
struct nouveau_fb *pfb = (void *)object;
int ret;

ret = nv_ofuncs(pfb->ram)->fini(nv_object(pfb->ram), suspend);
if (ret && suspend)
return ret;

return nouveau_subdev_fini(&pfb->base, suspend);
}

int
_nouveau_fb_init(struct nouveau_object *object)
{
struct nouveau_fb *pfb = (void *)object;
int ret, i;

ret = nouveau_subdev_init(&pfb->base);
if (ret)
return ret;

ret = nv_ofuncs(pfb->ram)->init(nv_object(pfb->ram));
if (ret)
return ret;

for (i = 0; i < pfb->tile.regions; i++)
pfb->tile.prog(pfb, i, &pfb->tile.region[i]);

return 0;
}

void
_nouveau_fb_dtor(struct nouveau_object *object)
{
struct nouveau_fb *pfb = (void *)object;
int i;

for (i = 0; i < pfb->tile.regions; i++)
pfb->tile.fini(pfb, i, &pfb->tile.region[i]);
nouveau_mm_fini(&pfb->tags);
nouveau_mm_fini(&pfb->vram);

nouveau_object_ref(NULL, (struct nouveau_object **)&pfb->ram);
nouveau_subdev_destroy(&pfb->base);
}

int
nouveau_fb_create_(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, struct nouveau_oclass *ramcls,
int length, void **pobject)
{
static const char *name[] = {
[NV_MEM_TYPE_UNKNOWN] = "unknown",
Expand All @@ -72,69 +122,42 @@ nouveau_fb_preinit(struct nouveau_fb *pfb)
[NV_MEM_TYPE_GDDR4 ] = "GDDR4",
[NV_MEM_TYPE_GDDR5 ] = "GDDR5",
};
int ret, tags;
struct nouveau_object *ram;
struct nouveau_fb *pfb;
int ret;

tags = pfb->ram.init(pfb);
if (tags < 0 || !pfb->ram.size) {
ret = nouveau_subdev_create_(parent, engine, oclass, 0, "PFB", "fb",
length, pobject);
pfb = *pobject;
if (ret)
return ret;

ret = nouveau_object_ctor(nv_object(pfb), nv_object(pfb),
ramcls, NULL, 0, &ram);
if (ret) {
nv_fatal(pfb, "error detecting memory configuration!!\n");
return (tags < 0) ? tags : -ERANGE;
return ret;
}

atomic_dec(&ram->parent->refcount);
atomic_dec(&ram->engine->refcount);
pfb->ram = (void *)ram;

if (!nouveau_mm_initialised(&pfb->vram)) {
ret = nouveau_mm_init(&pfb->vram, 0, pfb->ram.size >> 12, 1);
ret = nouveau_mm_init(&pfb->vram, 0, pfb->ram->size >> 12, 1);
if (ret)
return ret;
}

if (!nouveau_mm_initialised(&pfb->tags)) {
ret = nouveau_mm_init(&pfb->tags, 0, tags ? ++tags : 0, 1);
ret = nouveau_mm_init(&pfb->tags, 0, pfb->ram->tags ?
++pfb->ram->tags : 0, 1);
if (ret)
return ret;
}

nv_info(pfb, "RAM type: %s\n", name[pfb->ram.type]);
nv_info(pfb, "RAM size: %d MiB\n", (int)(pfb->ram.size >> 20));
nv_info(pfb, " ZCOMP: %d tags\n", tags);
nv_info(pfb, "RAM type: %s\n", name[pfb->ram->type]);
nv_info(pfb, "RAM size: %d MiB\n", (int)(pfb->ram->size >> 20));
nv_info(pfb, " ZCOMP: %d tags\n", pfb->ram->tags);
return 0;
}

void
nouveau_fb_destroy(struct nouveau_fb *pfb)
{
int i;

for (i = 0; i < pfb->tile.regions; i++)
pfb->tile.fini(pfb, i, &pfb->tile.region[i]);
nouveau_mm_fini(&pfb->tags);
nouveau_mm_fini(&pfb->vram);

nouveau_subdev_destroy(&pfb->base);
}

void
_nouveau_fb_dtor(struct nouveau_object *object)
{
struct nouveau_fb *pfb = (void *)object;
nouveau_fb_destroy(pfb);
}
int
nouveau_fb_init(struct nouveau_fb *pfb)
{
int ret, i;

ret = nouveau_subdev_init(&pfb->base);
if (ret)
return ret;

for (i = 0; i < pfb->tile.regions; i++)
pfb->tile.prog(pfb, i, &pfb->tile.region[i]);

return 0;
}

int
_nouveau_fb_init(struct nouveau_object *object)
{
struct nouveau_fb *pfb = (void *)object;
return nouveau_fb_init(pfb);
}
54 changes: 3 additions & 51 deletions drivers/gpu/drm/nouveau/core/subdev/fb/nv04.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,24 +22,8 @@
* Authors: Ben Skeggs
*/

#include <subdev/fb.h>
#include "priv.h"

#define NV04_PFB_BOOT_0 0x00100000
# define NV04_PFB_BOOT_0_RAM_AMOUNT 0x00000003
# define NV04_PFB_BOOT_0_RAM_AMOUNT_32MB 0x00000000
# define NV04_PFB_BOOT_0_RAM_AMOUNT_4MB 0x00000001
# define NV04_PFB_BOOT_0_RAM_AMOUNT_8MB 0x00000002
# define NV04_PFB_BOOT_0_RAM_AMOUNT_16MB 0x00000003
# define NV04_PFB_BOOT_0_RAM_WIDTH_128 0x00000004
# define NV04_PFB_BOOT_0_RAM_TYPE 0x00000028
# define NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_8MBIT 0x00000000
# define NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_16MBIT 0x00000008
# define NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_16MBIT_4BANK 0x00000010
# define NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_16MBIT 0x00000018
# define NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_64MBIT 0x00000020
# define NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_64MBITX16 0x00000028
# define NV04_PFB_BOOT_0_UMA_ENABLE 0x00000100
# define NV04_PFB_BOOT_0_UMA_SIZE 0x0000f000
#define NV04_PFB_CFG0 0x00100200

struct nv04_fb_priv {
Expand All @@ -55,37 +39,6 @@ nv04_fb_memtype_valid(struct nouveau_fb *pfb, u32 tile_flags)
return false;
}

static int
nv04_fb_vram_init(struct nouveau_fb *pfb)
{
u32 boot0 = nv_rd32(pfb, NV04_PFB_BOOT_0);
if (boot0 & 0x00000100) {
pfb->ram.size = ((boot0 >> 12) & 0xf) * 2 + 2;
pfb->ram.size *= 1024 * 1024;
} else {
switch (boot0 & NV04_PFB_BOOT_0_RAM_AMOUNT) {
case NV04_PFB_BOOT_0_RAM_AMOUNT_32MB:
pfb->ram.size = 32 * 1024 * 1024;
break;
case NV04_PFB_BOOT_0_RAM_AMOUNT_16MB:
pfb->ram.size = 16 * 1024 * 1024;
break;
case NV04_PFB_BOOT_0_RAM_AMOUNT_8MB:
pfb->ram.size = 8 * 1024 * 1024;
break;
case NV04_PFB_BOOT_0_RAM_AMOUNT_4MB:
pfb->ram.size = 4 * 1024 * 1024;
break;
}
}

if ((boot0 & 0x00000038) <= 0x10)
pfb->ram.type = NV_MEM_TYPE_SGRAM;
else
pfb->ram.type = NV_MEM_TYPE_SDRAM;
return 0;
}

static int
nv04_fb_init(struct nouveau_object *object)
{
Expand All @@ -112,14 +65,13 @@ nv04_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nv04_fb_priv *priv;
int ret;

ret = nouveau_fb_create(parent, engine, oclass, &priv);
ret = nouveau_fb_create(parent, engine, oclass, &nv04_ram_oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;

priv->base.memtype_valid = nv04_fb_memtype_valid;
priv->base.ram.init = nv04_fb_vram_init;
return nouveau_fb_preinit(&priv->base);
return 0;
}

struct nouveau_oclass
Expand Down
Loading

0 comments on commit dceef5d

Please sign in to comment.