Commit 78a43c7e authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nouveau/gr/gf100-: make global attrib_cb actually global



This was thought to be per-channel initially - it's not.  The backing
pages for the VMM mappings are shared for all channels.

- switches to more straight-forward patch interfaces
- prepares for sub-context support
- this is saving a *sizeable* amount of vram

v2:
- whitespace

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
Reviewed-by: default avatarLyude Paul <lyude@redhat.com>
parent 5eee9fdd
Loading
Loading
Loading
Loading
+26 −60
Original line number Diff line number Diff line
@@ -1003,45 +1003,6 @@ gf100_grctx_patch_wr32(struct gf100_gr_chan *chan, u32 addr, u32 data)
	nvkm_wo32(chan->mmio, chan->mmio_nr++ * 4, data);
}

int
gf100_grctx_mmio_data(struct gf100_grctx *info, u32 size, u32 align, bool priv)
{
	if (info->data) {
		info->buffer[info->buffer_nr] = round_up(info->addr, align);
		info->addr = info->buffer[info->buffer_nr] + size;
		info->data->size = size;
		info->data->align = align;
		info->data->priv = priv;
		info->data++;
		return info->buffer_nr++;
	}
	return -1;
}

void
gf100_grctx_mmio_item(struct gf100_grctx *info, u32 addr, u32 data,
		      int shift, int buffer)
{
	struct nvkm_device *device = info->gr->base.engine.subdev.device;
	if (info->data) {
		if (shift >= 0) {
			info->mmio->addr = addr;
			info->mmio->data = data;
			info->mmio->shift = shift;
			info->mmio->buffer = buffer;
			if (buffer >= 0)
				data |= info->buffer[buffer] >> shift;
			info->mmio++;
		} else
			return;
	} else {
		if (buffer >= 0)
			return;
	}

	nvkm_wr32(device, addr, data);
}

void
gf100_grctx_generate_r419cb8(struct gf100_gr *gr)
{
@@ -1068,31 +1029,41 @@ gf100_grctx_generate_pagepool(struct gf100_gr_chan *chan, u64 addr)
}

void
gf100_grctx_generate_attrib(struct gf100_grctx *info)
gf100_grctx_generate_attrib(struct gf100_gr_chan *chan)
{
	struct gf100_gr *gr = info->gr;
	struct gf100_gr *gr = chan->gr;
	const struct gf100_grctx_func *grctx = gr->func->grctx;
	const u32 attrib = grctx->attrib_nr;
	const u32   size = 0x20 * (grctx->attrib_nr_max + grctx->alpha_nr_max);
	const int s = 12;
	const int b = mmio_vram(info, size * gr->tpc_total, (1 << s), false);
	int gpc, tpc;
	u32 bo = 0;

	mmio_refn(info, 0x418810, 0x80000000, s, b);
	mmio_refn(info, 0x419848, 0x10000000, s, b);
	mmio_wr32(info, 0x405830, (attrib << 16));
	gf100_grctx_patch_wr32(chan, 0x405830, (attrib << 16));

	for (gpc = 0; gpc < gr->gpc_nr; gpc++) {
		for (tpc = 0; tpc < gr->tpc_nr[gpc]; tpc++) {
			const u32 o = TPC_UNIT(gpc, tpc, 0x0520);
			mmio_skip(info, o, (attrib << 16) | ++bo);
			mmio_wr32(info, o, (attrib << 16) | --bo);

			gf100_grctx_patch_wr32(chan, o, (attrib << 16) | bo);
			bo += grctx->attrib_nr_max;
		}
	}
}

void
gf100_grctx_generate_attrib_cb(struct gf100_gr_chan *chan, u64 addr, u32 size)
{
	gf100_grctx_patch_wr32(chan, 0x418810, 0x80000000 | addr >> 12);
	gf100_grctx_patch_wr32(chan, 0x419848, 0x10000000 | addr >> 12);
}

u32
gf100_grctx_generate_attrib_cb_size(struct gf100_gr *gr)
{
	const struct gf100_grctx_func *grctx = gr->func->grctx;

	return 0x20 * (grctx->attrib_nr_max + grctx->alpha_nr_max) * gr->tpc_total;
}

void
gf100_grctx_generate_unkn(struct gf100_gr *gr)
{
@@ -1368,7 +1339,7 @@ gf100_grctx_generate_floorsweep(struct gf100_gr *gr)
}

