void nvkm_falcon_ctor(const struct nvkm_falcon_func *func, struct nvkm_subdev *subdev, const char *name, u32 addr, struct nvkm_falcon *falcon) { u32 reg; falcon->func = func; falcon->owner = subdev; falcon->name = name; falcon->addr = addr; mutex_init(&falcon->mutex); reg = nvkm_falcon_rd32(falcon, 0x12c); falcon->version = reg & 0xf; falcon->secret = (reg >> 4) & 0x3; falcon->code.ports = (reg >> 8) & 0xf; falcon->data.ports = (reg >> 12) & 0xf; reg = nvkm_falcon_rd32(falcon, 0x108); falcon->code.limit = (reg & 0x1ff) << 8; falcon->data.limit = (reg & 0x3fe00) >> 1; reg = nvkm_falcon_rd32(falcon, 0xc08); falcon->debug = (reg >> 20) & 0x1; }
int acr_ls_sec2_post_run(const struct nvkm_acr *acr, const struct nvkm_secboot *sb) { const struct nvkm_subdev *subdev = &sb->subdev; struct nvkm_device *device = subdev->device; struct nvkm_sec2 *sec = device->sec2; /* on SEC arguments are always at the beginning of EMEM */ const u32 addr_args = 0x01000000; u32 reg; int ret; ret = acr_ls_msgqueue_post_run(sec->queue, sec->falcon, addr_args); if (ret) return ret; /* * There is a bug where the LS firmware sometimes require to be started * twice (this happens only on SEC). Detect and workaround that * condition. * * Once started, the falcon will end up in STOPPED condition (bit 5) * if successful, or in HALT condition (bit 4) if not. */ nvkm_msec(device, 1, if ((reg = nvkm_falcon_rd32(sb->boot_falcon, 0x100) & 0x30) != 0) break; );