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); ...@@ -223,6 +223,9 @@ void gm107_gr_init_shader_exceptions(struct gf100_gr *, int, int);
void gm107_gr_init_400054(struct gf100_gr *); void gm107_gr_init_400054(struct gf100_gr *);
int gk20a_gr_init(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_tiles(struct gf100_gr *);
void gm200_gr_oneinit_sm_id(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 *); ...@@ -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 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_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_nofw(struct gf100_gr *, int, const struct gf100_gr_fwif *);
int gm200_gr_load(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 ...@@ -33,35 +33,25 @@ struct gk20a_fw_av
u32 data; u32 data;
}; };
static int int
gk20a_gr_av_to_init(struct gf100_gr *gr, const char *path, const char *name, gk20a_gr_av_to_init(struct nvkm_blob *blob, struct gf100_gr_pack **ppack)
int ver, 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_init *init;
struct gf100_gr_pack *pack; struct gf100_gr_pack *pack;
int nent; int nent;
int ret;
int i; int i;
ret = nvkm_firmware_load_blob(subdev, path, name, ver, &blob); nent = (blob->size / sizeof(struct gk20a_fw_av));
if (ret)
return ret;
nent = (blob.size / sizeof(struct gk20a_fw_av));
pack = vzalloc((sizeof(*pack) * 2) + (sizeof(*init) * (nent + 1))); pack = vzalloc((sizeof(*pack) * 2) + (sizeof(*init) * (nent + 1)));
if (!pack) { if (!pack)
ret = -ENOMEM; return -ENOMEM;
goto end;
}
init = (void *)(pack + 2); init = (void *)(pack + 2);
pack[0].init = init; pack[0].init = init;
for (i = 0; i < nent; i++) { for (i = 0; i < nent; i++) {
struct gf100_gr_init *ent = &init[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->addr = av->addr;
ent->data = av->data; ent->data = av->data;
...@@ -70,10 +60,7 @@ gk20a_gr_av_to_init(struct gf100_gr *gr, const char *path, const char *name, ...@@ -70,10 +60,7 @@ gk20a_gr_av_to_init(struct gf100_gr *gr, const char *path, const char *name,
} }
*ppack = pack; *ppack = pack;
return 0;
end:
nvkm_blob_dtor(&blob);
return ret;
} }
struct gk20a_fw_aiv struct gk20a_fw_aiv
...@@ -83,35 +70,25 @@ struct gk20a_fw_aiv ...@@ -83,35 +70,25 @@ struct gk20a_fw_aiv
u32 data; u32 data;
}; };
static int int
gk20a_gr_aiv_to_init(struct gf100_gr *gr, const char *path, const char *name, gk20a_gr_aiv_to_init(struct nvkm_blob *blob, struct gf100_gr_pack **ppack)
int ver, 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_init *init;
struct gf100_gr_pack *pack; struct gf100_gr_pack *pack;
int nent; int nent;
int ret;
int i; int i;
ret = nvkm_firmware_load_blob(subdev, path, name, ver, &blob); nent = (blob->size / sizeof(struct gk20a_fw_aiv));
if (ret)
return ret;
nent = (blob.size / sizeof(struct gk20a_fw_aiv));
pack = vzalloc((sizeof(*pack) * 2) + (sizeof(*init) * (nent + 1))); pack = vzalloc((sizeof(*pack) * 2) + (sizeof(*init) * (nent + 1)));
if (!pack) { if (!pack)
ret = -ENOMEM; return -ENOMEM;
goto end;
}
init = (void *)(pack + 2); init = (void *)(pack + 2);
pack[0].init = init; pack[0].init = init;
for (i = 0; i < nent; i++) { for (i = 0; i < nent; i++) {
struct gf100_gr_init *ent = &init[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->addr = av->addr;
ent->data = av->data; ent->data = av->data;
...@@ -120,44 +97,30 @@ gk20a_gr_aiv_to_init(struct gf100_gr *gr, const char *path, const char *name, ...@@ -120,44 +97,30 @@ gk20a_gr_aiv_to_init(struct gf100_gr *gr, const char *path, const char *name,
} }
*ppack = pack; *ppack = pack;
return 0;
end:
nvkm_blob_dtor(&blob);
return ret;
} }
static int int
gk20a_gr_av_to_method(struct gf100_gr *gr, const char *path, const char *name, gk20a_gr_av_to_method(struct nvkm_blob *blob, struct gf100_gr_pack **ppack)
int ver, 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_init *init;
struct gf100_gr_pack *pack; struct gf100_gr_pack *pack;
/* We don't suppose we will initialize more than 16 classes here... */ /* We don't suppose we will initialize more than 16 classes here... */
static const unsigned int max_classes = 16; static const unsigned int max_classes = 16;
u32 classidx = 0, prevclass = 0; u32 classidx = 0, prevclass = 0;
int nent; int nent;
int ret;
int i; int i;
ret = nvkm_firmware_load_blob(subdev, path, name, ver, &blob); nent = (blob->size / sizeof(struct gk20a_fw_av));
if (ret)
return ret;
nent = (blob.size / sizeof(struct gk20a_fw_av));
pack = vzalloc((sizeof(*pack) * (max_classes + 1)) + pack = vzalloc((sizeof(*pack) * (max_classes + 1)) +
(sizeof(*init) * (nent + max_classes + 1))); (sizeof(*init) * (nent + max_classes + 1)));
if (!pack) { if (!pack)
ret = -ENOMEM; return -ENOMEM;
goto end;
}
init = (void *)(pack + max_classes + 1); init = (void *)(pack + max_classes + 1);
for (i = 0; i < nent; i++, init++) { 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 class = av->addr & 0xffff;
u32 addr = (av->addr & 0xffff0000) >> 14; 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, ...@@ -169,8 +132,7 @@ gk20a_gr_av_to_method(struct gf100_gr *gr, const char *path, const char *name,
prevclass = class; prevclass = class;
if (++classidx >= max_classes) { if (++classidx >= max_classes) {
vfree(pack); vfree(pack);
ret = -ENOSPC; return -ENOSPC;
goto end;
} }
} }
...@@ -181,10 +143,7 @@ gk20a_gr_av_to_method(struct gf100_gr *gr, const char *path, const char *name, ...@@ -181,10 +143,7 @@ gk20a_gr_av_to_method(struct gf100_gr *gr, const char *path, const char *name,
} }
*ppack = pack; *ppack = pack;
return 0;
end:
nvkm_blob_dtor(&blob);
return ret;
} }
static int static int
...@@ -308,13 +267,30 @@ gk20a_gr = { ...@@ -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 int
gk20a_gr_load_sw(struct gf100_gr *gr, const char *path, int ver) 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) || if (gk20a_gr_load_net(gr, path, "sw_nonctx", ver, gk20a_gr_av_to_init, &gr->sw_nonctx) ||
gk20a_gr_aiv_to_init(gr, path, "sw_ctx", ver, &gr->sw_ctx) || gk20a_gr_load_net(gr, path, "sw_ctx", ver, gk20a_gr_aiv_to_init, &gr->sw_ctx) ||
gk20a_gr_av_to_init(gr, path, "sw_bundle_init", ver, &gr->bundle) || gk20a_gr_load_net(gr, path, "sw_bundle_init", ver, gk20a_gr_av_to_init, &gr->bundle) ||
gk20a_gr_av_to_method(gr, path, "sw_method_init", ver, &gr->method)) gk20a_gr_load_net(gr, path, "sw_method_init", ver, gk20a_gr_av_to_method, &gr->method))
return -ENOENT; return -ENOENT;
return 0; 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