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

Commit 2c04ae01 authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nv50-/disp: share channel creation between nv50/gf110 impls



Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 410f3ec6
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -35,11 +35,11 @@

static struct nouveau_oclass
gm107_disp_sclass[] = {
	{ GM107_DISP_MAST_CLASS, &nvd0_disp_mast_ofuncs },
	{ GM107_DISP_SYNC_CLASS, &nvd0_disp_sync_ofuncs },
	{ GM107_DISP_OVLY_CLASS, &nvd0_disp_ovly_ofuncs },
	{ GM107_DISP_OIMM_CLASS, &nvd0_disp_oimm_ofuncs },
	{ GM107_DISP_CURS_CLASS, &nvd0_disp_curs_ofuncs },
	{ GM107_DISP_MAST_CLASS, &nvd0_disp_mast_ofuncs.base },
	{ GM107_DISP_SYNC_CLASS, &nvd0_disp_sync_ofuncs.base },
	{ GM107_DISP_OVLY_CLASS, &nvd0_disp_ovly_ofuncs.base },
	{ GM107_DISP_OIMM_CLASS, &nvd0_disp_oimm_ofuncs.base },
	{ GM107_DISP_CURS_CLASS, &nvd0_disp_curs_ofuncs.base },
	{}
};

+82 −71
Original line number Diff line number Diff line
@@ -43,14 +43,16 @@
 * EVO channel base class
 ******************************************************************************/

