Commit de8be616 authored by Ben Skeggs's avatar Ben Skeggs

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
......@@ -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 *);
......
......@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment