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

drm/nouveau/gr/gk20a,gm20b,gp10b: split out netlist parsing from fw loading



We'll want to reuse the former for loading from proper netlist images.

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
Reviewed-by: default avatarLyude Paul <lyude@redhat.com>
parent e2eeec75
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -223,6 +223,9 @@ void gm107_gr_init_shader_exceptions(struct gf100_gr *, int, int);
void gm107_gr_init_400054(struct gf100_gr *);

int gk20a_gr_init(struct gf100_gr *);
int gk20a_gr_av_to_init(struct nvkm_blob *, struct gf100_gr_pack **);
int gk20a_gr_aiv_to_init(struct nvkm_blob *, struct gf100_gr_pack **);
int gk20a_gr_av_to_method(struct nvkm_blob *, struct gf100_gr_pack **);

void gm200_gr_oneinit_tiles(struct gf100_gr *);
void gm200_gr_oneinit_sm_id(struct gf100_gr *);
@@ -400,6 +403,9 @@ int gf100_gr_load(struct gf100_gr *, int, const struct gf100_gr_fwif *);
int gf100_gr_nofw(struct gf100_gr *, int, const struct gf100_gr_fwif *);

int gk20a_gr_load_sw(struct gf100_gr *, const char *path, int ver);
int gk20a_gr_load_net(struct gf100_gr *, const char *, const char *, int,
		      int (*)(struct nvkm_blob *, struct gf100_gr_pack **),
		      struct gf100_gr_pack **);

int gm200_gr_nofw(struct gf100_gr *, int, const struct gf100_gr_fwif *);
int gm200_gr_load(struct gf100_gr *, int, const struct gf100_gr_fwif *);
+43 −67
Original line number Diff line number Diff line
@@ -33,35 +33,25 @@ struct gk20a_fw_av
	u32 data;
};

static int
gk20a_gr_av_to_init(struct gf100_gr *gr, const char *path, const char *name,
		    int ver, struct gf100_gr_pack **ppack)
int
gk20a_gr_av_to_init(struct nvkm_blob *blob, struct gf100_gr_pack **ppack)
{
	struct nvkm_subdev *subdev = &gr->base.engine.subdev;
	struct nvkm_blob blob;
	struct gf100_gr_init *init;
	struct gf100_gr_pack *pack;
	int nent;
	int ret;
	int i;

	ret = nvkm_firmware_load_blob(subdev, path, name, ver, &blob);
	if (ret)
		return ret;

	nent = (blob.size / sizeof(struct gk20a_fw_av));
	nent = (blob->size / sizeof(struct gk20a_fw_av));
	pack = vzalloc((sizeof(*pack) * 2) + (sizeof(*init) * (nent + 1)));
	if (!pack) {
		ret = -ENOMEM;
		goto end;
	}
	if (!pack)
		return -ENOMEM;

	init = (void *)(pack + 2);
	pack[0].init = init;

	for (i = 0; i < nent; i++) {
		struct gf100_gr_init *ent = &init[i];
		struct gk20a_fw_av *av = &((struct gk20a_fw_av *)blob.data)[i];
		struct gk20a_fw_av *av = &((struct gk20a_fw_av *)blob->data)[i];

		ent->addr = av->addr;
		ent->data = av->data;
@@ -70,10 +60,7 @@ gk20a_gr_av_to_init(struct gf100_gr *gr, const char *path, const char *name,
	}

	*ppack = pack;

end:
	nvkm_blob_dtor(&blob);
	return ret;
	return 0;
}

struct gk20a_fw_aiv
@@ -83,35 +70,25 @@ struct gk20a_fw_aiv
	u32 data;
};

static int
gk20a_gr_aiv_to_init(struct gf100_gr *gr, const char *path, const char *name,
		     int ver, struct gf100_gr_pack **ppack)