int
static int
nv50_disp_chan_create_(struct nouveau_object *parent,
		       struct nouveau_object *engine,
		       struct nouveau_oclass *oclass, int chid,
		       struct nouveau_oclass *oclass, int head,
		       int length, void **pobject)
{
	const struct nv50_disp_chan_impl *impl = (void *)oclass->ofuncs;
	struct nv50_disp_base *base = (void *)parent;
	struct nv50_disp_chan *chan;
	int chid = impl->chid + head;
	int ret;

	if (base->chan & (1 << chid))
@@ -63,12 +65,14 @@ nv50_disp_chan_create_(struct nouveau_object *parent,
	chan = *pobject;
	if (ret)
		return ret;

	chan->chid = chid;

	nv_parent(chan)->object_attach = impl->attach;
	nv_parent(chan)->object_detach = impl->detach;
	return 0;
}

void
static void
nv50_disp_chan_destroy(struct nv50_disp_chan *chan)
{
	struct nv50_disp_base *base = (void *)nv_object(chan)->parent;
@@ -115,16 +119,16 @@ nv50_disp_dmac_object_detach(struct nouveau_object *parent, int cookie)
	nouveau_ramht_remove(base->ramht, cookie);
}

int
static int
nv50_disp_dmac_create_(struct nouveau_object *parent,
		       struct nouveau_object *engine,
		       struct nouveau_oclass *oclass, u32 pushbuf, int chid,
		       struct nouveau_oclass *oclass, u32 pushbuf, int head,
		       int length, void **pobject)
{
	struct nv50_disp_dmac *dmac;
	int ret;

	ret = nv50_disp_chan_create_(parent, engine, oclass, chid,
	ret = nv50_disp_chan_create_(parent, engine, oclass, head,
				     length, pobject);
	dmac = *pobject;
	if (ret)
@@ -397,7 +401,7 @@ nv50_disp_mast_mthd_chan = {
	}
};

static int
int
nv50_disp_mast_ctor(struct nouveau_object *parent,
		    struct nouveau_object *engine,
		    struct nouveau_oclass *oclass, void *data, u32 size,
@@ -416,8 +420,6 @@ nv50_disp_mast_ctor(struct nouveau_object *parent,
	if (ret)
		return ret;

	nv_parent(mast)->object_attach = nv50_disp_dmac_object_attach;
	nv_parent(mast)->object_detach = nv50_disp_dmac_object_detach;
	return 0;
}

@@ -479,14 +481,17 @@ nv50_disp_mast_fini(struct nouveau_object *object, bool suspend)
	return nv50_disp_chan_fini(&mast->base, suspend);
}

struct nouveau_ofuncs
struct nv50_disp_chan_impl
nv50_disp_mast_ofuncs = {
	.ctor = nv50_disp_mast_ctor,
	.dtor = nv50_disp_dmac_dtor,
	.init = nv50_disp_mast_init,
	.fini = nv50_disp_mast_fini,
	.rd32 = nv50_disp_chan_rd32,
	.wr32 = nv50_disp_chan_wr32,
	.base.ctor = nv50_disp_mast_ctor,
	.base.dtor = nv50_disp_dmac_dtor,
	.base.init = nv50_disp_mast_init,
	.base.fini = nv50_disp_mast_fini,
	.base.rd32 = nv50_disp_chan_rd32,
	.base.wr32 = nv50_disp_chan_wr32,
	.chid = 0,
	.attach = nv50_disp_dmac_object_attach,
	.detach = nv50_disp_dmac_object_detach,
};

/*******************************************************************************
@@ -543,39 +548,40 @@ nv50_disp_sync_mthd_chan = {
	}
};

static int
int
nv50_disp_sync_ctor(struct nouveau_object *parent,
		    struct nouveau_object *engine,
		    struct nouveau_oclass *oclass, void *data, u32 size,
		    struct nouveau_object **pobject)
{
	struct nv50_display_sync_class *args = data;
	struct nv50_disp_priv *priv = (void *)engine;
	struct nv50_disp_dmac *dmac;
	int ret;

	if (size < sizeof(*args) || args->head > 1)
	if (size < sizeof(*args) || args->head >= priv->head.nr)
		return -EINVAL;

	ret = nv50_disp_dmac_create_(parent, engine, oclass, args->pushbuf,
				     1 + args->head, sizeof(*dmac),
				     (void **)&dmac);
				     args->head, sizeof(*dmac), (void **)&dmac);
	*pobject = nv_object(dmac);
	if (ret)
		return ret;

	nv_parent(dmac)->object_attach = nv50_disp_dmac_object_attach;
	nv_parent(dmac)->object_detach = nv50_disp_dmac_object_detach;
	return 0;
}

struct nouveau_ofuncs
struct nv50_disp_chan_impl
nv50_disp_sync_ofuncs = {
	.ctor = nv50_disp_sync_ctor,
	.dtor = nv50_disp_dmac_dtor,
	.init = nv50_disp_dmac_init,
	.fini = nv50_disp_dmac_fini,
	.rd32 = nv50_disp_chan_rd32,
	.wr32 = nv50_disp_chan_wr32,
	.base.ctor = nv50_disp_sync_ctor,
	.base.dtor = nv50_disp_dmac_dtor,
	.base.init = nv50_disp_dmac_init,
	.base.fini = nv50_disp_dmac_fini,
	.base.rd32 = nv50_disp_chan_rd32,
	.base.wr32 = nv50_disp_chan_wr32,
	.chid = 1,
	.attach = nv50_disp_dmac_object_attach,
	.detach = nv50_disp_dmac_object_detach,
};

/*******************************************************************************
@@ -620,39 +626,40 @@ nv50_disp_ovly_mthd_chan = {
	}
};

static int
int
nv50_disp_ovly_ctor(struct nouveau_object *parent,
		    struct nouveau_object *engine,
		    struct nouveau_oclass *oclass, void *data, u32 size,
		    struct nouveau_object **pobject)
{
	struct nv50_display_ovly_class *args = data;
	struct nv50_disp_priv *priv = (void *)engine;
	struct nv50_disp_dmac *dmac;
	int ret;

	if (size < sizeof(*args) || args->head > 1)
	if (size < sizeof(*args) || args->head >= priv->head.nr)
		return -EINVAL;

	ret = nv50_disp_dmac_create_(parent, engine, oclass, args->pushbuf,
				     3 + args->head, sizeof(*dmac),
				     (void **)&dmac);
				     args->head, sizeof(*dmac), (void **)&dmac);
	*pobject = nv_object(dmac);
	if (ret)
		return ret;

	nv_parent(dmac)->object_attach = nv50_disp_dmac_object_attach;
	nv_parent(dmac)->object_detach = nv50_disp_dmac_object_detach;
	return 0;
}

struct nouveau_ofuncs
struct nv50_disp_chan_impl
nv50_disp_ovly_ofuncs = {
	.ctor = nv50_disp_ovly_ctor,
	.dtor = nv50_disp_dmac_dtor,
	.init = nv50_disp_dmac_init,
	.fini = nv50_disp_dmac_fini,
	.rd32 = nv50_disp_chan_rd32,
	.wr32 = nv50_disp_chan_wr32,
	.base.ctor = nv50_disp_ovly_ctor,
	.base.dtor = nv50_disp_dmac_dtor,
	.base.init = nv50_disp_dmac_init,
	.base.fini = nv50_disp_dmac_fini,
	.base.rd32 = nv50_disp_chan_rd32,
	.base.wr32 = nv50_disp_chan_wr32,
	.chid = 3,
	.attach = nv50_disp_dmac_object_attach,
	.detach = nv50_disp_dmac_object_detach,
};

/*******************************************************************************
@@ -662,14 +669,14 @@ nv50_disp_ovly_ofuncs = {
static int
nv50_disp_pioc_create_(struct nouveau_object *parent,
		       struct nouveau_object *engine,
		       struct nouveau_oclass *oclass, int chid,
		       struct nouveau_oclass *oclass, int head,
		       int length, void **pobject)
{
	return nv50_disp_chan_create_(parent, engine, oclass, chid,
	return nv50_disp_chan_create_(parent, engine, oclass, head,
				      length, pobject);
}

static void
void
nv50_disp_pioc_dtor(struct nouveau_object *object)
{
	struct nv50_disp_pioc *pioc = (void *)object;
@@ -727,20 +734,21 @@ nv50_disp_pioc_fini(struct nouveau_object *object, bool suspend)
 * EVO immediate overlay channel objects
 ******************************************************************************/

static int
int
nv50_disp_oimm_ctor(struct nouveau_object *parent,
		    struct nouveau_object *engine,
		    struct nouveau_oclass *oclass, void *data, u32 size,
		    struct nouveau_object **pobject)
{
	struct nv50_display_oimm_class *args = data;
	struct nv50_disp_priv *priv = (void *)engine;
	struct nv50_disp_pioc *pioc;
	int ret;

	if (size < sizeof(*args) || args->head > 1)
	if (size < sizeof(*args) || args->head >= priv->head.nr)
		return -EINVAL;

	ret = nv50_disp_pioc_create_(parent, engine, oclass, 5 + args->head,
	ret = nv50_disp_pioc_create_(parent, engine, oclass, args->head,
				     sizeof(*pioc), (void **)&pioc);
	*pobject = nv_object(pioc);
	if (ret)
@@ -749,34 +757,36 @@ nv50_disp_oimm_ctor(struct nouveau_object *parent,
	return 0;
}

struct nouveau_ofuncs
struct nv50_disp_chan_impl
nv50_disp_oimm_ofuncs = {
	.ctor = nv50_disp_oimm_ctor,
	.dtor = nv50_disp_pioc_dtor,
	.init = nv50_disp_pioc_init,
	.fini = nv50_disp_pioc_fini,
	.rd32 = nv50_disp_chan_rd32,
	.wr32 = nv50_disp_chan_wr32,
	.base.ctor = nv50_disp_oimm_ctor,
	.base.dtor = nv50_disp_pioc_dtor,
	.base.init = nv50_disp_pioc_init,
	.base.fini = nv50_disp_pioc_fini,
	.base.rd32 = nv50_disp_chan_rd32,
	.base.wr32 = nv50_disp_chan_wr32,
	.chid = 5,
};

/*******************************************************************************
 * EVO cursor channel objects
 ******************************************************************************/

static int
int
nv50_disp_curs_ctor(struct nouveau_object *parent,
		    struct nouveau_object *engine,
		    struct nouveau_oclass *oclass, void *data, u32 size,
		    struct nouveau_object **pobject)
{
	struct nv50_display_curs_class *args = data;
	struct nv50_disp_priv *priv = (void *)engine;
	struct nv50_disp_pioc *pioc;
	int ret;

	if (size < sizeof(*args) || args->head > 1)
	if (size < sizeof(*args) || args->head >= priv->head.nr)
		return -EINVAL;

	ret = nv50_disp_pioc_create_(parent, engine, oclass, 7 + args->head,
	ret = nv50_disp_pioc_create_(parent, engine, oclass, args->head,
				     sizeof(*pioc), (void **)&pioc);
	*pobject = nv_object(pioc);
	if (ret)
@@ -785,14 +795,15 @@ nv50_disp_curs_ctor(struct nouveau_object *parent,
	return 0;
}

struct nouveau_ofuncs
struct nv50_disp_chan_impl
nv50_disp_curs_ofuncs = {
	.ctor = nv50_disp_curs_ctor,
	.dtor = nv50_disp_pioc_dtor,
	.init = nv50_disp_pioc_init,
	.fini = nv50_disp_pioc_fini,
	.rd32 = nv50_disp_chan_rd32,
	.wr32 = nv50_disp_chan_wr32,
	.base.ctor = nv50_disp_curs_ctor,
	.base.dtor = nv50_disp_pioc_dtor,
	.base.init = nv50_disp_pioc_init,
	.base.fini = nv50_disp_pioc_fini,
	.base.rd32 = nv50_disp_chan_rd32,
	.base.wr32 = nv50_disp_chan_wr32,
	.chid = 7,
};

/*******************************************************************************
@@ -966,11 +977,11 @@ nv50_disp_base_oclass[] = {

static struct nouveau_oclass
nv50_disp_sclass[] = {
	{ NV50_DISP_MAST_CLASS, &nv50_disp_mast_ofuncs },
	{ NV50_DISP_SYNC_CLASS, &nv50_disp_sync_ofuncs },
	{ NV50_DISP_OVLY_CLASS, &nv50_disp_ovly_ofuncs },
	{ NV50_DISP_OIMM_CLASS, &nv50_disp_oimm_ofuncs },
	{ NV50_DISP_CURS_CLASS, &nv50_disp_curs_ofuncs },
	{ NV50_DISP_MAST_CLASS, &nv50_disp_mast_ofuncs.base },
	{ NV50_DISP_SYNC_CLASS, &nv50_disp_sync_ofuncs.base },
	{ NV50_DISP_OVLY_CLASS, &nv50_disp_ovly_ofuncs.base },
	{ NV50_DISP_OIMM_CLASS, &nv50_disp_oimm_ofuncs.base },
	{ NV50_DISP_CURS_CLASS, &nv50_disp_curs_ofuncs.base },
	{}
};

+36 −17
Original line number Diff line number Diff line
@@ -104,14 +104,18 @@ struct nv50_disp_base {
	u32 chan;
};

struct nv50_disp_chan_impl {
	struct nouveau_ofuncs base;
	int chid;
	int  (*attach)(struct nouveau_object *, struct nouveau_object *, u32);
	void (*detach)(struct nouveau_object *, int);
};

struct nv50_disp_chan {
	struct nouveau_namedb base;
	int chid;
};

int  nv50_disp_chan_create_(struct nouveau_object *, struct nouveau_object *,
			    struct nouveau_oclass *, int, int, void **);
void nv50_disp_chan_destroy(struct nv50_disp_chan *);
u32  nv50_disp_chan_rd32(struct nouveau_object *, u64);
void nv50_disp_chan_wr32(struct nouveau_object *, u64, u32);

@@ -120,20 +124,20 @@ void nv50_disp_chan_wr32(struct nouveau_object *, u64, u32);
#define nv50_disp_chan_fini(a,b)                                               \
	nouveau_namedb_fini(&(a)->base, (b))

int  nv50_disp_dmac_create_(struct nouveau_object *, struct nouveau_object *,
			    struct nouveau_oclass *, u32, int, int, void **);
void nv50_disp_dmac_dtor(struct nouveau_object *);

struct nv50_disp_dmac {
	struct nv50_disp_chan base;
	struct nouveau_dmaobj *pushdma;
	u32 push;
};

void nv50_disp_dmac_dtor(struct nouveau_object *);

struct nv50_disp_pioc {
	struct nv50_disp_chan base;
};

void nv50_disp_pioc_dtor(struct nouveau_object *);

struct nv50_disp_mthd_list {
	u32 mthd;
	u32 addr;
@@ -154,16 +158,31 @@ struct nv50_disp_mthd_chan {
	} data[];
};

extern struct nouveau_ofuncs nv50_disp_mast_ofuncs;
extern struct nv50_disp_chan_impl nv50_disp_mast_ofuncs;
int nv50_disp_mast_ctor(struct nouveau_object *, struct nouveau_object *,
			struct nouveau_oclass *, void *, u32,
			struct nouveau_object **);
extern const struct nv50_disp_mthd_list nv50_disp_mast_mthd_base;
extern const struct nv50_disp_mthd_list nv50_disp_mast_mthd_sor;
extern const struct nv50_disp_mthd_list nv50_disp_mast_mthd_pior;
extern struct nouveau_ofuncs nv50_disp_sync_ofuncs;
extern struct nv50_disp_chan_impl nv50_disp_sync_ofuncs;
int nv50_disp_sync_ctor(struct nouveau_object *, struct nouveau_object *,
			struct nouveau_oclass *, void *, u32,
			struct nouveau_object **);
extern const struct nv50_disp_mthd_list nv50_disp_sync_mthd_image;
extern struct nouveau_ofuncs nv50_disp_ovly_ofuncs;
extern struct nv50_disp_chan_impl nv50_disp_ovly_ofuncs;
int nv50_disp_ovly_ctor(struct nouveau_object *, struct nouveau_object *,
			struct nouveau_oclass *, void *, u32,
			struct nouveau_object **);
extern const struct nv50_disp_mthd_list nv50_disp_ovly_mthd_base;
extern struct nouveau_ofuncs nv50_disp_oimm_ofuncs;
extern struct nouveau_ofuncs nv50_disp_curs_ofuncs;
extern struct nv50_disp_chan_impl nv50_disp_oimm_ofuncs;
int nv50_disp_oimm_ctor(struct nouveau_object *, struct nouveau_object *,
			struct nouveau_oclass *, void *, u32,
			struct nouveau_object **);
extern struct nv50_disp_chan_impl nv50_disp_curs_ofuncs;
int nv50_disp_curs_ctor(struct nouveau_object *, struct nouveau_object *,
			struct nouveau_oclass *, void *, u32,
			struct nouveau_object **);
extern struct nouveau_ofuncs nv50_disp_base_ofuncs;
int  nv50_disp_base_ctor(struct nouveau_object *, struct nouveau_object *,
			 struct nouveau_oclass *, void *, u32,
@@ -185,16 +204,16 @@ extern struct nouveau_omthds nv84_disp_base_omthds[];

extern const struct nv50_disp_mthd_chan nv94_disp_mast_mthd_chan;

extern struct nouveau_ofuncs nvd0_disp_mast_ofuncs;
extern struct nv50_disp_chan_impl nvd0_disp_mast_ofuncs;
extern const struct nv50_disp_mthd_list nvd0_disp_mast_mthd_base;
extern const struct nv50_disp_mthd_list nvd0_disp_mast_mthd_dac;
extern const struct nv50_disp_mthd_list nvd0_disp_mast_mthd_sor;
extern const struct nv50_disp_mthd_list nvd0_disp_mast_mthd_pior;
extern struct nouveau_ofuncs nvd0_disp_sync_ofuncs;
extern struct nouveau_ofuncs nvd0_disp_ovly_ofuncs;
extern struct nv50_disp_chan_impl nvd0_disp_sync_ofuncs;
extern struct nv50_disp_chan_impl nvd0_disp_ovly_ofuncs;
extern const struct nv50_disp_mthd_chan nvd0_disp_sync_mthd_chan;
extern struct nouveau_ofuncs nvd0_disp_oimm_ofuncs;
extern struct nouveau_ofuncs nvd0_disp_curs_ofuncs;
extern struct nv50_disp_chan_impl nvd0_disp_oimm_ofuncs;
extern struct nv50_disp_chan_impl nvd0_disp_curs_ofuncs;
extern struct nouveau_omthds nvd0_disp_base_omthds[];
extern struct nouveau_ofuncs nvd0_disp_base_ofuncs;
extern struct nouveau_oclass nvd0_disp_cclass;
+5 −5
Original line number Diff line number Diff line
@@ -204,11 +204,11 @@ nv84_disp_ovly_mthd_chan = {

static struct nouveau_oclass
nv84_disp_sclass[] = {
	{ NV84_DISP_MAST_CLASS, &nv50_disp_mast_ofuncs },
	{ NV84_DISP_SYNC_CLASS, &nv50_disp_sync_ofuncs },
	{ NV84_DISP_OVLY_CLASS, &nv50_disp_ovly_ofuncs },
	{ NV84_DISP_OIMM_CLASS, &nv50_disp_oimm_ofuncs },
	{ NV84_DISP_CURS_CLASS, &nv50_disp_curs_ofuncs },
	{ NV84_DISP_MAST_CLASS, &nv50_disp_mast_ofuncs.base },
	{ NV84_DISP_SYNC_CLASS, &nv50_disp_sync_ofuncs.base },
	{ NV84_DISP_OVLY_CLASS, &nv50_disp_ovly_ofuncs.base },
	{ NV84_DISP_OIMM_CLASS, &nv50_disp_oimm_ofuncs.base },
	{ NV84_DISP_CURS_CLASS, &nv50_disp_curs_ofuncs.base },
	{}
};

+5 −5
Original line number Diff line number Diff line
@@ -63,11 +63,11 @@ nv94_disp_mast_mthd_chan = {

static struct nouveau_oclass
nv94_disp_sclass[] = {
	{ NV94_DISP_MAST_CLASS, &nv50_disp_mast_ofuncs },
	{ NV94_DISP_SYNC_CLASS, &nv50_disp_sync_ofuncs },
	{ NV94_DISP_OVLY_CLASS, &nv50_disp_ovly_ofuncs },
	{ NV94_DISP_OIMM_CLASS, &nv50_disp_oimm_ofuncs },
	{ NV94_DISP_CURS_CLASS, &nv50_disp_curs_ofuncs },
	{ NV94_DISP_MAST_CLASS, &nv50_disp_mast_ofuncs.base },
	{ NV94_DISP_SYNC_CLASS, &nv50_disp_sync_ofuncs.base },
	{ NV94_DISP_OVLY_CLASS, &nv50_disp_ovly_ofuncs.base },
	{ NV94_DISP_OIMM_CLASS, &nv50_disp_oimm_ofuncs.base },
	{ NV94_DISP_CURS_CLASS, &nv50_disp_curs_ofuncs.base },
	{}
};

Loading