Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dceef5d8 authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nouveau/fb: initialise vram controller as pfb sub-object



Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 54ecff3e
Loading
Loading
Loading
Loading
+11 −0
Original line number Original line Diff line number Diff line
@@ -80,6 +80,17 @@ nouveau-y += core/subdev/fb/nv49.o
nouveau-y += core/subdev/fb/nv4e.o
nouveau-y += core/subdev/fb/nv4e.o
nouveau-y += core/subdev/fb/nv50.o
nouveau-y += core/subdev/fb/nv50.o
nouveau-y += core/subdev/fb/nvc0.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/base.o
nouveau-y += core/subdev/gpio/nv10.o
nouveau-y += core/subdev/gpio/nv10.o
nouveau-y += core/subdev/gpio/nv50.o
nouveau-y += core/subdev/gpio/nv50.o
+1 −1
Original line number Original line Diff line number Diff line
@@ -320,7 +320,7 @@ nv40_fifo_init(struct nouveau_object *object)
		break;
		break;
	default:
	default:
		nv_wr32(priv, 0x002230, 0x00000000);
		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) |
					 priv->ramfc->addr) >> 16) |
					0x00030000);
					0x00030000);
		break;
		break;
+25 −70
Original line number Original line Diff line number Diff line
@@ -53,31 +53,7 @@ struct nouveau_fb {


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


	struct {
	struct nouveau_ram *ram;
		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_mm vram;
	struct nouveau_mm vram;
	struct nouveau_mm tags;
	struct nouveau_mm tags;
@@ -102,18 +78,6 @@ nouveau_fb(void *obj)
	return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_FB];
	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 nv04_fb_oclass;
extern struct nouveau_oclass nv10_fb_oclass;
extern struct nouveau_oclass nv10_fb_oclass;
extern struct nouveau_oclass nv1a_fb_oclass;
extern struct nouveau_oclass nv1a_fb_oclass;
@@ -132,40 +96,31 @@ extern struct nouveau_oclass nv4e_fb_oclass;
extern struct nouveau_oclass nv50_fb_oclass;
extern struct nouveau_oclass nv50_fb_oclass;
extern struct nouveau_oclass nvc0_fb_oclass;
extern struct nouveau_oclass nvc0_fb_oclass;


struct nouveau_bios;
struct nouveau_ram {
int  nouveau_fb_bios_memtype(struct nouveau_bios *);
	struct nouveau_object base;

	enum {
bool nv04_fb_memtype_valid(struct nouveau_fb *, u32 memtype);
		NV_MEM_TYPE_UNKNOWN = 0,

		NV_MEM_TYPE_STOLEN,
void nv10_fb_tile_init(struct nouveau_fb *, int i, u32 addr, u32 size,
		NV_MEM_TYPE_SGRAM,
		       u32 pitch, u32 flags, struct nouveau_fb_tile *);
		NV_MEM_TYPE_SDRAM,
void nv10_fb_tile_fini(struct nouveau_fb *, int i, struct nouveau_fb_tile *);
		NV_MEM_TYPE_DDR1,
void nv10_fb_tile_prog(struct nouveau_fb *, int, struct nouveau_fb_tile *);
		NV_MEM_TYPE_DDR2,

		NV_MEM_TYPE_DDR3,
int  nv20_fb_vram_init(struct nouveau_fb *);
		NV_MEM_TYPE_GDDR2,
void nv20_fb_tile_init(struct nouveau_fb *, int i, u32 addr, u32 size,
		NV_MEM_TYPE_GDDR3,
		       u32 pitch, u32 flags, struct nouveau_fb_tile *);
		NV_MEM_TYPE_GDDR4,
void nv20_fb_tile_fini(struct nouveau_fb *, int i, struct nouveau_fb_tile *);
		NV_MEM_TYPE_GDDR5
void nv20_fb_tile_prog(struct nouveau_fb *, int, struct nouveau_fb_tile *);
	} type;

	u64 stolen;
int  nv30_fb_init(struct nouveau_object *);
	u64 size;
void nv30_fb_tile_init(struct nouveau_fb *, int i, u32 addr, u32 size,
	u32 tags;
		       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 *);


void nv46_fb_tile_init(struct nouveau_fb *, int i, u32 addr, u32 size,
	int ranks;
		       u32 pitch, u32 flags, struct nouveau_fb_tile *);
	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
#endif
+74 −51
Original line number Original line Diff line number Diff line
@@ -57,50 +57,42 @@ nouveau_fb_bios_memtype(struct nouveau_bios *bios)
}
}