int
gk20a_gr_aiv_to_init(struct nvkm_blob *blob, struct gf100_gr_pack **ppack)
{
	struct nvkm_subdev *subdev = &gr->base.engine.subdev;
	struct nvkm_blob blob;
	struct gf100_gr_init *init;
	struct gf100_gr_pack *pack;
	int nent;
	int ret;
	int i;

	ret = nvkm_firmware_load_blob(subdev, path, name, ver, &blob);
	if (ret)
		return ret;

	nent = (blob.size / sizeof(struct gk20a_fw_aiv));
	nent = (blob->size / sizeof(struct gk20a_fw_aiv));
	pack = vzalloc((sizeof(*pack) * 2) + (sizeof(*init) * (nent + 1)));
	if (!pack) {
		ret = -ENOMEM;
		goto end;
	}
	if (!pack)
		return -ENOMEM;

	init = (void *)(pack + 2);
	pack[0].init = init;

	for (i = 0; i < nent; i++) {
		struct gf100_gr_init *ent = &init[i];
		struct gk20a_fw_aiv *av = &((struct gk20a_fw_aiv *)blob.data)[i];
		struct gk20a_fw_aiv *av = &((struct gk20a_fw_aiv *)blob->data)[i];

		ent->addr = av->addr;
		ent->data = av->data;
@@ -120,44 +97,30 @@ gk20a_gr_aiv_to_init(struct gf100_gr *gr, const char *path, const char *name,
	}

	*ppack = pack;

end:
	nvkm_blob_dtor(&blob);
	return ret;
	return 0;
}

static int
gk20a_gr_av_to_method(struct gf100_gr *gr, const char *path, const char *name,
		      int ver, struct gf100_gr_pack **ppack)
int
gk20a_gr_av_to_method(struct nvkm_blob *blob, struct gf100_gr_pack **ppack)
{
	struct nvkm_subdev *subdev = &gr->base.engine.subdev;
	struct nvkm_blob blob;
	struct gf100_gr_init *init;
	struct gf100_gr_pack *pack;
	/* We don't suppose we will initialize more than 16 classes here... */
	static const unsigned int max_classes = 16;
	u32 classidx = 0, prevclass = 0;
	int nent;
	int ret;
	int i;

	ret = nvkm_firmware_load_blob(subdev, path, name, ver, &blob);
	if (ret)
		return ret;

	nent = (blob.size / sizeof(struct gk20a_fw_av));

	nent = (blob->size / sizeof(struct gk20a_fw_av));
	pack = vzalloc((sizeof(*pack) * (max_classes + 1)) +
		       (sizeof(*init) * (nent + max_classes + 1)));
	if (!pack) {
		ret = -ENOMEM;
		goto end;
	}
	if (!pack)
		return -ENOMEM;

	init = (void *)(pack + max_classes + 1);

	for (i = 0; i < nent; i++, init++) {
		struct gk20a_fw_av *av = &((struct gk20a_fw_av *)blob.data)[i];
		struct gk20a_fw_av *av = &((struct gk20a_fw_av *)blob->data)[i];
		u32 class = av->addr & 0xffff;
		u32 addr = (av->addr & 0xffff0000) >> 14;

@@ -169,8 +132,7 @@ gk20a_gr_av_to_method(struct gf100_gr *gr, const char *path, const char *name,
			prevclass = class;
			if (++classidx >= max_classes) {
				vfree(pack);
				ret = -ENOSPC;
				goto end;
				return -ENOSPC;
			}
		}

@@ -181,10 +143,7 @@ gk20a_gr_av_to_method(struct gf100_gr *gr, const char *path, const char *name,
	}

	*ppack = pack;

end:
	nvkm_blob_dtor(&blob);
	return ret;
	return 0;
}

static int
@@ -308,13 +267,30 @@ gk20a_gr = {
	}
};

int
gk20a_gr_load_net(struct gf100_gr *gr, const char *path, const char *name, int ver,
		  int (*load)(struct nvkm_blob *, struct gf100_gr_pack **),
		  struct gf100_gr_pack **ppack)
{
	struct nvkm_blob blob;
	int ret;

	ret = nvkm_firmware_load_blob(&gr->base.engine.subdev, path, name, ver, &blob);
	if (ret)
		return ret;

	ret = load(&blob, ppack);
	nvkm_blob_dtor(&blob);
	return 0;
}

int
gk20a_gr_load_sw(struct gf100_gr *gr, const char *path, int ver)
{
	if (gk20a_gr_av_to_init(gr, path, "sw_nonctx", ver, &gr->sw_nonctx) ||
	    gk20a_gr_aiv_to_init(gr, path, "sw_ctx", ver, &gr->sw_ctx) ||
	    gk20a_gr_av_to_init(gr, path, "sw_bundle_init", ver, &gr->bundle) ||
	    gk20a_gr_av_to_method(gr, path, "sw_method_init", ver, &gr->method))
	if (gk20a_gr_load_net(gr, path, "sw_nonctx", ver, gk20a_gr_av_to_init, &gr->sw_nonctx) ||
	    gk20a_gr_load_net(gr, path, "sw_ctx", ver, gk20a_gr_aiv_to_init, &gr->sw_ctx) ||
	    gk20a_gr_load_net(gr, path, "sw_bundle_init", ver, gk20a_gr_av_to_init, &gr->bundle) ||
	    gk20a_gr_load_net(gr, path, "sw_method_init", ver, gk20a_gr_av_to_method, &gr->method))
		return -ENOENT;

	return 0;