void
gf100_grctx_generate_main(struct gf100_gr_chan *chan, struct gf100_grctx *info)
gf100_grctx_generate_main(struct gf100_gr_chan *chan)
{
	struct gf100_gr *gr = chan->gr;
	struct nvkm_device *device = gr->base.engine.subdev.device;
@@ -1394,7 +1365,8 @@ gf100_grctx_generate_main(struct gf100_gr_chan *chan, struct gf100_grctx *info)

	grctx->pagepool(chan, chan->pagepool->addr);
	grctx->bundle(chan, chan->bundle_cb->addr, grctx->bundle_size);
	grctx->attrib(info);
	grctx->attrib_cb(chan, chan->attrib_cb->addr, grctx->attrib_cb_size(gr));
	grctx->attrib(chan);
	if (grctx->patch_ltc)
		grctx->patch_ltc(chan);
	if (grctx->unknown_size)
@@ -1450,7 +1422,6 @@ gf100_grctx_generate(struct gf100_gr *gr, struct gf100_gr_chan *chan, struct nvk
	struct nvkm_device *device = subdev->device;
	struct nvkm_memory *data = NULL;
	struct nvkm_vma *ctx = NULL;
	struct gf100_grctx info;
	int ret, i;
	u64 addr;

@@ -1500,13 +1471,6 @@ gf100_grctx_generate(struct gf100_gr *gr, struct gf100_gr_chan *chan, struct nvk
	nvkm_wo32(inst, 0x0214, upper_32_bits(ctx->addr + CB_RESERVED));
	nvkm_done(inst);

	/* Setup default state for mmio list construction. */
	info.gr = gr;
	info.data = gr->mmio_data;
	info.mmio = gr->mmio_list;
	info.addr = ctx->addr;
	info.buffer_nr = 0;

	/* Make channel current. */
	addr = inst->addr >> 12;
	if (gr->firmware) {
@@ -1530,7 +1494,7 @@ gf100_grctx_generate(struct gf100_gr *gr, struct gf100_gr_chan *chan, struct nvk
		);
	}

	grctx->main(chan, &info);
	grctx->main(chan);

	/* Trigger a context unload by unsetting the "next channel valid" bit
	 * and faking a context switch interrupt.
@@ -1582,6 +1546,8 @@ gf100_grctx = {
	.bundle_size = 0x1800,
	.pagepool = gf100_grctx_generate_pagepool,
	.pagepool_size = 0x8000,
	.attrib_cb_size = gf100_grctx_generate_attrib_cb_size,
	.attrib_cb = gf100_grctx_generate_attrib_cb,
	.attrib = gf100_grctx_generate_attrib,
	.attrib_nr_max = 0x324,
	.attrib_nr = 0x218,
+17 −25
Original line number Diff line number Diff line
@@ -3,28 +3,12 @@
#define __NVKM_GRCTX_NVC0_H__
#include "gf100.h"

struct gf100_grctx {
	struct gf100_gr *gr;
	struct gf100_gr_data *data;
	struct gf100_gr_mmio *mmio;
	int buffer_nr;
	u64 buffer[4];
	u64 addr;
};

int  gf100_grctx_mmio_data(struct gf100_grctx *, u32 size, u32 align, bool priv);
void gf100_grctx_mmio_item(struct gf100_grctx *, u32 addr, u32 data, int s, int);
void gf100_grctx_patch_wr32(struct gf100_gr_chan *, u32 addr, u32 data);

#define mmio_vram(a,b,c,d) gf100_grctx_mmio_data((a), (b), (c), (d))
#define mmio_refn(a,b,c,d,e) gf100_grctx_mmio_item((a), (b), (c), (d), (e))
#define mmio_skip(a,b,c) mmio_refn((a), (b), (c), -1, -1)
#define mmio_wr32(a,b,c) mmio_refn((a), (b), (c),  0, -1)

struct gf100_grctx_func {
	void (*unkn88c)(struct gf100_gr *, bool on);
	/* main context generation function */
	void  (*main)(struct gf100_gr_chan *, struct gf100_grctx *);
	void  (*main)(struct gf100_gr_chan *);
	/* context-specific modify-on-first-load list generation function */
	void  (*unkn)(struct gf100_gr *);
	/* mmio context data */
@@ -47,7 +31,9 @@ struct gf100_grctx_func {
	void (*pagepool)(struct gf100_gr_chan *, u64 addr);
	u32 pagepool_size;
	/* attribute(/alpha) circular buffer */
	void (*attrib)(struct gf100_grctx *);
	u32 (*attrib_cb_size)(struct gf100_gr *);
	void (*attrib_cb)(struct gf100_gr_chan *, u64 addr, u32 size);
	void (*attrib)(struct gf100_gr_chan *);
	u32 attrib_nr_max;
	u32 attrib_nr;
	u32 alpha_nr_max;
@@ -86,10 +72,12 @@ struct gf100_grctx_func {

extern const struct gf100_grctx_func gf100_grctx;
int  gf100_grctx_generate(struct gf100_gr *, struct gf100_gr_chan *, struct nvkm_gpuobj *inst);
void gf100_grctx_generate_main(struct gf100_gr_chan *, struct gf100_grctx *);
void gf100_grctx_generate_main(struct gf100_gr_chan *);
void gf100_grctx_generate_pagepool(struct gf100_gr_chan *, u64);
void gf100_grctx_generate_bundle(struct gf100_gr_chan *, u64, u32);
void gf100_grctx_generate_attrib(struct gf100_grctx *);
u32 gf100_grctx_generate_attrib_cb_size(struct gf100_gr *);
void gf100_grctx_generate_attrib_cb(struct gf100_gr_chan *, u64, u32);
void gf100_grctx_generate_attrib(struct gf100_gr_chan *);
void gf100_grctx_generate_unkn(struct gf100_gr *);
void gf100_grctx_generate_floorsweep(struct gf100_gr *);
void gf100_grctx_generate_sm_id(struct gf100_gr *, int, int, int);
@@ -101,14 +89,14 @@ void gf100_grctx_generate_max_ways_evict(struct gf100_gr *);
void gf100_grctx_generate_r419cb8(struct gf100_gr *);

extern const struct gf100_grctx_func gf108_grctx;
void gf108_grctx_generate_attrib(struct gf100_grctx *);
void gf108_grctx_generate_attrib(struct gf100_gr_chan *);
void gf108_grctx_generate_unkn(struct gf100_gr *);

extern const struct gf100_grctx_func gf104_grctx;
extern const struct gf100_grctx_func gf110_grctx;

extern const struct gf100_grctx_func gf117_grctx;
void gf117_grctx_generate_attrib(struct gf100_grctx *);
void gf117_grctx_generate_attrib(struct gf100_gr_chan *);
void gf117_grctx_generate_rop_mapping(struct gf100_gr *);
void gf117_grctx_generate_dist_skip_table(struct gf100_gr *);

@@ -134,7 +122,8 @@ extern const struct gf100_grctx_func gk208_grctx;
extern const struct gf100_grctx_func gm107_grctx;
void gm107_grctx_generate_pagepool(struct gf100_gr_chan *, u64);
void gm107_grctx_generate_bundle(struct gf100_gr_chan *, u64, u32);
void gm107_grctx_generate_attrib(struct gf100_grctx *);
void gm107_grctx_generate_attrib_cb(struct gf100_gr_chan *, u64, u32);
void gm107_grctx_generate_attrib(struct gf100_gr_chan *);
void gm107_grctx_generate_sm_id(struct gf100_gr *, int, int, int);

extern const struct gf100_grctx_func gm200_grctx;
@@ -148,10 +137,12 @@ extern const struct gf100_grctx_func gm20b_grctx;

extern const struct gf100_grctx_func gp100_grctx;
void gp100_grctx_generate_pagepool(struct gf100_gr_chan *, u64);
void gp100_grctx_generate_attrib_cb(struct gf100_gr_chan *, u64, u32);
void gp100_grctx_generate_smid_config(struct gf100_gr *);

extern const struct gf100_grctx_func gp102_grctx;
void gp102_grctx_generate_attrib(struct gf100_grctx *);
u32 gp102_grctx_generate_attrib_cb_size(struct gf100_gr *);
void gp102_grctx_generate_attrib(struct gf100_gr_chan *);

extern const struct gf100_grctx_func gp104_grctx;

@@ -163,7 +154,8 @@ extern const struct gf100_grctx_func tu102_grctx;
void gv100_grctx_unkn88c(struct gf100_gr *, bool);
void gv100_grctx_generate_unkn(struct gf100_gr *);
extern const struct gf100_gr_init gv100_grctx_init_sw_veid_bundle_init_0[];
void gv100_grctx_generate_attrib(struct gf100_grctx *);
void gv100_grctx_generate_attrib_cb(struct gf100_gr_chan *, u64, u32);
void gv100_grctx_generate_attrib(struct gf100_gr_chan *);
void gv100_grctx_generate_rop_mapping(struct gf100_gr *);
void gv100_grctx_generate_r400088(struct gf100_gr *, bool);

+2 −0
Original line number Diff line number Diff line
@@ -94,6 +94,8 @@ gf104_grctx = {
	.bundle_size = 0x1800,
	.pagepool = gf100_grctx_generate_pagepool,
	.pagepool_size = 0x8000,
	.attrib_cb_size = gf100_grctx_generate_attrib_cb_size,
	.attrib_cb = gf100_grctx_generate_attrib_cb,
	.attrib = gf100_grctx_generate_attrib,
	.attrib_nr_max = 0x324,
	.attrib_nr = 0x218,
+9 −12
Original line number Diff line number Diff line
@@ -733,25 +733,20 @@ gf108_grctx_pack_tpc[] = {
 ******************************************************************************/

void
gf108_grctx_generate_attrib(struct gf100_grctx *info)
gf108_grctx_generate_attrib(struct gf100_gr_chan *chan)
{
	struct gf100_gr *gr = info->gr;
	struct gf100_gr *gr = chan->gr;
	const struct gf100_grctx_func *grctx = gr->func->grctx;
	const u32  alpha = grctx->alpha_nr;
	const u32   beta = grctx->attrib_nr;
	const u32   size = 0x20 * (grctx->attrib_nr_max + grctx->alpha_nr_max);
	const int s = 12;
	const int b = mmio_vram(info, size * gr->tpc_total, (1 << s), false);
	const int timeslice_mode = 1;
	const int max_batches = 0xffff;
	u32 bo = 0;
	u32 ao = bo + grctx->attrib_nr_max * gr->tpc_total;
	int gpc, tpc;

	mmio_refn(info, 0x418810, 0x80000000, s, b);
	mmio_refn(info, 0x419848, 0x10000000, s, b);
	mmio_wr32(info, 0x405830, (beta << 16) | alpha);
	mmio_wr32(info, 0x4064c4, ((alpha / 4) << 16) | max_batches);
	gf100_grctx_patch_wr32(chan, 0x405830, (beta << 16) | alpha);
	gf100_grctx_patch_wr32(chan, 0x4064c4, ((alpha / 4) << 16) | max_batches);

	for (gpc = 0; gpc < gr->gpc_nr; gpc++) {
		for (tpc = 0; tpc < gr->tpc_nr[gpc]; tpc++) {
@@ -759,10 +754,10 @@ gf108_grctx_generate_attrib(struct gf100_grctx *info)
			const u32 b =  beta;
			const u32 t = timeslice_mode;
			const u32 o = TPC_UNIT(gpc, tpc, 0x500);
			mmio_skip(info, o + 0x20, (t << 28) | (b << 16) | ++bo);
			mmio_wr32(info, o + 0x20, (t << 28) | (b << 16) | --bo);

			gf100_grctx_patch_wr32(chan, o + 0x20, (t << 28) | (b << 16) | bo);
			bo += grctx->attrib_nr_max;
			mmio_wr32(info, o + 0x44, (a << 16) | ao);
			gf100_grctx_patch_wr32(chan, o + 0x44, (a << 16) | ao);
			ao += grctx->alpha_nr_max;
		}
	}
@@ -795,6 +790,8 @@ gf108_grctx = {
	.bundle_size = 0x1800,
	.pagepool = gf100_grctx_generate_pagepool,
	.pagepool_size = 0x8000,
	.attrib_cb_size = gf100_grctx_generate_attrib_cb_size,
	.attrib_cb = gf100_grctx_generate_attrib_cb,
	.attrib = gf108_grctx_generate_attrib,
	.attrib_nr_max = 0x324,
	.attrib_nr = 0x218,
+2 −0
Original line number Diff line number Diff line
@@ -342,6 +342,8 @@ gf110_grctx = {
	.bundle_size = 0x1800,
	.pagepool = gf100_grctx_generate_pagepool,
	.pagepool_size = 0x8000,
	.attrib_cb_size = gf100_grctx_generate_attrib_cb_size,
	.attrib_cb = gf100_grctx_generate_attrib_cb,
	.attrib = gf100_grctx_generate_attrib,
	.attrib_nr_max = 0x324,
	.attrib_nr = 0x218,
Loading