int
int
nouveau_fb_preinit(struct nouveau_fb *pfb)
_nouveau_fb_fini(struct nouveau_object *object, bool suspend)
{
{
	static const char *name[] = {
	struct nouveau_fb *pfb = (void *)object;
		[NV_MEM_TYPE_UNKNOWN] = "unknown",
	int ret;
		[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",
	};
	int ret, tags;


	tags = pfb->ram.init(pfb);
	ret = nv_ofuncs(pfb->ram)->fini(nv_object(pfb->ram), suspend);
	if (tags < 0 || !pfb->ram.size) {
	if (ret && suspend)
		nv_fatal(pfb, "error detecting memory configuration!!\n");
		return ret;
		return (tags < 0) ? tags : -ERANGE;

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


	if (!nouveau_mm_initialised(&pfb->vram)) {
int
		ret = nouveau_mm_init(&pfb->vram, 0, pfb->ram.size >> 12, 1);
_nouveau_fb_init(struct nouveau_object *object)
{
	struct nouveau_fb *pfb = (void *)object;
	int ret, i;

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


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


	nv_info(pfb, "RAM type: %s\n", name[pfb->ram.type]);
	for (i = 0; i < pfb->tile.regions; i++)
	nv_info(pfb, "RAM size: %d MiB\n", (int)(pfb->ram.size >> 20));
		pfb->tile.prog(pfb, i, &pfb->tile.region[i]);
	nv_info(pfb, "   ZCOMP: %d tags\n", tags);

	return 0;
	return 0;
}
}


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


	for (i = 0; i < pfb->tile.regions; i++)
	for (i = 0; i < pfb->tile.regions; i++)
@@ -108,33 +100,64 @@ nouveau_fb_destroy(struct nouveau_fb *pfb)
	nouveau_mm_fini(&pfb->tags);
	nouveau_mm_fini(&pfb->tags);
	nouveau_mm_fini(&pfb->vram);
	nouveau_mm_fini(&pfb->vram);


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


void
_nouveau_fb_dtor(struct nouveau_object *object)
{
	struct nouveau_fb *pfb = (void *)object;
	nouveau_fb_destroy(pfb);
}
int
int
nouveau_fb_init(struct nouveau_fb *pfb)
nouveau_fb_create_(struct nouveau_object *parent, struct nouveau_object *engine,
		   struct nouveau_oclass *oclass, struct nouveau_oclass *ramcls,
		   int length, void **pobject)
{
{
	int ret, i;
	static const char *name[] = {
		[NV_MEM_TYPE_UNKNOWN] = "unknown",
		[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 nouveau_object *ram;
	struct nouveau_fb *pfb;
	int ret;


	ret = nouveau_subdev_init(&pfb->base);
	ret = nouveau_subdev_create_(parent, engine, oclass, 0, "PFB", "fb",
				     length, pobject);
	pfb = *pobject;
	if (ret)
	if (ret)
		return ret;
		return ret;


	for (i = 0; i < pfb->tile.regions; i++)
	ret = nouveau_object_ctor(nv_object(pfb), nv_object(pfb),
		pfb->tile.prog(pfb, i, &pfb->tile.region[i]);
				  ramcls, NULL, 0, &ram);
	if (ret) {
		nv_fatal(pfb, "error detecting memory configuration!!\n");
		return ret;
	}


	return 0;
	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);
		if (ret)
			return ret;
	}
	}


int
	if (!nouveau_mm_initialised(&pfb->tags)) {
_nouveau_fb_init(struct nouveau_object *object)
		ret = nouveau_mm_init(&pfb->tags, 0, pfb->ram->tags ?
{
				     ++pfb->ram->tags : 0, 1);
	struct nouveau_fb *pfb = (void *)object;
		if (ret)
	return nouveau_fb_init(pfb);
			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", pfb->ram->tags);
	return 0;
}
}
+3 −51
Original line number Original line Diff line number Diff line
@@ -22,24 +22,8 @@
 * Authors: Ben Skeggs
 * 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
#define NV04_PFB_CFG0						0x00100200


struct nv04_fb_priv {
struct nv04_fb_priv {
@@ -55,37 +39,6 @@ nv04_fb_memtype_valid(struct nouveau_fb *pfb, u32 tile_flags)
	return false;
	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
static int
nv04_fb_init(struct nouveau_object *object)
nv04_fb_init(struct nouveau_object *object)
{
{
@@ -112,14 +65,13 @@ nv04_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
	struct nv04_fb_priv *priv;
	struct nv04_fb_priv *priv;
	int ret;
	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);
	*pobject = nv_object(priv);
	if (ret)
	if (ret)
		return ret;
		return ret;


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


struct nouveau_oclass
struct nouveau_oclass
Loading