diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/falcon.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/falcon.h index 23b582d696c6..087ef96fc123 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/engine/falcon.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/falcon.h @@ -23,6 +23,8 @@ struct nvkm_falcon { struct mutex mutex; struct mutex dmem_mutex; + bool oneinit; + const struct nvkm_subdev *user; u8 version; diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/base.c b/drivers/gpu/drm/nouveau/nvkm/falcon/base.c index 366c87de6e72..3ed421058b08 100644 --- a/drivers/gpu/drm/nouveau/nvkm/falcon/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/falcon/base.c @@ -134,52 +134,13 @@ nvkm_falcon_clear_interrupt(struct nvkm_falcon *falcon, u32 mask) return falcon->func->clear_interrupt(falcon, mask); } -void -nvkm_falcon_put(struct nvkm_falcon *falcon, const struct nvkm_subdev *user) -{ - if (unlikely(!falcon)) - return; - - mutex_lock(&falcon->mutex); - if (falcon->user == user) { - nvkm_debug(falcon->user, "released %s falcon\n", falcon->name); - falcon->user = NULL; - } - mutex_unlock(&falcon->mutex); -} - -int -nvkm_falcon_get(struct nvkm_falcon *falcon, const struct nvkm_subdev *user) -{ - mutex_lock(&falcon->mutex); - if (falcon->user) { - nvkm_error(user, "%s falcon already acquired by %s!\n", - falcon->name, nvkm_subdev_name[falcon->user->index]); - mutex_unlock(&falcon->mutex); - return -EBUSY; - } - - nvkm_debug(user, "acquired %s falcon\n", falcon->name); - falcon->user = user; - mutex_unlock(&falcon->mutex); - return 0; -} - -void -nvkm_falcon_ctor(const struct nvkm_falcon_func *func, - struct nvkm_subdev *subdev, const char *name, u32 addr, - struct nvkm_falcon *falcon) +static int +nvkm_falcon_oneinit(struct nvkm_falcon *falcon) { + const struct nvkm_subdev *subdev = falcon->owner; u32 debug_reg; u32 reg; - falcon->func = func; - falcon->owner = subdev; - falcon->name = name; - falcon->addr = addr; - mutex_init(&falcon->mutex); - mutex_init(&falcon->dmem_mutex); - reg = nvkm_falcon_rd32(falcon, 0x12c); falcon->version = reg & 0xf; falcon->secret = (reg >> 4) & 0x3; @@ -218,6 +179,56 @@ nvkm_falcon_ctor(const struct nvkm_falcon_func *func, u32 val = nvkm_falcon_rd32(falcon, debug_reg); falcon->debug = (val >> 20) & 0x1; } + + return 0; +} + +void +nvkm_falcon_put(struct nvkm_falcon *falcon, const struct nvkm_subdev *user) +{ + if (unlikely(!falcon)) + return; + + mutex_lock(&falcon->mutex); + if (falcon->user == user) { + nvkm_debug(falcon->user, "released %s falcon\n", falcon->name); + falcon->user = NULL; + } + mutex_unlock(&falcon->mutex); +} + +int +nvkm_falcon_get(struct nvkm_falcon *falcon, const struct nvkm_subdev *user) +{ + int ret = 0; + + mutex_lock(&falcon->mutex); + if (falcon->user) { + nvkm_error(user, "%s falcon already acquired by %s!\n", + falcon->name, nvkm_subdev_name[falcon->user->index]); + mutex_unlock(&falcon->mutex); + return -EBUSY; + } + + nvkm_debug(user, "acquired %s falcon\n", falcon->name); + if (!falcon->oneinit) + ret = nvkm_falcon_oneinit(falcon); + falcon->user = user; + mutex_unlock(&falcon->mutex); + return ret; +} + +void +nvkm_falcon_ctor(const struct nvkm_falcon_func *func, + struct nvkm_subdev *subdev, const char *name, u32 addr, + struct nvkm_falcon *falcon) +{ + falcon->func = func; + falcon->owner = subdev; + falcon->name = name; + falcon->addr = addr; + mutex_init(&falcon->mutex); + mutex_init(&falcon->dmem_mutex); } void